From 777c36005bdcdc09e1813a84f3f2c0acc0b47fac Mon Sep 17 00:00:00 2001 From: emeric Date: Fri, 13 Sep 2024 23:27:53 +0200 Subject: [PATCH] Do not use pipe2 to make code more portable, ref #514 --- src/libs/core/impl/ChildProcess.cpp | 39 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/libs/core/impl/ChildProcess.cpp b/src/libs/core/impl/ChildProcess.cpp index d2956a3d..599bd16b 100644 --- a/src/libs/core/impl/ChildProcess.cpp +++ b/src/libs/core/impl/ChildProcess.cpp @@ -66,36 +66,49 @@ namespace lms::core static std::mutex mutex; std::unique_lock lock{ mutex }; - int pipe[2]; + int pipefd[2]; - int res{ pipe2(pipe, O_NONBLOCK | O_CLOEXEC) }; - if (res < 0) - throw SystemException{ errno, "pipe2 failed!" }; + // Use 'pipe' instead of 'pipe2', more portable + if (pipe(pipefd) < 0) + throw SystemException{ errno, "pipe failed!" }; + + // Manually set the O_NONBLOCK and O_CLOEXEC flags for both ends of the pipe + if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1) + throw SystemException{ errno, "fcntl failed to set O_NONBLOCK!" }; + + if (fcntl(pipefd[1], F_SETFL, O_NONBLOCK) == -1) + throw SystemException{ errno, "fcntl failed to set O_NONBLOCK!" }; + + if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) == -1) + throw SystemException{ errno, "fcntl failed to set FD_CLOEXEC!" }; + + if (fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1) + throw SystemException{ errno, "fcntl failed to set FD_CLOEXEC!" }; - { #if defined(__linux__) && defined(F_SETPIPE_SZ) + { // Just a hint here to prevent the writer from writing too many bytes ahead of the reader constexpr std::size_t pipeSize{ 65536 * 4 }; - if (fcntl(pipe[0], F_SETPIPE_SZ, pipeSize) == -1) + if (fcntl(pipefd[0], F_SETPIPE_SZ, pipeSize) == -1) throw SystemException{ errno, "fcntl failed!" }; - if (fcntl(pipe[1], F_SETPIPE_SZ, pipeSize) == -1) + if (fcntl(pipefd[1], F_SETPIPE_SZ, pipeSize) == -1) throw SystemException{ errno, "fcntl failed!" }; -#endif } +#endif - res = fork(); + int res{ fork() }; if (res == -1) throw SystemException{ errno, "fork failed!" }; if (res == 0) // CHILD { - close(pipe[0]); + close(pipefd[0]); close(STDIN_FILENO); close(STDERR_FILENO); // Replace stdout with pipe write - if (dup2(pipe[1], STDOUT_FILENO) == -1) + if (dup2(pipefd[1], STDOUT_FILENO) == -1) exit(-1); std::vector execArgs; @@ -108,10 +121,10 @@ namespace lms::core } else // PARENT { - close(pipe[1]); + close(pipefd[1]); { boost::system::error_code assignError; - _childStdout.assign(pipe[0], assignError); + _childStdout.assign(pipefd[0], assignError); if (assignError) throw SystemException{ assignError, "fork failed!" }; }