You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jp...@apache.org on 2018/08/17 22:21:45 UTC
[mesos] 01/02: Updated `os::pipe()` to always return O_CLOEXEC
descriptors.
This is an automated email from the ASF dual-hosted git repository.
jpeach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 2388ca4bd3be3ed5da266e74b518dd284de1be94
Author: James Peach <jp...@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/
---
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;
}