process-util: Use pidref_wait_for_terminate_and_check in pidref_safe_fork()

Note that we still have to block SIGCHLD so that
we can be certain the process is not reaped before
we get the pidfd to it. safe_fork() and friends are
used in libsystemd where we don't control how the
SIGCHLD signal is configured. Specifically, kernel
autoreaping could be enabled which is why we have
to block SIGCHLD until we get the pidfd so that the
kernel cannot autoreap the process before we get
the pidfd.
This commit is contained in:
Daan De Meyer
2025-12-20 15:44:20 +01:00
parent a1e5d7f865
commit 8c367868ee
+11 -4
View File
@@ -1566,9 +1566,13 @@ int pidref_safe_fork_full(
pidref_transport_fds[1] = safe_close(pidref_transport_fds[1]);
if (pidref_transport_fds[0] >= 0) {
/* Wait for the intermediary child to exit so the caller can be certain the actual child
* process has been reparented by the time this function returns. */
r = wait_for_terminate_and_check(name, pid, FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
/* Wait for the intermediary child to exit so the caller can be
* certain the actual child process has been reparented by the time
* this function returns. */
r = pidref_wait_for_terminate_and_check(
name,
&PIDREF_MAKE_FROM_PID(pid),
FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
if (r < 0)
return log_full_errno(prio, r, "Failed to wait for intermediary process: %m");
if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */
@@ -1644,7 +1648,10 @@ int pidref_safe_fork_full(
(void) sigprocmask(SIG_SETMASK, &ss, NULL);
}
r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0));
r = pidref_wait_for_terminate_and_check(
name,
&PIDREF_MAKE_FROM_PID(pid),
FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
if (r < 0)
return r;
if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */