mirror of
https://github.com/systemd/systemd.git
synced 2026-08-03 22:50:29 +00:00
pidref: add pidref_set_parent() for race-freely getting pidref on ppid
This commit is contained in:
@@ -106,6 +106,38 @@ int pidref_set_pidfd_consume(PidRef *pidref, int fd) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int pidref_set_parent(PidRef *ret) {
|
||||
_cleanup_(pidref_done) PidRef parent = PIDREF_NULL;
|
||||
pid_t ppid;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
/* Acquires a pidref to our parent process. Deals with the fact that parent processes might exit, and
|
||||
* we get reparented to other processes, with our old parent's PID already being recycled. */
|
||||
|
||||
ppid = getppid();
|
||||
for (;;) {
|
||||
r = pidref_set_pid(&parent, ppid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (parent.fd < 0) /* If pidfds are not available, then we are done */
|
||||
break;
|
||||
|
||||
pid_t now_ppid = getppid();
|
||||
if (now_ppid == ppid) /* If our ppid is still the same, then we are done */
|
||||
break;
|
||||
|
||||
/* Otherwise let's try again with the new ppid */
|
||||
ppid = now_ppid;
|
||||
pidref_done(&parent);
|
||||
}
|
||||
|
||||
*ret = TAKE_PIDREF(parent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pidref_done(PidRef *pidref) {
|
||||
assert(pidref);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ int pidref_set_pidstr(PidRef *pidref, const char *pid);
|
||||
int pidref_set_pidfd(PidRef *pidref, int fd);
|
||||
int pidref_set_pidfd_take(PidRef *pidref, int fd); /* takes ownership of the passed pidfd on success*/
|
||||
int pidref_set_pidfd_consume(PidRef *pidref, int fd); /* takes ownership of the passed pidfd in both success and failure */
|
||||
|
||||
int pidref_set_parent(PidRef *ret);
|
||||
static inline int pidref_set_self(PidRef *pidref) {
|
||||
return pidref_set_pid(pidref, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user