]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: add API for enumerating processes in /proc/ and pinning them via PidRef
authorLennart Poettering <lennart@poettering.net>
Tue, 17 Oct 2023 11:41:08 +0000 (13:41 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 18 Oct 2023 12:49:40 +0000 (14:49 +0200)
src/basic/process-util.c
src/basic/process-util.h

index 75bbebd60fb70da560c40e26c18faaffc81f6913..c5883b05d1b0266e49f25795e2b2cd55ecd7b583 100644 (file)
@@ -25,6 +25,7 @@
 #include "alloc-util.h"
 #include "architecture.h"
 #include "argv-util.h"
+#include "dirent-util.h"
 #include "env-file.h"
 #include "env-util.h"
 #include "errno-util.h"
@@ -1963,6 +1964,74 @@ fail:
         return -r;
 }
 
+int proc_dir_open(DIR **ret) {
+        DIR *d;
+
+        assert(ret);
+
+        d = opendir("/proc");
+        if (!d)
+                return -errno;
+
+        *ret = d;
+        return 0;
+}
+
+int proc_dir_read(DIR *d, pid_t *ret) {
+        assert(d);
+
+        for (;;) {
+                struct dirent *de;
+
+                errno = 0;
+                de = readdir_no_dot(d);
+                if (!de) {
+                        if (errno != 0)
+                                return -errno;
+
+                        break;
+                }
+
+                if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
+                        continue;
+
+                if (parse_pid(de->d_name, ret) >= 0)
+                        return 1;
+        }
+
+        if (ret)
+                *ret = 0;
+        return 0;
+}
+
+int proc_dir_read_pidref(DIR *d, PidRef *ret) {
+        int r;
+
+        assert(d);
+
+        for (;;) {
+                pid_t pid;
+
+                r = proc_dir_read(d, &pid);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
+
+                r = pidref_set_pid(ret, pid);
+                if (r == -ESRCH) /* gone by now? skip it */
+                        continue;
+                if (r < 0)
+                        return r;
+
+                return 1;
+        }
+
+        if (ret)
+                *ret = PIDREF_NULL;
+        return 0;
+}
+
 static const char *const sigchld_code_table[] = {
         [CLD_EXITED] = "exited",
         [CLD_KILLED] = "killed",
index 7c05a69ca0971e85676b0a44bbcfc7f8910f1d60..a18a7309362dc744b716e653b67d52ac292d1d71 100644 (file)
@@ -223,3 +223,7 @@ int is_reaper_process(void);
 int make_reaper_process(bool b);
 
 int posix_spawn_wrapper(const char *path, char *const *argv, char *const *envp, pid_t *ret_pid);
+
+int proc_dir_open(DIR **ret);
+int proc_dir_read(DIR *d, pid_t *ret);
+int proc_dir_read_pidref(DIR *d, PidRef *ret);