diff --git a/cbits/posix/fork_exec.c b/cbits/posix/fork_exec.c index 309ea4ebef0cafe1025c227e5ae94634bb5fe911..c6242b4db3633c4b05f6889b47b53dd276317720 100644 --- a/cbits/posix/fork_exec.c +++ b/cbits/posix/fork_exec.c @@ -1,4 +1,4 @@ -/* ensure that execvpe is provided if possible */ +/* Ensure that execvpe and pipe2 are provided if possible */ #define _GNU_SOURCE 1 /* Ensure getpwuid_r(3) is available on Solaris. */ @@ -31,10 +31,7 @@ #include <Rts.h> -#if defined(HAVE_WORKING_FORK) -#define myfork fork -// We don't need a fork command on Windows -#else +#if !defined(HAVE_WORKING_FORK) #error Cannot find a working fork command #endif @@ -101,8 +98,11 @@ setup_std_handle_fork(int fd, } } -/* We must ensure that the fork communications pipe does not inhabit fds 0 - * through 2 since we will need to manipulate these fds in +/* This will `dup` the given fd such that it does not fall in the range of + * stdin/stdout/stderr, if necessary. The new handle will have O_CLOEXEC. + * + * This is necessary as we must ensure that the fork communications pipe does + * not inhabit fds 0 through 2 since we will need to manipulate these fds in * setup_std_handle_fork while keeping the pipe available so that it can report * errors. See #266. */ @@ -111,7 +111,7 @@ int unshadow_pipe_fd(int fd, char **failed_doing) { return fd; } - int new_fd = fcntl(fd, F_DUPFD, 3); + int new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); if (new_fd == -1) { *failed_doing = "fcntl(F_DUP_FD)"; return -1; @@ -132,7 +132,13 @@ do_spawn_fork (char *const args[], char **failed_doing) { int forkCommunicationFds[2]; - int r = pipe(forkCommunicationFds); + int r; + +#if defined(HAVE_PIPE2) + r = pipe2(forkCommunicationFds, O_CLOEXEC); +#else + r = pipe(forkCommunicationFds); +#endif if (r == -1) { *failed_doing = "pipe"; return -1; diff --git a/configure.ac b/configure.ac index e0f7828105a60ace51c41716de98144868159bbd..f7f1729b40f1f84dcc41a48826f5f038518659af 100644 --- a/configure.ac +++ b/configure.ac @@ -15,6 +15,11 @@ AC_CHECK_HEADERS([signal.h sys/wait.h fcntl.h]) AC_CHECK_FUNCS([setitimer sysconf]) AC_CHECK_FUNCS([execvpe]) +AC_CHECK_FUNCS([pipe2],[],[],[ + #define _GNU_SOURCE + #include <unistd.h> + #include <fcntl.h> +]) # posix_spawn checks AC_CHECK_HEADERS([spawn.h])