diff options
Diffstat (limited to 'src/basic/process-util.c')
-rw-r--r-- | src/basic/process-util.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 73c1ab75ef..94d8681c29 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1228,18 +1228,53 @@ int pidref_is_alive(const PidRef *pidref) { return result; } -int pid_from_same_root_fs(pid_t pid) { - const char *root; +int pidref_from_same_root_fs(PidRef *a, PidRef *b) { + _cleanup_(pidref_done) PidRef self = PIDREF_NULL; + int r; - if (pid < 0) + /* Checks if the two specified processes have the same root fs. Either can be specified as NULL in + * which case we'll check against ourselves. */ + + if (!a || !b) { + r = pidref_set_self(&self); + if (r < 0) + return r; + if (!a) + a = &self; + if (!b) + b = &self; + } + + if (!pidref_is_set(a) || !pidref_is_set(b)) + return -ESRCH; + + /* If one of the two processes have the same root they cannot have the same root fs, but if both of + * them do we don't know */ + if (pidref_is_remote(a) && pidref_is_remote(b)) + return -EREMOTE; + if (pidref_is_remote(a) || pidref_is_remote(b)) return false; - if (pid == 0 || pid == getpid_cached()) + if (pidref_equal(a, b)) return true; - root = procfs_file_alloca(pid, "root"); + const char *roota = procfs_file_alloca(a->pid, "root"); + const char *rootb = procfs_file_alloca(b->pid, "root"); + + int result = inode_same(roota, rootb, 0); + if (result == -ENOENT) + return proc_mounted() == 0 ? -ENOSYS : -ESRCH; + if (result < 0) + return result; - return inode_same(root, "/proc/1/root", 0); + r = pidref_verify(a); + if (r < 0) + return r; + r = pidref_verify(b); + if (r < 0) + return r; + + return result; } bool is_main_thread(void) { |