pidref: now that we have the cached pidfdid of our own process, use it
Note that this drops a lot of "const" qualifiers on PidRef arguments. That's because pidref_is_self() suddenly might end changing the PidRef because it acquires the pidfd ID. We had this previously already with pidfd_equal(), but this amplifies the problem. I guess we C's "const" doesn't really work for stuff that contains caches, that is just conceptually constant, but not actually.
This commit is contained in:
+25
-6
@@ -83,14 +83,17 @@ bool pidref_equal(PidRef *a, PidRef *b) {
|
||||
}
|
||||
|
||||
int pidref_set_pid(PidRef *pidref, pid_t pid) {
|
||||
uint64_t pidfdid = 0;
|
||||
int fd;
|
||||
|
||||
assert(pidref);
|
||||
|
||||
if (pid < 0)
|
||||
return -ESRCH;
|
||||
if (pid == 0)
|
||||
if (pid == 0) {
|
||||
pid = getpid_cached();
|
||||
(void) pidfd_get_inode_id_self_cached(&pidfdid);
|
||||
}
|
||||
|
||||
fd = pidfd_open(pid, 0);
|
||||
if (fd < 0) {
|
||||
@@ -104,6 +107,7 @@ int pidref_set_pid(PidRef *pidref, pid_t pid) {
|
||||
*pidref = (PidRef) {
|
||||
.fd = fd,
|
||||
.pid = pid,
|
||||
.fd_id = pidfdid,
|
||||
};
|
||||
|
||||
return 0;
|
||||
@@ -388,17 +392,32 @@ int pidref_verify(const PidRef *pidref) {
|
||||
return 1; /* We have a pidfd and it still points to the PID we have, hence all is *really* OK → return 1 */
|
||||
}
|
||||
|
||||
bool pidref_is_self(const PidRef *pidref) {
|
||||
if (!pidref)
|
||||
bool pidref_is_self(PidRef *pidref) {
|
||||
if (!pidref_is_set(pidref))
|
||||
return false;
|
||||
|
||||
if (pidref_is_remote(pidref))
|
||||
return false;
|
||||
|
||||
return pidref->pid == getpid_cached();
|
||||
if (pidref->pid != getpid_cached())
|
||||
return false;
|
||||
|
||||
/* PID1 cannot exit, hence no point in comparing pidfd IDs, they can never change */
|
||||
if (pidref->pid == 1)
|
||||
return true;
|
||||
|
||||
/* Also compare pidfd ID if we can get it */
|
||||
if (pidref_acquire_pidfd_id(pidref) < 0)
|
||||
return true;
|
||||
|
||||
uint64_t self_id;
|
||||
if (pidfd_get_inode_id_self_cached(&self_id) < 0)
|
||||
return true;
|
||||
|
||||
return pidref->fd_id == self_id;
|
||||
}
|
||||
|
||||
int pidref_wait(const PidRef *pidref, siginfo_t *ret, int options) {
|
||||
int pidref_wait(PidRef *pidref, siginfo_t *ret, int options) {
|
||||
int r;
|
||||
|
||||
if (!pidref_is_set(pidref))
|
||||
@@ -424,7 +443,7 @@ int pidref_wait(const PidRef *pidref, siginfo_t *ret, int options) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pidref_wait_for_terminate(const PidRef *pidref, siginfo_t *ret) {
|
||||
int pidref_wait_for_terminate(PidRef *pidref, siginfo_t *ret) {
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
|
||||
+4
-4
@@ -39,7 +39,7 @@ struct PidRef {
|
||||
their own pidfs and each process comes with a unique inode number */
|
||||
};
|
||||
|
||||
#define PIDREF_NULL (const PidRef) { .fd = -EBADF }
|
||||
#define PIDREF_NULL (PidRef) { .fd = -EBADF }
|
||||
|
||||
/* A special pidref value that we are using when a PID shall be automatically acquired from some surrounding
|
||||
* context, for example connection peer. Much like PIDREF_NULL it will be considered unset by
|
||||
@@ -77,7 +77,7 @@ static inline int pidref_set_self(PidRef *pidref) {
|
||||
return pidref_set_pid(pidref, 0);
|
||||
}
|
||||
|
||||
bool pidref_is_self(const PidRef *pidref);
|
||||
bool pidref_is_self(PidRef *pidref);
|
||||
|
||||
void pidref_done(PidRef *pidref);
|
||||
PidRef* pidref_free(PidRef *pidref);
|
||||
@@ -92,8 +92,8 @@ int pidref_kill(const PidRef *pidref, int sig);
|
||||
int pidref_kill_and_sigcont(const PidRef *pidref, int sig);
|
||||
int pidref_sigqueue(const PidRef *pidref, int sig, int value);
|
||||
|
||||
int pidref_wait(const PidRef *pidref, siginfo_t *siginfo, int options);
|
||||
int pidref_wait_for_terminate(const PidRef *pidref, siginfo_t *ret);
|
||||
int pidref_wait(PidRef *pidref, siginfo_t *siginfo, int options);
|
||||
int pidref_wait_for_terminate(PidRef *pidref, siginfo_t *ret);
|
||||
|
||||
static inline void pidref_done_sigkill_wait(PidRef *pidref) {
|
||||
if (!pidref_is_set(pidref))
|
||||
|
||||
@@ -1120,7 +1120,7 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pidref_is_my_child(const PidRef *pid) {
|
||||
int pidref_is_my_child(PidRef *pid) {
|
||||
int r;
|
||||
|
||||
if (!pidref_is_set(pid))
|
||||
@@ -1150,7 +1150,7 @@ int pid_is_my_child(pid_t pid) {
|
||||
return pidref_is_my_child(&PIDREF_MAKE_FROM_PID(pid));
|
||||
}
|
||||
|
||||
int pidref_is_unwaited(const PidRef *pid) {
|
||||
int pidref_is_unwaited(PidRef *pid) {
|
||||
int r;
|
||||
|
||||
/* Checks whether a PID is still valid at all, including a zombie */
|
||||
|
||||
@@ -90,9 +90,9 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value);
|
||||
int pid_is_alive(pid_t pid);
|
||||
int pidref_is_alive(const PidRef *pidref);
|
||||
int pid_is_unwaited(pid_t pid);
|
||||
int pidref_is_unwaited(const PidRef *pidref);
|
||||
int pidref_is_unwaited(PidRef *pidref);
|
||||
int pid_is_my_child(pid_t pid);
|
||||
int pidref_is_my_child(const PidRef *pidref);
|
||||
int pidref_is_my_child(PidRef *pidref);
|
||||
int pidref_from_same_root_fs(PidRef *a, PidRef *b);
|
||||
|
||||
bool is_main_thread(void);
|
||||
|
||||
Reference in New Issue
Block a user