From: Lennart Poettering Date: Tue, 17 Oct 2023 10:32:00 +0000 (+0200) Subject: process-util: add pidref_is_unwaited() and make pid_is_unwaited() return errors X-Git-Tag: v255-rc1~209^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4d9f092b5e21bb9d186d5abeb1617635f059353a;p=thirdparty%2Fsystemd.git process-util: add pidref_is_unwaited() and make pid_is_unwaited() return errors --- diff --git a/src/basic/process-util.c b/src/basic/process-util.c index c15460d8c0c..75bbebd60fb 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1045,11 +1045,11 @@ int pidref_is_my_child(const PidRef *pid) { return result; } -bool pid_is_unwaited(pid_t pid) { +int pid_is_unwaited(pid_t pid) { /* Checks whether a PID is still valid at all, including a zombie */ if (pid < 0) - return false; + return -ESRCH; if (pid <= 1) /* If we or PID 1 would be dead and have been waited for, this code would not be running */ return true; @@ -1063,6 +1063,24 @@ bool pid_is_unwaited(pid_t pid) { return errno != ESRCH; } +int pidref_is_unwaited(const PidRef *pid) { + int r; + + if (!pidref_is_set(pid)) + return -ESRCH; + + if (pid->pid == 1 || pidref_is_self(pid)) + return true; + + r = pidref_kill(pid, 0); + if (r == -ESRCH) + return false; + if (r < 0) + return r; + + return true; +} + int pid_is_alive(pid_t pid) { int r; diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 437a0ccd306..7c05a69ca09 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -88,7 +88,8 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value); int pid_is_alive(pid_t pid); int pidref_is_alive(const PidRef *pidref); -bool pid_is_unwaited(pid_t pid); +int pid_is_unwaited(pid_t pid); +int pidref_is_unwaited(const PidRef *pidref); int pid_is_my_child(pid_t pid); int pidref_is_my_child(const PidRef *pidref); int pid_from_same_root_fs(pid_t pid); diff --git a/src/core/mount.c b/src/core/mount.c index b6b76c56025..123c87ea1af 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -796,7 +796,7 @@ static int mount_coldplug(Unit *u) { return 0; if (pidref_is_set(&m->control_pid) && - pid_is_unwaited(m->control_pid.pid) && + pidref_is_unwaited(&m->control_pid) > 0 && MOUNT_STATE_WITH_PROCESS(m->deserialized_state)) { r = unit_watch_pidref(UNIT(m), &m->control_pid, /* exclusive= */ false); diff --git a/src/core/service.c b/src/core/service.c index fbd09844598..e2b8401560a 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1326,7 +1326,7 @@ static int service_coldplug(Unit *u) { return r; if (pidref_is_set(&s->main_pid) && - pid_is_unwaited(s->main_pid.pid) && + pidref_is_unwaited(&s->main_pid) > 0 && (IN_SET(s->deserialized_state, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, @@ -1339,7 +1339,7 @@ static int service_coldplug(Unit *u) { } if (pidref_is_set(&s->control_pid) && - pid_is_unwaited(s->control_pid.pid) && + pidref_is_unwaited(&s->control_pid) > 0 && IN_SET(s->deserialized_state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY, diff --git a/src/core/socket.c b/src/core/socket.c index dff4bc42d79..62ce29076ee 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1852,7 +1852,7 @@ static int socket_coldplug(Unit *u) { return 0; if (pidref_is_set(&s->control_pid) && - pid_is_unwaited(s->control_pid.pid) && + pidref_is_unwaited(&s->control_pid) > 0 && IN_SET(s->deserialized_state, SOCKET_START_PRE, SOCKET_START_CHOWN, diff --git a/src/core/swap.c b/src/core/swap.c index d0bce8c44bd..d0aae9a5343 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -557,7 +557,7 @@ static int swap_coldplug(Unit *u) { return 0; if (pidref_is_set(&s->control_pid) && - pid_is_unwaited(s->control_pid.pid) && + pidref_is_unwaited(&s->control_pid) > 0 && SWAP_STATE_WITH_PROCESS(new_state)) { r = unit_watch_pidref(UNIT(s), &s->control_pid, /* exclusive= */ false); diff --git a/src/core/unit.c b/src/core/unit.c index da71e09f156..a60656709ad 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2982,7 +2982,7 @@ static void unit_tidy_watch_pids(Unit *u) { if (pidref_equal(except1, e) || pidref_equal(except2, e)) continue; - if (!pid_is_unwaited(e->pid)) + if (pidref_is_unwaited(e) <= 0) unit_unwatch_pidref(u, e); } } diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c index 1f653801ad7..cc5b4bc6add 100644 --- a/src/journal/journald-context.c +++ b/src/journal/journald-context.c @@ -609,7 +609,7 @@ static void client_context_try_shrink_to(Server *s, size_t limit) { assert(c->n_ref == 0); - if (!pid_is_unwaited(c->pid)) + if (pid_is_unwaited(c->pid) == 0) client_context_free(s, c); else idx ++; diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 64af18de9e5..c6d8caaf6d7 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -1097,7 +1097,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (r == 0) return -ESRCH; - if (tid > 0 && tid != pid && !pid_is_unwaited(tid)) + if (tid > 0 && tid != pid && pid_is_unwaited(tid) == 0) return -ESRCH; c->augmented = missing & c->mask; diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c index e6dea2f05f0..2ff9f1fad5a 100644 --- a/src/test/test-process-util.c +++ b/src/test/test-process-util.c @@ -207,11 +207,11 @@ TEST(pid_is_unwaited) { } else { int status; - waitpid(pid, &status, 0); - assert_se(!pid_is_unwaited(pid)); + assert_se(waitpid(pid, &status, 0) == pid); + assert_se(pid_is_unwaited(pid) == 0); } - assert_se(pid_is_unwaited(getpid_cached())); - assert_se(!pid_is_unwaited(-1)); + assert_se(pid_is_unwaited(getpid_cached()) > 0); + assert_se(pid_is_unwaited(-1) < 0); } TEST(pid_is_alive) {