]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: add helper for getting our own pidfdid
authorLennart Poettering <lennart@poettering.net>
Mon, 18 Nov 2024 10:23:07 +0000 (11:23 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 18 Nov 2024 22:50:52 +0000 (23:50 +0100)
src/basic/process-util.c
src/basic/process-util.h
src/test/test-process-util.c

index adc576a84f8cc906da38ff90a34377cd3ed89f3b..a8578a0c40237b96058c6eecc2591e3f9d5a4141 100644 (file)
@@ -3,6 +3,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <limits.h>
+#include <linux/magic.h>
 #include <linux/oom.h>
 #include <pthread.h>
 #include <spawn.h>
@@ -11,6 +12,9 @@
 #include <stdlib.h>
 #include <sys/mount.h>
 #include <sys/personality.h>
+#if HAVE_PIDFD_OPEN
+#include <sys/pidfd.h>
+#endif
 #include <sys/prctl.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -40,6 +44,7 @@
 #include "log.h"
 #include "macro.h"
 #include "memory-util.h"
+#include "missing_magic.h"
 #include "missing_sched.h"
 #include "missing_syscall.h"
 #include "missing_threads.h"
@@ -2262,3 +2267,42 @@ _noreturn_ void report_errno_and_exit(int errno_fd, int error) {
 
         _exit(EXIT_FAILURE);
 }
+
+int getpidfdid_cached(uint64_t *ret) {
+        static uint64_t cached = 0;
+        static int initialized = 0;
+        int r;
+
+        assert(ret);
+
+        if (initialized > 0) {
+                *ret = cached;
+                return 0;
+        }
+        if (initialized < 0)
+                return initialized;
+
+        _cleanup_close_ int fd = pidfd_open(getpid_cached(), 0);
+        if (fd < 0) {
+                if (ERRNO_IS_NOT_SUPPORTED(errno))
+                        return (initialized = -EOPNOTSUPP);
+
+                return -errno;
+        }
+
+        r = fd_is_fs_type(fd, PID_FS_MAGIC);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return (initialized = -EOPNOTSUPP);
+
+        struct stat st;
+        if (fstat(fd, &st) < 0)
+                return -errno;
+        if (st.st_ino == 0)
+                return (initialized = -EOPNOTSUPP);
+
+        *ret = cached = st.st_ino;
+        initialized = 1;
+        return 0;
+}
index 0763b64cff0f2529efd729a0f0733fec782f53e1..a97ae387ceca3961358955ee2b0a96b856173389 100644 (file)
@@ -275,3 +275,5 @@ int proc_dir_read(DIR *d, pid_t *ret);
 int proc_dir_read_pidref(DIR *d, PidRef *ret);
 
 _noreturn_ void report_errno_and_exit(int errno_fd, int error);
+
+int getpidfdid_cached(uint64_t *ret);
index e6ba6fea707f87f14819378e0537c00a2601f228..e517d6b467d0580bff9e5d821469fc78d9df9eca 100644 (file)
@@ -994,6 +994,21 @@ TEST(pid_get_start_time) {
         ASSERT_GE(start_time2, start_time);
 }
 
+TEST(getpidfdid_cached) {
+        int r;
+
+        log_info("pid=" PID_FMT, getpid_cached());
+
+        uint64_t id;
+        r = getpidfdid_cached(&id);
+        if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
+                log_info("pidfdid not supported");
+        else {
+                assert(r >= 0);
+                log_info("pidfdid=%" PRIu64, id);
+        }
+}
+
 static int intro(void) {
         log_show_color(true);
         return EXIT_SUCCESS;