diff --git a/src/ProcessPosix.cpp b/src/ProcessPosix.cpp index 1ca61b5..bf20916 100644 --- a/src/ProcessPosix.cpp +++ b/src/ProcessPosix.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,24 @@ namespace vix::engine::process ::close(fd); } + static void write_child_error_code_or_exit(int fd, int code) noexcept + { + const auto *bytes = reinterpret_cast(&code); + std::size_t offset = 0; + while (offset < sizeof(code)) + { + const ssize_t written = ::write(fd, bytes + offset, sizeof(code) - offset); + if (written > 0) + { + offset += static_cast(written); + continue; + } + if (written < 0 && errno == EINTR) + continue; + _exit(127); + } + } + static bool set_close_on_exec(int fd) noexcept { const int flags = ::fcntl(fd, F_GETFD); @@ -238,7 +257,7 @@ namespace vix::engine::process if (::dup2(stdoutPipe[1], STDOUT_FILENO) < 0) { const int code = errno; - (void)::write(errorPipe[1], &code, sizeof(code)); + write_child_error_code_or_exit(errorPipe[1], code); _exit(127); } @@ -247,7 +266,7 @@ namespace vix::engine::process if (::dup2(stdoutPipe[1], STDERR_FILENO) < 0) { const int code = errno; - (void)::write(errorPipe[1], &code, sizeof(code)); + write_child_error_code_or_exit(errorPipe[1], code); _exit(127); } } @@ -257,7 +276,7 @@ namespace vix::engine::process if (::dup2(stderrPipe[1], STDERR_FILENO) < 0) { const int code = errno; - (void)::write(errorPipe[1], &code, sizeof(code)); + write_child_error_code_or_exit(errorPipe[1], code); _exit(127); } } @@ -269,7 +288,7 @@ namespace vix::engine::process ::chdir(command.workingDirectory.c_str()) != 0) { const int code = errno; - (void)::write(errorPipe[1], &code, sizeof(code)); + write_child_error_code_or_exit(errorPipe[1], code); _exit(127); } @@ -296,7 +315,7 @@ namespace vix::engine::process } const int code = errno; - (void)::write(errorPipe[1], &code, sizeof(code)); + write_child_error_code_or_exit(errorPipe[1], code); _exit(127); }