Let's no eat up errors, but propagate unexpected ones.
return errno != ESRCH;
}
-bool pid_is_alive(pid_t pid) {
+int pid_is_alive(pid_t pid) {
int r;
/* Checks whether a PID is still valid and not a zombie */
if (pid < 0)
- return false;
+ return -ESRCH;
if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
return true;
return true;
r = get_process_state(pid);
- if (IN_SET(r, -ESRCH, 'Z'))
+ if (r == -ESRCH)
return false;
+ if (r < 0)
+ return r;
+
+ return r != 'Z';
+}
+
+int pidref_is_alive(const PidRef *pidref) {
+ int r, result;
+
+ if (!pidref_is_set(pidref))
+ return -ESRCH;
- return true;
+ result = pid_is_alive(pidref->pid);
+ if (result < 0)
+ return result;
+
+ r = pidref_verify(pidref);
+ if (r == -ESRCH)
+ return false;
+ if (r < 0)
+ return r;
+
+ return result;
}
int pid_from_same_root_fs(pid_t pid) {
int getenv_for_pid(pid_t pid, const char *field, char **_value);
-bool pid_is_alive(pid_t pid);
+int pid_is_alive(pid_t pid);
+int pidref_is_alive(const PidRef *pidref);
bool pid_is_unwaited(pid_t pid);
int pid_is_my_child(pid_t pid);
int pid_from_same_root_fs(pid_t pid);
static int service_is_suitable_main_pid(Service *s, PidRef *pid, int prio) {
Unit *owner;
+ int r;
assert(s);
assert(pidref_is_set(pid));
if (pidref_equal(pid, &s->control_pid))
return log_unit_full_errno(UNIT(s), prio, SYNTHETIC_ERRNO(EPERM), "New main PID "PID_FMT" is the control process, refusing.", pid->pid);
- if (!pid_is_alive(pid->pid))
+ r = pidref_is_alive(pid);
+ if (r == 0)
return log_unit_full_errno(UNIT(s), prio, SYNTHETIC_ERRNO(ESRCH), "New main PID "PID_FMT" does not exist or is a zombie.", pid->pid);
+ if (r < 0)
+ return log_unit_full_errno(UNIT(s), prio, r, "Failed to check if main PID "PID_FMT" exists or is a zombie.", pid->pid);
owner = manager_get_unit_by_pidref(UNIT(s)->manager, pid);
if (owner == UNIT(s)) {
/* If it's an alien child let's check if it is still alive ... */
if (s->main_pid_alien && pidref_is_set(&s->main_pid))
- return pid_is_alive(s->main_pid.pid);
+ return pidref_is_alive(&s->main_pid);
/* .. otherwise assume we'll get a SIGCHLD for it, which we really should wait for to collect
* exit status and code */
}
_public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
- sd_bus_creds *c;
+ _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL;
int r;
assert_return(pid >= 0, -EINVAL);
return -ENOMEM;
r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
- if (r < 0) {
- sd_bus_creds_unref(c);
+ if (r < 0)
return r;
- }
/* Check if the process existed at all, in case we haven't
* figured that out already */
- if (!pid_is_alive(pid)) {
- sd_bus_creds_unref(c);
+ r = pid_is_alive(pid);
+ if (r < 0)
+ return r;
+ if (r == 0)
return -ESRCH;
- }
- *ret = c;
+ *ret = TAKE_PTR(c);
return 0;
}
c->mask |= SD_BUS_CREDS_TTY;
}
- /* In case only the exe path was to be read we cannot
- * distinguish the case where the exe path was unreadable
- * because the process was a kernel thread, or when the
- * process didn't exist at all. Hence, let's do a final check,
- * to be sure. */
- if (!pid_is_alive(pid))
+ /* In case only the exe path was to be read we cannot distinguish the case where the exe path was
+ * unreadable because the process was a kernel thread, or when the process didn't exist at
+ * all. Hence, let's do a final check, to be sure. */
+ r = pid_is_alive(pid);
+ if (r < 0)
+ return r;
+ if (r == 0)
return -ESRCH;
if (tid > 0 && tid != pid && !pid_is_unwaited(tid))
} else {
int status;
- waitpid(pid, &status, 0);
- assert_se(!pid_is_alive(pid));
+ assert_se(waitpid(pid, &status, 0) == pid);
+ assert_se(pid_is_alive(pid) == 0);
}
- assert_se(pid_is_alive(getpid_cached()));
- assert_se(!pid_is_alive(-1));
+ assert_se(pid_is_alive(getpid_cached()) > 0);
+ assert_se(pid_is_alive(-1) < 0);
}
TEST(personality) {
if (not_after > 0 && now(CLOCK_MONOTONIC) > not_after)
return 0;
- if (pid > 0 && !pid_is_alive(pid))
+ if (pid > 0 && pid_is_alive(pid) <= 0)
return 0;
switch (arg_action) {