]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: add pidref_safe_fork() helper
authorLennart Poettering <lennart@poettering.net>
Thu, 23 Nov 2023 17:07:44 +0000 (18:07 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 2 Jan 2024 16:57:34 +0000 (17:57 +0100)
This combines safe_fork() with pidref_set_pid().

Eventually we really should switch this to use CLONE_PIDFD, but as that
is not wrapped by glibc yet, it's hard. But this is not crucial anyway,
as a child we just forked off can always safely be referenced also by
PID, given the reaping is under our own control.

A simple test case is added in a follow-up commit.

src/basic/process-util.c
src/basic/process-util.h

index 201c5596ae9f969ee771395189b036c52a59d4e8..664222ec842e890a4f6f9d74e52ce9c97a6bac1a 100644 (file)
@@ -1650,6 +1650,30 @@ int safe_fork_full(
         return 0;
 }
 
+int pidref_safe_fork_full(
+                const char *name,
+                const int stdio_fds[3],
+                const int except_fds[],
+                size_t n_except_fds,
+                ForkFlags flags,
+                PidRef *ret_pid) {
+
+        pid_t pid;
+        int r, q;
+
+        assert(!FLAGS_SET(flags, FORK_WAIT));
+
+        r = safe_fork_full(name, stdio_fds, except_fds, n_except_fds, flags, &pid);
+        if (r < 0)
+                return r;
+
+        q = pidref_set_pid(ret_pid, pid);
+        if (q < 0) /* Let's not fail for this, no matter what, the process exists after all, and that's key */
+                *ret_pid = PIDREF_MAKE_FROM_PID(pid);
+
+        return r;
+}
+
 int namespace_fork(
                 const char *outer_name,
                 const char *inner_name,
index af6cba13ebdd3f6e09422fe71b3ad475b57acf3f..83ebda6faba4e0f099e4f3129028fde88d16688b 100644 (file)
@@ -191,6 +191,18 @@ static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
         return safe_fork_full(name, NULL, NULL, 0, flags, ret_pid);
 }
 
+int pidref_safe_fork_full(
+                const char *name,
+                const int stdio_fds[3],
+                const int except_fds[],
+                size_t n_except_fds,
+                ForkFlags flags,
+                PidRef *ret_pid);
+
+static inline int pidref_safe_fork(const char *name, ForkFlags flags, PidRef *ret_pid) {
+        return pidref_safe_fork_full(name, NULL, NULL, 0, flags, ret_pid);
+}
+
 int namespace_fork(const char *outer_name, const char *inner_name, const int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid);
 
 int set_oom_score_adjust(int value);