#include "pidref.h"
#include "process-util.h"
#include "signal-util.h"
+#include "stat-util.h"
+
+bool pidref_equal(const PidRef *a, const PidRef *b) {
+ int r;
+
+ if (pidref_is_set(a)) {
+ if (!pidref_is_set(b))
+ return false;
+
+ if (a->pid != b->pid)
+ return false;
+
+ if (a->fd < 0 || b->fd < 0)
+ return true;
+
+ /* pidfds live in their own pidfs and each process comes with a unique inode number since
+ * kernel 6.8. We can safely do this on older kernels too though, as previously anonymous
+ * inode was used and inode number was the same for all pidfds. */
+ r = fd_inode_same(a->fd, b->fd);
+ if (r < 0)
+ log_debug_errno(r, "Failed to check whether pidfds for pid " PID_FMT " are equal, assuming yes: %m",
+ a->pid);
+ return r != 0;
+ }
+
+ return !pidref_is_set(b);
+}
int pidref_set_pid(PidRef *pidref, pid_t pid) {
int fd;
return pidref && pidref->pid > 0;
}
-static inline bool pidref_equal(const PidRef *a, const PidRef *b) {
-
- if (pidref_is_set(a)) {
- if (!pidref_is_set(b))
- return false;
-
- return a->pid == b->pid;
- }
-
- return !pidref_is_set(b);
-}
+bool pidref_equal(const PidRef *a, const PidRef *b);
/* This turns a pid_t into a PidRef structure, and acquires a pidfd for it, if possible. (As opposed to
* PIDREF_MAKE_FROM_PID() above, which does not acquire a pidfd.) */