process-util: add pidref_is_unwaited() and make pid_is_unwaited() return errors

This commit is contained in:
Lennart Poettering 2023-10-17 12:32:00 +02:00
parent 6774be4206
commit 4d9f092b5e
10 changed files with 34 additions and 15 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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,

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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 ++;

View file

@ -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;

View file

@ -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) {