Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #29142 from poettering/pidref
core: first step towards a pidfd focused future
- Loading branch information
Showing
27 changed files
with
564 additions
and
271 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* SPDX-License-Identifier: LGPL-2.1-or-later */ | ||
|
||
#include "errno-util.h" | ||
#include "fd-util.h" | ||
#include "missing_syscall.h" | ||
#include "parse-util.h" | ||
#include "pidref.h" | ||
#include "process-util.h" | ||
|
||
int pidref_set_pid(PidRef *pidref, pid_t pid) { | ||
int fd; | ||
|
||
assert(pidref); | ||
|
||
if (pid < 0) | ||
return -ESRCH; | ||
if (pid == 0) | ||
pid = getpid_cached(); | ||
|
||
fd = pidfd_open(pid, 0); | ||
if (fd < 0) { | ||
/* Graceful fallback in case the kernel doesn't support pidfds or is out of fds */ | ||
if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno) && !ERRNO_IS_RESOURCE(errno)) | ||
return -errno; | ||
|
||
fd = -EBADF; | ||
} | ||
|
||
*pidref = (PidRef) { | ||
.fd = fd, | ||
.pid = pid, | ||
}; | ||
|
||
return 0; | ||
} | ||
|
||
int pidref_set_pidstr(PidRef *pidref, const char *pid) { | ||
pid_t nr; | ||
int r; | ||
|
||
assert(pidref); | ||
|
||
r = parse_pid(pid, &nr); | ||
if (r < 0) | ||
return r; | ||
|
||
return pidref_set_pid(pidref, nr); | ||
} | ||
|
||
int pidref_set_pidfd(PidRef *pidref, int fd) { | ||
int r; | ||
|
||
assert(pidref); | ||
|
||
if (fd < 0) | ||
return -EBADF; | ||
|
||
int fd_copy = fcntl(fd, F_DUPFD_CLOEXEC, 3); | ||
if (fd_copy < 0) { | ||
pid_t pid; | ||
|
||
if (!ERRNO_IS_RESOURCE(errno)) | ||
return -errno; | ||
|
||
/* Graceful fallback if we are out of fds */ | ||
r = pidfd_get_pid(fd, &pid); | ||
if (r < 0) | ||
return r; | ||
|
||
*pidref = (PidRef) { | ||
.fd = -EBADF, | ||
.pid = pid, | ||
}; | ||
|
||
return 0; | ||
} | ||
|
||
return pidref_set_pidfd_consume(pidref, fd_copy); | ||
} | ||
|
||
int pidref_set_pidfd_take(PidRef *pidref, int fd) { | ||
pid_t pid; | ||
int r; | ||
|
||
assert(pidref); | ||
|
||
if (fd < 0) | ||
return -EBADF; | ||
|
||
r = pidfd_get_pid(fd, &pid); | ||
if (r < 0) | ||
return r; | ||
|
||
*pidref = (PidRef) { | ||
.fd = fd, | ||
.pid = pid, | ||
}; | ||
|
||
return 0; | ||
} | ||
|
||
int pidref_set_pidfd_consume(PidRef *pidref, int fd) { | ||
int r; | ||
|
||
r = pidref_set_pidfd_take(pidref, fd); | ||
if (r < 0) | ||
safe_close(fd); | ||
|
||
return r; | ||
} | ||
|
||
void pidref_done(PidRef *pidref) { | ||
assert(pidref); | ||
|
||
*pidref = (PidRef) { | ||
.fd = safe_close(pidref->fd), | ||
}; | ||
} | ||
|
||
int pidref_kill(PidRef *pidref, int sig) { | ||
|
||
if (!pidref) | ||
return -ESRCH; | ||
|
||
if (pidref->fd >= 0) | ||
return RET_NERRNO(pidfd_send_signal(pidref->fd, sig, NULL, 0)); | ||
|
||
if (pidref->pid > 0) | ||
return RET_NERRNO(kill(pidref->pid, sig)); | ||
|
||
return -ESRCH; | ||
} | ||
|
||
int pidref_kill_and_sigcont(PidRef *pidref, int sig) { | ||
int r; | ||
|
||
r = pidref_kill(pidref, sig); | ||
if (r < 0) | ||
return r; | ||
|
||
if (!IN_SET(sig, SIGCONT, SIGKILL)) | ||
(void) pidref_kill(pidref, SIGCONT); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* SPDX-License-Identifier: LGPL-2.1-or-later */ | ||
#pragma once | ||
|
||
#include "macro.h" | ||
|
||
/* An embeddable structure carrying a reference to a process. Supposed to be used when tracking processes continously. */ | ||
typedef struct PidRef { | ||
pid_t pid; /* always valid */ | ||
int fd; /* only valid if pidfd are available in the kernel, and we manage to get an fd */ | ||
} PidRef; | ||
|
||
#define PIDREF_NULL (PidRef) { .fd = -EBADF } | ||
|
||
static inline bool pidref_is_set(const PidRef *pidref) { | ||
return pidref && pidref->pid > 0; | ||
} | ||
|
||
int pidref_set_pid(PidRef *pidref, pid_t pid); | ||
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 */ | ||
|
||
void pidref_done(PidRef *pidref); | ||
|
||
int pidref_kill(PidRef *pidref, int sig); | ||
int pidref_kill_and_sigcont(PidRef *pidref, int sig); | ||
|
||
#define TAKE_PIDREF(p) TAKE_GENERIC((p), PidRef, PIDREF_NULL) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.