]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: Use pidref_wait_for_terminate_and_check()
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 19 Nov 2025 13:34:11 +0000 (14:34 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 20 Dec 2025 14:50:47 +0000 (15:50 +0100)
Let's use the pidref variants for waiting and
checking a process everywhere and get rid of the
non pidref variants.

56 files changed:
src/basic/lock-util.c
src/basic/namespace-util.c
src/basic/namespace-util.h
src/basic/pidref.h
src/basic/process-util.c
src/basic/process-util.h
src/basic/uid-range.c
src/core/crash-handler.c
src/core/exec-invoke.c
src/coredump/coredumpctl.c
src/delta/delta.c
src/fsck/fsck.c
src/home/homectl.c
src/home/homework-cifs.c
src/home/homework-luks.c
src/import/pull-common.c
src/libsystemd/sd-bus/bus-internal.h
src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-varlink/sd-varlink.c
src/libsystemd/sd-varlink/varlink-internal.h
src/login/inhibit.c
src/machine/image-dbus.c
src/machine/image-varlink.c
src/machine/image.c
src/machine/machine.c
src/machine/operation.c
src/machine/operation.h
src/nspawn/nspawn-setuid.c
src/nspawn/nspawn.c
src/nsresourced/nsresourcework.c
src/nsresourced/test-userns-restrict.c
src/portable/portable.c
src/portable/portabled-image-bus.c
src/portable/portabled-operation.c
src/portable/portabled-operation.h
src/shared/ask-password-agent.c
src/shared/dissect-image.c
src/shared/exec-util.c
src/shared/exec-util.h
src/shared/pager.c
src/shared/polkit-agent.c
src/shared/tests.c
src/sulogin-shell/sulogin-shell.c
src/sysext/sysext.c
src/systemctl/systemctl-sysv-compat.c
src/sysupdate/sysupdate-resource.c
src/test/test-argv-util.c
src/test/test-data-fd-util.c
src/test/test-execute.c
src/test/test-fileio.c
src/test/test-fs-util.c
src/test/test-namespace.c
src/test/test-path-util.c
src/test/test-process-util.c
src/vconsole/vconsole-setup.c

index 4f0bc8b50cb6e69259d4022d7207d4c1324ed8ce..85c7dc0562fc1b45335b21104230938dd3e060d7 100644 (file)
@@ -15,6 +15,7 @@
 #include "lock-util.h"
 #include "log.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "string-util.h"
 #include "time-util.h"
@@ -199,7 +200,6 @@ int lock_generic(int fd, LockType type, int operation) {
 }
 
 int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeout) {
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
         int r;
 
         assert(fd >= 0);
@@ -223,8 +223,8 @@ int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeo
                 return r;
 
         /* If that didn't work, try with a child */
-
-        r = safe_fork("(sd-flock)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pid);
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork("(sd-flock)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pidref);
         if (r < 0)
                 return log_error_errno(r, "Failed to flock block device in child process: %m");
         if (r == 0) {
@@ -256,11 +256,11 @@ int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeo
         }
 
         siginfo_t status;
-        r = wait_for_terminate(pid, &status);
+        r = pidref_wait_for_terminate(&pidref, &status);
         if (r < 0)
                 return r;
 
-        TAKE_PID(pid);
+        pidref_done(&pidref);
 
         switch (status.si_code) {
 
index 3a960e19cc5d271922eba56638b7f92f82c15c0d..555138c2559dd03c9d31d5db6d20a3983b8fac76 100644 (file)
@@ -601,25 +601,25 @@ int userns_acquire_self_root(void) {
         return userns_acquire(uid_map, gid_map, /* setgroups_deny= */ true);
 }
 
-int userns_enter_and_pin(int userns_fd, pid_t *ret_pid) {
+int userns_enter_and_pin(int userns_fd, PidRef *ret) {
         _cleanup_close_pair_ int pfd[2] = EBADF_PAIR;
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         ssize_t n;
         char x;
         int r;
 
         assert(userns_fd >= 0);
-        assert(ret_pid);
+        assert(ret);
 
         if (pipe2(pfd, O_CLOEXEC) < 0)
                 return -errno;
 
-        r = safe_fork_full(
+        r = pidref_safe_fork_full(
                         "(sd-pinuserns)",
                         /* stdio_fds= */ NULL,
                         (int[]) { pfd[1], userns_fd }, 2,
                         FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL,
-                        &pid);
+                        &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -652,7 +652,7 @@ int userns_enter_and_pin(int userns_fd, pid_t *ret_pid) {
         assert(n == 1);
         assert(x == 'x');
 
-        *ret_pid = TAKE_PID(pid);
+        *ret = TAKE_PIDREF(pidref);
         return 0;
 }
 
@@ -661,22 +661,22 @@ bool userns_supported(void) {
 }
 
 int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid) {
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         int r;
 
         assert(userns_fd >= 0);
 
-        r = userns_enter_and_pin(userns_fd, &pid);
+        r = userns_enter_and_pin(userns_fd, &pidref);
         if (r < 0)
                 return r;
 
         uid_t uid;
-        r = uid_map_search_root(pid, UID_RANGE_USERNS_OUTSIDE, &uid);
+        r = uid_map_search_root(pidref.pid, UID_RANGE_USERNS_OUTSIDE, &uid);
         if (r < 0)
                 return r;
 
         gid_t gid;
-        r = uid_map_search_root(pid, GID_RANGE_USERNS_OUTSIDE, &gid);
+        r = uid_map_search_root(pidref.pid, GID_RANGE_USERNS_OUTSIDE, &gid);
         if (r < 0)
                 return r;
 
index 2c4a7da29f137d2c30a330b2b3fe8d873c0f8758..32e64fa9e6801490bc7dbcbc0136018b2811b375 100644 (file)
@@ -82,7 +82,7 @@ int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_r
 int userns_acquire_empty(void);
 int userns_acquire(const char *uid_map, const char *gid_map, bool setgroups_deny);
 int userns_acquire_self_root(void);
-int userns_enter_and_pin(int userns_fd, pid_t *ret_pid);
+int userns_enter_and_pin(int userns_fd, PidRef *ret);
 bool userns_supported(void);
 
 int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid);
index d778d49f09a3f90f357095932d9911fb3bc0420d..864acb569df91265288ff741c6888ce0b90129ac 100644 (file)
@@ -101,6 +101,15 @@ static inline int pidref_wait_for_terminate(PidRef *pidref, siginfo_t *ret) {
         return pidref_wait_for_terminate_full(pidref, USEC_INFINITY, ret);
 }
 
+static inline void pidref_done_sigterm_wait(PidRef *pidref) {
+        if (!pidref_is_set(pidref))
+                return;
+
+        (void) pidref_kill(pidref, SIGTERM);
+        (void) pidref_wait_for_terminate(pidref, NULL);
+        pidref_done(pidref);
+}
+
 static inline void pidref_done_sigkill_wait(PidRef *pidref) {
         if (!pidref_is_set(pidref))
                 return;
index 94522fb495e2e488eea7e87207ecd8657b27893f..4c59ea4918f80b836677fbc02291da4b3df841a3 100644 (file)
@@ -845,13 +845,9 @@ int get_process_umask(pid_t pid, mode_t *ret) {
         return parse_mode(m, ret);
 }
 
-int wait_for_terminate(pid_t pid, siginfo_t *ret) {
-        return pidref_wait_for_terminate(&PIDREF_MAKE_FROM_PID(pid), ret);
-}
-
 /*
  * Return values:
- * < 0 : wait_for_terminate() failed to get the state of the
+ * < 0 : pidref_wait_for_terminate() failed to get the state of the
  *       process, the process was terminated by a signal, or
  *       failed for an unknown reason.
  * >=0 : The process terminated normally, and its exit code is
@@ -908,52 +904,6 @@ int pidref_wait_for_terminate_and_check(const char *name, PidRef *pidref, WaitFl
         return -EPROTO;
 }
 
-int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) {
-        return pidref_wait_for_terminate_and_check(name, &PIDREF_MAKE_FROM_PID(pid), flags);
-}
-
-void sigkill_wait(pid_t pid) {
-        assert(pid > 1);
-
-        (void) kill(pid, SIGKILL);
-        (void) wait_for_terminate(pid, NULL);
-}
-
-void sigkill_waitp(pid_t *pid) {
-        PROTECT_ERRNO;
-
-        if (!pid)
-                return;
-        if (*pid <= 1)
-                return;
-
-        sigkill_wait(*pid);
-}
-
-void sigterm_wait(pid_t pid) {
-        assert(pid > 1);
-
-        (void) kill_and_sigcont(pid, SIGTERM);
-        (void) wait_for_terminate(pid, NULL);
-}
-
-void sigkill_nowait(pid_t pid) {
-        assert(pid > 1);
-
-        (void) kill(pid, SIGKILL);
-}
-
-void sigkill_nowaitp(pid_t *pid) {
-        PROTECT_ERRNO;
-
-        if (!pid)
-                return;
-        if (*pid <= 1)
-                return;
-
-        sigkill_nowait(*pid);
-}
-
 int kill_and_sigcont(pid_t pid, int sig) {
         int r;
 
@@ -1280,7 +1230,9 @@ void valgrind_summary_hack(void) {
                         exit(EXIT_SUCCESS);
                 else {
                         log_info("Spawned valgrind helper as PID "PID_FMT".", pid);
-                        (void) wait_for_terminate(pid, NULL);
+                        _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pid);
+                        (void) pidref_set_pid(&pidref, pid);
+                        (void) pidref_wait_for_terminate(&pidref, NULL);
                 }
         }
 #endif
index 4b7641da6ba156caca4837a51a0b42186bc5c39d..24873b448e2e287e4aeb1ee48e294d52d8a43374 100644 (file)
@@ -60,8 +60,6 @@ static inline bool SIGINFO_CODE_IS_DEAD(int code) {
         return IN_SET(code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
 }
 
-int wait_for_terminate(pid_t pid, siginfo_t *ret);
-
 typedef enum WaitFlags {
         WAIT_LOG_ABNORMAL             = 1 << 0,
         WAIT_LOG_NON_ZERO_EXIT_STATUS = 1 << 1,
@@ -71,13 +69,6 @@ typedef enum WaitFlags {
 } WaitFlags;
 
 int pidref_wait_for_terminate_and_check(const char *name, PidRef *pidref, WaitFlags flags);
-int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags);
-
-void sigkill_wait(pid_t pid);
-void sigkill_waitp(pid_t *pid);
-void sigterm_wait(pid_t pid);
-void sigkill_nowait(pid_t pid);
-void sigkill_nowaitp(pid_t *pid);
 
 int kill_and_sigcont(pid_t pid, int sig);
 
index 0b87e789abe31bbe63de55a7b570bdd1e83e8413..81e736ef5af0dea2f66e3a478f48f53eb4a81268 100644 (file)
@@ -8,6 +8,7 @@
 #include "format-util.h"
 #include "namespace-util.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "sort-util.h"
 #include "stat-util.h"
@@ -286,7 +287,7 @@ int uid_range_load_userns(const char *path, UIDRangeUsernsMode mode, UIDRange **
 }
 
 int uid_range_load_userns_by_fd(int userns_fd, UIDRangeUsernsMode mode, UIDRange **ret) {
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         int r;
 
         assert(userns_fd >= 0);
@@ -294,12 +295,12 @@ int uid_range_load_userns_by_fd(int userns_fd, UIDRangeUsernsMode mode, UIDRange
         assert(mode < _UID_RANGE_USERNS_MODE_MAX);
         assert(ret);
 
-        r = userns_enter_and_pin(userns_fd, &pid);
+        r = userns_enter_and_pin(userns_fd, &pidref);
         if (r < 0)
                 return r;
 
         const char *p = procfs_file_alloca(
-                        pid,
+                        pidref.pid,
                         IN_SET(mode, UID_RANGE_USERNS_INSIDE, UID_RANGE_USERNS_OUTSIDE) ? "uid_map" : "gid_map");
 
         return uid_range_load_userns(p, mode, ret);
index 495e9efc9b5acb7b7855e0ad7becf0dbf3e9d0e6..b5286c8e69e34e9f905aea194438900093ef2af0 100644 (file)
@@ -12,6 +12,7 @@
 #include "format-util.h"
 #include "log.h"
 #include "main.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "raw-clone.h"
 #include "rlimit-util.h"
@@ -127,8 +128,11 @@ _noreturn_ static void crash(int sig, siginfo_t *siginfo, void *context) {
                                                    LOG_MESSAGE_ID(SD_MESSAGE_CRASH_PROCESS_SIGNAL_STR));
                         }
 
+                        _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pid);
+                        (void) pidref_set_pid(&pidref, pid);
+
                         /* Order things nicely. */
-                        r = wait_for_terminate(pid, &status);
+                        r = pidref_wait_for_terminate(&pidref, &status);
                         if (r < 0)
                                 log_struct_errno(LOG_EMERG, r,
                                                  LOG_MESSAGE("Caught <%s>, waitpid() failed: %m", signal_to_string(sig)),
@@ -181,7 +185,9 @@ _noreturn_ static void crash(int sig, siginfo_t *siginfo, void *context) {
                         _exit(EXIT_EXCEPTION);
                 } else {
                         log_info("Spawned crash shell as PID "PID_FMT".", pid);
-                        (void) wait_for_terminate(pid, NULL);
+                        _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pid);
+                        (void) pidref_set_pid(&pidref, pid);
+                        (void) pidref_wait_for_terminate(&pidref, NULL);
                 }
         }
 
index 24e553e1225b5ff73cbb96311b170da7c03f9690..01a653f2f1c429278898c9a141d40ff2a4529138 100644 (file)
@@ -2406,7 +2406,7 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
         _cleanup_free_ char *uid_map = NULL, *gid_map = NULL;
         _cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;
         _cleanup_close_ int unshare_ready_fd = -EBADF;
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         uint64_t c = 1;
         ssize_t n;
         int r;
@@ -2503,7 +2503,7 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
         if (pipe2(errno_pipe, O_CLOEXEC) < 0)
                 return -errno;
 
-        r = safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pid);
+        r = pidref_safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -2535,9 +2535,10 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
         if (n != 0) /* on success we should have read 0 bytes */
                 return -EIO;
 
-        r = wait_for_terminate_and_check("(sd-userns)", TAKE_PID(pid), 0);
+        r = pidref_wait_for_terminate_and_check("(sd-userns)", &pidref, 0);
         if (r < 0)
                 return r;
+        pidref_done(&pidref);
         if (r != EXIT_SUCCESS) /* If something strange happened with the child, let's consider this fatal, too */
                 return -EIO;
 
@@ -2546,7 +2547,7 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi
 
 static int can_mount_proc(void) {
         _cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         ssize_t n;
         int r;
 
@@ -2561,8 +2562,10 @@ static int can_mount_proc(void) {
 
         /* Fork a child process into its own mount and PID namespace. Note safe_fork() already remounts / as SLAVE
          * with FORK_MOUNTNS_SLAVE. */
-        r = safe_fork("(sd-proc-check)",
-                      FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_PIDNS, &pid);
+        r = pidref_safe_fork(
+                        "(sd-proc-check)",
+                        FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_PIDNS,
+                        &pidref);
         if (r < 0)
                 return log_debug_errno(r, "Failed to fork child process (sd-proc-check): %m");
         if (r == 0) {
@@ -2597,9 +2600,10 @@ static int can_mount_proc(void) {
         if (n != 0) /* on success we should have read 0 bytes */
                 return -EIO;
 
-        r = wait_for_terminate_and_check("(sd-proc-check)", TAKE_PID(pid), /* flags= */ 0);
+        r = pidref_wait_for_terminate_and_check("(sd-proc-check)", &pidref, /* flags= */ 0);
         if (r < 0)
                 return log_debug_errno(r, "Failed to wait for (sd-proc-check) child process to terminate: %m");
+        pidref_done(&pidref);
         if (r != EXIT_SUCCESS) /* If something strange happened with the child, let's consider this fatal, too */
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Child process (sd-proc-check) exited with unexpected exit status '%d'.", r);
 
index 321e9067f3bb880828fa19f233d60dbd38afb7be..64f7ae99a10f0237df6d280ad1d5a4304ed2e99e 100644 (file)
@@ -42,6 +42,7 @@
 #include "parse-argument.h"
 #include "parse-util.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "pretty-print.h"
 #include "process-util.h"
 #include "signal-util.h"
@@ -1177,7 +1178,6 @@ static int run_debug(int argc, char **argv, void *userdata) {
         bool unlink_path = false;
         const char *data, *fork_name;
         size_t len;
-        pid_t pid;
         int r;
 
         if (!arg_debugger) {
@@ -1271,7 +1271,11 @@ static int run_debug(int argc, char **argv, void *userdata) {
 
         fork_name = strjoina("(", debugger_call[0], ")");
 
-        r = safe_fork(fork_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_FLUSH_STDIO, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork(
+                        fork_name,
+                        FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_FLUSH_STDIO,
+                        &pidref);
         if (r < 0)
                 goto finish;
         if (r == 0) {
@@ -1281,7 +1285,7 @@ static int run_debug(int argc, char **argv, void *userdata) {
                 _exit(EXIT_FAILURE);
         }
 
-        r = wait_for_terminate_and_check(debugger_call[0], pid, WAIT_LOG_ABNORMAL);
+        r = pidref_wait_for_terminate_and_check(debugger_call[0], &pidref, WAIT_LOG_ABNORMAL);
 
 finish:
         (void) default_signals(SIGINT, SIGTERM);
index 7eb9d91871c1cc7326c27282aad735335e448c93..df28a730a54e65fedbd2ef960396ad88646beb28 100644 (file)
@@ -19,6 +19,7 @@
 #include "pager.h"
 #include "parse-argument.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "pretty-print.h"
 #include "process-util.h"
 #include "stat-util.h"
@@ -140,7 +141,6 @@ static int notify_override_unchanged(const char *f) {
 
 static int found_override(const char *top, const char *bottom) {
         _cleanup_free_ char *dest = NULL;
-        pid_t pid;
         int r;
 
         assert(top);
@@ -165,7 +165,11 @@ static int found_override(const char *top, const char *bottom) {
 
         fflush(stdout);
 
-        r = safe_fork("(diff)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork(
+                        "(diff)",
+                        FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG,
+                        &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -175,7 +179,7 @@ static int found_override(const char *top, const char *bottom) {
                 _exit(EXIT_FAILURE);
         }
 
-        (void) wait_for_terminate_and_check("diff", pid, WAIT_LOG_ABNORMAL);
+        (void) pidref_wait_for_terminate_and_check("diff", &pidref, WAIT_LOG_ABNORMAL);
         putchar('\n');
 
         return r;
index 6ea5a9f0e7cc544593e0abb6fb4b9a11c9741f32..9767568724faf43e85697630c5426ed2744ef747 100644 (file)
@@ -23,6 +23,7 @@
 #include "fsck-util.h"
 #include "main-func.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "proc-cmdline.h"
 #include "process-util.h"
 #include "socket-util.h"
@@ -267,7 +268,6 @@ static int run(int argc, char *argv[]) {
         bool root_directory;
         struct stat st;
         int r, exit_status;
-        pid_t pid;
 
         log_setup();
 
@@ -366,7 +366,11 @@ static int run(int argc, char *argv[]) {
             pipe(progress_pipe) < 0)
                 return log_error_errno(errno, "pipe(): %m");
 
-        r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork(
+                        "(fsck)",
+                        FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+                        &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -424,7 +428,7 @@ static int run(int argc, char *argv[]) {
                 (void) process_progress(TAKE_FD(progress_pipe[0]), console);
         }
 
-        exit_status = wait_for_terminate_and_check("fsck", pid, WAIT_LOG_ABNORMAL);
+        exit_status = pidref_wait_for_terminate_and_check("fsck", &pidref, WAIT_LOG_ABNORMAL);
         if (exit_status < 0)
                 return exit_status;
         if ((exit_status & ~FSCK_ERROR_CORRECTED) != FSCK_SUCCESS) {
index 8d8f2c0f121918c8d303f6c513e0ae9b5586e7b1..ce45ec30c4a2d0f79ade1222fbd780182f068401 100644 (file)
@@ -46,6 +46,7 @@
 #include "password-quality-util.h"
 #include "path-util.h"
 #include "percent-util.h"
+#include "pidref.h"
 #include "pkcs11-util.h"
 #include "polkit-agent.h"
 #include "pretty-print.h"
@@ -2341,7 +2342,6 @@ static int with_home(int argc, char *argv[], void *userdata) {
         _cleanup_strv_free_ char **cmdline  = NULL;
         const char *home;
         int r, ret;
-        pid_t pid;
 
         r = acquire_bus(&bus);
         if (r < 0)
@@ -2414,7 +2414,11 @@ static int with_home(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        r = safe_fork("(with)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REOPEN_LOG, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork(
+                        "(with)",
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REOPEN_LOG,
+                        &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -2428,7 +2432,7 @@ static int with_home(int argc, char *argv[], void *userdata) {
                 _exit(255);
         }
 
-        ret = wait_for_terminate_and_check(cmdline[0], pid, WAIT_LOG_ABNORMAL);
+        ret = pidref_wait_for_terminate_and_check(cmdline[0], &pidref, WAIT_LOG_ABNORMAL);
 
         /* Close the fd that pings the home now. */
         acquired_fd = safe_close(acquired_fd);
index a34f075499930f1f8e73f4ed74d9564ec41c9674..23d5abb019b3f576fb4ece9e03ccc2f4e577aeec 100644 (file)
@@ -15,6 +15,7 @@
 #include "memfd-util.h"
 #include "mount-util.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "stat-util.h"
 #include "string-util.h"
@@ -75,14 +76,17 @@ int home_setup_cifs(
 
         STRV_FOREACH(pw, h->password) {
                 _cleanup_close_ int passwd_fd = -EBADF;
-                pid_t mount_pid;
                 int exit_status;
 
                 passwd_fd = memfd_new_and_seal_string("cifspw", *pw);
                 if (passwd_fd < 0)
                         return log_error_errno(passwd_fd, "Failed to create data FD for password: %m");
 
-                r = safe_fork("(mount)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR, &mount_pid);
+                _cleanup_(pidref_done) PidRef mount_pidref = PIDREF_NULL;
+                r = pidref_safe_fork(
+                                "(mount)",
+                                FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR,
+                                &mount_pidref);
                 if (r < 0)
                         return r;
                 if (r == 0) {
@@ -108,7 +112,7 @@ int home_setup_cifs(
                         _exit(EXIT_FAILURE);
                 }
 
-                exit_status = wait_for_terminate_and_check("mount", mount_pid, WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS);
+                exit_status = pidref_wait_for_terminate_and_check("mount", &mount_pidref, WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS);
                 if (exit_status < 0)
                         return exit_status;
                 if (exit_status == EXIT_SUCCESS) {
index 316afb6f5ec4b4c7d627a731c5fa05feea609e42..8ed455545114c96657c8a8e79155af113cf43e31 100644 (file)
@@ -7,6 +7,7 @@
 #include <sys/ioctl.h>
 #include <sys/xattr.h>
 #include <unistd.h>
+#include "pidref.h"
 #if HAVE_VALGRIND_MEMCHECK_H
 #include <valgrind/memcheck.h>
 #endif
@@ -227,7 +228,6 @@ static int block_get_size_by_path(const char *path, uint64_t *ret) {
 
 static int run_fsck(const char *node, const char *fstype) {
         int r, exit_status;
-        pid_t fsck_pid;
 
         assert(node);
         assert(fstype);
@@ -240,9 +240,11 @@ static int run_fsck(const char *node, const char *fstype) {
                 return 0;
         }
 
-        r = safe_fork("(fsck)",
-                      FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
-                      &fsck_pid);
+        _cleanup_(pidref_done) PidRef fsck_pidref = PIDREF_NULL;
+        r = pidref_safe_fork(
+                        "(fsck)",
+                        FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
+                        &fsck_pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -253,7 +255,7 @@ static int run_fsck(const char *node, const char *fstype) {
                 _exit(FSCK_OPERATIONAL_ERROR);
         }
 
-        exit_status = wait_for_terminate_and_check("fsck", fsck_pid, WAIT_LOG_ABNORMAL);
+        exit_status = pidref_wait_for_terminate_and_check("fsck", &fsck_pidref, WAIT_LOG_ABNORMAL);
         if (exit_status < 0)
                 return exit_status;
         if ((exit_status & ~FSCK_ERROR_CORRECTED) != 0) {
@@ -2604,7 +2606,7 @@ static int ext4_offline_resize_fs(
 
         _cleanup_free_ char *size_str = NULL;
         bool re_open = false, re_mount = false;
-        pid_t resize_pid, fsck_pid;
+        _cleanup_(pidref_done) PidRef resize_pidref = PIDREF_NULL, fsck_pidref = PIDREF_NULL;
         int r, exit_status;
 
         assert(setup);
@@ -2627,9 +2629,10 @@ static int ext4_offline_resize_fs(
         log_info("Temporary unmounting of file system completed.");
 
         /* resize2fs requires that the file system is force checked first, do so. */
-        r = safe_fork("(e2fsck)",
-                      FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
-                      &fsck_pid);
+        r = pidref_safe_fork(
+                        "(e2fsck)",
+                        FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
+                        &fsck_pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -2640,7 +2643,7 @@ static int ext4_offline_resize_fs(
                 _exit(EXIT_FAILURE);
         }
 
-        exit_status = wait_for_terminate_and_check("e2fsck", fsck_pid, WAIT_LOG_ABNORMAL);
+        exit_status = pidref_wait_for_terminate_and_check("e2fsck", &fsck_pidref, WAIT_LOG_ABNORMAL);
         if (exit_status < 0)
                 return exit_status;
         if ((exit_status & ~FSCK_ERROR_CORRECTED) != 0) {
@@ -2659,9 +2662,10 @@ static int ext4_offline_resize_fs(
                 return log_oom();
 
         /* Resize the thing */
-        r = safe_fork("(e2resize)",
-                      FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
-                      &resize_pid);
+        r = pidref_safe_fork(
+                        "(e2resize)",
+                        FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
+                        &resize_pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
index 4154487fd57b6f315d7647a3378587dabdd8ccb8..cc06fe4f1db0a755d8b458661d1295c8f83b62c4 100644 (file)
@@ -12,6 +12,7 @@
 #include "memory-util.h"
 #include "os-util.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "pull-common.h"
 #include "pull-job.h"
@@ -404,7 +405,7 @@ static int verify_gpg(
         _cleanup_close_pair_ int gpg_pipe[2] = EBADF_PAIR;
         _cleanup_(rm_rf_physical_and_freep) char *gpg_home = NULL;
         char sig_file_path[] = "/tmp/sigXXXXXX";
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         int r;
 
         assert(iovec_is_valid(payload));
@@ -434,11 +435,12 @@ static int verify_gpg(
                 goto finish;
         }
 
-        r = safe_fork_full("(gpg)",
-                           (int[]) { gpg_pipe[0], -EBADF, STDERR_FILENO },
-                           NULL, 0,
-                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
-                           &pid);
+        r = pidref_safe_fork_full(
+                        "(gpg)",
+                        (int[]) { gpg_pipe[0], -EBADF, STDERR_FILENO },
+                        /* except_fds= */ NULL, /* n_except_fds= */ 0,
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+                        &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -497,9 +499,10 @@ static int verify_gpg(
 
         gpg_pipe[1] = safe_close(gpg_pipe[1]);
 
-        r = wait_for_terminate_and_check("gpg", TAKE_PID(pid), WAIT_LOG_ABNORMAL);
+        r = pidref_wait_for_terminate_and_check("gpg", &pidref, WAIT_LOG_ABNORMAL);
         if (r < 0)
                 goto finish;
+        pidref_done(&pidref);
         if (r != EXIT_SUCCESS)
                 r = log_error_errno(SYNTHETIC_ERRNO(EBADMSG),
                                     "DOWNLOAD INVALID: Signature verification failed.");
index 177f88c2c7a4c73ab4128128e932982638de72e6..999e62f0081851cf4f08e58ac76588abb0493885 100644 (file)
@@ -8,6 +8,7 @@
 #include "bus-match.h"
 #include "constants.h"
 #include "list.h"
+#include "pidref.h"
 #include "runtime-scope.h"
 #include "socket-util.h"
 
@@ -271,7 +272,7 @@ typedef struct sd_bus {
         unsigned n_memfd_cache;
 
         uint64_t origin_id;
-        pid_t busexec_pid;
+        PidRef busexec_pidref;
 
         unsigned iteration_counter;
 
index 5f8d015569de2179275d6b1df6923644dd400656..32eda5627e71d0ad493e86acb00642259d78ebc5 100644 (file)
@@ -1163,7 +1163,7 @@ int bus_socket_exec(sd_bus *b) {
         assert(b->input_fd < 0);
         assert(b->output_fd < 0);
         assert(b->exec_path);
-        assert(b->busexec_pid == 0);
+        assert(!pidref_is_set(&b->busexec_pidref));
 
         if (DEBUG_LOGGING) {
                 _cleanup_free_ char *line = NULL;
@@ -1181,10 +1181,12 @@ int bus_socket_exec(sd_bus *b) {
         if (r < 0)
                 return -errno;
 
-        r = safe_fork_full("(sd-busexec)",
-                           (int[]) { s[1], s[1], STDERR_FILENO },
-                           NULL, 0,
-                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid);
+        r = pidref_safe_fork_full(
+                        "(sd-busexec)",
+                        (int[]) { s[1], s[1], STDERR_FILENO },
+                        NULL, 0,
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO|FORK_RLIMIT_NOFILE_SAFE,
+                        &b->busexec_pidref);
         if (r < 0) {
                 safe_close_pair(s);
                 return r;
index eecde50d7415661667451f87136aaf60bb6552a1..8318bc5853745dc9cab070a6458f52a2e01db044 100644 (file)
@@ -41,7 +41,6 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "prioq.h"
-#include "process-util.h"
 #include "set.h"
 #include "string-util.h"
 #include "strv.h"
@@ -262,6 +261,7 @@ _public_ int sd_bus_new(sd_bus **ret) {
                 .creds_mask = SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME,
                 .accept_fd = true,
                 .origin_id = origin_id_query(),
+                .busexec_pidref = PIDREF_NULL,
                 .n_groups = SIZE_MAX,
                 .close_on_exit = true,
                 .ucred = UCRED_INVALID,
@@ -1121,13 +1121,6 @@ static int bus_parse_next_address(sd_bus *b) {
         return 1;
 }
 
-static void bus_kill_exec(sd_bus *bus) {
-        if (!pid_is_valid(bus->busexec_pid))
-                return;
-
-        sigterm_wait(TAKE_PID(bus->busexec_pid));
-}
-
 static int bus_start_address(sd_bus *b) {
         int r;
 
@@ -1136,7 +1129,7 @@ static int bus_start_address(sd_bus *b) {
         for (;;) {
                 bus_close_fds(b);
 
-                bus_kill_exec(b);
+                pidref_done_sigterm_wait(&b->busexec_pidref);
 
                 /* If you provide multiple different bus-addresses, we
                  * try all of them in order and use the first one that
@@ -1778,7 +1771,7 @@ _public_ void sd_bus_close(sd_bus *bus) {
                 return;
 
         /* Don't leave ssh hanging around */
-        bus_kill_exec(bus);
+        pidref_done_sigterm_wait(&bus->busexec_pidref);
 
         bus_set_state(bus, BUS_CLOSED);
 
@@ -1809,7 +1802,7 @@ _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
                 return NULL;
 
         /* Have to do this before flush() to prevent hang */
-        bus_kill_exec(bus);
+        pidref_done_sigterm_wait(&bus->busexec_pidref);
         sd_bus_flush(bus);
 
         return sd_bus_close_unref(bus);
index b7b5052a930a61fb6168ec562d126bf44d448547..4532d2335c1a495ab11edad922c48e70d52464ce 100644 (file)
@@ -26,6 +26,7 @@
 #include "mkdir.h"
 #include "path-util.h"
 #include "pidfd-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "socket-util.h"
 #include "string-table.h"
@@ -149,6 +150,8 @@ static int varlink_new(sd_varlink **ret) {
                 .allow_fd_passing_input = -1,
 
                 .af = -1,
+
+                .exec_pidref = PIDREF_NULL,
         };
 
         *ret = v;
@@ -209,7 +212,7 @@ _public_ int sd_varlink_connect_address(sd_varlink **ret, const char *address) {
 
 _public_ int sd_varlink_connect_exec(sd_varlink **ret, const char *_command, char **_argv) {
         _cleanup_close_pair_ int pair[2] = EBADF_PAIR;
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         _cleanup_free_ char *command = NULL;
         _cleanup_strv_free_ char **argv = NULL;
         int r;
@@ -239,13 +242,13 @@ _public_ int sd_varlink_connect_exec(sd_varlink **ret, const char *_command, cha
         if (r < 0)
                 return log_debug_errno(r, "Failed to disable O_NONBLOCK for varlink socket: %m");
 
-        r = safe_fork_full(
+        r = pidref_safe_fork_full(
                         "(sd-vlexec)",
                         /* stdio_fds= */ NULL,
                         /* except_fds= */ (int[]) { pair[1] },
                         /* n_except_fds= */ 1,
                         FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
-                        &pid);
+                        &pidref);
         if (r < 0)
                 return log_debug_errno(r, "Failed to spawn process: %m");
         if (r == 0) {
@@ -266,7 +269,7 @@ _public_ int sd_varlink_connect_exec(sd_varlink **ret, const char *_command, cha
                         _exit(EXIT_FAILURE);
                 }
 
-                xsprintf(spid, PID_FMT, pid);
+                xsprintf(spid, PID_FMT, pidref.pid);
 
                 uint64_t pidfdid;
                 if (pidfd_get_inode_id_self_cached(&pidfdid) >= 0) {
@@ -298,7 +301,7 @@ _public_ int sd_varlink_connect_exec(sd_varlink **ret, const char *_command, cha
 
         v->output_fd = v->input_fd = TAKE_FD(pair[0]);
         v->af = AF_UNIX;
-        v->exec_pid = TAKE_PID(pid);
+        v->exec_pidref = TAKE_PIDREF(pidref);
         varlink_set_state(v, VARLINK_IDLE_CLIENT);
 
         *ret = v;
@@ -318,7 +321,7 @@ static int ssh_path(const char **ret) {
 
 static int varlink_connect_ssh_unix(sd_varlink **ret, const char *where) {
         _cleanup_close_pair_ int pair[2] = EBADF_PAIR;
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         int r;
 
         assert_return(ret, -EINVAL);
@@ -356,13 +359,13 @@ static int varlink_connect_ssh_unix(sd_varlink **ret, const char *where) {
         if (socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, pair) < 0)
                 return log_debug_errno(errno, "Failed to allocate AF_UNIX socket pair: %m");
 
-        r = safe_fork_full(
+        r = pidref_safe_fork_full(
                         "(sd-vlssh)",
                         /* stdio_fds= */ (int[]) { pair[1], pair[1], STDERR_FILENO },
                         /* except_fds= */ NULL,
                         /* n_except_fds= */ 0,
                         FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO,
-                        &pid);
+                        &pidref);
         if (r < 0)
                 return log_debug_errno(r, "Failed to spawn process: %m");
         if (r == 0) {
@@ -382,7 +385,7 @@ static int varlink_connect_ssh_unix(sd_varlink **ret, const char *where) {
 
         v->output_fd = v->input_fd = TAKE_FD(pair[0]);
         v->af = AF_UNIX;
-        v->exec_pid = TAKE_PID(pid);
+        v->exec_pidref = TAKE_PIDREF(pidref);
         varlink_set_state(v, VARLINK_IDLE_CLIENT);
 
         *ret = v;
@@ -391,7 +394,7 @@ static int varlink_connect_ssh_unix(sd_varlink **ret, const char *where) {
 
 static int varlink_connect_ssh_exec(sd_varlink **ret, const char *where) {
         _cleanup_close_pair_ int input_pipe[2] = EBADF_PAIR, output_pipe[2] = EBADF_PAIR;
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         int r;
 
         assert_return(ret, -EINVAL);
@@ -440,13 +443,13 @@ static int varlink_connect_ssh_exec(sd_varlink **ret, const char *where) {
         if (pipe2(output_pipe, O_CLOEXEC) < 0)
                 return log_debug_errno(errno, "Failed to allocate output pipe: %m");
 
-        r = safe_fork_full(
+        r = pidref_safe_fork_full(
                         "(sd-vlssh)",
                         /* stdio_fds= */ (int[]) { input_pipe[0], output_pipe[1], STDERR_FILENO },
                         /* except_fds= */ NULL,
                         /* n_except_fds= */ 0,
                         FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO,
-                        &pid);
+                        &pidref);
         if (r < 0)
                 return log_debug_errno(r, "Failed to spawn process: %m");
         if (r == 0) {
@@ -475,7 +478,7 @@ static int varlink_connect_ssh_exec(sd_varlink **ret, const char *where) {
         v->input_fd = TAKE_FD(output_pipe[0]);
         v->output_fd = TAKE_FD(input_pipe[1]);
         v->af = AF_UNSPEC;
-        v->exec_pid = TAKE_PID(pid);
+        v->exec_pidref = TAKE_PIDREF(pidref);
         varlink_set_state(v, VARLINK_IDLE_CLIENT);
 
         *ret = v;
@@ -648,10 +651,7 @@ static void varlink_clear(sd_varlink *v) {
 
         v->event = sd_event_unref(v->event);
 
-        if (v->exec_pid > 0) {
-                sigterm_wait(v->exec_pid);
-                v->exec_pid = 0;
-        }
+        pidref_done_sigterm_wait(&v->exec_pidref);
 
         v->peer_pidfd = safe_close(v->peer_pidfd);
 }
index 8041a30a5ea8ee1f468ab69fe08b073d014707fd..a2c54a0bf5a80fbb031d580985c02b3127aff3de 100644 (file)
@@ -6,6 +6,7 @@
 #include "sd-varlink.h"
 
 #include "list.h"
+#include "pidref.h"
 #include "sd-forward.h"
 
 typedef enum VarlinkState {
@@ -187,7 +188,7 @@ struct sd_varlink {
         sd_event_source *quit_event_source;
         sd_event_source *defer_event_source;
 
-        pid_t exec_pid;
+        PidRef exec_pidref;
 };
 
 typedef struct VarlinkServerSocket VarlinkServerSocket;
index 51379edc37e488ff2f2403984ab8d282cd31de53..786594c9ee33d4a1f8d42a2049fa1bbd0aacc160 100644 (file)
@@ -20,6 +20,7 @@
 #include "main-func.h"
 #include "pager.h"
 #include "parse-argument.h"
+#include "pidref.h"
 #include "polkit-agent.h"
 #include "pretty-print.h"
 #include "process-util.h"
@@ -330,7 +331,6 @@ static int run(int argc, char *argv[]) {
                 _cleanup_strv_free_ char **arguments = NULL;
                 _cleanup_free_ char *w = NULL;
                 _cleanup_close_ int fd = -EBADF;
-                pid_t pid;
 
                 /* Ignore SIGINT and allow the forked process to receive it */
                 (void) ignore_signals(SIGINT);
@@ -360,7 +360,8 @@ static int run(int argc, char *argv[]) {
                 if (!arguments)
                         return log_oom();
 
-                r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+                r = pidref_safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
                 if (r < 0)
                         return r;
                 if (r == 0) {
@@ -371,7 +372,7 @@ static int run(int argc, char *argv[]) {
                         _exit(EXIT_FAILURE);
                 }
 
-                return wait_for_terminate_and_check(argv[optind], pid, WAIT_LOG);
+                return pidref_wait_for_terminate_and_check(argv[optind], &pidref, WAIT_LOG);
         }
 }
 
index f7e3f7f93c52c9a382852121afd5943d08653b44..9579ae0c12aee984e555ca5413917a1ef38c6556 100644 (file)
@@ -32,7 +32,7 @@ int bus_image_method_remove(
         _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
         Image *image = ASSERT_PTR(userdata);
         Manager *m = image->userdata;
-        pid_t child;
+        _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
         int r;
 
         assert(message);
@@ -62,7 +62,7 @@ int bus_image_method_remove(
         if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
                 return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
 
-        r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
+        r = pidref_safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
         if (r < 0)
                 return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
         if (r == 0) {
@@ -73,11 +73,11 @@ int bus_image_method_remove(
 
         errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
 
-        r = operation_new_with_bus_reply(m, /* machine= */ NULL, child, message, errno_pipe_fd[0], /* ret= */ NULL);
-        if (r < 0) {
-                sigkill_wait(child);
+        r = operation_new_with_bus_reply(m, /* machine= */ NULL, &child, message, errno_pipe_fd[0], /* ret= */ NULL);
+        if (r < 0)
                 return r;
-        }
+
+        TAKE_PIDREF(child);
 
         errno_pipe_fd[0] = -EBADF;
 
@@ -140,7 +140,7 @@ int bus_image_method_clone(
         Manager *m = ASSERT_PTR(image->userdata);
         const char *new_name;
         int r, read_only;
-        pid_t child;
+        _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
 
         assert(message);
 
@@ -177,7 +177,7 @@ int bus_image_method_clone(
         if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
                 return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
 
-        r = safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
+        r = pidref_safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
         if (r < 0)
                 return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
         if (r == 0) {
@@ -188,11 +188,11 @@ int bus_image_method_clone(
 
         errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
 
-        r = operation_new_with_bus_reply(m, /* machine= */ NULL, child, message, errno_pipe_fd[0], /* ret= */ NULL);
-        if (r < 0) {
-                sigkill_wait(child);
+        r = operation_new_with_bus_reply(m, /* machine= */ NULL, &child, message, errno_pipe_fd[0], /* ret= */ NULL);
+        if (r < 0)
                 return r;
-        }
+
+        TAKE_PIDREF(child);
 
         errno_pipe_fd[0] = -EBADF;
 
index 908952dcf57232439fefca5db2cb7e085348bf61..bf9826c6812b4d2eb0f6e950ff65bcf232436d2e 100644 (file)
@@ -115,7 +115,7 @@ int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varl
         _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
         ImageUpdateParameters p = IMAGE_UPDATE_PARAMETERS_NULL;
         Image *image;
-        pid_t child;
+        _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
         int r;
 
         assert(link);
@@ -156,7 +156,7 @@ int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varl
         if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
                 return log_debug_errno(errno, "Failed to open pipe: %m");
 
-        r = safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
+        r = pidref_safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
         if (r < 0)
                 return log_debug_errno(r, "Failed to fork: %m");
         if (r == 0) {
@@ -167,12 +167,11 @@ int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varl
 
         errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
 
-        r = operation_new_with_varlink_reply(manager, /* machine= */ NULL, child, link, errno_pipe_fd[0], /* ret= */ NULL);
-        if (r < 0) {
-                sigkill_wait(child);
+        r = operation_new_with_varlink_reply(manager, /* machine= */ NULL, &child, link, errno_pipe_fd[0], /* ret= */ NULL);
+        if (r < 0)
                 return r;
-        }
 
+        TAKE_PIDREF(child);
         TAKE_FD(errno_pipe_fd[0]);
         return 1;
 }
@@ -188,7 +187,7 @@ int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_var
         _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
         const char *image_name;
         Image *image;
-        pid_t child;
+        _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
         int r;
 
         assert(link);
@@ -225,7 +224,7 @@ int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_var
         if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
                 return log_debug_errno(errno, "Failed to open pipe: %m");
 
-        r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
+        r = pidref_safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
         if (r < 0)
                 return log_debug_errno(r, "Failed to fork: %m");
         if (r == 0) {
@@ -236,12 +235,11 @@ int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_var
 
         errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
 
-        r = operation_new_with_varlink_reply(manager, /* machine= */ NULL, child, link, errno_pipe_fd[0], /* ret= */ NULL);
-        if (r < 0) {
-                sigkill_wait(child);
+        r = operation_new_with_varlink_reply(manager, /* machine= */ NULL, &child, link, errno_pipe_fd[0], /* ret= */ NULL);
+        if (r < 0)
                 return r;
-        }
 
+        TAKE_PIDREF(child);
         TAKE_FD(errno_pipe_fd[0]);
         return 1;
 }
index 0abee746db6975314da958cd5bd97e7c9ed18ba5..c1ad25668a08964b737d1b098bed864db317d297 100644 (file)
@@ -96,7 +96,7 @@ int clean_pool_read_next_entry(FILE *file, char **ret_name, uint64_t *ret_usage)
 int image_clean_pool_operation(Manager *manager, ImageCleanPoolMode mode, Operation **ret_operation) {
         _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
         _cleanup_close_ int result_fd = -EBADF;
-        _cleanup_(sigkill_waitp) pid_t child = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
         int r;
 
         assert(manager);
@@ -113,7 +113,7 @@ int image_clean_pool_operation(Manager *manager, ImageCleanPoolMode mode, Operat
                 return log_debug_errno(result_fd, "Failed to open tmpfile: %m");
 
         /* This might be a slow operation, run it asynchronously in a background process */
-        r = safe_fork("(sd-clean)", FORK_RESET_SIGNALS, &child);
+        r = pidref_safe_fork("(sd-clean)", FORK_RESET_SIGNALS, &child);
         if (r < 0)
                 return log_debug_errno(r, "Failed to fork(): %m");
         if (r == 0) {
@@ -183,13 +183,13 @@ int image_clean_pool_operation(Manager *manager, ImageCleanPoolMode mode, Operat
         errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
 
         /* The clean-up might take a while, hence install a watch on the child and return */
-        r = operation_new(manager, /* machine= */ NULL, child, errno_pipe_fd[0], ret_operation);
+        r = operation_new(manager, /* machine= */ NULL, &child, errno_pipe_fd[0], ret_operation);
         if (r < 0)
                  return r;
 
         (*ret_operation)->extra_fd = TAKE_FD(result_fd);
         TAKE_FD(errno_pipe_fd[0]);
-        TAKE_PID(child);
+        TAKE_PIDREF(child);
         return 0;
 }
 
index 1176649388ae647aaa9329b569fc28625d60ee5a..6914b912ce913f442cf0b9d792f0ee2a3c62ae60 100644 (file)
@@ -1244,7 +1244,7 @@ int machine_copy_from_to_operation(
 
         // TODO: port to PidRef and donate child rather than destroying it
         Operation *operation;
-        r = operation_new(manager, machine, child.pid, errno_pipe_fd[0], &operation);
+        r = operation_new(manager, machine, &child, errno_pipe_fd[0], &operation);
         if (r < 0)
                 return r;
 
index 8c43cc200f33440ff9c867c07c7a8d75d3abeb21..0e8fd3a5d8b8ba90dcbef9a155ac92e0448ee52f 100644 (file)
@@ -8,6 +8,7 @@
 #include "sd-varlink.h"
 
 #include "alloc-util.h"
+#include "event-util.h"
 #include "fd-util.h"
 #include "format-util.h"
 #include "log.h"
@@ -45,10 +46,10 @@ static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdat
         assert(si);
 
         log_debug("Operation " PID_FMT " is now complete with code=%s status=%i",
-                  o->pid,
+                  o->pidref.pid,
                   sigchld_code_to_string(si->si_code), si->si_status);
 
-        o->pid = 0;
+        pidref_done(&o->pidref);
 
         r = read_operation_errno(si, o);
         if (r < 0)
@@ -96,12 +97,12 @@ static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdat
         return 0;
 }
 
-int operation_new(Manager *manager, Machine *machine, pid_t child, int errno_fd, Operation **ret) {
+int operation_new(Manager *manager, Machine *machine, PidRef *child, int errno_fd, Operation **ret) {
         Operation *o;
         int r;
 
         assert(manager);
-        assert(child > 1);
+        assert(pidref_is_set(child));
         assert(errno_fd >= 0);
         assert(ret);
 
@@ -110,12 +111,12 @@ int operation_new(Manager *manager, Machine *machine, pid_t child, int errno_fd,
                 return -ENOMEM;
 
         *o = (Operation) {
-                .pid = child,
+                .pidref = TAKE_PIDREF(*child),
                 .errno_fd = errno_fd,
                 .extra_fd = -EBADF
         };
 
-        r = sd_event_add_child(manager->event, &o->event_source, child, WEXITED, operation_done, o);
+        r = event_add_child_pidref(manager->event, &o->event_source, &o->pidref, WEXITED, operation_done, o);
         if (r < 0) {
                 free(o);
                 return r;
@@ -130,7 +131,7 @@ int operation_new(Manager *manager, Machine *machine, pid_t child, int errno_fd,
                 o->machine = machine;
         }
 
-        log_debug("Started new operation " PID_FMT ".", child);
+        log_debug("Started new operation " PID_FMT ".", o->pidref.pid);
 
         /* At this point we took ownership of both the child and the errno file descriptor! */
 
@@ -147,8 +148,7 @@ Operation *operation_free(Operation *o) {
         safe_close(o->errno_fd);
         safe_close(o->extra_fd);
 
-        if (o->pid > 1)
-                sigkill_wait(o->pid);
+        pidref_done_sigkill_wait(&o->pidref);
 
         sd_bus_message_unref(o->message);
         sd_varlink_unref(o->link);
index 2425694aff1a7ff057575ca1756782689a92ad00..db9c8dfbda4ae5f2d57ee46854b81b22cfd2980a 100644 (file)
@@ -3,13 +3,14 @@
 
 #include "list.h"
 #include "machine-forward.h"
+#include "pidref.h"
 
 #define OPERATIONS_MAX 64
 
 typedef struct Operation {
         Manager *manager;
         Machine *machine;
-        pid_t pid;
+        PidRef pidref;
 
         /* only one of these two fields should be set */
         sd_varlink *link;
@@ -23,7 +24,7 @@ typedef struct Operation {
         LIST_FIELDS(Operation, operations_by_machine);
 } Operation;
 
-int operation_new(Manager *manager, Machine *machine, pid_t child, int errno_fd, Operation **ret);
+int operation_new(Manager *manager, Machine *machine, PidRef *child, int errno_fd, Operation **ret);
 Operation *operation_free(Operation *o);
 
 void operation_attach_bus_reply(Operation *op, sd_bus_message *message);
@@ -32,7 +33,7 @@ void operation_attach_varlink_reply(Operation *op, sd_varlink *link);
 static inline int operation_new_with_bus_reply(
                 Manager *manager,
                 Machine *machine,
-                pid_t child,
+                PidRef *child,
                 sd_bus_message *message,
                 int errno_fd,
                 Operation **ret) {
@@ -55,7 +56,7 @@ static inline int operation_new_with_bus_reply(
 static inline int operation_new_with_varlink_reply(
                 Manager *manager,
                 Machine *machine,
-                pid_t child,
+                PidRef *child,
                 sd_varlink *link,
                 int errno_fd,
                 Operation **ret) {
index 342a9b9212ebedf297da424e678a2ae620d9458d..1c167ebc029ac23a02c44bdc6afe6606bc6f5da5 100644 (file)
 #include "log.h"
 #include "mkdir.h"
 #include "nspawn-setuid.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "user-util.h"
 
-static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
+static int spawn_getent(const char *database, const char *key, PidRef *ret) {
         int pipe_fds[2], r;
-        pid_t pid;
 
         assert(database);
         assert(key);
-        assert(rpid);
+        assert(ret);
 
         if (pipe2(pipe_fds, O_CLOEXEC) < 0)
                 return log_error_errno(errno, "Failed to allocate pipe: %m");
 
-        r = safe_fork_full("(getent)",
-                           (int[]) { -EBADF, pipe_fds[1], -EBADF }, NULL, 0,
-                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
-                           &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork_full(
+                        "(getent)",
+                        (int[]) { -EBADF, pipe_fds[1], -EBADF }, NULL, 0,
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+                        &pidref);
         if (r < 0) {
                 safe_close_pair(pipe_fds);
                 return r;
@@ -43,7 +45,7 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
 
         pipe_fds[1] = safe_close(pipe_fds[1]);
 
-        *rpid = pid;
+        *ret = TAKE_PIDREF(pidref);
 
         return pipe_fds[0];
 }
@@ -84,7 +86,6 @@ int change_uid_gid(const char *user, bool chown_stdio, char **ret_home) {
         unsigned n_gids = 0;
         uid_t uid;
         gid_t gid;
-        pid_t pid;
         int r;
 
         assert(ret_home);
@@ -101,7 +102,8 @@ int change_uid_gid(const char *user, bool chown_stdio, char **ret_home) {
         }
 
         /* First, get user credentials */
-        fd = spawn_getent("passwd", user, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        fd = spawn_getent("passwd", user, &pidref);
         if (fd < 0)
                 return fd;
 
@@ -116,7 +118,7 @@ int change_uid_gid(const char *user, bool chown_stdio, char **ret_home) {
         if (r < 0)
                 return log_error_errno(r, "Failed to read from getent: %m");
 
-        (void) wait_for_terminate_and_check("getent passwd", pid, WAIT_LOG);
+        (void) pidref_wait_for_terminate_and_check("getent passwd", &pidref, WAIT_LOG);
 
         x = strchr(line, ':');
         if (!x)
@@ -173,7 +175,8 @@ int change_uid_gid(const char *user, bool chown_stdio, char **ret_home) {
         line = mfree(line);
 
         /* Second, get group memberships */
-        fd = spawn_getent("initgroups", user, &pid);
+        pidref_done(&pidref);
+        fd = spawn_getent("initgroups", user, &pidref);
         if (fd < 0)
                 return fd;
 
@@ -188,7 +191,7 @@ int change_uid_gid(const char *user, bool chown_stdio, char **ret_home) {
         if (r < 0)
                 return log_error_errno(r, "Failed to read from getent: %m");
 
-        (void) wait_for_terminate_and_check("getent initgroups", pid, WAIT_LOG);
+        (void) pidref_wait_for_terminate_and_check("getent initgroups", &pidref, WAIT_LOG);
 
         /* Skip over the username and subsequent separator whitespace */
         x = line;
index e4fccaa3a7860ecefa039fdd578f89cba6d9668b..bb90cc1c9404d79e944e8b6fdfccd3878516f01c 100644 (file)
@@ -2884,7 +2884,7 @@ static int recursive_chown(const char *directory, uid_t shift, uid_t range) {
 
 /*
  * Return values:
- * < 0 : wait_for_terminate() failed to get the state of the
+ * < 0 : pidref_wait_for_terminate() failed to get the state of the
  *       container, the container was terminated by a signal, or
  *       failed for an unknown reason.  No change is made to the
  *       container argument.
index 15aaca61fc26ef7791826eb38a7ce74b5bd8d062..7004d03c4829873e435f56dcb038460d7ed03b3a 100644 (file)
@@ -541,7 +541,7 @@ static int allocate_now(
 }
 
 static int write_userns(int usernsfd, const UserNamespaceInfo *userns_info) {
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         _cleanup_close_ int efd = -EBADF;
         uint64_t u;
         int r;
@@ -560,7 +560,7 @@ static int write_userns(int usernsfd, const UserNamespaceInfo *userns_info) {
         if (efd < 0)
                 return log_error_errno(errno, "Failed to allocate eventfd(): %m");
 
-        r = safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_LOG, &pid);
+        r = pidref_safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_LOG, &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -590,7 +590,7 @@ static int write_userns(int usernsfd, const UserNamespaceInfo *userns_info) {
 
         _cleanup_free_ char *pmap = NULL;
 
-        if (asprintf(&pmap, "/proc/" PID_FMT "/uid_map", pid) < 0)
+        if (asprintf(&pmap, "/proc/" PID_FMT "/uid_map", pidref.pid) < 0)
                 return log_oom();
 
         r = write_string_filef(pmap, 0, UID_FMT " " UID_FMT " %" PRIu32 "\n", userns_info->target_uid, userns_info->start_uid, userns_info->size);
@@ -598,7 +598,7 @@ static int write_userns(int usernsfd, const UserNamespaceInfo *userns_info) {
                 return log_error_errno(r, "Failed to write 'uid_map' file of user namespace: %m");
 
         pmap = mfree(pmap);
-        if (asprintf(&pmap, "/proc/" PID_FMT "/gid_map", pid) < 0)
+        if (asprintf(&pmap, "/proc/" PID_FMT "/gid_map", pidref.pid) < 0)
                 return log_oom();
 
         r = write_string_filef(pmap, 0, GID_FMT " " GID_FMT " %" PRIu32 "\n", userns_info->target_gid, userns_info->start_gid, userns_info->size);
index 68ac3e47220794bbfd08f1363e73a8ff970689a6..b40c6551bca949e08541376e61a926cf1ff21f37 100644 (file)
@@ -11,6 +11,7 @@
 #include "log.h"
 #include "main-func.h"
 #include "namespace-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "rm-rf.h"
 #include "tmpfile-util.h"
@@ -56,7 +57,7 @@ static int run(int argc, char *argv[]) {
         _cleanup_(userns_restrict_bpf_freep) struct userns_restrict_bpf *obj = NULL;
         _cleanup_close_ int userns_fd = -EBADF, host_fd1 = -EBADF, host_tmpfs = -EBADF, afd = -EBADF, bfd = -EBADF;
         _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
-        _cleanup_(sigkill_waitp) pid_t pid = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         int r;
 
         log_set_max_level(LOG_DEBUG);
@@ -100,7 +101,7 @@ static int run(int argc, char *argv[]) {
 
         assert_se(afd >= 0 && bfd >= 0);
 
-        r = safe_fork("(test)", FORK_DEATHSIG_SIGKILL, &pid);
+        r = pidref_safe_fork("(test)", FORK_DEATHSIG_SIGKILL, &pidref);
         assert_se(r >= 0);
         if (r == 0) {
                 _cleanup_close_ int private_tmpfs = -EBADF;
@@ -178,7 +179,7 @@ static int run(int argc, char *argv[]) {
 
         assert_se(eventfd_write(bfd, 1) >= 0);
 
-        assert_se(wait_for_terminate_and_check("(test)", pid, WAIT_LOG) >= 0);
+        assert_se(pidref_wait_for_terminate_and_check("(test)", &pidref, WAIT_LOG) >= 0);
 
         return 0;
 }
index c30fac53fe1a8a2ba1ae55ef930ca690de4c4445..c3fdf5d5afb428f32f8be67dbab281ae7b45e94f 100644 (file)
 #include "mkdir.h"
 #include "os-util.h"
 #include "path-lookup.h"
+#include "pidref.h"
 #include "portable.h"
 #include "portable-util.h"
 #include "process-util.h"
 #include "rm-rf.h"
 #include "selinux-util.h"
 #include "set.h"
-#include "signal-util.h"
 #include "socket-util.h"
 #include "sort-util.h"
 #include "string-table.h"
@@ -400,7 +400,7 @@ static int portable_extract_by_path(
                 _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
                 _cleanup_(rmdir_and_freep) char *tmpdir = NULL;
                 _cleanup_close_pair_ int seq[2] = EBADF_PAIR;
-                _cleanup_(sigkill_waitp) pid_t child = 0;
+                _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
                 DissectImageFlags flags =
                         DISSECT_IMAGE_READ_ONLY |
                         DISSECT_IMAGE_GENERIC_ROOT |
@@ -420,8 +420,6 @@ static int portable_extract_by_path(
                 /* We now have a loopback block device, let's fork off a child in its own mount namespace, mount it
                  * there, and extract the metadata we need. The metadata is sent from the child back to us. */
 
-                BLOCK_SIGNALS(SIGCHLD);
-
                 /* Load some libraries before we fork workers off that want to use them */
                 (void) dlopen_cryptsetup();
                 (void) dlopen_libmount();
@@ -454,7 +452,7 @@ static int portable_extract_by_path(
                 if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, seq) < 0)
                         return log_debug_errno(errno, "Failed to allocated SOCK_SEQPACKET socket: %m");
 
-                r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_LOG, &child);
+                r = pidref_safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_LOG, &child);
                 if (r < 0)
                         return r;
                 if (r == 0) {
@@ -540,10 +538,11 @@ static int portable_extract_by_path(
                                 assert_not_reached();
                 }
 
-                r = wait_for_terminate_and_check("(sd-dissect)", child, 0);
+                r = pidref_wait_for_terminate_and_check("(sd-dissect)", &child, 0);
                 if (r < 0)
                         return r;
-                child = 0;
+
+                TAKE_PIDREF(child);
         }
 
         if (!os_release)
index 21d7bab262c4bd41ec1cbef8a82fd9694bfbca3a..3dbc094a217467e0ff45d36985df0a27c3bc0f28 100644 (file)
@@ -488,7 +488,7 @@ int bus_image_common_remove(
                 sd_bus_error *error) {
 
         _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
-        _cleanup_(sigkill_waitp) pid_t child = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
         PortableState state;
         int r;
 
@@ -533,7 +533,7 @@ int bus_image_common_remove(
         if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
                 return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
 
-        r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
+        r = pidref_safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
         if (r < 0)
                 return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
         if (r == 0) {
@@ -550,11 +550,11 @@ int bus_image_common_remove(
 
         errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
 
-        r = operation_new(m, child, message, errno_pipe_fd[0], NULL);
+        r = operation_new(m, &child, message, errno_pipe_fd[0], NULL);
         if (r < 0)
                 return r;
 
-        child = 0;
+        TAKE_PIDREF(child);
         errno_pipe_fd[0] = -EBADF;
 
         return 1;
index c0039957dc2343161d70b80fad7e41c3d3394d2a..99d933a6322845f0a43008a9271ddce161ed5709 100644 (file)
@@ -7,6 +7,7 @@
 #include "sd-event.h"
 
 #include "alloc-util.h"
+#include "event-util.h"
 #include "fd-util.h"
 #include "format-util.h"
 #include "log.h"
@@ -22,10 +23,10 @@ static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdat
         assert(si);
 
         log_debug("Operation " PID_FMT " is now complete with code=%s status=%i",
-                  o->pid,
+                  o->pidref.pid,
                   sigchld_code_to_string(si->si_code), si->si_status);
 
-        o->pid = 0;
+        pidref_done(&o->pidref);
 
         if (si->si_code != CLD_EXITED) {
                 r = sd_bus_error_set(&error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
@@ -74,12 +75,12 @@ fail:
         return 0;
 }
 
-int operation_new(Manager *manager, pid_t child, sd_bus_message *message, int errno_fd, Operation **ret) {
+int operation_new(Manager *manager, PidRef *child, sd_bus_message *message, int errno_fd, Operation **ret) {
         Operation *o;
         int r;
 
         assert(manager);
-        assert(child > 1);
+        assert(pidref_is_set(child));
         assert(message);
         assert(errno_fd >= 0);
 
@@ -89,13 +90,13 @@ int operation_new(Manager *manager, pid_t child, sd_bus_message *message, int er
 
         o->extra_fd = -EBADF;
 
-        r = sd_event_add_child(manager->event, &o->event_source, child, WEXITED, operation_done, o);
+        r = event_add_child_pidref(manager->event, &o->event_source, child, WEXITED, operation_done, o);
         if (r < 0) {
                 free(o);
                 return r;
         }
 
-        o->pid = child;
+        o->pidref = TAKE_PIDREF(*child);
         o->message = sd_bus_message_ref(message);
         o->errno_fd = errno_fd;
 
@@ -103,7 +104,7 @@ int operation_new(Manager *manager, pid_t child, sd_bus_message *message, int er
         manager->n_operations++;
         o->manager = manager;
 
-        log_debug("Started new operation " PID_FMT ".", child);
+        log_debug("Started new operation " PID_FMT ".", o->pidref.pid);
 
         /* At this point we took ownership of both the child and the errno file descriptor! */
 
@@ -122,8 +123,7 @@ Operation *operation_free(Operation *o) {
         safe_close(o->errno_fd);
         safe_close(o->extra_fd);
 
-        if (o->pid > 1)
-                sigkill_wait(o->pid);
+        pidref_done_sigkill_wait(&o->pidref);
 
         sd_bus_message_unref(o->message);
 
index 7d3210a3f35eeee9e580bd44840a35f664e8ccb4..7e46264a04a3863547242586b2291d3dbd8e58b1 100644 (file)
@@ -2,13 +2,14 @@
 #pragma once
 
 #include "list.h"
+#include "pidref.h"
 #include "portabled-forward.h"
 
 #define OPERATIONS_MAX 64
 
 typedef struct Operation {
         Manager *manager;
-        pid_t pid;
+        PidRef pidref;
         sd_bus_message *message;
         int errno_fd;
         int extra_fd;
@@ -17,5 +18,5 @@ typedef struct Operation {
         LIST_FIELDS(Operation, operations);
 } Operation;
 
-int operation_new(Manager *manager, pid_t child, sd_bus_message *message, int errno_fd, Operation **ret);
+int operation_new(Manager *manager, PidRef *child, sd_bus_message *message, int errno_fd, Operation **ret);
 Operation *operation_free(Operation *o);
index 015d413506c7e08fa8a57010a933f21b157b5906..438fda7c45df14d7cf067f9d3679a1cf7e9df5d4 100644 (file)
@@ -1,19 +1,17 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <signal.h>
-
 #include "ask-password-agent.h"
 #include "bus-util.h"
 #include "exec-util.h"
 #include "log.h"
-#include "process-util.h"
+#include "pidref.h"
 
-static pid_t agent_pid = 0;
+static PidRef agent_pidref = PIDREF_NULL;
 
 int ask_password_agent_open(void) {
         int r;
 
-        if (agent_pid > 0)
+        if (pidref_is_set(&agent_pidref))
                 return 0;
 
         r = shall_fork_agent();
@@ -22,7 +20,7 @@ int ask_password_agent_open(void) {
 
         r = fork_agent("(sd-askpwagent)",
                        NULL, 0,
-                       &agent_pid,
+                       &agent_pidref,
                        SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH,
                        "--watch");
         if (r < 0)
@@ -32,12 +30,8 @@ int ask_password_agent_open(void) {
 }
 
 void ask_password_agent_close(void) {
-
-        if (agent_pid <= 0)
-                return;
-
         /* Inform agent that we are done */
-        sigterm_wait(TAKE_PID(agent_pid));
+        pidref_done_sigterm_wait(&agent_pidref);
 }
 
 int ask_password_agent_open_if_enabled(BusTransport transport, bool ask_password) {
index e155970e313cc5627e6a3161bc2652b4922affd9..bb83386c5a2681502d58fdd69103bb157e7e77c5 100644 (file)
 #include "openssl-util.h"
 #include "os-util.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "proc-cmdline.h"
 #include "process-util.h"
 #include "resize-fs.h"
 #include "runtime-scope.h"
-#include "signal-util.h"
 #include "siphash24.h"
 #include "stat-util.h"
 #include "string-util.h"
@@ -2237,7 +2237,6 @@ static int is_loop_device(const char *path) {
 
 static int run_fsck(int node_fd, const char *fstype) {
         int r, exit_status;
-        pid_t pid;
 
         assert(node_fd >= 0);
         assert(fstype);
@@ -2252,12 +2251,13 @@ static int run_fsck(int node_fd, const char *fstype) {
                 return 0;
         }
 
-        r = safe_fork_full(
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork_full(
                         "(fsck)",
                         NULL,
                         &node_fd, 1, /* Leave the node fd open */
                         FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_CLOEXEC_OFF,
-                        &pid);
+                        &pidref);
         if (r < 0)
                 return log_debug_errno(r, "Failed to fork off fsck: %m");
         if (r == 0) {
@@ -2268,7 +2268,7 @@ static int run_fsck(int node_fd, const char *fstype) {
                 _exit(FSCK_OPERATIONAL_ERROR);
         }
 
-        exit_status = wait_for_terminate_and_check("fsck", pid, 0);
+        exit_status = pidref_wait_for_terminate_and_check("fsck", &pidref, 0);
         if (exit_status < 0)
                 return log_debug_errno(exit_status, "Failed to fork off fsck: %m");
 
@@ -4170,15 +4170,13 @@ int dissected_image_acquire_metadata(
         _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **initrd_release = NULL, **sysext_release = NULL, **confext_release = NULL;
         _cleanup_free_ char *hostname = NULL, *t = NULL;
         _cleanup_close_pair_ int error_pipe[2] = EBADF_PAIR;
-        _cleanup_(sigkill_waitp) pid_t child = 0;
+        _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
         sd_id128_t machine_id = SD_ID128_NULL;
         unsigned n_meta_initialized = 0;
         int fds[2 * _META_MAX], r, v;
         int has_init_system = -1;
         ssize_t n;
 
-        BLOCK_SIGNALS(SIGCHLD);
-
         assert(m);
 
         r = dlopen_libmount();
@@ -4203,7 +4201,7 @@ int dissected_image_acquire_metadata(
                 goto finish;
         }
 
-        r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM, &child);
+        r = pidref_safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM, &child);
         if (r < 0)
                 goto finish;
         if (r == 0) {
@@ -4426,11 +4424,12 @@ int dissected_image_acquire_metadata(
                 }}
         }
 
-        r = wait_for_terminate_and_check("(sd-dissect)", child, 0);
-        child = 0;
+        r = pidref_wait_for_terminate_and_check("(sd-dissect)", &child, 0);
         if (r < 0)
                 goto finish;
 
+        TAKE_PIDREF(child);
+
         n = read(error_pipe[0], &v, sizeof(v));
         if (n < 0) {
                 r = -errno;
index 673460efb650df101706dc4f4d4b41d961263c43..98c3f6748d4f2912181638e597082d0beafe9a5d 100644 (file)
@@ -17,6 +17,7 @@
 #include "hashmap.h"
 #include "log.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "serialize.h"
 #include "stat-util.h"
 
 #define EXIT_SKIP_REMAINING 77
 
+DEFINE_PRIVATE_HASH_OPS_FULL(pidref_hash_ops_free_free,
+                             PidRef, pidref_hash_func, pidref_compare_func,
+                             pidref_free, char*, free);
+
 /* Put this test here for a lack of better place */
 assert_cc(EAGAIN == EWOULDBLOCK);
 
@@ -36,25 +41,25 @@ static int do_spawn(
                 char *argv[],
                 int stdout_fd,
                 bool set_systemd_exec_pid,
-                pid_t *ret_pid) {
+                PidRef *ret) {
 
         int r;
 
         assert(path);
-        assert(ret_pid);
+        assert(ret);
 
         if (null_or_empty_path(path) > 0) {
                 log_debug("%s is masked, skipping.", path);
                 return 0;
         }
 
-        pid_t pid;
-        r = safe_fork_full(
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork_full(
                         "(exec-inner)",
                         (const int[]) { STDIN_FILENO, stdout_fd < 0 ? STDOUT_FILENO : stdout_fd, STDERR_FILENO },
                         /* except_fds= */ NULL, /* n_except_fds= */ 0,
                         FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO|FORK_CLOSE_ALL_FDS,
-                        &pid);
+                        &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -78,7 +83,7 @@ static int do_spawn(
                 _exit(EXIT_FAILURE);
         }
 
-        *ret_pid = pid;
+        *ret = TAKE_PIDREF(pidref);
         return 1;
 }
 
@@ -121,7 +126,6 @@ static int do_execute(
         STRV_FOREACH(path, paths) {
                 _cleanup_free_ char *t = NULL;
                 _cleanup_close_ int fd = -EBADF;
-                pid_t pid;
 
                 t = path_join(root, *path);
                 if (!t)
@@ -161,19 +165,27 @@ static int do_execute(
                                             "permission bits. Proceeding anyway.", t);
                 }
 
-                r = do_spawn(t, argv, fd, FLAGS_SET(flags, EXEC_DIR_SET_SYSTEMD_EXEC_PID), &pid);
+                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+                r = do_spawn(t, argv, fd, FLAGS_SET(flags, EXEC_DIR_SET_SYSTEMD_EXEC_PID), &pidref);
                 if (r <= 0)
                         continue;
 
                 if (parallel_execution) {
-                        r = hashmap_ensure_put(&pids, &trivial_hash_ops_value_free, PID_TO_PTR(pid), t);
+                        _cleanup_(pidref_freep) PidRef *dup = NULL;
+                        r = pidref_dup(&pidref, &dup);
+                        if (r < 0)
+                                return r;
+
+                        r = hashmap_ensure_put(&pids, &pidref_hash_ops_free_free, dup, t);
                         if (r < 0)
                                 return log_oom();
-                        t = NULL;
+
+                        TAKE_PTR(dup);
+                        TAKE_PTR(t);
                 } else {
                         bool skip_remaining = false;
 
-                        r = wait_for_terminate_and_check(t, pid, WAIT_LOG_ABNORMAL);
+                        r = pidref_wait_for_terminate_and_check(t, &pidref, WAIT_LOG_ABNORMAL);
                         if (r < 0)
                                 return r;
                         if (r > 0) {
@@ -211,14 +223,12 @@ static int do_execute(
 
         while (!hashmap_isempty(pids)) {
                 _cleanup_free_ char *t = NULL;
-                pid_t pid;
                 void *p;
 
                 t = ASSERT_PTR(hashmap_steal_first_key_and_value(pids, &p));
-                pid = PTR_TO_PID(p);
-                assert(pid > 0);
+                _cleanup_(pidref_freep) PidRef *pidref = p;
 
-                r = wait_for_terminate_and_check(t, pid, WAIT_LOG);
+                r = pidref_wait_for_terminate_and_check(t, pidref, WAIT_LOG);
                 if (r < 0)
                         return r;
                 if (!FLAGS_SET(flags, EXEC_DIR_IGNORE_ERRORS) && r > 0)
@@ -240,7 +250,6 @@ int execute_strv(
                 ExecDirFlags flags) {
 
         _cleanup_close_ int fd = -EBADF;
-        pid_t executor_pid;
         int r;
 
         assert(name);
@@ -266,7 +275,8 @@ int execute_strv(
 
         const char *process_name = strjoina("(", name, ")");
 
-        r = safe_fork(process_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &executor_pid);
+        PidRef executor_pidref = PIDREF_NULL;
+        r = pidref_safe_fork(process_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &executor_pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -274,7 +284,7 @@ int execute_strv(
                 _exit(r < 0 ? EXIT_FAILURE : r);
         }
 
-        r = wait_for_terminate_and_check(process_name, executor_pid, 0);
+        r = pidref_wait_for_terminate_and_check(process_name, &executor_pidref, 0);
         if (r < 0)
                 return r;
         if (!FLAGS_SET(flags, EXEC_DIR_IGNORE_ERRORS) && r > 0)
@@ -560,19 +570,19 @@ int shall_fork_agent(void) {
         return true;
 }
 
-int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, pid_t *ret_pid) {
+int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, PidRef *ret) {
         int r;
 
         assert(!strv_isempty(argv));
 
         /* Spawns a temporary TTY agent, making sure it goes away when we go away */
 
-        r = safe_fork_full(name,
-                           NULL,
-                           (int*) except, /* safe_fork_full only changes except if you pass in FORK_PACK_FDS, which we don't */
-                           n_except,
-                           FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_RLIMIT_NOFILE_SAFE,
-                           ret_pid);
+        r = pidref_safe_fork_full(
+                        name,
+                        /* stdio_fds= */ NULL,
+                        (int*) except, n_except, /* safe_fork_full only changes except if you pass in FORK_PACK_FDS, which we don't */
+                        FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_RLIMIT_NOFILE_SAFE,
+                        ret);
         if (r < 0)
                 return r;
         if (r > 0)
index bb825e9969064c2e35c7ae2e379fceb58f213f5f..245b7773f4bdb41ba3aa7fc58aadb21cdccc5ebb 100644 (file)
@@ -62,5 +62,5 @@ ExecCommandFlags exec_command_flags_from_string(const char *s);
 int fexecve_or_execve(int executable_fd, const char *executable, char *const argv[], char *const envp[]);
 
 int shall_fork_agent(void);
-int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, pid_t *ret_pid);
-#define fork_agent(name, except, n_except, ret_pid, ...) _fork_agent(name, STRV_MAKE(__VA_ARGS__), except, n_except, ret_pid)
+int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, PidRef *ret);
+#define fork_agent(name, except, n_except, ret, ...) _fork_agent(name, STRV_MAKE(__VA_ARGS__), except, n_except, ret)
index 2b66dc91d207c7a6c70b96d3bc012097722ad2c5..203e65038898d7c2042f76cd3ca97f7ba36d1a06 100644 (file)
@@ -14,6 +14,7 @@
 #include "locale-util.h"
 #include "log.h"
 #include "pager.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "signal-util.h"
 #include "string-util.h"
@@ -288,8 +289,10 @@ void pager_close(void) {
         stdout_redirected = stderr_redirected = false;
 
         (void) kill(pager_pid, SIGCONT);
-        (void) wait_for_terminate(TAKE_PID(pager_pid), NULL);
-        pager_pid = 0;
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pager_pid);
+        (void) pidref_set_pid(&pidref, pager_pid);
+        (void) pidref_wait_for_terminate(&pidref, NULL);
+        TAKE_PID(pager_pid);
 }
 
 bool pager_have(void) {
@@ -299,7 +302,6 @@ bool pager_have(void) {
 int show_man_page(const char *desc, bool null_stdio) {
         const char *args[4] = { "man", NULL, NULL, NULL };
         const char *e = NULL;
-        pid_t pid;
         size_t k;
         int r;
 
@@ -319,7 +321,11 @@ int show_man_page(const char *desc, bool null_stdio) {
         } else
                 args[1] = desc;
 
-        r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|(null_stdio ? FORK_REARRANGE_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork(
+                        "(man)",
+                        FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|(null_stdio ? FORK_REARRANGE_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_WAIT,
+                        &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -329,5 +335,5 @@ int show_man_page(const char *desc, bool null_stdio) {
                 _exit(EXIT_FAILURE);
         }
 
-        return wait_for_terminate_and_check(NULL, pid, 0);
+        return pidref_wait_for_terminate_and_check(NULL, &pidref, 0);
 }
index 491b494b1e7581b09df20debd5b7c9384e1b21ae..5b4e5db819e30d363febf4be5b5125a587b53404 100644 (file)
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include <poll.h>
-#include <signal.h>
 #include <unistd.h>
 
 #include "bus-util.h"
@@ -9,19 +8,19 @@
 #include "fd-util.h"
 #include "io-util.h"
 #include "log.h"
+#include "pidref.h"
 #include "polkit-agent.h"
-#include "process-util.h"
 #include "stdio-util.h"
 
 #if ENABLE_POLKIT
-static pid_t agent_pid = 0;
+static PidRef agent_pidref = PIDREF_NULL;
 
 int polkit_agent_open(void) {
         _cleanup_close_pair_ int pipe_fd[2] = EBADF_PAIR;
         char notify_fd[DECIMAL_STR_MAX(int) + 1];
         int r;
 
-        if (agent_pid > 0)
+        if (pidref_is_set(&agent_pidref))
                 return 0;
 
         /* Clients that run as root don't need to activate/query polkit */
@@ -40,7 +39,7 @@ int polkit_agent_open(void) {
         r = fork_agent("(polkit-agent)",
                        &pipe_fd[1],
                        1,
-                       &agent_pid,
+                       &agent_pidref,
                        POLKIT_AGENT_BINARY_PATH,
                        "--notify-fd", notify_fd,
                        "--fallback");
@@ -57,12 +56,8 @@ int polkit_agent_open(void) {
 }
 
 void polkit_agent_close(void) {
-
-        if (agent_pid <= 0)
-                return;
-
         /* Inform agent that we are done */
-        sigterm_wait(TAKE_PID(agent_pid));
+        pidref_done_sigterm_wait(&agent_pidref);
 }
 
 #else
index c851278d0683d2b975f7b3feccfcca0c948732f4..55464c3553fbebeb224bfc03df01cc486e84f55c 100644 (file)
@@ -448,7 +448,12 @@ int assert_signal_internal(int *ret_signal) {
                 return ASSERT_SIGNAL_FORK_CHILD;
         }
 
-        r = wait_for_terminate(r, &siginfo);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_set_pid(&pidref, r);
+        if (r < 0)
+                return r;
+
+        r = pidref_wait_for_terminate(&pidref, &siginfo);
         if (r < 0)
                 return r;
 
index 5d691d3d47273758e566cf40992c748c4dca5ab6..7705097c6cfde3c598fe9b5400852669c969a6d6 100644 (file)
@@ -16,6 +16,7 @@
 #include "initrd-util.h"
 #include "log.h"
 #include "main-func.h"
+#include "pidref.h"
 #include "proc-cmdline.h"
 #include "process-util.h"
 #include "special.h"
@@ -66,10 +67,10 @@ static int start_target(sd_bus *bus, const char *target) {
 }
 
 static int fork_wait(const char* const cmdline[]) {
-        pid_t pid;
         int r;
 
-        r = safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -79,7 +80,7 @@ static int fork_wait(const char* const cmdline[]) {
                 _exit(EXIT_FAILURE); /* Operational error */
         }
 
-        return wait_for_terminate_and_check(cmdline[0], pid, WAIT_LOG_ABNORMAL);
+        return pidref_wait_for_terminate_and_check(cmdline[0], &pidref, WAIT_LOG_ABNORMAL);
 }
 
 static void print_mode(const char* mode) {
index 7b60dd346b50cf3d3d584adf3b332b357ad5f5c3..33a5ea8bcda09ee783f3e843ea7a8317e4b415ae 100644 (file)
@@ -48,6 +48,7 @@
 #include "parse-argument.h"
 #include "parse-util.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "pretty-print.h"
 #include "process-util.h"
 #include "rm-rf.h"
@@ -2139,14 +2140,15 @@ static int merge(ImageClass image_class,
                  bool no_reload,
                  int noexec,
                  Hashmap *images) {
-        pid_t pid;
+
         int r;
 
         (void) dlopen_cryptsetup();
         (void) dlopen_libblkid();
         (void) dlopen_libmount();
 
-        r = safe_fork("(sd-merge)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork("(sd-merge)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, &pidref);
         if (r < 0)
                 return log_error_errno(r, "Failed to fork off child: %m");
         if (r == 0) {
@@ -2162,7 +2164,7 @@ static int merge(ImageClass image_class,
                 _exit(r > 0 ? EXIT_SUCCESS : 123); /* 123 means: didn't find any extensions */
         }
 
-        r = wait_for_terminate_and_check("(sd-merge)", pid, WAIT_LOG_ABNORMAL);
+        r = pidref_wait_for_terminate_and_check("(sd-merge)", &pidref, WAIT_LOG_ABNORMAL);
         if (r < 0)
                 return r;
         if (r == 123) /* exit code 123 means: didn't do anything */
index 3905a678b6de7f98811756d020853f4894bd27cb..adc73c310ec5491ad02f479e411b80e558425a4f 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -9,6 +8,7 @@
 #include "log.h"
 #include "path-lookup.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "string-util.h"
 #include "strv.h"
@@ -56,7 +56,6 @@ int enable_sysv_units(const char *verb, char **args) {
                 bool found_native = false, found_sysv;
                 const char *name;
                 unsigned c = 1;
-                pid_t pid;
                 int j;
 
                 name = args[f++];
@@ -122,7 +121,8 @@ int enable_sysv_units(const char *verb, char **args) {
                 if (!arg_quiet)
                         log_info("Executing: %s", l);
 
-                j = safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+                j = pidref_safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
                 if (j < 0)
                         return j;
                 if (j == 0) {
@@ -132,7 +132,7 @@ int enable_sysv_units(const char *verb, char **args) {
                         _exit(EXIT_FAILURE);
                 }
 
-                j = wait_for_terminate_and_check("sysv-install", pid, WAIT_LOG_ABNORMAL);
+                j = pidref_wait_for_terminate_and_check("sysv-install", &pidref, WAIT_LOG_ABNORMAL);
                 if (j < 0)
                         return j;
                 if (streq(verb, "is-enabled")) {
index 2cbc26ea53942bd658973d0ca50c7dbb0bb90a7a..b48be8bab01ff003ce30e762fa4e2ce747948a88 100644 (file)
@@ -21,6 +21,7 @@
 #include "gpt.h"
 #include "hexdecoct.h"
 #include "import-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "sort-util.h"
 #include "stat-util.h"
@@ -274,7 +275,6 @@ static int download_manifest(
         _cleanup_close_pair_ int pfd[2] = EBADF_PAIR;
         _cleanup_fclose_ FILE *manifest = NULL;
         size_t size = 0;
-        pid_t pid;
         int r;
 
         assert(url);
@@ -293,11 +293,13 @@ static int download_manifest(
         log_info("%s Acquiring manifest file %s%s", glyph(GLYPH_DOWNLOAD),
                  suffixed_url, glyph(GLYPH_ELLIPSIS));
 
-        r = safe_fork_full("(sd-pull)",
-                           (int[]) { -EBADF, pfd[1], STDERR_FILENO },
-                           NULL, 0,
-                           FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG,
-                           &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork_full(
+                        "(sd-pull)",
+                        (int[]) { -EBADF, pfd[1], STDERR_FILENO },
+                        NULL, 0,
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG,
+                        &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -337,7 +339,7 @@ static int download_manifest(
 
         manifest = safe_fclose(manifest);
 
-        r = wait_for_terminate_and_check("(sd-pull)", pid, WAIT_LOG);
+        r = pidref_wait_for_terminate_and_check("(sd-pull)", &pidref, WAIT_LOG);
         if (r < 0)
                 return r;
         if (r != 0)
index f7a99ff26d94d116b21d38ddc1b7cb4ba9196fbf..f449f2aefa2c2993f51bcb8536bb9d12b9d49ead 100644 (file)
@@ -59,53 +59,38 @@ static void test_rename_process_now(const char *p, int ret) {
 }
 
 static void test_rename_process_one(const char *p, int ret) {
-        siginfo_t si;
-        pid_t pid;
+        int r;
 
         log_info("/* %s(%s) */", __func__, p);
 
-        pid = fork();
-        assert_se(pid >= 0);
+        r = ASSERT_OK(safe_fork("(rename)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
 
-        if (pid == 0) {
+        if (r == 0) {
                 /* child */
                 test_rename_process_now(p, ret);
                 _exit(EXIT_SUCCESS);
         }
-
-        assert_se(wait_for_terminate(pid, &si) >= 0);
-        assert_se(si.si_code == CLD_EXITED);
-        assert_se(si.si_status == EXIT_SUCCESS);
 }
 
 TEST(rename_process_invalid) {
-        assert_se(rename_process(NULL) == -EINVAL);
-        assert_se(rename_process("") == -EINVAL);
+        ASSERT_ERROR(rename_process(NULL), EINVAL);
+        ASSERT_ERROR(rename_process(""), EINVAL);
 }
 
 TEST(rename_process_multi) {
-        pid_t pid;
-
-        pid = fork();
-        assert_se(pid >= 0);
-
-        if (pid > 0) {
-                siginfo_t si;
+        int r;
 
-                assert_se(wait_for_terminate(pid, &si) >= 0);
-                assert_se(si.si_code == CLD_EXITED);
-                assert_se(si.si_status == EXIT_SUCCESS);
+        r = ASSERT_OK(safe_fork("(rename)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
 
-                return;
+        if (r == 0) {
+                /* child */
+                test_rename_process_now("one", 1);
+                test_rename_process_now("more", 0); /* longer than "one", hence truncated */
+                (void) setresuid(99, 99, 99); /* change uid when running privileged */
+                test_rename_process_now("time!", 0);
+                test_rename_process_now("0", 1); /* shorter than "one", should fit */
+                _exit(EXIT_SUCCESS);
         }
-
-        /* child */
-        test_rename_process_now("one", 1);
-        test_rename_process_now("more", 0); /* longer than "one", hence truncated */
-        (void) setresuid(99, 99, 99); /* change uid when running privileged */
-        test_rename_process_now("time!", 0);
-        test_rename_process_now("0", 1); /* shorter than "one", should fit */
-        _exit(EXIT_SUCCESS);
 }
 
 TEST(rename_process) {
index 97b5cd4a7e5823945a92168ba907331899892154..0a4ce4fdd4343e020528a81654a8ce4cf60a9d84 100644 (file)
@@ -7,6 +7,7 @@
 #include "data-fd-util.h"
 #include "fd-util.h"
 #include "memfd-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "tests.h"
 
@@ -33,7 +34,7 @@ static void assert_equal_fd(int fd1, int fd2) {
 TEST(copy_data_fd) {
         _cleanup_close_ int fd1 = -EBADF, fd2 = -EBADF;
         _cleanup_close_pair_ int sfd[2] = EBADF_PAIR;
-        _cleanup_(sigkill_waitp) pid_t pid = -1;
+        _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         int r;
 
         fd1 = open("/etc/fstab", O_RDONLY|O_CLOEXEC);
@@ -66,7 +67,7 @@ TEST(copy_data_fd) {
 
         assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, sfd) >= 0);
 
-        r = safe_fork("(sd-pipe)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &pid);
+        r = pidref_safe_fork("(sd-pipe)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &pidref);
         assert_se(r >= 0);
 
         if (r == 0) {
index 973387b3de8b98fc30cd1c93d885fd6f63f94bf9..6c05b3e6a7e6de57ec3a2c6432019a02843726f5 100644 (file)
@@ -246,18 +246,17 @@ static bool apparmor_restrict_unprivileged_userns(void) {
 }
 
 static bool have_userns_privileges(void) {
-        pid_t pid;
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
         int r;
 
         if (apparmor_restrict_unprivileged_userns())
                 return false;
 
-        r = safe_fork("(sd-test-check-userns)",
-                      FORK_RESET_SIGNALS |
-                      FORK_CLOSE_ALL_FDS |
-                      FORK_DEATHSIG_SIGKILL,
-                      &pid);
-        ASSERT_OK(r);
+        r = ASSERT_OK(pidref_safe_fork(
+                        "(sd-test-check-userns)",
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL,
+                        &pidref));
+
         if (r == 0) {
                 /* Keep CAP_SYS_ADMIN if we have it to ensure we give an
                  * accurate result to the caller. Some kernels have a
@@ -282,7 +281,7 @@ static bool have_userns_privileges(void) {
          *  EXIT_SUCCESS => we can use user namespaces
          *  EXIT_FAILURE => we can NOT use user namespaces
          *  2            => some other error occurred */
-        r = wait_for_terminate_and_check("(sd-test-check-userns)", pid, 0);
+        r = pidref_wait_for_terminate_and_check("(sd-test-check-userns)", &pidref, 0);
         if (!IN_SET(r, EXIT_SUCCESS, EXIT_FAILURE))
                 log_debug("Failed to check if user namespaces can be used, assuming not.");
 
index c5f014c63019ddb5abc2b9bca56079db47c0a42c..38d92299467a75cd23ea99d86595319ab162e343 100644 (file)
@@ -12,6 +12,7 @@
 #include "memfd-util.h"
 #include "parse-util.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "random-util.h"
 #include "rm-rf.h"
@@ -492,7 +493,6 @@ TEST(read_full_file_socket) {
         union sockaddr_union sa;
         const char *j, *jj;
         size_t size;
-        pid_t pid;
         int r;
 
         ASSERT_OK(listener = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0));
@@ -513,7 +513,8 @@ TEST(read_full_file_socket) {
         /* Bind the *client* socket to some randomized name, to verify that this works correctly. */
         ASSERT_OK(asprintf(&clientname, "@%" PRIx64 "/test-bindname", random_u64()));
 
-        ASSERT_OK(r = safe_fork("(server)", FORK_DEATHSIG_SIGTERM|FORK_LOG, &pid));
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = ASSERT_OK(pidref_safe_fork("(server)", FORK_DEATHSIG_SIGTERM|FORK_LOG, &pidref));
         if (r == 0) {
                 union sockaddr_union peer = {};
                 socklen_t peerlen = sizeof(peer);
@@ -540,7 +541,7 @@ TEST(read_full_file_socket) {
         ASSERT_EQ(size, strlen(TEST_STR));
         ASSERT_STREQ(data, TEST_STR);
 
-        ASSERT_OK(wait_for_terminate_and_check("(server)", pid, WAIT_LOG));
+        ASSERT_OK(pidref_wait_for_terminate_and_check("(server)", &pidref, WAIT_LOG));
 #undef TEST_STR
 }
 
index 723cc8d0a1023a3d54a76e9b9f5bce380e25f0fb..51b7b146fe3b031d50dfb01da9555354c9a9fea8 100644 (file)
@@ -12,6 +12,7 @@
 #include "fs-util.h"
 #include "mkdir.h"
 #include "path-util.h"
+#include "pidref.h"
 #include "process-util.h"
 #include "random-util.h"
 #include "rm-rf.h"
@@ -743,30 +744,29 @@ TEST(xopenat_lock_full) {
         _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
         _cleanup_close_ int tfd = -EBADF, fd = -EBADF;
         siginfo_t si;
+        int r;
 
-        assert_se((tfd = mkdtemp_open(NULL, 0, &t)) >= 0);
+        ASSERT_OK((tfd = mkdtemp_open(NULL, 0, &t)));
 
         /* Test that we can acquire an exclusive lock on a directory in one process, remove the directory,
          * and close the file descriptor and still properly create the directory and acquire the lock in
          * another process.  */
 
-        fd = xopenat_lock_full(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX);
-        assert_se(fd >= 0);
-        assert_se(faccessat(tfd, "abc", F_OK, 0) >= 0);
-        assert_se(fd_verify_directory(fd) >= 0);
-        assert_se(xopenat_lock_full(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN);
+        fd = ASSERT_OK(xopenat_lock_full(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX));
+        ASSERT_OK_ERRNO(faccessat(tfd, "abc", F_OK, 0));
+        ASSERT_OK(fd_verify_directory(fd));
+        ASSERT_ERROR(xopenat_lock_full(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB), EAGAIN);
 
-        pid_t pid = fork();
-        assert_se(pid >= 0);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = ASSERT_OK(pidref_safe_fork("(lock)", FORK_DEATHSIG_SIGKILL|FORK_LOG, &pidref));
 
-        if (pid == 0) {
+        if (r == 0) {
                 safe_close(fd);
 
-                fd = xopenat_lock_full(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX);
-                assert_se(fd >= 0);
-                assert_se(faccessat(tfd, "abc", F_OK, 0) >= 0);
-                assert_se(fd_verify_directory(fd) >= 0);
-                assert_se(xopenat_lock_full(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN);
+                fd = ASSERT_OK(xopenat_lock_full(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX));
+                ASSERT_OK_ERRNO(faccessat(tfd, "abc", F_OK, 0));
+                ASSERT_OK(fd_verify_directory(fd));
+                ASSERT_ERROR(xopenat_lock_full(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB), EAGAIN);
 
                 _exit(EXIT_SUCCESS);
         }
@@ -777,16 +777,16 @@ TEST(xopenat_lock_full) {
          * for a little and assume that's enough time for the child process to get along far enough. It
          * doesn't matter if it doesn't get far enough, in that case we just won't trigger the fallback logic
          * in xopenat_lock_full(), but the test will still succeed. */
-        assert_se(usleep_safe(20 * USEC_PER_MSEC) >= 0);
+        ASSERT_OK(usleep_safe(20 * USEC_PER_MSEC));
 
-        assert_se(unlinkat(tfd, "abc", AT_REMOVEDIR) >= 0);
+        ASSERT_OK(unlinkat(tfd, "abc", AT_REMOVEDIR));
         fd = safe_close(fd);
 
-        assert_se(wait_for_terminate(pid, &si) >= 0);
-        assert_se(si.si_code == CLD_EXITED);
+        ASSERT_OK(pidref_wait_for_terminate(&pidref, &si));
+        ASSERT_EQ(si.si_code, CLD_EXITED);
 
-        assert_se(xopenat_lock_full(tfd, "abc", 0, 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF);
-        assert_se(xopenat_lock_full(tfd, "def", O_DIRECTORY, 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF);
+        ASSERT_ERROR(xopenat_lock_full(tfd, "abc", 0, 0, 0755, LOCK_POSIX, LOCK_EX), EBADF);
+        ASSERT_ERROR(xopenat_lock_full(tfd, "def", O_DIRECTORY, 0, 0755, LOCK_POSIX, LOCK_EX), EBADF);
 }
 
 TEST(linkat_replace) {
index f162075c7c44a758cd50657630dc8091619fbbf5..1c43c7ab10ea6da87cba546c8bb21fd65d37f528 100644 (file)
@@ -94,7 +94,7 @@ TEST(tmpdir) {
 static void test_shareable_ns(unsigned long nsflag) {
         _cleanup_close_pair_ int s[2] = EBADF_PAIR;
         bool permission_denied = false;
-        pid_t pid1, pid2, pid3;
+        _cleanup_(pidref_done) PidRef pidref1 = PIDREF_NULL, pidref2 = PIDREF_NULL, pidref3 = PIDREF_NULL;
         int r, n = 0;
         siginfo_t si;
 
@@ -105,51 +105,48 @@ static void test_shareable_ns(unsigned long nsflag) {
 
         ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, s));
 
-        pid1 = fork();
-        ASSERT_OK_ERRNO(pid1);
+        r = ASSERT_OK(pidref_safe_fork("(share-ns-1)", FORK_LOG|FORK_DEATHSIG_SIGKILL, &pidref1));
 
-        if (pid1 == 0) {
+        if (r == 0) {
                 r = setup_shareable_ns(s, nsflag);
                 if (!ERRNO_IS_PRIVILEGE(r))
                         ASSERT_OK(r);
                 _exit(r >= 0 ? r : EX_NOPERM);
         }
 
-        pid2 = fork();
-        ASSERT_OK_ERRNO(pid2);
+        r = ASSERT_OK(pidref_safe_fork("(share-ns-2)", FORK_LOG|FORK_DEATHSIG_SIGKILL, &pidref2));
 
-        if (pid2 == 0) {
+        if (r == 0) {
                 r = setup_shareable_ns(s, nsflag);
                 if (!ERRNO_IS_PRIVILEGE(r))
                         ASSERT_OK(r);
                 _exit(r >= 0 ? r : EX_NOPERM);
         }
 
-        pid3 = fork();
-        ASSERT_OK_ERRNO(pid3);
+        r = ASSERT_OK(pidref_safe_fork("(share-ns-3)", FORK_LOG|FORK_DEATHSIG_SIGKILL, &pidref3));
 
-        if (pid3 == 0) {
+        if (r == 0) {
                 r = setup_shareable_ns(s, nsflag);
                 if (!ERRNO_IS_PRIVILEGE(r))
                         ASSERT_OK(r);
                 _exit(r >= 0 ? r : EX_NOPERM);
         }
 
-        ASSERT_OK(wait_for_terminate(pid1, &si));
+        ASSERT_OK(pidref_wait_for_terminate(&pidref1, &si));
         ASSERT_EQ(si.si_code, CLD_EXITED);
         if (si.si_status == EX_NOPERM)
                 permission_denied = true;
         else
                 n += si.si_status;
 
-        ASSERT_OK(wait_for_terminate(pid2, &si));
+        ASSERT_OK(pidref_wait_for_terminate(&pidref2, &si));
         ASSERT_EQ(si.si_code, CLD_EXITED);
         if (si.si_status == EX_NOPERM)
                 permission_denied = true;
         else
                 n += si.si_status;
 
-        ASSERT_OK(wait_for_terminate(pid3, &si));
+        ASSERT_OK(pidref_wait_for_terminate(&pidref3, &si));
         ASSERT_EQ(si.si_code, CLD_EXITED);
         if (si.si_status == EX_NOPERM)
                 permission_denied = true;
@@ -203,7 +200,6 @@ TEST(protect_kernel_logs) {
                 .protect_kernel_logs = true,
                 .root_directory_fd = -EBADF,
         };
-        pid_t pid;
         int r;
 
         if (geteuid() > 0) {
@@ -224,10 +220,9 @@ TEST(protect_kernel_logs) {
         }
         ASSERT_OK(r);
 
-        pid = fork();
-        ASSERT_OK_ERRNO(pid);
+        r = ASSERT_OK(safe_fork("(protect)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
 
-        if (pid == 0) {
+        if (r == 0) {
                 _cleanup_close_ int fd = -EBADF;
 
                 ASSERT_OK_ERRNO(fd = open("/dev/kmsg", O_RDONLY | O_CLOEXEC));
@@ -239,8 +234,6 @@ TEST(protect_kernel_logs) {
 
                 _exit(EXIT_SUCCESS);
         }
-
-        ASSERT_OK_EQ(wait_for_terminate_and_check("ns-kernellogs", pid, WAIT_LOG), EXIT_SUCCESS);
 }
 
 TEST(idmapping_supported) {
index e1a43b8b644a0bbad2fd074726189409b0338520..3df3e747ffafe6b17201d7e381e1a25d7e20bfaf 100644 (file)
@@ -464,7 +464,6 @@ TEST(find_executable) {
 static void test_find_executable_exec_one(const char *path) {
         _cleanup_free_ char *t = NULL;
         _cleanup_close_ int fd = -EBADF;
-        pid_t pid;
         int r;
 
         r = find_executable_full(path, NULL, NULL, false, &t, &fd);
@@ -476,15 +475,13 @@ static void test_find_executable_exec_one(const char *path) {
         if (path_is_absolute(path))
                 ASSERT_STREQ(t, path);
 
-        pid = fork();
-        assert_se(pid >= 0);
-        if (pid == 0) {
+        r = ASSERT_OK(safe_fork("(find-exec)", FORK_LOG|FORK_DEATHSIG_SIGKILL|FORK_WAIT, /* ret_pid= */ NULL));
+
+        if (r == 0) {
                 r = fexecve_or_execve(fd, t, STRV_MAKE(t, "--version"), STRV_MAKE(NULL));
                 log_error_errno(r, "[f]execve: %m");
                 _exit(EXIT_FAILURE);
         }
-
-        assert_se(wait_for_terminate_and_check(t, pid, WAIT_LOG) == 0);
 }
 
 TEST(find_executable_exec) {
index b79784533442ea9962b186d25f5c32815f79d5fa..d4f39bf3ee91ccce19558bfddae06c5f6c7ddb4e 100644 (file)
@@ -263,7 +263,6 @@ TEST(pid_get_cmdline_harder) {
         _cleanup_close_ int fd = -EBADF;
         _cleanup_free_ char *line = NULL;
         _cleanup_strv_free_ char **args = NULL;
-        pid_t pid;
         int r;
 
         if (geteuid() != 0) {
@@ -286,297 +285,286 @@ TEST(pid_get_cmdline_harder) {
         }
 #endif
 
-        pid = fork();
-        if (pid > 0) {
-                siginfo_t si;
-
-                (void) wait_for_terminate(pid, &si);
-
-                ASSERT_EQ(si.si_code, CLD_EXITED);
-                ASSERT_OK_ZERO(si.si_status);
-
-                return;
-        }
-
-        ASSERT_OK_ZERO(pid);
-
-        r = detach_mount_namespace();
-        if (r < 0) {
-                log_warning_errno(r, "detach mount namespace failed: %m");
-                if (!ERRNO_IS_PRIVILEGE(r))
-                        ASSERT_OK(r);
-                return;
-        }
+        r = ASSERT_OK(safe_fork("(cmdline)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
+        if (r == 0) {
+                r = detach_mount_namespace();
+                if (r < 0) {
+                        log_warning_errno(r, "detach mount namespace failed: %m");
+                        if (!ERRNO_IS_PRIVILEGE(r))
+                                ASSERT_OK(r);
+                        return;
+                }
 
-        fd = mkostemp(path, O_CLOEXEC);
-        ASSERT_OK_ERRNO(fd);
+                fd = mkostemp(path, O_CLOEXEC);
+                ASSERT_OK_ERRNO(fd);
 
-        /* Note that we don't unmount the following bind-mount at the end of the test because the kernel
-         * will clear up its /proc/PID/ hierarchy automatically as soon as the test stops. */
-        if (mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) < 0) {
-                /* This happens under selinux… Abort the test in this case. */
-                log_warning_errno(errno, "mount(..., \"/proc/self/cmdline\", \"bind\", ...) failed: %m");
-                ASSERT_TRUE(IN_SET(errno, EPERM, EACCES));
-                return;
-        }
+                /* Note that we don't unmount the following bind-mount at the end of the test because the kernel
+                * will clear up its /proc/PID/ hierarchy automatically as soon as the test stops. */
+                if (mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) < 0) {
+                        /* This happens under selinux… Abort the test in this case. */
+                        log_warning_errno(errno, "mount(..., \"/proc/self/cmdline\", \"bind\", ...) failed: %m");
+                        ASSERT_TRUE(IN_SET(errno, EPERM, EACCES));
+                        return;
+                }
 
-        /* Set RLIMIT_STACK to infinity to test we don't try to allocate unnecessarily large values to read
-         * the cmdline. */
-        if (setrlimit(RLIMIT_STACK, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
-                log_warning("Testing without RLIMIT_STACK=infinity");
+                /* Set RLIMIT_STACK to infinity to test we don't try to allocate unnecessarily large values to read
+                * the cmdline. */
+                if (setrlimit(RLIMIT_STACK, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
+                        log_warning("Testing without RLIMIT_STACK=infinity");
 
-        ASSERT_OK_ERRNO(unlink(path));
+                ASSERT_OK_ERRNO(unlink(path));
 
-        ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "testa"));
+                ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "testa"));
 
-        ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
+                ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
 
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "[testa]");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "[testa]");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "\"[testa]\""); /* quoting is enabled here */
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "\"[testa]\""); /* quoting is enabled here */
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, 0, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, 0, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        ASSERT_STREQ(line, "…");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                ASSERT_STREQ(line, "…");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        ASSERT_STREQ(line, "[…");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                ASSERT_STREQ(line, "[…");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        ASSERT_STREQ(line, "[t…");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                ASSERT_STREQ(line, "[t…");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        ASSERT_STREQ(line, "[te…");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                ASSERT_STREQ(line, "[te…");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        ASSERT_STREQ(line, "[tes…");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                ASSERT_STREQ(line, "[tes…");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        ASSERT_STREQ(line, "[test…");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                ASSERT_STREQ(line, "[test…");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        ASSERT_STREQ(line, "[testa]");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                ASSERT_STREQ(line, "[testa]");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        ASSERT_STREQ(line, "[testa]");
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                ASSERT_STREQ(line, "[testa]");
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
-        ASSERT_TRUE(strv_equal(args, STRV_MAKE("[testa]")));
-        args = strv_free(args);
+                ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
+                ASSERT_TRUE(strv_equal(args, STRV_MAKE("[testa]")));
+                args = strv_free(args);
 
         /* Test with multiple arguments that don't require quoting */
 
-        ASSERT_OK_EQ_ERRNO(write(fd, "foo\0bar", 8), 8);
-
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        ASSERT_STREQ(line, "foo bar");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
-        ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar")));
-        args = strv_free(args);
-
-        ASSERT_OK_EQ_ERRNO(write(fd, "quux", 4), 4);
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar quux");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar quux");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "f…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "fo…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo …");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo b…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo ba…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 9, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar …");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar q…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar qu…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar quux");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 13, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar quux");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 14, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar quux");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 1000, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "foo bar quux");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
-        ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar", "quux")));
-        args = strv_free(args);
-
-        ASSERT_OK_ERRNO(ftruncate(fd, 0));
-        ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "aaaa bbbb cccc"));
-
-        ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
-
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "[aaaa bbbb cccc]");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "[aaaa bbb…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "[aaaa bbbb…");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
-        log_debug("'%s'", line);
-        ASSERT_STREQ(line, "[aaaa bbbb …");
-        line = mfree(line);
-
-        ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
-        ASSERT_TRUE(strv_equal(args, STRV_MAKE("[aaaa bbbb cccc]")));
-        args = strv_free(args);
-
-        /* Test with multiple arguments that do require quoting */
+                ASSERT_OK_EQ_ERRNO(write(fd, "foo\0bar", 8), 8);
+
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                ASSERT_STREQ(line, "foo bar");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
+                ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar")));
+                args = strv_free(args);
+
+                ASSERT_OK_EQ_ERRNO(write(fd, "quux", 4), 4);
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar quux");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar quux");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "f…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "fo…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo …");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo b…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo ba…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 9, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar …");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar q…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar qu…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar quux");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 13, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar quux");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 14, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar quux");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 1000, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "foo bar quux");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
+                ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar", "quux")));
+                args = strv_free(args);
+
+                ASSERT_OK_ERRNO(ftruncate(fd, 0));
+                ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "aaaa bbbb cccc"));
+
+                ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
+
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "[aaaa bbbb cccc]");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "[aaaa bbb…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "[aaaa bbbb…");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+                log_debug("'%s'", line);
+                ASSERT_STREQ(line, "[aaaa bbbb …");
+                line = mfree(line);
+
+                ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
+                ASSERT_TRUE(strv_equal(args, STRV_MAKE("[aaaa bbbb cccc]")));
+                args = strv_free(args);
+
+                /* Test with multiple arguments that do require quoting */
 
 #define CMDLINE1 "foo\0'bar'\0\"bar$\"\0x y z\0!``\0"
 #define EXPECT1  "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\""
 #define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``'"
 #define EXPECT1v STRV_MAKE("foo", "'bar'", "\"bar$\"", "x y z", "!``")
 
-        ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
-        ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE1, sizeof(CMDLINE1)), (ssize_t) sizeof(CMDLINE1));
-        ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof(CMDLINE1)));
+                ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
+                ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE1, sizeof(CMDLINE1)), (ssize_t) sizeof(CMDLINE1));
+                ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof(CMDLINE1)));
 
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
-        log_debug("got: ==%s==", line);
-        log_debug("exp: ==%s==", EXPECT1);
-        ASSERT_STREQ(line, EXPECT1);
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
+                log_debug("got: ==%s==", line);
+                log_debug("exp: ==%s==", EXPECT1);
+                ASSERT_STREQ(line, EXPECT1);
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
-        log_debug("got: ==%s==", line);
-        log_debug("exp: ==%s==", EXPECT1p);
-        ASSERT_STREQ(line, EXPECT1p);
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
+                log_debug("got: ==%s==", line);
+                log_debug("exp: ==%s==", EXPECT1p);
+                ASSERT_STREQ(line, EXPECT1p);
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
-        ASSERT_TRUE(strv_equal(args, EXPECT1v));
-        args = strv_free(args);
+                ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
+                ASSERT_TRUE(strv_equal(args, EXPECT1v));
+                args = strv_free(args);
 
 #define CMDLINE2 "foo\0\1\2\3\0\0"
 #define EXPECT2  "foo \"\\001\\002\\003\""
 #define EXPECT2p "foo $'\\001\\002\\003'"
 #define EXPECT2v STRV_MAKE("foo", "\1\2\3")
 
-        ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
-        ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE2, sizeof(CMDLINE2)), (ssize_t) sizeof(CMDLINE2));
-        ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof CMDLINE2));
+                ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
+                ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE2, sizeof(CMDLINE2)), (ssize_t) sizeof(CMDLINE2));
+                ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof CMDLINE2));
 
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
-        log_debug("got: ==%s==", line);
-        log_debug("exp: ==%s==", EXPECT2);
-        ASSERT_STREQ(line, EXPECT2);
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
+                log_debug("got: ==%s==", line);
+                log_debug("exp: ==%s==", EXPECT2);
+                ASSERT_STREQ(line, EXPECT2);
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
-        log_debug("got: ==%s==", line);
-        log_debug("exp: ==%s==", EXPECT2p);
-        ASSERT_STREQ(line, EXPECT2p);
-        line = mfree(line);
+                ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
+                log_debug("got: ==%s==", line);
+                log_debug("exp: ==%s==", EXPECT2p);
+                ASSERT_STREQ(line, EXPECT2p);
+                line = mfree(line);
 
-        ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
-        ASSERT_TRUE(strv_equal(args, EXPECT2v));
-        args = strv_free(args);
+                ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
+                ASSERT_TRUE(strv_equal(args, EXPECT2v));
+                args = strv_free(args);
 
-        safe_close(fd);
-        _exit(EXIT_SUCCESS);
+                safe_close(fd);
+                _exit(EXIT_SUCCESS);
+        }
 }
 
 TEST(getpid_cached) {
-        siginfo_t si;
-        pid_t a, b, c, d, e, f, child;
+        pid_t a, b, c, d, e, f;
+        int r;
 
         a = getpid();
         b = getpid_cached();
@@ -585,10 +573,9 @@ TEST(getpid_cached) {
         ASSERT_EQ(a, b);
         ASSERT_EQ(a, c);
 
-        child = fork();
-        ASSERT_OK_ERRNO(child);
+        r = ASSERT_OK(safe_fork("(getpid)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
 
-        if (child == 0) {
+        if (r == 0) {
                 /* In child */
                 a = getpid();
                 b = getpid_cached();
@@ -606,10 +593,6 @@ TEST(getpid_cached) {
         ASSERT_EQ(a, d);
         ASSERT_EQ(a, e);
         ASSERT_EQ(a, f);
-
-        ASSERT_OK(wait_for_terminate(child, &si));
-        ASSERT_EQ(si.si_status, 0);
-        ASSERT_EQ(si.si_code, CLD_EXITED);
 }
 
 TEST(getpid_measure) {
@@ -641,8 +624,6 @@ TEST(safe_fork) {
         pid_t pid;
         int r;
 
-        BLOCK_SIGNALS(SIGCHLD);
-
         r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &pid);
         ASSERT_OK(r);
 
@@ -653,11 +634,14 @@ TEST(safe_fork) {
                 _exit(88);
         }
 
-        ASSERT_OK(wait_for_terminate(pid, &status));
+        _cleanup_(pidref_done) PidRef child = PIDREF_NULL;
+        ASSERT_OK(pidref_set_pid(&child, pid));
+
+        ASSERT_OK(pidref_wait_for_terminate(&child, &status));
         ASSERT_EQ(status.si_code, CLD_EXITED);
         ASSERT_EQ(status.si_status, 88);
 
-        _cleanup_(pidref_done) PidRef child = PIDREF_NULL;
+        pidref_done(&child);
         r = pidref_safe_fork("(test-child)", FORK_DETACH, &child);
         if (r == 0) {
                 /* Don't freeze so this doesn't linger around forever in case something goes wrong. */
index 024a0fd3a21a5572e458b650ddc61fa4dc9d2ab9..f1039319fd872ae5ac126061f10b2e327181664e 100644 (file)
@@ -23,6 +23,7 @@
 #include "locale-util.h"
 #include "log.h"
 #include "main-func.h"
+#include "pidref.h"
 #include "proc-cmdline.h"
 #include "process-util.h"
 #include "stdio-util.h"
@@ -255,7 +256,6 @@ assert_cc(STRLEN(SYSTEMD_DEFAULT_KEYMAP) > 0);
 static int keyboard_load_and_wait(const char *vc, Context *c, bool utf8) {
         const char* args[8];
         unsigned i = 0;
-        pid_t pid;
         int r;
 
         assert(vc);
@@ -286,7 +286,8 @@ static int keyboard_load_and_wait(const char *vc, Context *c, bool utf8) {
                 log_debug("Executing \"%s\"...", strnull(cmd));
         }
 
-        r = safe_fork("(loadkeys)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork("(loadkeys)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -294,13 +295,12 @@ static int keyboard_load_and_wait(const char *vc, Context *c, bool utf8) {
                 _exit(EXIT_FAILURE);
         }
 
-        return wait_for_terminate_and_check(KBD_LOADKEYS, pid, WAIT_LOG);
+        return pidref_wait_for_terminate_and_check(KBD_LOADKEYS, &pidref, WAIT_LOG);
 }
 
 static int font_load_and_wait(const char *vc, Context *c) {
         const char* args[9];
         unsigned i = 0;
-        pid_t pid;
         int r;
 
         assert(vc);
@@ -337,7 +337,8 @@ static int font_load_and_wait(const char *vc, Context *c) {
                 log_debug("Executing \"%s\"...", strnull(cmd));
         }
 
-        r = safe_fork("(setfont)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_safe_fork("(setfont)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -348,7 +349,7 @@ static int font_load_and_wait(const char *vc, Context *c) {
         /* setfont returns EX_OSERR when ioctl(KDFONTOP/PIO_FONTX/PIO_FONTX) fails. This might mean various
          * things, but in particular lack of a graphical console. Let's be generous and not treat this as an
          * error. */
-        r = wait_for_terminate_and_check(KBD_SETFONT, pid, WAIT_LOG_ABNORMAL);
+        r = pidref_wait_for_terminate_and_check(KBD_SETFONT, &pidref, WAIT_LOG_ABNORMAL);
         if (r == EX_OSERR)
                 log_notice(KBD_SETFONT " failed with a \"system error\" (EX_OSERR), ignoring.");
         else if (r >= 0 && r != EXIT_SUCCESS)