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.
This commit is contained in:
Lennart Poettering
2024-01-02 17:57:34 +01:00
parent a3f3243613
commit f17132260f
2 changed files with 36 additions and 0 deletions
+24
View 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,
+12
View 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);