summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/forkfd/forkfd.c8
-rw-r--r--src/3rdparty/forkfd/forkfd.h7
-rw-r--r--src/3rdparty/forkfd/forkfd_linux.c5
3 files changed, 15 insertions, 5 deletions
diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c
index 80f0e448e6..50784deaa5 100644
--- a/src/3rdparty/forkfd/forkfd.c
+++ b/src/3rdparty/forkfd/forkfd.c
@@ -611,12 +611,18 @@ static int create_pipe(int filedes[], int flags)
* descriptor. You probably want to set this flag, since forkfd() does not work
* if the original parent process dies.
*
- * @li @C FFD_USE_FORK Tell forkfd() to actually call fork() instead of a
+ * @li @c FFD_USE_FORK Tell forkfd() to actually call fork() instead of a
* different system implementation that may be available. On systems where a
* different implementation is available, its behavior may differ from that of
* fork(), such as not calling the functions registered with pthread_atfork().
* If that's necessary, pass this flag.
*
+ * @li @c FFD_VFORK_SEMANTICS Tell forkfd() to use semantics similar to
+ * vfork(), if that's available. For example, on Linux with pidfd support
+ * available, this will add the CLONE_VFORK option. On most other systems,
+ * including Linux without pidfd support, this option does nothing, as using
+ * the actual vfork() system call would cause a race condition.
+ *
* The file descriptor returned by forkfd() supports the following operations:
*
* @li read(2) When the child process exits, then the buffer supplied to
diff --git a/src/3rdparty/forkfd/forkfd.h b/src/3rdparty/forkfd/forkfd.h
index 205928cc2b..a864b59861 100644
--- a/src/3rdparty/forkfd/forkfd.h
+++ b/src/3rdparty/forkfd/forkfd.h
@@ -38,9 +38,10 @@
extern "C" {
#endif
-#define FFD_CLOEXEC 1
-#define FFD_NONBLOCK 2
-#define FFD_USE_FORK 4
+#define FFD_CLOEXEC 1
+#define FFD_NONBLOCK 2
+#define FFD_USE_FORK 4
+#define FFD_VFORK_SEMANTICS 8
#define FFD_CHILD_PROCESS (-2)
diff --git a/src/3rdparty/forkfd/forkfd_linux.c b/src/3rdparty/forkfd/forkfd_linux.c
index 87acdc3341..c4f723343f 100644
--- a/src/3rdparty/forkfd/forkfd_linux.c
+++ b/src/3rdparty/forkfd/forkfd_linux.c
@@ -147,7 +147,10 @@ int system_forkfd(int flags, pid_t *ppid, int *system)
}
*system = 1;
- pid = sys_clone(CLONE_PIDFD, &pidfd);
+ unsigned long cloneflags = CLONE_PIDFD;
+ if (flags & FFD_VFORK_SEMANTICS)
+ cloneflags |= CLONE_VFORK;
+ pid = sys_clone(cloneflags, &pidfd);
if (ppid)
*ppid = pid;