]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: change pid_is_alive() to not eat up errors, and add pidref_is_alive()
authorLennart Poettering <lennart@poettering.net>
Tue, 17 Oct 2023 10:12:05 +0000 (12:12 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 18 Oct 2023 12:40:25 +0000 (14:40 +0200)
Let's no eat up errors, but propagate unexpected ones.

src/basic/process-util.c
src/basic/process-util.h
src/core/service.c
src/libsystemd/sd-bus/bus-creds.c
src/test/test-process-util.c
src/tty-ask-password-agent/tty-ask-password-agent.c

index f381b6369cd0472176d79ac18fd9c49201a35b23..2414f263dd2bd7282d361b0115d0b52676fb5970 100644 (file)
@@ -1043,13 +1043,13 @@ bool pid_is_unwaited(pid_t pid) {
         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;
@@ -1058,10 +1058,31 @@ bool pid_is_alive(pid_t pid) {
                 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) {
index 53dce1ee71f22a61e12f1ae6285c2cedfd1de49e..7824127a6de0bea4b19c06bca745ed177f42ccde 100644 (file)
@@ -86,7 +86,8 @@ int pidref_is_kernel_thread(const PidRef *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);
index bb268eb9397a06a32c236745e4119be1ad82390e..a2f8bc7c87015963e660304e9787544cbd0a95a2 100644 (file)
@@ -1053,6 +1053,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
 
 static int service_is_suitable_main_pid(Service *s, PidRef *pid, int prio) {
         Unit *owner;
+        int r;
 
         assert(s);
         assert(pidref_is_set(pid));
@@ -1067,8 +1068,11 @@ static int service_is_suitable_main_pid(Service *s, PidRef *pid, int prio) {
         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)) {
@@ -1827,7 +1831,7 @@ static int main_pid_good(Service *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 */
index 48990a27f097ece6624ab6db55b40dba49894372..64af18de9e59605c064f1a7aca7b14453fa80576 100644 (file)
@@ -139,7 +139,7 @@ sd_bus_creds* bus_creds_new(void) {
 }
 
 _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);
@@ -154,19 +154,18 @@ _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t m
                 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;
 }
 
@@ -1089,12 +1088,13 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                         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))
index 6f548ecae9c1605c1c033de539821595005699b8..e6dea2f05f09e3cdd1cea4e2b8d7073e50c76d8f 100644 (file)
@@ -224,11 +224,11 @@ TEST(pid_is_alive) {
         } 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) {
index 87c610bc73be7e8bb206a3217fc2d9b31d0b96f4..3a30bfe042e437490fe40f1792c244ac6fd1658f 100644 (file)
@@ -207,7 +207,7 @@ static int process_one_password_file(const char *filename) {
         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) {