diff --git a/src/basic/process-util.c b/src/basic/process-util.c index ee15f72df4..d3c43c3ba4 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -879,27 +879,8 @@ int get_process_umask(pid_t pid, mode_t *ret) { return parse_mode(m, ret); } -int wait_for_terminate(pid_t pid, siginfo_t *status) { - siginfo_t dummy; - - assert(pid >= 1); - - if (!status) - status = &dummy; - - for (;;) { - zero(*status); - - if (waitid(P_PID, pid, status, WEXITED) < 0) { - - if (errno == EINTR) - continue; - - return negative_errno(); - } - - return 0; - } +int wait_for_terminate(pid_t pid, siginfo_t *ret) { + return pidref_wait_for_terminate(&PIDREF_MAKE_FROM_PID(pid), ret); } /* @@ -916,24 +897,29 @@ int wait_for_terminate(pid_t pid, siginfo_t *status) { * A warning is emitted if the process terminates abnormally, * and also if it returns non-zero unless check_exit_code is true. */ -int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) { +int pidref_wait_for_terminate_and_check(const char *name, PidRef *pidref, WaitFlags flags) { + int r; + + if (!pidref_is_set(pidref)) + return -ESRCH; + if (pidref_is_remote(pidref)) + return -EREMOTE; + if (pidref->pid == 1 || pidref_is_self(pidref)) + return -ECHILD; + _cleanup_free_ char *buffer = NULL; - siginfo_t status; - int r, prio; - - assert(pid > 1); - if (!name) { - r = pid_get_comm(pid, &buffer); + r = pidref_get_comm(pidref, &buffer); if (r < 0) - log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pid); + log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pidref->pid); else name = buffer; } - prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG; + int prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG; - r = wait_for_terminate(pid, &status); + siginfo_t status; + r = pidref_wait_for_terminate(pidref, &status); if (r < 0) return log_full_errno(prio, r, "Failed to wait for %s: %m", strna(name)); @@ -956,6 +942,10 @@ int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) { 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); +} + /* * Return values: * diff --git a/src/basic/process-util.h b/src/basic/process-util.h index c3b86f064f..fd24ee41ce 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -65,7 +65,7 @@ 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 *status); +int wait_for_terminate(pid_t pid, siginfo_t *ret); typedef enum WaitFlags { WAIT_LOG_ABNORMAL = 1 << 0, @@ -75,7 +75,9 @@ typedef enum WaitFlags { WAIT_LOG = WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS, } 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); + int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout); void sigkill_wait(pid_t pid); diff --git a/src/udev/udevadm-lock.c b/src/udev/udevadm-lock.c index 78dd43ea45..9b495fda3c 100644 --- a/src/udev/udevadm-lock.c +++ b/src/udev/udevadm-lock.c @@ -232,7 +232,6 @@ int lock_main(int argc, char *argv[], void *userdata) { _cleanup_free_ dev_t *devnos = NULL; size_t n_devnos = 0; usec_t deadline; - pid_t pid; int r; r = parse_argv(argc, argv); @@ -290,7 +289,11 @@ int lock_main(int argc, char *argv[], void *userdata) { /* Ignore SIGINT and allow the forked process to receive it */ (void) ignore_signals(SIGINT); - r = safe_fork("(lock)", 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( + "(lock)", + 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) { @@ -302,5 +305,5 @@ int lock_main(int argc, char *argv[], void *userdata) { _exit(EXIT_FAILURE); } - return wait_for_terminate_and_check(arg_cmdline[0], pid, 0); + return pidref_wait_for_terminate_and_check(arg_cmdline[0], &pidref, 0); }