This is an automated email from the ASF dual-hosted git repository. gilbert pushed a commit to branch 1.4.x in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 011be7bfb78cf88902c74c54802d101d7958b800 Author: James Peach <jpe...@apache.org> AuthorDate: Fri Aug 17 11:45:52 2018 -0700 Updated `os::pipe()` to always return O_CLOEXEC descriptors. Updated `os::pipe()` to always return O_CLOEXEC descriptors, atomically if we are on Linux or FreeBSD and the `pipe2(2)` system call is available. Review: https://reviews.apache.org/r/63270/ (cherry picked from commit 2388ca4bd3be3ed5da266e74b518dd284de1be94) --- 3rdparty/stout/include/stout/os/posix/pipe.hpp | 52 +++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/3rdparty/stout/include/stout/os/posix/pipe.hpp b/3rdparty/stout/include/stout/os/posix/pipe.hpp index ac76224..9838d7b 100644 --- a/3rdparty/stout/include/stout/os/posix/pipe.hpp +++ b/3rdparty/stout/include/stout/os/posix/pipe.hpp @@ -15,20 +15,70 @@ #include <unistd.h> +#include <sys/syscall.h> + #include <array> #include <stout/error.hpp> #include <stout/try.hpp> +#include <stout/os/posix/fcntl.hpp> + namespace os { -// Create pipes for interprocess communication. +// Create pipes for interprocess communication. The pipe file descriptors +// will be marked O_CLOEXEC (atomically if the platform supports it). To +// pass the pipe to a child process, the caller should clear the CLOEXEC +// flag after fork(2) but before exec(2). inline Try<std::array<int, 2>> pipe() { std::array<int, 2> result; + + // The pipe2() function appeared in FreeBSD 10.0. +#if defined(_FreeBSD__) && __FreeBSD_version >= 1000000 + + if (::pipe2(result.data(), O_CLOEXEC) < 0) { + return ErrnoError(); + } + +#else + + // pipe2() appeared in Linux 2.6.27 and glibc 2.9. +#if defined(__linux__) && defined(SYS_pipe2) + if (::syscall(SYS_pipe2, result.data(), O_CLOEXEC) == 0) { + return result; + } + + // Fall back if the kernel doesn't support pipe2(). + if (errno != ENOSYS) { + return ErrnoError(); + } +#endif + if (::pipe(result.data()) < 0) { return ErrnoError(); } + + Try<Nothing> cloexec = Nothing(); + + cloexec = os::cloexec(result[0]); + if (cloexec.isError()) { + Error error = Error("Failed to cloexec pipe: " + cloexec.error()); + ::close(result[0]); + ::close(result[1]); + return error; + } + + cloexec = os::cloexec(result[1]); + if (cloexec.isError()) { + Error error = Error("Failed to cloexec pipe: " + cloexec.error()); + ::close(result[0]); + ::close(result[1]); + return error; + } + +#endif + return result; }