mirror of
https://github.com/systemd/systemd
synced 2024-10-15 12:34:37 +00:00
Merge pull request #31713 from YHNdnzj/pidref-equal
pidref: use fd_inode_same to compare pidfds
This commit is contained in:
commit
18eebde33a
|
@ -8,6 +8,33 @@
|
|||
#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;
|
||||
|
|
|
@ -19,17 +19,7 @@ static inline bool pidref_is_set(const PidRef *pidref) {
|
|||
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.) */
|
||||
|
|
|
@ -365,7 +365,7 @@ bool stat_inode_same(const struct stat *a, const struct stat *b) {
|
|||
* a thorough check, comparing inode nr, backing device and if the inode is still of the same type. */
|
||||
|
||||
return a && b &&
|
||||
(a->st_mode & S_IFMT) != 0 && /* We use the check for .st_mode if the structure was ever initialized */
|
||||
a->st_dev != 0 && /* is the structure ever initialized? */
|
||||
((a->st_mode ^ b->st_mode) & S_IFMT) == 0 && /* same inode type */
|
||||
a->st_dev == b->st_dev &&
|
||||
a->st_ino == b->st_ino;
|
||||
|
@ -395,7 +395,6 @@ bool statx_inode_same(const struct statx *a, const struct statx *b) {
|
|||
|
||||
return a && b &&
|
||||
FLAGS_SET(a->stx_mask, STATX_TYPE|STATX_INO) && FLAGS_SET(b->stx_mask, STATX_TYPE|STATX_INO) &&
|
||||
(a->stx_mode & S_IFMT) != 0 &&
|
||||
((a->stx_mode ^ b->stx_mode) & S_IFMT) == 0 &&
|
||||
a->stx_dev_major == b->stx_dev_major &&
|
||||
a->stx_dev_minor == b->stx_dev_minor &&
|
||||
|
|
|
@ -47,10 +47,12 @@ static inline int null_or_empty_path(const char *fn) {
|
|||
int path_is_read_only_fs(const char *path);
|
||||
|
||||
int inode_same_at(int fda, const char *filea, int fdb, const char *fileb, int flags);
|
||||
|
||||
static inline int inode_same(const char *filea, const char *fileb, int flags) {
|
||||
return inode_same_at(AT_FDCWD, filea, AT_FDCWD, fileb, flags);
|
||||
}
|
||||
static inline int fd_inode_same(int fda, int fdb) {
|
||||
return inode_same_at(fda, NULL, fdb, NULL, AT_EMPTY_PATH);
|
||||
}
|
||||
|
||||
/* The .f_type field of struct statfs is really weird defined on
|
||||
* different archs. Let's give its type a name. */
|
||||
|
|
|
@ -884,7 +884,7 @@ int pty_forward_new(
|
|||
|
||||
assert(f->input_fd >= 0);
|
||||
|
||||
same = inode_same_at(f->input_fd, NULL, f->output_fd, NULL, AT_EMPTY_PATH);
|
||||
same = fd_inode_same(f->input_fd, f->output_fd);
|
||||
if (same < 0)
|
||||
return same;
|
||||
|
||||
|
|
Loading…
Reference in a new issue