From: Lennart Poettering Date: Thu, 23 Nov 2023 17:07:44 +0000 (+0100) Subject: process-util: add pidref_safe_fork() helper X-Git-Tag: v256-rc1~1307^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f17132260f36e3db863afcb8bbbbec7ebd49bfb1;p=thirdparty%2Fsystemd.git process-util: add pidref_safe_fork() helper 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. --- diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 201c5596ae9..664222ec842 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -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, diff --git a/src/basic/process-util.h b/src/basic/process-util.h index af6cba13ebd..83ebda6faba 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -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);