summaryrefslogtreecommitdiff
path: root/src/libnm-systemd-shared/src/basic/process-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnm-systemd-shared/src/basic/process-util.c')
-rw-r--r--src/libnm-systemd-shared/src/basic/process-util.c136
1 files changed, 23 insertions, 113 deletions
diff --git a/src/libnm-systemd-shared/src/basic/process-util.c b/src/libnm-systemd-shared/src/basic/process-util.c
index 20b2441468..ecb14306f8 100644
--- a/src/libnm-systemd-shared/src/basic/process-util.c
+++ b/src/libnm-systemd-shared/src/basic/process-util.c
@@ -643,20 +643,23 @@ int get_process_environ(pid_t pid, char **env) {
return 0;
}
-int get_process_ppid(pid_t pid, pid_t *_ppid) {
- int r;
+int get_process_ppid(pid_t pid, pid_t *ret) {
_cleanup_free_ char *line = NULL;
long unsigned ppid;
const char *p;
+ int r;
assert(pid >= 0);
- assert(_ppid);
if (pid == 0 || pid == getpid_cached()) {
- *_ppid = getppid();
+ if (ret)
+ *ret = getppid();
return 0;
}
+ if (pid == 1) /* PID 1 has no parent, shortcut this case */
+ return -EADDRNOTAVAIL;
+
p = procfs_file_alloca(pid, "stat");
r = read_one_line_file(p, &line);
if (r == -ENOENT)
@@ -664,9 +667,8 @@ int get_process_ppid(pid_t pid, pid_t *_ppid) {
if (r < 0)
return r;
- /* Let's skip the pid and comm fields. The latter is enclosed
- * in () but does not escape any () in its value, so let's
- * skip over it manually */
+ /* Let's skip the pid and comm fields. The latter is enclosed in () but does not escape any () in its
+ * value, so let's skip over it manually */
p = strrchr(line, ')');
if (!p)
@@ -680,10 +682,17 @@ int get_process_ppid(pid_t pid, pid_t *_ppid) {
&ppid) != 1)
return -EIO;
- if ((long unsigned) (pid_t) ppid != ppid)
+ /* If ppid is zero the process has no parent. Which might be the case for PID 1 but also for
+ * processes originating in other namespaces that are inserted into a pidns. Return a recognizable
+ * error in this case. */
+ if (ppid == 0)
+ return -EADDRNOTAVAIL;
+
+ if ((pid_t) ppid < 0 || (long unsigned) (pid_t) ppid != ppid)
return -ERANGE;
- *_ppid = (pid_t) ppid;
+ if (ret)
+ *ret = (pid_t) ppid;
return 0;
}
@@ -1028,30 +1037,6 @@ bool is_main_thread(void) {
return cached > 0;
}
-_noreturn_ void freeze(void) {
-
- log_close();
-
- /* Make sure nobody waits for us on a socket anymore */
- (void) close_all_fds(NULL, 0);
-
- sync();
-
- /* Let's not freeze right away, but keep reaping zombies. */
- for (;;) {
- int r;
- siginfo_t si = {};
-
- r = waitid(P_ALL, 0, &si, WEXITED);
- if (r < 0 && errno != EINTR)
- break;
- }
-
- /* waitid() failed with an unexpected error, things are really borked. Freeze now! */
- for (;;)
- pause();
-}
-
bool oom_score_adjust_is_valid(int oa) {
return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
}
@@ -1262,7 +1247,7 @@ static void restore_sigsetp(sigset_t **ssp) {
int safe_fork_full(
const char *name,
- const int except_fds[],
+ int except_fds[],
size_t n_except_fds,
ForkFlags flags,
pid_t *ret_pid) {
@@ -1457,7 +1442,7 @@ int safe_fork_full(
int namespace_fork(
const char *outer_name,
const char *inner_name,
- const int except_fds[],
+ int except_fds[],
size_t n_except_fds,
ForkFlags flags,
int pidns_fd,
@@ -1473,7 +1458,8 @@ int namespace_fork(
* process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that
* /proc/self/fd works correctly. */
- r = safe_fork_full(outer_name, except_fds, n_except_fds, (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
+ r = safe_fork_full(outer_name, except_fds, n_except_fds,
+ (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
if (r < 0)
return r;
if (r == 0) {
@@ -1508,86 +1494,10 @@ int namespace_fork(
return 1;
}
-int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) {
- bool stdout_is_tty, stderr_is_tty;
- size_t n, i;
- va_list ap;
- char **l;
- int r;
-
- assert(path);
-
- /* Spawns a temporary TTY agent, making sure it goes away when we go away */
-
- r = safe_fork_full(name,
- except,
- n_except,
- FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG,
- ret_pid);
- if (r < 0)
- return r;
- if (r > 0)
- return 0;
-
- /* In the child: */
-
- stdout_is_tty = isatty(STDOUT_FILENO);
- stderr_is_tty = isatty(STDERR_FILENO);
-
- if (!stdout_is_tty || !stderr_is_tty) {
- int fd;
-
- /* Detach from stdout/stderr. and reopen
- * /dev/tty for them. This is important to
- * ensure that when systemctl is started via
- * popen() or a similar call that expects to
- * read EOF we actually do generate EOF and
- * not delay this indefinitely by because we
- * keep an unused copy of stdin around. */
- fd = open("/dev/tty", O_WRONLY);
- if (fd < 0) {
- log_error_errno(errno, "Failed to open /dev/tty: %m");
- _exit(EXIT_FAILURE);
- }
-
- if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) {
- log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
- _exit(EXIT_FAILURE);
- }
-
- if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) {
- log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
- _exit(EXIT_FAILURE);
- }
-
- safe_close_above_stdio(fd);
- }
-
- (void) rlimit_nofile_safe();
-
- /* Count arguments */
- va_start(ap, path);
- for (n = 0; va_arg(ap, char*); n++)
- ;
- va_end(ap);
-
- /* Allocate strv */
- l = newa(char*, n + 1);
-
- /* Fill in arguments */
- va_start(ap, path);
- for (i = 0; i <= n; i++)
- l[i] = va_arg(ap, char*);
- va_end(ap);
-
- execv(path, l);
- _exit(EXIT_FAILURE);
-}
-
int set_oom_score_adjust(int value) {
char t[DECIMAL_STR_MAX(int)];
- sprintf(t, "%i", value);
+ xsprintf(t, "%i", value);
return write_string_file("/proc/self/oom_score_adj", t,
WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);