#include "lock-util.h"
#include "log.h"
#include "path-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "string-util.h"
#include "time-util.h"
}
int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeout) {
- _cleanup_(sigkill_waitp) pid_t pid = 0;
int r;
assert(fd >= 0);
return r;
/* If that didn't work, try with a child */
-
- r = safe_fork("(sd-flock)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pid);
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork("(sd-flock)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pidref);
if (r < 0)
return log_error_errno(r, "Failed to flock block device in child process: %m");
if (r == 0) {
}
siginfo_t status;
- r = wait_for_terminate(pid, &status);
+ r = pidref_wait_for_terminate(&pidref, &status);
if (r < 0)
return r;
- TAKE_PID(pid);
+ pidref_done(&pidref);
switch (status.si_code) {
return userns_acquire(uid_map, gid_map, /* setgroups_deny= */ true);
}
-int userns_enter_and_pin(int userns_fd, pid_t *ret_pid) {
+int userns_enter_and_pin(int userns_fd, PidRef *ret) {
_cleanup_close_pair_ int pfd[2] = EBADF_PAIR;
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
ssize_t n;
char x;
int r;
assert(userns_fd >= 0);
- assert(ret_pid);
+ assert(ret);
if (pipe2(pfd, O_CLOEXEC) < 0)
return -errno;
- r = safe_fork_full(
+ r = pidref_safe_fork_full(
"(sd-pinuserns)",
/* stdio_fds= */ NULL,
(int[]) { pfd[1], userns_fd }, 2,
FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL,
- &pid);
+ &pidref);
if (r < 0)
return r;
if (r == 0) {
assert(n == 1);
assert(x == 'x');
- *ret_pid = TAKE_PID(pid);
+ *ret = TAKE_PIDREF(pidref);
return 0;
}
}
int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid) {
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
int r;
assert(userns_fd >= 0);
- r = userns_enter_and_pin(userns_fd, &pid);
+ r = userns_enter_and_pin(userns_fd, &pidref);
if (r < 0)
return r;
uid_t uid;
- r = uid_map_search_root(pid, UID_RANGE_USERNS_OUTSIDE, &uid);
+ r = uid_map_search_root(pidref.pid, UID_RANGE_USERNS_OUTSIDE, &uid);
if (r < 0)
return r;
gid_t gid;
- r = uid_map_search_root(pid, GID_RANGE_USERNS_OUTSIDE, &gid);
+ r = uid_map_search_root(pidref.pid, GID_RANGE_USERNS_OUTSIDE, &gid);
if (r < 0)
return r;
int userns_acquire_empty(void);
int userns_acquire(const char *uid_map, const char *gid_map, bool setgroups_deny);
int userns_acquire_self_root(void);
-int userns_enter_and_pin(int userns_fd, pid_t *ret_pid);
+int userns_enter_and_pin(int userns_fd, PidRef *ret);
bool userns_supported(void);
int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid);
return pidref_wait_for_terminate_full(pidref, USEC_INFINITY, ret);
}
+static inline void pidref_done_sigterm_wait(PidRef *pidref) {
+ if (!pidref_is_set(pidref))
+ return;
+
+ (void) pidref_kill(pidref, SIGTERM);
+ (void) pidref_wait_for_terminate(pidref, NULL);
+ pidref_done(pidref);
+}
+
static inline void pidref_done_sigkill_wait(PidRef *pidref) {
if (!pidref_is_set(pidref))
return;
return parse_mode(m, ret);
}
-int wait_for_terminate(pid_t pid, siginfo_t *ret) {
- return pidref_wait_for_terminate(&PIDREF_MAKE_FROM_PID(pid), ret);
-}
-
/*
* Return values:
- * < 0 : wait_for_terminate() failed to get the state of the
+ * < 0 : pidref_wait_for_terminate() failed to get the state of the
* process, the process was terminated by a signal, or
* failed for an unknown reason.
* >=0 : The process terminated normally, and its exit code is
return -EPROTO;
}
-int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) {
- return pidref_wait_for_terminate_and_check(name, &PIDREF_MAKE_FROM_PID(pid), flags);
-}
-
-void sigkill_wait(pid_t pid) {
- assert(pid > 1);
-
- (void) kill(pid, SIGKILL);
- (void) wait_for_terminate(pid, NULL);
-}
-
-void sigkill_waitp(pid_t *pid) {
- PROTECT_ERRNO;
-
- if (!pid)
- return;
- if (*pid <= 1)
- return;
-
- sigkill_wait(*pid);
-}
-
-void sigterm_wait(pid_t pid) {
- assert(pid > 1);
-
- (void) kill_and_sigcont(pid, SIGTERM);
- (void) wait_for_terminate(pid, NULL);
-}
-
-void sigkill_nowait(pid_t pid) {
- assert(pid > 1);
-
- (void) kill(pid, SIGKILL);
-}
-
-void sigkill_nowaitp(pid_t *pid) {
- PROTECT_ERRNO;
-
- if (!pid)
- return;
- if (*pid <= 1)
- return;
-
- sigkill_nowait(*pid);
-}
-
int kill_and_sigcont(pid_t pid, int sig) {
int r;
exit(EXIT_SUCCESS);
else {
log_info("Spawned valgrind helper as PID "PID_FMT".", pid);
- (void) wait_for_terminate(pid, NULL);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pid);
+ (void) pidref_set_pid(&pidref, pid);
+ (void) pidref_wait_for_terminate(&pidref, NULL);
}
}
#endif
return IN_SET(code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
}
-int wait_for_terminate(pid_t pid, siginfo_t *ret);
-
typedef enum WaitFlags {
WAIT_LOG_ABNORMAL = 1 << 0,
WAIT_LOG_NON_ZERO_EXIT_STATUS = 1 << 1,
} WaitFlags;
int pidref_wait_for_terminate_and_check(const char *name, PidRef *pidref, WaitFlags flags);
-int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags);
-
-void sigkill_wait(pid_t pid);
-void sigkill_waitp(pid_t *pid);
-void sigterm_wait(pid_t pid);
-void sigkill_nowait(pid_t pid);
-void sigkill_nowaitp(pid_t *pid);
int kill_and_sigcont(pid_t pid, int sig);
#include "format-util.h"
#include "namespace-util.h"
#include "path-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "sort-util.h"
#include "stat-util.h"
}
int uid_range_load_userns_by_fd(int userns_fd, UIDRangeUsernsMode mode, UIDRange **ret) {
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
int r;
assert(userns_fd >= 0);
assert(mode < _UID_RANGE_USERNS_MODE_MAX);
assert(ret);
- r = userns_enter_and_pin(userns_fd, &pid);
+ r = userns_enter_and_pin(userns_fd, &pidref);
if (r < 0)
return r;
const char *p = procfs_file_alloca(
- pid,
+ pidref.pid,
IN_SET(mode, UID_RANGE_USERNS_INSIDE, UID_RANGE_USERNS_OUTSIDE) ? "uid_map" : "gid_map");
return uid_range_load_userns(p, mode, ret);
#include "format-util.h"
#include "log.h"
#include "main.h"
+#include "pidref.h"
#include "process-util.h"
#include "raw-clone.h"
#include "rlimit-util.h"
LOG_MESSAGE_ID(SD_MESSAGE_CRASH_PROCESS_SIGNAL_STR));
}
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pid);
+ (void) pidref_set_pid(&pidref, pid);
+
/* Order things nicely. */
- r = wait_for_terminate(pid, &status);
+ r = pidref_wait_for_terminate(&pidref, &status);
if (r < 0)
log_struct_errno(LOG_EMERG, r,
LOG_MESSAGE("Caught <%s>, waitpid() failed: %m", signal_to_string(sig)),
_exit(EXIT_EXCEPTION);
} else {
log_info("Spawned crash shell as PID "PID_FMT".", pid);
- (void) wait_for_terminate(pid, NULL);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pid);
+ (void) pidref_set_pid(&pidref, pid);
+ (void) pidref_wait_for_terminate(&pidref, NULL);
}
}
_cleanup_free_ char *uid_map = NULL, *gid_map = NULL;
_cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;
_cleanup_close_ int unshare_ready_fd = -EBADF;
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
uint64_t c = 1;
ssize_t n;
int r;
if (pipe2(errno_pipe, O_CLOEXEC) < 0)
return -errno;
- r = safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pid);
+ r = pidref_safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pidref);
if (r < 0)
return r;
if (r == 0) {
if (n != 0) /* on success we should have read 0 bytes */
return -EIO;
- r = wait_for_terminate_and_check("(sd-userns)", TAKE_PID(pid), 0);
+ r = pidref_wait_for_terminate_and_check("(sd-userns)", &pidref, 0);
if (r < 0)
return r;
+ pidref_done(&pidref);
if (r != EXIT_SUCCESS) /* If something strange happened with the child, let's consider this fatal, too */
return -EIO;
static int can_mount_proc(void) {
_cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
ssize_t n;
int r;
/* Fork a child process into its own mount and PID namespace. Note safe_fork() already remounts / as SLAVE
* with FORK_MOUNTNS_SLAVE. */
- r = safe_fork("(sd-proc-check)",
- FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_PIDNS, &pid);
+ r = pidref_safe_fork(
+ "(sd-proc-check)",
+ FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_PIDNS,
+ &pidref);
if (r < 0)
return log_debug_errno(r, "Failed to fork child process (sd-proc-check): %m");
if (r == 0) {
if (n != 0) /* on success we should have read 0 bytes */
return -EIO;
- r = wait_for_terminate_and_check("(sd-proc-check)", TAKE_PID(pid), /* flags= */ 0);
+ r = pidref_wait_for_terminate_and_check("(sd-proc-check)", &pidref, /* flags= */ 0);
if (r < 0)
return log_debug_errno(r, "Failed to wait for (sd-proc-check) child process to terminate: %m");
+ pidref_done(&pidref);
if (r != EXIT_SUCCESS) /* If something strange happened with the child, let's consider this fatal, too */
return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Child process (sd-proc-check) exited with unexpected exit status '%d'.", r);
#include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h"
+#include "pidref.h"
#include "pretty-print.h"
#include "process-util.h"
#include "signal-util.h"
bool unlink_path = false;
const char *data, *fork_name;
size_t len;
- pid_t pid;
int r;
if (!arg_debugger) {
fork_name = strjoina("(", debugger_call[0], ")");
- r = safe_fork(fork_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_FLUSH_STDIO, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork(
+ fork_name,
+ FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_FLUSH_STDIO,
+ &pidref);
if (r < 0)
goto finish;
if (r == 0) {
_exit(EXIT_FAILURE);
}
- r = wait_for_terminate_and_check(debugger_call[0], pid, WAIT_LOG_ABNORMAL);
+ r = pidref_wait_for_terminate_and_check(debugger_call[0], &pidref, WAIT_LOG_ABNORMAL);
finish:
(void) default_signals(SIGINT, SIGTERM);
#include "pager.h"
#include "parse-argument.h"
#include "path-util.h"
+#include "pidref.h"
#include "pretty-print.h"
#include "process-util.h"
#include "stat-util.h"
static int found_override(const char *top, const char *bottom) {
_cleanup_free_ char *dest = NULL;
- pid_t pid;
int r;
assert(top);
fflush(stdout);
- r = safe_fork("(diff)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork(
+ "(diff)",
+ FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG,
+ &pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(EXIT_FAILURE);
}
- (void) wait_for_terminate_and_check("diff", pid, WAIT_LOG_ABNORMAL);
+ (void) pidref_wait_for_terminate_and_check("diff", &pidref, WAIT_LOG_ABNORMAL);
putchar('\n');
return r;
#include "fsck-util.h"
#include "main-func.h"
#include "path-util.h"
+#include "pidref.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "socket-util.h"
bool root_directory;
struct stat st;
int r, exit_status;
- pid_t pid;
log_setup();
pipe(progress_pipe) < 0)
return log_error_errno(errno, "pipe(): %m");
- r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork(
+ "(fsck)",
+ FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+ &pidref);
if (r < 0)
return r;
if (r == 0) {
(void) process_progress(TAKE_FD(progress_pipe[0]), console);
}
- exit_status = wait_for_terminate_and_check("fsck", pid, WAIT_LOG_ABNORMAL);
+ exit_status = pidref_wait_for_terminate_and_check("fsck", &pidref, WAIT_LOG_ABNORMAL);
if (exit_status < 0)
return exit_status;
if ((exit_status & ~FSCK_ERROR_CORRECTED) != FSCK_SUCCESS) {
#include "password-quality-util.h"
#include "path-util.h"
#include "percent-util.h"
+#include "pidref.h"
#include "pkcs11-util.h"
#include "polkit-agent.h"
#include "pretty-print.h"
_cleanup_strv_free_ char **cmdline = NULL;
const char *home;
int r, ret;
- pid_t pid;
r = acquire_bus(&bus);
if (r < 0)
if (r < 0)
return bus_log_parse_error(r);
- r = safe_fork("(with)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REOPEN_LOG, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork(
+ "(with)",
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REOPEN_LOG,
+ &pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(255);
}
- ret = wait_for_terminate_and_check(cmdline[0], pid, WAIT_LOG_ABNORMAL);
+ ret = pidref_wait_for_terminate_and_check(cmdline[0], &pidref, WAIT_LOG_ABNORMAL);
/* Close the fd that pings the home now. */
acquired_fd = safe_close(acquired_fd);
#include "memfd-util.h"
#include "mount-util.h"
#include "path-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "stat-util.h"
#include "string-util.h"
STRV_FOREACH(pw, h->password) {
_cleanup_close_ int passwd_fd = -EBADF;
- pid_t mount_pid;
int exit_status;
passwd_fd = memfd_new_and_seal_string("cifspw", *pw);
if (passwd_fd < 0)
return log_error_errno(passwd_fd, "Failed to create data FD for password: %m");
- r = safe_fork("(mount)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR, &mount_pid);
+ _cleanup_(pidref_done) PidRef mount_pidref = PIDREF_NULL;
+ r = pidref_safe_fork(
+ "(mount)",
+ FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR,
+ &mount_pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(EXIT_FAILURE);
}
- exit_status = wait_for_terminate_and_check("mount", mount_pid, WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS);
+ exit_status = pidref_wait_for_terminate_and_check("mount", &mount_pidref, WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS);
if (exit_status < 0)
return exit_status;
if (exit_status == EXIT_SUCCESS) {
#include <sys/ioctl.h>
#include <sys/xattr.h>
#include <unistd.h>
+#include "pidref.h"
#if HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
static int run_fsck(const char *node, const char *fstype) {
int r, exit_status;
- pid_t fsck_pid;
assert(node);
assert(fstype);
return 0;
}
- r = safe_fork("(fsck)",
- FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
- &fsck_pid);
+ _cleanup_(pidref_done) PidRef fsck_pidref = PIDREF_NULL;
+ r = pidref_safe_fork(
+ "(fsck)",
+ FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
+ &fsck_pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(FSCK_OPERATIONAL_ERROR);
}
- exit_status = wait_for_terminate_and_check("fsck", fsck_pid, WAIT_LOG_ABNORMAL);
+ exit_status = pidref_wait_for_terminate_and_check("fsck", &fsck_pidref, WAIT_LOG_ABNORMAL);
if (exit_status < 0)
return exit_status;
if ((exit_status & ~FSCK_ERROR_CORRECTED) != 0) {
_cleanup_free_ char *size_str = NULL;
bool re_open = false, re_mount = false;
- pid_t resize_pid, fsck_pid;
+ _cleanup_(pidref_done) PidRef resize_pidref = PIDREF_NULL, fsck_pidref = PIDREF_NULL;
int r, exit_status;
assert(setup);
log_info("Temporary unmounting of file system completed.");
/* resize2fs requires that the file system is force checked first, do so. */
- r = safe_fork("(e2fsck)",
- FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
- &fsck_pid);
+ r = pidref_safe_fork(
+ "(e2fsck)",
+ FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
+ &fsck_pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(EXIT_FAILURE);
}
- exit_status = wait_for_terminate_and_check("e2fsck", fsck_pid, WAIT_LOG_ABNORMAL);
+ exit_status = pidref_wait_for_terminate_and_check("e2fsck", &fsck_pidref, WAIT_LOG_ABNORMAL);
if (exit_status < 0)
return exit_status;
if ((exit_status & ~FSCK_ERROR_CORRECTED) != 0) {
return log_oom();
/* Resize the thing */
- r = safe_fork("(e2resize)",
- FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
- &resize_pid);
+ r = pidref_safe_fork(
+ "(e2resize)",
+ FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
+ &resize_pidref);
if (r < 0)
return r;
if (r == 0) {
#include "memory-util.h"
#include "os-util.h"
#include "path-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "pull-common.h"
#include "pull-job.h"
_cleanup_close_pair_ int gpg_pipe[2] = EBADF_PAIR;
_cleanup_(rm_rf_physical_and_freep) char *gpg_home = NULL;
char sig_file_path[] = "/tmp/sigXXXXXX";
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
int r;
assert(iovec_is_valid(payload));
goto finish;
}
- r = safe_fork_full("(gpg)",
- (int[]) { gpg_pipe[0], -EBADF, STDERR_FILENO },
- NULL, 0,
- FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
- &pid);
+ r = pidref_safe_fork_full(
+ "(gpg)",
+ (int[]) { gpg_pipe[0], -EBADF, STDERR_FILENO },
+ /* except_fds= */ NULL, /* n_except_fds= */ 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+ &pidref);
if (r < 0)
return r;
if (r == 0) {
gpg_pipe[1] = safe_close(gpg_pipe[1]);
- r = wait_for_terminate_and_check("gpg", TAKE_PID(pid), WAIT_LOG_ABNORMAL);
+ r = pidref_wait_for_terminate_and_check("gpg", &pidref, WAIT_LOG_ABNORMAL);
if (r < 0)
goto finish;
+ pidref_done(&pidref);
if (r != EXIT_SUCCESS)
r = log_error_errno(SYNTHETIC_ERRNO(EBADMSG),
"DOWNLOAD INVALID: Signature verification failed.");
#include "bus-match.h"
#include "constants.h"
#include "list.h"
+#include "pidref.h"
#include "runtime-scope.h"
#include "socket-util.h"
unsigned n_memfd_cache;
uint64_t origin_id;
- pid_t busexec_pid;
+ PidRef busexec_pidref;
unsigned iteration_counter;
assert(b->input_fd < 0);
assert(b->output_fd < 0);
assert(b->exec_path);
- assert(b->busexec_pid == 0);
+ assert(!pidref_is_set(&b->busexec_pidref));
if (DEBUG_LOGGING) {
_cleanup_free_ char *line = NULL;
if (r < 0)
return -errno;
- r = safe_fork_full("(sd-busexec)",
- (int[]) { s[1], s[1], STDERR_FILENO },
- NULL, 0,
- FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO|FORK_RLIMIT_NOFILE_SAFE, &b->busexec_pid);
+ r = pidref_safe_fork_full(
+ "(sd-busexec)",
+ (int[]) { s[1], s[1], STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO|FORK_RLIMIT_NOFILE_SAFE,
+ &b->busexec_pidref);
if (r < 0) {
safe_close_pair(s);
return r;
#include "parse-util.h"
#include "path-util.h"
#include "prioq.h"
-#include "process-util.h"
#include "set.h"
#include "string-util.h"
#include "strv.h"
.creds_mask = SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME,
.accept_fd = true,
.origin_id = origin_id_query(),
+ .busexec_pidref = PIDREF_NULL,
.n_groups = SIZE_MAX,
.close_on_exit = true,
.ucred = UCRED_INVALID,
return 1;
}
-static void bus_kill_exec(sd_bus *bus) {
- if (!pid_is_valid(bus->busexec_pid))
- return;
-
- sigterm_wait(TAKE_PID(bus->busexec_pid));
-}
-
static int bus_start_address(sd_bus *b) {
int r;
for (;;) {
bus_close_fds(b);
- bus_kill_exec(b);
+ pidref_done_sigterm_wait(&b->busexec_pidref);
/* If you provide multiple different bus-addresses, we
* try all of them in order and use the first one that
return;
/* Don't leave ssh hanging around */
- bus_kill_exec(bus);
+ pidref_done_sigterm_wait(&bus->busexec_pidref);
bus_set_state(bus, BUS_CLOSED);
return NULL;
/* Have to do this before flush() to prevent hang */
- bus_kill_exec(bus);
+ pidref_done_sigterm_wait(&bus->busexec_pidref);
sd_bus_flush(bus);
return sd_bus_close_unref(bus);
#include "mkdir.h"
#include "path-util.h"
#include "pidfd-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "socket-util.h"
#include "string-table.h"
.allow_fd_passing_input = -1,
.af = -1,
+
+ .exec_pidref = PIDREF_NULL,
};
*ret = v;
_public_ int sd_varlink_connect_exec(sd_varlink **ret, const char *_command, char **_argv) {
_cleanup_close_pair_ int pair[2] = EBADF_PAIR;
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
_cleanup_free_ char *command = NULL;
_cleanup_strv_free_ char **argv = NULL;
int r;
if (r < 0)
return log_debug_errno(r, "Failed to disable O_NONBLOCK for varlink socket: %m");
- r = safe_fork_full(
+ r = pidref_safe_fork_full(
"(sd-vlexec)",
/* stdio_fds= */ NULL,
/* except_fds= */ (int[]) { pair[1] },
/* n_except_fds= */ 1,
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
- &pid);
+ &pidref);
if (r < 0)
return log_debug_errno(r, "Failed to spawn process: %m");
if (r == 0) {
_exit(EXIT_FAILURE);
}
- xsprintf(spid, PID_FMT, pid);
+ xsprintf(spid, PID_FMT, pidref.pid);
uint64_t pidfdid;
if (pidfd_get_inode_id_self_cached(&pidfdid) >= 0) {
v->output_fd = v->input_fd = TAKE_FD(pair[0]);
v->af = AF_UNIX;
- v->exec_pid = TAKE_PID(pid);
+ v->exec_pidref = TAKE_PIDREF(pidref);
varlink_set_state(v, VARLINK_IDLE_CLIENT);
*ret = v;
static int varlink_connect_ssh_unix(sd_varlink **ret, const char *where) {
_cleanup_close_pair_ int pair[2] = EBADF_PAIR;
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
int r;
assert_return(ret, -EINVAL);
if (socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, pair) < 0)
return log_debug_errno(errno, "Failed to allocate AF_UNIX socket pair: %m");
- r = safe_fork_full(
+ r = pidref_safe_fork_full(
"(sd-vlssh)",
/* stdio_fds= */ (int[]) { pair[1], pair[1], STDERR_FILENO },
/* except_fds= */ NULL,
/* n_except_fds= */ 0,
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO,
- &pid);
+ &pidref);
if (r < 0)
return log_debug_errno(r, "Failed to spawn process: %m");
if (r == 0) {
v->output_fd = v->input_fd = TAKE_FD(pair[0]);
v->af = AF_UNIX;
- v->exec_pid = TAKE_PID(pid);
+ v->exec_pidref = TAKE_PIDREF(pidref);
varlink_set_state(v, VARLINK_IDLE_CLIENT);
*ret = v;
static int varlink_connect_ssh_exec(sd_varlink **ret, const char *where) {
_cleanup_close_pair_ int input_pipe[2] = EBADF_PAIR, output_pipe[2] = EBADF_PAIR;
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
int r;
assert_return(ret, -EINVAL);
if (pipe2(output_pipe, O_CLOEXEC) < 0)
return log_debug_errno(errno, "Failed to allocate output pipe: %m");
- r = safe_fork_full(
+ r = pidref_safe_fork_full(
"(sd-vlssh)",
/* stdio_fds= */ (int[]) { input_pipe[0], output_pipe[1], STDERR_FILENO },
/* except_fds= */ NULL,
/* n_except_fds= */ 0,
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO,
- &pid);
+ &pidref);
if (r < 0)
return log_debug_errno(r, "Failed to spawn process: %m");
if (r == 0) {
v->input_fd = TAKE_FD(output_pipe[0]);
v->output_fd = TAKE_FD(input_pipe[1]);
v->af = AF_UNSPEC;
- v->exec_pid = TAKE_PID(pid);
+ v->exec_pidref = TAKE_PIDREF(pidref);
varlink_set_state(v, VARLINK_IDLE_CLIENT);
*ret = v;
v->event = sd_event_unref(v->event);
- if (v->exec_pid > 0) {
- sigterm_wait(v->exec_pid);
- v->exec_pid = 0;
- }
+ pidref_done_sigterm_wait(&v->exec_pidref);
v->peer_pidfd = safe_close(v->peer_pidfd);
}
#include "sd-varlink.h"
#include "list.h"
+#include "pidref.h"
#include "sd-forward.h"
typedef enum VarlinkState {
sd_event_source *quit_event_source;
sd_event_source *defer_event_source;
- pid_t exec_pid;
+ PidRef exec_pidref;
};
typedef struct VarlinkServerSocket VarlinkServerSocket;
#include "main-func.h"
#include "pager.h"
#include "parse-argument.h"
+#include "pidref.h"
#include "polkit-agent.h"
#include "pretty-print.h"
#include "process-util.h"
_cleanup_strv_free_ char **arguments = NULL;
_cleanup_free_ char *w = NULL;
_cleanup_close_ int fd = -EBADF;
- pid_t pid;
/* Ignore SIGINT and allow the forked process to receive it */
(void) ignore_signals(SIGINT);
if (!arguments)
return log_oom();
- r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(EXIT_FAILURE);
}
- return wait_for_terminate_and_check(argv[optind], pid, WAIT_LOG);
+ return pidref_wait_for_terminate_and_check(argv[optind], &pidref, WAIT_LOG);
}
}
_cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
Image *image = ASSERT_PTR(userdata);
Manager *m = image->userdata;
- pid_t child;
+ _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
int r;
assert(message);
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
- r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
+ r = pidref_safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) {
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
- r = operation_new_with_bus_reply(m, /* machine= */ NULL, child, message, errno_pipe_fd[0], /* ret= */ NULL);
- if (r < 0) {
- sigkill_wait(child);
+ r = operation_new_with_bus_reply(m, /* machine= */ NULL, &child, message, errno_pipe_fd[0], /* ret= */ NULL);
+ if (r < 0)
return r;
- }
+
+ TAKE_PIDREF(child);
errno_pipe_fd[0] = -EBADF;
Manager *m = ASSERT_PTR(image->userdata);
const char *new_name;
int r, read_only;
- pid_t child;
+ _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
assert(message);
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
- r = safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
+ r = pidref_safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) {
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
- r = operation_new_with_bus_reply(m, /* machine= */ NULL, child, message, errno_pipe_fd[0], /* ret= */ NULL);
- if (r < 0) {
- sigkill_wait(child);
+ r = operation_new_with_bus_reply(m, /* machine= */ NULL, &child, message, errno_pipe_fd[0], /* ret= */ NULL);
+ if (r < 0)
return r;
- }
+
+ TAKE_PIDREF(child);
errno_pipe_fd[0] = -EBADF;
_cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
ImageUpdateParameters p = IMAGE_UPDATE_PARAMETERS_NULL;
Image *image;
- pid_t child;
+ _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
int r;
assert(link);
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return log_debug_errno(errno, "Failed to open pipe: %m");
- r = safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
+ r = pidref_safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
if (r < 0)
return log_debug_errno(r, "Failed to fork: %m");
if (r == 0) {
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
- r = operation_new_with_varlink_reply(manager, /* machine= */ NULL, child, link, errno_pipe_fd[0], /* ret= */ NULL);
- if (r < 0) {
- sigkill_wait(child);
+ r = operation_new_with_varlink_reply(manager, /* machine= */ NULL, &child, link, errno_pipe_fd[0], /* ret= */ NULL);
+ if (r < 0)
return r;
- }
+ TAKE_PIDREF(child);
TAKE_FD(errno_pipe_fd[0]);
return 1;
}
_cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
const char *image_name;
Image *image;
- pid_t child;
+ _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
int r;
assert(link);
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return log_debug_errno(errno, "Failed to open pipe: %m");
- r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
+ r = pidref_safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
if (r < 0)
return log_debug_errno(r, "Failed to fork: %m");
if (r == 0) {
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
- r = operation_new_with_varlink_reply(manager, /* machine= */ NULL, child, link, errno_pipe_fd[0], /* ret= */ NULL);
- if (r < 0) {
- sigkill_wait(child);
+ r = operation_new_with_varlink_reply(manager, /* machine= */ NULL, &child, link, errno_pipe_fd[0], /* ret= */ NULL);
+ if (r < 0)
return r;
- }
+ TAKE_PIDREF(child);
TAKE_FD(errno_pipe_fd[0]);
return 1;
}
int image_clean_pool_operation(Manager *manager, ImageCleanPoolMode mode, Operation **ret_operation) {
_cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
_cleanup_close_ int result_fd = -EBADF;
- _cleanup_(sigkill_waitp) pid_t child = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
int r;
assert(manager);
return log_debug_errno(result_fd, "Failed to open tmpfile: %m");
/* This might be a slow operation, run it asynchronously in a background process */
- r = safe_fork("(sd-clean)", FORK_RESET_SIGNALS, &child);
+ r = pidref_safe_fork("(sd-clean)", FORK_RESET_SIGNALS, &child);
if (r < 0)
return log_debug_errno(r, "Failed to fork(): %m");
if (r == 0) {
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
/* The clean-up might take a while, hence install a watch on the child and return */
- r = operation_new(manager, /* machine= */ NULL, child, errno_pipe_fd[0], ret_operation);
+ r = operation_new(manager, /* machine= */ NULL, &child, errno_pipe_fd[0], ret_operation);
if (r < 0)
return r;
(*ret_operation)->extra_fd = TAKE_FD(result_fd);
TAKE_FD(errno_pipe_fd[0]);
- TAKE_PID(child);
+ TAKE_PIDREF(child);
return 0;
}
// TODO: port to PidRef and donate child rather than destroying it
Operation *operation;
- r = operation_new(manager, machine, child.pid, errno_pipe_fd[0], &operation);
+ r = operation_new(manager, machine, &child, errno_pipe_fd[0], &operation);
if (r < 0)
return r;
#include "sd-varlink.h"
#include "alloc-util.h"
+#include "event-util.h"
#include "fd-util.h"
#include "format-util.h"
#include "log.h"
assert(si);
log_debug("Operation " PID_FMT " is now complete with code=%s status=%i",
- o->pid,
+ o->pidref.pid,
sigchld_code_to_string(si->si_code), si->si_status);
- o->pid = 0;
+ pidref_done(&o->pidref);
r = read_operation_errno(si, o);
if (r < 0)
return 0;
}
-int operation_new(Manager *manager, Machine *machine, pid_t child, int errno_fd, Operation **ret) {
+int operation_new(Manager *manager, Machine *machine, PidRef *child, int errno_fd, Operation **ret) {
Operation *o;
int r;
assert(manager);
- assert(child > 1);
+ assert(pidref_is_set(child));
assert(errno_fd >= 0);
assert(ret);
return -ENOMEM;
*o = (Operation) {
- .pid = child,
+ .pidref = TAKE_PIDREF(*child),
.errno_fd = errno_fd,
.extra_fd = -EBADF
};
- r = sd_event_add_child(manager->event, &o->event_source, child, WEXITED, operation_done, o);
+ r = event_add_child_pidref(manager->event, &o->event_source, &o->pidref, WEXITED, operation_done, o);
if (r < 0) {
free(o);
return r;
o->machine = machine;
}
- log_debug("Started new operation " PID_FMT ".", child);
+ log_debug("Started new operation " PID_FMT ".", o->pidref.pid);
/* At this point we took ownership of both the child and the errno file descriptor! */
safe_close(o->errno_fd);
safe_close(o->extra_fd);
- if (o->pid > 1)
- sigkill_wait(o->pid);
+ pidref_done_sigkill_wait(&o->pidref);
sd_bus_message_unref(o->message);
sd_varlink_unref(o->link);
#include "list.h"
#include "machine-forward.h"
+#include "pidref.h"
#define OPERATIONS_MAX 64
typedef struct Operation {
Manager *manager;
Machine *machine;
- pid_t pid;
+ PidRef pidref;
/* only one of these two fields should be set */
sd_varlink *link;
LIST_FIELDS(Operation, operations_by_machine);
} Operation;
-int operation_new(Manager *manager, Machine *machine, pid_t child, int errno_fd, Operation **ret);
+int operation_new(Manager *manager, Machine *machine, PidRef *child, int errno_fd, Operation **ret);
Operation *operation_free(Operation *o);
void operation_attach_bus_reply(Operation *op, sd_bus_message *message);
static inline int operation_new_with_bus_reply(
Manager *manager,
Machine *machine,
- pid_t child,
+ PidRef *child,
sd_bus_message *message,
int errno_fd,
Operation **ret) {
static inline int operation_new_with_varlink_reply(
Manager *manager,
Machine *machine,
- pid_t child,
+ PidRef *child,
sd_varlink *link,
int errno_fd,
Operation **ret) {
#include "log.h"
#include "mkdir.h"
#include "nspawn-setuid.h"
+#include "pidref.h"
#include "process-util.h"
#include "string-util.h"
#include "strv.h"
#include "user-util.h"
-static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
+static int spawn_getent(const char *database, const char *key, PidRef *ret) {
int pipe_fds[2], r;
- pid_t pid;
assert(database);
assert(key);
- assert(rpid);
+ assert(ret);
if (pipe2(pipe_fds, O_CLOEXEC) < 0)
return log_error_errno(errno, "Failed to allocate pipe: %m");
- r = safe_fork_full("(getent)",
- (int[]) { -EBADF, pipe_fds[1], -EBADF }, NULL, 0,
- FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
- &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork_full(
+ "(getent)",
+ (int[]) { -EBADF, pipe_fds[1], -EBADF }, NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
+ &pidref);
if (r < 0) {
safe_close_pair(pipe_fds);
return r;
pipe_fds[1] = safe_close(pipe_fds[1]);
- *rpid = pid;
+ *ret = TAKE_PIDREF(pidref);
return pipe_fds[0];
}
unsigned n_gids = 0;
uid_t uid;
gid_t gid;
- pid_t pid;
int r;
assert(ret_home);
}
/* First, get user credentials */
- fd = spawn_getent("passwd", user, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ fd = spawn_getent("passwd", user, &pidref);
if (fd < 0)
return fd;
if (r < 0)
return log_error_errno(r, "Failed to read from getent: %m");
- (void) wait_for_terminate_and_check("getent passwd", pid, WAIT_LOG);
+ (void) pidref_wait_for_terminate_and_check("getent passwd", &pidref, WAIT_LOG);
x = strchr(line, ':');
if (!x)
line = mfree(line);
/* Second, get group memberships */
- fd = spawn_getent("initgroups", user, &pid);
+ pidref_done(&pidref);
+ fd = spawn_getent("initgroups", user, &pidref);
if (fd < 0)
return fd;
if (r < 0)
return log_error_errno(r, "Failed to read from getent: %m");
- (void) wait_for_terminate_and_check("getent initgroups", pid, WAIT_LOG);
+ (void) pidref_wait_for_terminate_and_check("getent initgroups", &pidref, WAIT_LOG);
/* Skip over the username and subsequent separator whitespace */
x = line;
/*
* Return values:
- * < 0 : wait_for_terminate() failed to get the state of the
+ * < 0 : pidref_wait_for_terminate() failed to get the state of the
* container, the container was terminated by a signal, or
* failed for an unknown reason. No change is made to the
* container argument.
}
static int write_userns(int usernsfd, const UserNamespaceInfo *userns_info) {
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
_cleanup_close_ int efd = -EBADF;
uint64_t u;
int r;
if (efd < 0)
return log_error_errno(errno, "Failed to allocate eventfd(): %m");
- r = safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_LOG, &pid);
+ r = pidref_safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_LOG, &pidref);
if (r < 0)
return r;
if (r == 0) {
_cleanup_free_ char *pmap = NULL;
- if (asprintf(&pmap, "/proc/" PID_FMT "/uid_map", pid) < 0)
+ if (asprintf(&pmap, "/proc/" PID_FMT "/uid_map", pidref.pid) < 0)
return log_oom();
r = write_string_filef(pmap, 0, UID_FMT " " UID_FMT " %" PRIu32 "\n", userns_info->target_uid, userns_info->start_uid, userns_info->size);
return log_error_errno(r, "Failed to write 'uid_map' file of user namespace: %m");
pmap = mfree(pmap);
- if (asprintf(&pmap, "/proc/" PID_FMT "/gid_map", pid) < 0)
+ if (asprintf(&pmap, "/proc/" PID_FMT "/gid_map", pidref.pid) < 0)
return log_oom();
r = write_string_filef(pmap, 0, GID_FMT " " GID_FMT " %" PRIu32 "\n", userns_info->target_gid, userns_info->start_gid, userns_info->size);
#include "log.h"
#include "main-func.h"
#include "namespace-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "rm-rf.h"
#include "tmpfile-util.h"
_cleanup_(userns_restrict_bpf_freep) struct userns_restrict_bpf *obj = NULL;
_cleanup_close_ int userns_fd = -EBADF, host_fd1 = -EBADF, host_tmpfs = -EBADF, afd = -EBADF, bfd = -EBADF;
_cleanup_(rm_rf_physical_and_freep) char *t = NULL;
- _cleanup_(sigkill_waitp) pid_t pid = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
int r;
log_set_max_level(LOG_DEBUG);
assert_se(afd >= 0 && bfd >= 0);
- r = safe_fork("(test)", FORK_DEATHSIG_SIGKILL, &pid);
+ r = pidref_safe_fork("(test)", FORK_DEATHSIG_SIGKILL, &pidref);
assert_se(r >= 0);
if (r == 0) {
_cleanup_close_ int private_tmpfs = -EBADF;
assert_se(eventfd_write(bfd, 1) >= 0);
- assert_se(wait_for_terminate_and_check("(test)", pid, WAIT_LOG) >= 0);
+ assert_se(pidref_wait_for_terminate_and_check("(test)", &pidref, WAIT_LOG) >= 0);
return 0;
}
#include "mkdir.h"
#include "os-util.h"
#include "path-lookup.h"
+#include "pidref.h"
#include "portable.h"
#include "portable-util.h"
#include "process-util.h"
#include "rm-rf.h"
#include "selinux-util.h"
#include "set.h"
-#include "signal-util.h"
#include "socket-util.h"
#include "sort-util.h"
#include "string-table.h"
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
_cleanup_(rmdir_and_freep) char *tmpdir = NULL;
_cleanup_close_pair_ int seq[2] = EBADF_PAIR;
- _cleanup_(sigkill_waitp) pid_t child = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
DissectImageFlags flags =
DISSECT_IMAGE_READ_ONLY |
DISSECT_IMAGE_GENERIC_ROOT |
/* We now have a loopback block device, let's fork off a child in its own mount namespace, mount it
* there, and extract the metadata we need. The metadata is sent from the child back to us. */
- BLOCK_SIGNALS(SIGCHLD);
-
/* Load some libraries before we fork workers off that want to use them */
(void) dlopen_cryptsetup();
(void) dlopen_libmount();
if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, seq) < 0)
return log_debug_errno(errno, "Failed to allocated SOCK_SEQPACKET socket: %m");
- r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_LOG, &child);
+ r = pidref_safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_LOG, &child);
if (r < 0)
return r;
if (r == 0) {
assert_not_reached();
}
- r = wait_for_terminate_and_check("(sd-dissect)", child, 0);
+ r = pidref_wait_for_terminate_and_check("(sd-dissect)", &child, 0);
if (r < 0)
return r;
- child = 0;
+
+ TAKE_PIDREF(child);
}
if (!os_release)
sd_bus_error *error) {
_cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
- _cleanup_(sigkill_waitp) pid_t child = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
PortableState state;
int r;
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
- r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
+ r = pidref_safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) {
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
- r = operation_new(m, child, message, errno_pipe_fd[0], NULL);
+ r = operation_new(m, &child, message, errno_pipe_fd[0], NULL);
if (r < 0)
return r;
- child = 0;
+ TAKE_PIDREF(child);
errno_pipe_fd[0] = -EBADF;
return 1;
#include "sd-event.h"
#include "alloc-util.h"
+#include "event-util.h"
#include "fd-util.h"
#include "format-util.h"
#include "log.h"
assert(si);
log_debug("Operation " PID_FMT " is now complete with code=%s status=%i",
- o->pid,
+ o->pidref.pid,
sigchld_code_to_string(si->si_code), si->si_status);
- o->pid = 0;
+ pidref_done(&o->pidref);
if (si->si_code != CLD_EXITED) {
r = sd_bus_error_set(&error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
return 0;
}
-int operation_new(Manager *manager, pid_t child, sd_bus_message *message, int errno_fd, Operation **ret) {
+int operation_new(Manager *manager, PidRef *child, sd_bus_message *message, int errno_fd, Operation **ret) {
Operation *o;
int r;
assert(manager);
- assert(child > 1);
+ assert(pidref_is_set(child));
assert(message);
assert(errno_fd >= 0);
o->extra_fd = -EBADF;
- r = sd_event_add_child(manager->event, &o->event_source, child, WEXITED, operation_done, o);
+ r = event_add_child_pidref(manager->event, &o->event_source, child, WEXITED, operation_done, o);
if (r < 0) {
free(o);
return r;
}
- o->pid = child;
+ o->pidref = TAKE_PIDREF(*child);
o->message = sd_bus_message_ref(message);
o->errno_fd = errno_fd;
manager->n_operations++;
o->manager = manager;
- log_debug("Started new operation " PID_FMT ".", child);
+ log_debug("Started new operation " PID_FMT ".", o->pidref.pid);
/* At this point we took ownership of both the child and the errno file descriptor! */
safe_close(o->errno_fd);
safe_close(o->extra_fd);
- if (o->pid > 1)
- sigkill_wait(o->pid);
+ pidref_done_sigkill_wait(&o->pidref);
sd_bus_message_unref(o->message);
#pragma once
#include "list.h"
+#include "pidref.h"
#include "portabled-forward.h"
#define OPERATIONS_MAX 64
typedef struct Operation {
Manager *manager;
- pid_t pid;
+ PidRef pidref;
sd_bus_message *message;
int errno_fd;
int extra_fd;
LIST_FIELDS(Operation, operations);
} Operation;
-int operation_new(Manager *manager, pid_t child, sd_bus_message *message, int errno_fd, Operation **ret);
+int operation_new(Manager *manager, PidRef *child, sd_bus_message *message, int errno_fd, Operation **ret);
Operation *operation_free(Operation *o);
/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include <signal.h>
-
#include "ask-password-agent.h"
#include "bus-util.h"
#include "exec-util.h"
#include "log.h"
-#include "process-util.h"
+#include "pidref.h"
-static pid_t agent_pid = 0;
+static PidRef agent_pidref = PIDREF_NULL;
int ask_password_agent_open(void) {
int r;
- if (agent_pid > 0)
+ if (pidref_is_set(&agent_pidref))
return 0;
r = shall_fork_agent();
r = fork_agent("(sd-askpwagent)",
NULL, 0,
- &agent_pid,
+ &agent_pidref,
SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH,
"--watch");
if (r < 0)
}
void ask_password_agent_close(void) {
-
- if (agent_pid <= 0)
- return;
-
/* Inform agent that we are done */
- sigterm_wait(TAKE_PID(agent_pid));
+ pidref_done_sigterm_wait(&agent_pidref);
}
int ask_password_agent_open_if_enabled(BusTransport transport, bool ask_password) {
#include "openssl-util.h"
#include "os-util.h"
#include "path-util.h"
+#include "pidref.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "resize-fs.h"
#include "runtime-scope.h"
-#include "signal-util.h"
#include "siphash24.h"
#include "stat-util.h"
#include "string-util.h"
static int run_fsck(int node_fd, const char *fstype) {
int r, exit_status;
- pid_t pid;
assert(node_fd >= 0);
assert(fstype);
return 0;
}
- r = safe_fork_full(
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork_full(
"(fsck)",
NULL,
&node_fd, 1, /* Leave the node fd open */
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_CLOEXEC_OFF,
- &pid);
+ &pidref);
if (r < 0)
return log_debug_errno(r, "Failed to fork off fsck: %m");
if (r == 0) {
_exit(FSCK_OPERATIONAL_ERROR);
}
- exit_status = wait_for_terminate_and_check("fsck", pid, 0);
+ exit_status = pidref_wait_for_terminate_and_check("fsck", &pidref, 0);
if (exit_status < 0)
return log_debug_errno(exit_status, "Failed to fork off fsck: %m");
_cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **initrd_release = NULL, **sysext_release = NULL, **confext_release = NULL;
_cleanup_free_ char *hostname = NULL, *t = NULL;
_cleanup_close_pair_ int error_pipe[2] = EBADF_PAIR;
- _cleanup_(sigkill_waitp) pid_t child = 0;
+ _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
sd_id128_t machine_id = SD_ID128_NULL;
unsigned n_meta_initialized = 0;
int fds[2 * _META_MAX], r, v;
int has_init_system = -1;
ssize_t n;
- BLOCK_SIGNALS(SIGCHLD);
-
assert(m);
r = dlopen_libmount();
goto finish;
}
- r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM, &child);
+ r = pidref_safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM, &child);
if (r < 0)
goto finish;
if (r == 0) {
}}
}
- r = wait_for_terminate_and_check("(sd-dissect)", child, 0);
- child = 0;
+ r = pidref_wait_for_terminate_and_check("(sd-dissect)", &child, 0);
if (r < 0)
goto finish;
+ TAKE_PIDREF(child);
+
n = read(error_pipe[0], &v, sizeof(v));
if (n < 0) {
r = -errno;
#include "hashmap.h"
#include "log.h"
#include "path-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "serialize.h"
#include "stat-util.h"
#define EXIT_SKIP_REMAINING 77
+DEFINE_PRIVATE_HASH_OPS_FULL(pidref_hash_ops_free_free,
+ PidRef, pidref_hash_func, pidref_compare_func,
+ pidref_free, char*, free);
+
/* Put this test here for a lack of better place */
assert_cc(EAGAIN == EWOULDBLOCK);
char *argv[],
int stdout_fd,
bool set_systemd_exec_pid,
- pid_t *ret_pid) {
+ PidRef *ret) {
int r;
assert(path);
- assert(ret_pid);
+ assert(ret);
if (null_or_empty_path(path) > 0) {
log_debug("%s is masked, skipping.", path);
return 0;
}
- pid_t pid;
- r = safe_fork_full(
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork_full(
"(exec-inner)",
(const int[]) { STDIN_FILENO, stdout_fd < 0 ? STDOUT_FILENO : stdout_fd, STDERR_FILENO },
/* except_fds= */ NULL, /* n_except_fds= */ 0,
FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO|FORK_CLOSE_ALL_FDS,
- &pid);
+ &pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(EXIT_FAILURE);
}
- *ret_pid = pid;
+ *ret = TAKE_PIDREF(pidref);
return 1;
}
STRV_FOREACH(path, paths) {
_cleanup_free_ char *t = NULL;
_cleanup_close_ int fd = -EBADF;
- pid_t pid;
t = path_join(root, *path);
if (!t)
"permission bits. Proceeding anyway.", t);
}
- r = do_spawn(t, argv, fd, FLAGS_SET(flags, EXEC_DIR_SET_SYSTEMD_EXEC_PID), &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = do_spawn(t, argv, fd, FLAGS_SET(flags, EXEC_DIR_SET_SYSTEMD_EXEC_PID), &pidref);
if (r <= 0)
continue;
if (parallel_execution) {
- r = hashmap_ensure_put(&pids, &trivial_hash_ops_value_free, PID_TO_PTR(pid), t);
+ _cleanup_(pidref_freep) PidRef *dup = NULL;
+ r = pidref_dup(&pidref, &dup);
+ if (r < 0)
+ return r;
+
+ r = hashmap_ensure_put(&pids, &pidref_hash_ops_free_free, dup, t);
if (r < 0)
return log_oom();
- t = NULL;
+
+ TAKE_PTR(dup);
+ TAKE_PTR(t);
} else {
bool skip_remaining = false;
- r = wait_for_terminate_and_check(t, pid, WAIT_LOG_ABNORMAL);
+ r = pidref_wait_for_terminate_and_check(t, &pidref, WAIT_LOG_ABNORMAL);
if (r < 0)
return r;
if (r > 0) {
while (!hashmap_isempty(pids)) {
_cleanup_free_ char *t = NULL;
- pid_t pid;
void *p;
t = ASSERT_PTR(hashmap_steal_first_key_and_value(pids, &p));
- pid = PTR_TO_PID(p);
- assert(pid > 0);
+ _cleanup_(pidref_freep) PidRef *pidref = p;
- r = wait_for_terminate_and_check(t, pid, WAIT_LOG);
+ r = pidref_wait_for_terminate_and_check(t, pidref, WAIT_LOG);
if (r < 0)
return r;
if (!FLAGS_SET(flags, EXEC_DIR_IGNORE_ERRORS) && r > 0)
ExecDirFlags flags) {
_cleanup_close_ int fd = -EBADF;
- pid_t executor_pid;
int r;
assert(name);
const char *process_name = strjoina("(", name, ")");
- r = safe_fork(process_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &executor_pid);
+ PidRef executor_pidref = PIDREF_NULL;
+ r = pidref_safe_fork(process_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &executor_pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(r < 0 ? EXIT_FAILURE : r);
}
- r = wait_for_terminate_and_check(process_name, executor_pid, 0);
+ r = pidref_wait_for_terminate_and_check(process_name, &executor_pidref, 0);
if (r < 0)
return r;
if (!FLAGS_SET(flags, EXEC_DIR_IGNORE_ERRORS) && r > 0)
return true;
}
-int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, pid_t *ret_pid) {
+int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, PidRef *ret) {
int r;
assert(!strv_isempty(argv));
/* Spawns a temporary TTY agent, making sure it goes away when we go away */
- r = safe_fork_full(name,
- NULL,
- (int*) except, /* safe_fork_full only changes except if you pass in FORK_PACK_FDS, which we don't */
- n_except,
- FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_RLIMIT_NOFILE_SAFE,
- ret_pid);
+ r = pidref_safe_fork_full(
+ name,
+ /* stdio_fds= */ NULL,
+ (int*) except, n_except, /* safe_fork_full only changes except if you pass in FORK_PACK_FDS, which we don't */
+ FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_RLIMIT_NOFILE_SAFE,
+ ret);
if (r < 0)
return r;
if (r > 0)
int fexecve_or_execve(int executable_fd, const char *executable, char *const argv[], char *const envp[]);
int shall_fork_agent(void);
-int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, pid_t *ret_pid);
-#define fork_agent(name, except, n_except, ret_pid, ...) _fork_agent(name, STRV_MAKE(__VA_ARGS__), except, n_except, ret_pid)
+int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, PidRef *ret);
+#define fork_agent(name, except, n_except, ret, ...) _fork_agent(name, STRV_MAKE(__VA_ARGS__), except, n_except, ret)
#include "locale-util.h"
#include "log.h"
#include "pager.h"
+#include "pidref.h"
#include "process-util.h"
#include "signal-util.h"
#include "string-util.h"
stdout_redirected = stderr_redirected = false;
(void) kill(pager_pid, SIGCONT);
- (void) wait_for_terminate(TAKE_PID(pager_pid), NULL);
- pager_pid = 0;
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pager_pid);
+ (void) pidref_set_pid(&pidref, pager_pid);
+ (void) pidref_wait_for_terminate(&pidref, NULL);
+ TAKE_PID(pager_pid);
}
bool pager_have(void) {
int show_man_page(const char *desc, bool null_stdio) {
const char *args[4] = { "man", NULL, NULL, NULL };
const char *e = NULL;
- pid_t pid;
size_t k;
int r;
} else
args[1] = desc;
- r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|(null_stdio ? FORK_REARRANGE_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork(
+ "(man)",
+ FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|(null_stdio ? FORK_REARRANGE_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_WAIT,
+ &pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(EXIT_FAILURE);
}
- return wait_for_terminate_and_check(NULL, pid, 0);
+ return pidref_wait_for_terminate_and_check(NULL, &pidref, 0);
}
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <poll.h>
-#include <signal.h>
#include <unistd.h>
#include "bus-util.h"
#include "fd-util.h"
#include "io-util.h"
#include "log.h"
+#include "pidref.h"
#include "polkit-agent.h"
-#include "process-util.h"
#include "stdio-util.h"
#if ENABLE_POLKIT
-static pid_t agent_pid = 0;
+static PidRef agent_pidref = PIDREF_NULL;
int polkit_agent_open(void) {
_cleanup_close_pair_ int pipe_fd[2] = EBADF_PAIR;
char notify_fd[DECIMAL_STR_MAX(int) + 1];
int r;
- if (agent_pid > 0)
+ if (pidref_is_set(&agent_pidref))
return 0;
/* Clients that run as root don't need to activate/query polkit */
r = fork_agent("(polkit-agent)",
&pipe_fd[1],
1,
- &agent_pid,
+ &agent_pidref,
POLKIT_AGENT_BINARY_PATH,
"--notify-fd", notify_fd,
"--fallback");
}
void polkit_agent_close(void) {
-
- if (agent_pid <= 0)
- return;
-
/* Inform agent that we are done */
- sigterm_wait(TAKE_PID(agent_pid));
+ pidref_done_sigterm_wait(&agent_pidref);
}
#else
return ASSERT_SIGNAL_FORK_CHILD;
}
- r = wait_for_terminate(r, &siginfo);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_set_pid(&pidref, r);
+ if (r < 0)
+ return r;
+
+ r = pidref_wait_for_terminate(&pidref, &siginfo);
if (r < 0)
return r;
#include "initrd-util.h"
#include "log.h"
#include "main-func.h"
+#include "pidref.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "special.h"
}
static int fork_wait(const char* const cmdline[]) {
- pid_t pid;
int r;
- r = safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(EXIT_FAILURE); /* Operational error */
}
- return wait_for_terminate_and_check(cmdline[0], pid, WAIT_LOG_ABNORMAL);
+ return pidref_wait_for_terminate_and_check(cmdline[0], &pidref, WAIT_LOG_ABNORMAL);
}
static void print_mode(const char* mode) {
#include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h"
+#include "pidref.h"
#include "pretty-print.h"
#include "process-util.h"
#include "rm-rf.h"
bool no_reload,
int noexec,
Hashmap *images) {
- pid_t pid;
+
int r;
(void) dlopen_cryptsetup();
(void) dlopen_libblkid();
(void) dlopen_libmount();
- r = safe_fork("(sd-merge)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork("(sd-merge)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, &pidref);
if (r < 0)
return log_error_errno(r, "Failed to fork off child: %m");
if (r == 0) {
_exit(r > 0 ? EXIT_SUCCESS : 123); /* 123 means: didn't find any extensions */
}
- r = wait_for_terminate_and_check("(sd-merge)", pid, WAIT_LOG_ABNORMAL);
+ r = pidref_wait_for_terminate_and_check("(sd-merge)", &pidref, WAIT_LOG_ABNORMAL);
if (r < 0)
return r;
if (r == 123) /* exit code 123 means: didn't do anything */
/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include "log.h"
#include "path-lookup.h"
#include "path-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "string-util.h"
#include "strv.h"
bool found_native = false, found_sysv;
const char *name;
unsigned c = 1;
- pid_t pid;
int j;
name = args[f++];
if (!arg_quiet)
log_info("Executing: %s", l);
- j = safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ j = pidref_safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
if (j < 0)
return j;
if (j == 0) {
_exit(EXIT_FAILURE);
}
- j = wait_for_terminate_and_check("sysv-install", pid, WAIT_LOG_ABNORMAL);
+ j = pidref_wait_for_terminate_and_check("sysv-install", &pidref, WAIT_LOG_ABNORMAL);
if (j < 0)
return j;
if (streq(verb, "is-enabled")) {
#include "gpt.h"
#include "hexdecoct.h"
#include "import-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "sort-util.h"
#include "stat-util.h"
_cleanup_close_pair_ int pfd[2] = EBADF_PAIR;
_cleanup_fclose_ FILE *manifest = NULL;
size_t size = 0;
- pid_t pid;
int r;
assert(url);
log_info("%s Acquiring manifest file %s%s", glyph(GLYPH_DOWNLOAD),
suffixed_url, glyph(GLYPH_ELLIPSIS));
- r = safe_fork_full("(sd-pull)",
- (int[]) { -EBADF, pfd[1], STDERR_FILENO },
- NULL, 0,
- FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG,
- &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork_full(
+ "(sd-pull)",
+ (int[]) { -EBADF, pfd[1], STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG,
+ &pidref);
if (r < 0)
return r;
if (r == 0) {
manifest = safe_fclose(manifest);
- r = wait_for_terminate_and_check("(sd-pull)", pid, WAIT_LOG);
+ r = pidref_wait_for_terminate_and_check("(sd-pull)", &pidref, WAIT_LOG);
if (r < 0)
return r;
if (r != 0)
}
static void test_rename_process_one(const char *p, int ret) {
- siginfo_t si;
- pid_t pid;
+ int r;
log_info("/* %s(%s) */", __func__, p);
- pid = fork();
- assert_se(pid >= 0);
+ r = ASSERT_OK(safe_fork("(rename)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
- if (pid == 0) {
+ if (r == 0) {
/* child */
test_rename_process_now(p, ret);
_exit(EXIT_SUCCESS);
}
-
- assert_se(wait_for_terminate(pid, &si) >= 0);
- assert_se(si.si_code == CLD_EXITED);
- assert_se(si.si_status == EXIT_SUCCESS);
}
TEST(rename_process_invalid) {
- assert_se(rename_process(NULL) == -EINVAL);
- assert_se(rename_process("") == -EINVAL);
+ ASSERT_ERROR(rename_process(NULL), EINVAL);
+ ASSERT_ERROR(rename_process(""), EINVAL);
}
TEST(rename_process_multi) {
- pid_t pid;
-
- pid = fork();
- assert_se(pid >= 0);
-
- if (pid > 0) {
- siginfo_t si;
+ int r;
- assert_se(wait_for_terminate(pid, &si) >= 0);
- assert_se(si.si_code == CLD_EXITED);
- assert_se(si.si_status == EXIT_SUCCESS);
+ r = ASSERT_OK(safe_fork("(rename)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
- return;
+ if (r == 0) {
+ /* child */
+ test_rename_process_now("one", 1);
+ test_rename_process_now("more", 0); /* longer than "one", hence truncated */
+ (void) setresuid(99, 99, 99); /* change uid when running privileged */
+ test_rename_process_now("time!", 0);
+ test_rename_process_now("0", 1); /* shorter than "one", should fit */
+ _exit(EXIT_SUCCESS);
}
-
- /* child */
- test_rename_process_now("one", 1);
- test_rename_process_now("more", 0); /* longer than "one", hence truncated */
- (void) setresuid(99, 99, 99); /* change uid when running privileged */
- test_rename_process_now("time!", 0);
- test_rename_process_now("0", 1); /* shorter than "one", should fit */
- _exit(EXIT_SUCCESS);
}
TEST(rename_process) {
#include "data-fd-util.h"
#include "fd-util.h"
#include "memfd-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "tests.h"
TEST(copy_data_fd) {
_cleanup_close_ int fd1 = -EBADF, fd2 = -EBADF;
_cleanup_close_pair_ int sfd[2] = EBADF_PAIR;
- _cleanup_(sigkill_waitp) pid_t pid = -1;
+ _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
int r;
fd1 = open("/etc/fstab", O_RDONLY|O_CLOEXEC);
assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, sfd) >= 0);
- r = safe_fork("(sd-pipe)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &pid);
+ r = pidref_safe_fork("(sd-pipe)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &pidref);
assert_se(r >= 0);
if (r == 0) {
}
static bool have_userns_privileges(void) {
- pid_t pid;
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
int r;
if (apparmor_restrict_unprivileged_userns())
return false;
- r = safe_fork("(sd-test-check-userns)",
- FORK_RESET_SIGNALS |
- FORK_CLOSE_ALL_FDS |
- FORK_DEATHSIG_SIGKILL,
- &pid);
- ASSERT_OK(r);
+ r = ASSERT_OK(pidref_safe_fork(
+ "(sd-test-check-userns)",
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL,
+ &pidref));
+
if (r == 0) {
/* Keep CAP_SYS_ADMIN if we have it to ensure we give an
* accurate result to the caller. Some kernels have a
* EXIT_SUCCESS => we can use user namespaces
* EXIT_FAILURE => we can NOT use user namespaces
* 2 => some other error occurred */
- r = wait_for_terminate_and_check("(sd-test-check-userns)", pid, 0);
+ r = pidref_wait_for_terminate_and_check("(sd-test-check-userns)", &pidref, 0);
if (!IN_SET(r, EXIT_SUCCESS, EXIT_FAILURE))
log_debug("Failed to check if user namespaces can be used, assuming not.");
#include "memfd-util.h"
#include "parse-util.h"
#include "path-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "random-util.h"
#include "rm-rf.h"
union sockaddr_union sa;
const char *j, *jj;
size_t size;
- pid_t pid;
int r;
ASSERT_OK(listener = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0));
/* Bind the *client* socket to some randomized name, to verify that this works correctly. */
ASSERT_OK(asprintf(&clientname, "@%" PRIx64 "/test-bindname", random_u64()));
- ASSERT_OK(r = safe_fork("(server)", FORK_DEATHSIG_SIGTERM|FORK_LOG, &pid));
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = ASSERT_OK(pidref_safe_fork("(server)", FORK_DEATHSIG_SIGTERM|FORK_LOG, &pidref));
if (r == 0) {
union sockaddr_union peer = {};
socklen_t peerlen = sizeof(peer);
ASSERT_EQ(size, strlen(TEST_STR));
ASSERT_STREQ(data, TEST_STR);
- ASSERT_OK(wait_for_terminate_and_check("(server)", pid, WAIT_LOG));
+ ASSERT_OK(pidref_wait_for_terminate_and_check("(server)", &pidref, WAIT_LOG));
#undef TEST_STR
}
#include "fs-util.h"
#include "mkdir.h"
#include "path-util.h"
+#include "pidref.h"
#include "process-util.h"
#include "random-util.h"
#include "rm-rf.h"
_cleanup_(rm_rf_physical_and_freep) char *t = NULL;
_cleanup_close_ int tfd = -EBADF, fd = -EBADF;
siginfo_t si;
+ int r;
- assert_se((tfd = mkdtemp_open(NULL, 0, &t)) >= 0);
+ ASSERT_OK((tfd = mkdtemp_open(NULL, 0, &t)));
/* Test that we can acquire an exclusive lock on a directory in one process, remove the directory,
* and close the file descriptor and still properly create the directory and acquire the lock in
* another process. */
- fd = xopenat_lock_full(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX);
- assert_se(fd >= 0);
- assert_se(faccessat(tfd, "abc", F_OK, 0) >= 0);
- assert_se(fd_verify_directory(fd) >= 0);
- assert_se(xopenat_lock_full(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN);
+ fd = ASSERT_OK(xopenat_lock_full(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX));
+ ASSERT_OK_ERRNO(faccessat(tfd, "abc", F_OK, 0));
+ ASSERT_OK(fd_verify_directory(fd));
+ ASSERT_ERROR(xopenat_lock_full(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB), EAGAIN);
- pid_t pid = fork();
- assert_se(pid >= 0);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = ASSERT_OK(pidref_safe_fork("(lock)", FORK_DEATHSIG_SIGKILL|FORK_LOG, &pidref));
- if (pid == 0) {
+ if (r == 0) {
safe_close(fd);
- fd = xopenat_lock_full(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX);
- assert_se(fd >= 0);
- assert_se(faccessat(tfd, "abc", F_OK, 0) >= 0);
- assert_se(fd_verify_directory(fd) >= 0);
- assert_se(xopenat_lock_full(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN);
+ fd = ASSERT_OK(xopenat_lock_full(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX));
+ ASSERT_OK_ERRNO(faccessat(tfd, "abc", F_OK, 0));
+ ASSERT_OK(fd_verify_directory(fd));
+ ASSERT_ERROR(xopenat_lock_full(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB), EAGAIN);
_exit(EXIT_SUCCESS);
}
* for a little and assume that's enough time for the child process to get along far enough. It
* doesn't matter if it doesn't get far enough, in that case we just won't trigger the fallback logic
* in xopenat_lock_full(), but the test will still succeed. */
- assert_se(usleep_safe(20 * USEC_PER_MSEC) >= 0);
+ ASSERT_OK(usleep_safe(20 * USEC_PER_MSEC));
- assert_se(unlinkat(tfd, "abc", AT_REMOVEDIR) >= 0);
+ ASSERT_OK(unlinkat(tfd, "abc", AT_REMOVEDIR));
fd = safe_close(fd);
- assert_se(wait_for_terminate(pid, &si) >= 0);
- assert_se(si.si_code == CLD_EXITED);
+ ASSERT_OK(pidref_wait_for_terminate(&pidref, &si));
+ ASSERT_EQ(si.si_code, CLD_EXITED);
- assert_se(xopenat_lock_full(tfd, "abc", 0, 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF);
- assert_se(xopenat_lock_full(tfd, "def", O_DIRECTORY, 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF);
+ ASSERT_ERROR(xopenat_lock_full(tfd, "abc", 0, 0, 0755, LOCK_POSIX, LOCK_EX), EBADF);
+ ASSERT_ERROR(xopenat_lock_full(tfd, "def", O_DIRECTORY, 0, 0755, LOCK_POSIX, LOCK_EX), EBADF);
}
TEST(linkat_replace) {
static void test_shareable_ns(unsigned long nsflag) {
_cleanup_close_pair_ int s[2] = EBADF_PAIR;
bool permission_denied = false;
- pid_t pid1, pid2, pid3;
+ _cleanup_(pidref_done) PidRef pidref1 = PIDREF_NULL, pidref2 = PIDREF_NULL, pidref3 = PIDREF_NULL;
int r, n = 0;
siginfo_t si;
ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, s));
- pid1 = fork();
- ASSERT_OK_ERRNO(pid1);
+ r = ASSERT_OK(pidref_safe_fork("(share-ns-1)", FORK_LOG|FORK_DEATHSIG_SIGKILL, &pidref1));
- if (pid1 == 0) {
+ if (r == 0) {
r = setup_shareable_ns(s, nsflag);
if (!ERRNO_IS_PRIVILEGE(r))
ASSERT_OK(r);
_exit(r >= 0 ? r : EX_NOPERM);
}
- pid2 = fork();
- ASSERT_OK_ERRNO(pid2);
+ r = ASSERT_OK(pidref_safe_fork("(share-ns-2)", FORK_LOG|FORK_DEATHSIG_SIGKILL, &pidref2));
- if (pid2 == 0) {
+ if (r == 0) {
r = setup_shareable_ns(s, nsflag);
if (!ERRNO_IS_PRIVILEGE(r))
ASSERT_OK(r);
_exit(r >= 0 ? r : EX_NOPERM);
}
- pid3 = fork();
- ASSERT_OK_ERRNO(pid3);
+ r = ASSERT_OK(pidref_safe_fork("(share-ns-3)", FORK_LOG|FORK_DEATHSIG_SIGKILL, &pidref3));
- if (pid3 == 0) {
+ if (r == 0) {
r = setup_shareable_ns(s, nsflag);
if (!ERRNO_IS_PRIVILEGE(r))
ASSERT_OK(r);
_exit(r >= 0 ? r : EX_NOPERM);
}
- ASSERT_OK(wait_for_terminate(pid1, &si));
+ ASSERT_OK(pidref_wait_for_terminate(&pidref1, &si));
ASSERT_EQ(si.si_code, CLD_EXITED);
if (si.si_status == EX_NOPERM)
permission_denied = true;
else
n += si.si_status;
- ASSERT_OK(wait_for_terminate(pid2, &si));
+ ASSERT_OK(pidref_wait_for_terminate(&pidref2, &si));
ASSERT_EQ(si.si_code, CLD_EXITED);
if (si.si_status == EX_NOPERM)
permission_denied = true;
else
n += si.si_status;
- ASSERT_OK(wait_for_terminate(pid3, &si));
+ ASSERT_OK(pidref_wait_for_terminate(&pidref3, &si));
ASSERT_EQ(si.si_code, CLD_EXITED);
if (si.si_status == EX_NOPERM)
permission_denied = true;
.protect_kernel_logs = true,
.root_directory_fd = -EBADF,
};
- pid_t pid;
int r;
if (geteuid() > 0) {
}
ASSERT_OK(r);
- pid = fork();
- ASSERT_OK_ERRNO(pid);
+ r = ASSERT_OK(safe_fork("(protect)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
- if (pid == 0) {
+ if (r == 0) {
_cleanup_close_ int fd = -EBADF;
ASSERT_OK_ERRNO(fd = open("/dev/kmsg", O_RDONLY | O_CLOEXEC));
_exit(EXIT_SUCCESS);
}
-
- ASSERT_OK_EQ(wait_for_terminate_and_check("ns-kernellogs", pid, WAIT_LOG), EXIT_SUCCESS);
}
TEST(idmapping_supported) {
static void test_find_executable_exec_one(const char *path) {
_cleanup_free_ char *t = NULL;
_cleanup_close_ int fd = -EBADF;
- pid_t pid;
int r;
r = find_executable_full(path, NULL, NULL, false, &t, &fd);
if (path_is_absolute(path))
ASSERT_STREQ(t, path);
- pid = fork();
- assert_se(pid >= 0);
- if (pid == 0) {
+ r = ASSERT_OK(safe_fork("(find-exec)", FORK_LOG|FORK_DEATHSIG_SIGKILL|FORK_WAIT, /* ret_pid= */ NULL));
+
+ if (r == 0) {
r = fexecve_or_execve(fd, t, STRV_MAKE(t, "--version"), STRV_MAKE(NULL));
log_error_errno(r, "[f]execve: %m");
_exit(EXIT_FAILURE);
}
-
- assert_se(wait_for_terminate_and_check(t, pid, WAIT_LOG) == 0);
}
TEST(find_executable_exec) {
_cleanup_close_ int fd = -EBADF;
_cleanup_free_ char *line = NULL;
_cleanup_strv_free_ char **args = NULL;
- pid_t pid;
int r;
if (geteuid() != 0) {
}
#endif
- pid = fork();
- if (pid > 0) {
- siginfo_t si;
-
- (void) wait_for_terminate(pid, &si);
-
- ASSERT_EQ(si.si_code, CLD_EXITED);
- ASSERT_OK_ZERO(si.si_status);
-
- return;
- }
-
- ASSERT_OK_ZERO(pid);
-
- r = detach_mount_namespace();
- if (r < 0) {
- log_warning_errno(r, "detach mount namespace failed: %m");
- if (!ERRNO_IS_PRIVILEGE(r))
- ASSERT_OK(r);
- return;
- }
+ r = ASSERT_OK(safe_fork("(cmdline)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
+ if (r == 0) {
+ r = detach_mount_namespace();
+ if (r < 0) {
+ log_warning_errno(r, "detach mount namespace failed: %m");
+ if (!ERRNO_IS_PRIVILEGE(r))
+ ASSERT_OK(r);
+ return;
+ }
- fd = mkostemp(path, O_CLOEXEC);
- ASSERT_OK_ERRNO(fd);
+ fd = mkostemp(path, O_CLOEXEC);
+ ASSERT_OK_ERRNO(fd);
- /* Note that we don't unmount the following bind-mount at the end of the test because the kernel
- * will clear up its /proc/PID/ hierarchy automatically as soon as the test stops. */
- if (mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) < 0) {
- /* This happens under selinux… Abort the test in this case. */
- log_warning_errno(errno, "mount(..., \"/proc/self/cmdline\", \"bind\", ...) failed: %m");
- ASSERT_TRUE(IN_SET(errno, EPERM, EACCES));
- return;
- }
+ /* Note that we don't unmount the following bind-mount at the end of the test because the kernel
+ * will clear up its /proc/PID/ hierarchy automatically as soon as the test stops. */
+ if (mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) < 0) {
+ /* This happens under selinux… Abort the test in this case. */
+ log_warning_errno(errno, "mount(..., \"/proc/self/cmdline\", \"bind\", ...) failed: %m");
+ ASSERT_TRUE(IN_SET(errno, EPERM, EACCES));
+ return;
+ }
- /* Set RLIMIT_STACK to infinity to test we don't try to allocate unnecessarily large values to read
- * the cmdline. */
- if (setrlimit(RLIMIT_STACK, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
- log_warning("Testing without RLIMIT_STACK=infinity");
+ /* Set RLIMIT_STACK to infinity to test we don't try to allocate unnecessarily large values to read
+ * the cmdline. */
+ if (setrlimit(RLIMIT_STACK, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
+ log_warning("Testing without RLIMIT_STACK=infinity");
- ASSERT_OK_ERRNO(unlink(path));
+ ASSERT_OK_ERRNO(unlink(path));
- ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "testa"));
+ ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "testa"));
- ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
+ ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "[testa]");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "[testa]");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "\"[testa]\""); /* quoting is enabled here */
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "\"[testa]\""); /* quoting is enabled here */
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, 0, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, 0, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- ASSERT_STREQ(line, "…");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ ASSERT_STREQ(line, "…");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- ASSERT_STREQ(line, "[…");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ ASSERT_STREQ(line, "[…");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- ASSERT_STREQ(line, "[t…");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ ASSERT_STREQ(line, "[t…");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- ASSERT_STREQ(line, "[te…");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ ASSERT_STREQ(line, "[te…");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- ASSERT_STREQ(line, "[tes…");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ ASSERT_STREQ(line, "[tes…");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- ASSERT_STREQ(line, "[test…");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ ASSERT_STREQ(line, "[test…");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- ASSERT_STREQ(line, "[testa]");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ ASSERT_STREQ(line, "[testa]");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- ASSERT_STREQ(line, "[testa]");
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ ASSERT_STREQ(line, "[testa]");
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
- ASSERT_TRUE(strv_equal(args, STRV_MAKE("[testa]")));
- args = strv_free(args);
+ ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
+ ASSERT_TRUE(strv_equal(args, STRV_MAKE("[testa]")));
+ args = strv_free(args);
/* Test with multiple arguments that don't require quoting */
- ASSERT_OK_EQ_ERRNO(write(fd, "foo\0bar", 8), 8);
-
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- ASSERT_STREQ(line, "foo bar");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
- ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar")));
- args = strv_free(args);
-
- ASSERT_OK_EQ_ERRNO(write(fd, "quux", 4), 4);
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar quux");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar quux");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "f…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "fo…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo …");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo b…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo ba…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 9, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar …");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar q…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar qu…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar quux");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 13, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar quux");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 14, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar quux");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 1000, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "foo bar quux");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
- ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar", "quux")));
- args = strv_free(args);
-
- ASSERT_OK_ERRNO(ftruncate(fd, 0));
- ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "aaaa bbbb cccc"));
-
- ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
-
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "[aaaa bbbb cccc]");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "[aaaa bbb…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "[aaaa bbbb…");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
- log_debug("'%s'", line);
- ASSERT_STREQ(line, "[aaaa bbbb …");
- line = mfree(line);
-
- ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
- ASSERT_TRUE(strv_equal(args, STRV_MAKE("[aaaa bbbb cccc]")));
- args = strv_free(args);
-
- /* Test with multiple arguments that do require quoting */
+ ASSERT_OK_EQ_ERRNO(write(fd, "foo\0bar", 8), 8);
+
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ ASSERT_STREQ(line, "foo bar");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
+ ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar")));
+ args = strv_free(args);
+
+ ASSERT_OK_EQ_ERRNO(write(fd, "quux", 4), 4);
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar quux");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar quux");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "f…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "fo…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo …");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo b…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo ba…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 9, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar …");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar q…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar qu…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar quux");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 13, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar quux");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 14, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar quux");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 1000, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "foo bar quux");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
+ ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar", "quux")));
+ args = strv_free(args);
+
+ ASSERT_OK_ERRNO(ftruncate(fd, 0));
+ ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "aaaa bbbb cccc"));
+
+ ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
+
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "[aaaa bbbb cccc]");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "[aaaa bbb…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "[aaaa bbbb…");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
+ log_debug("'%s'", line);
+ ASSERT_STREQ(line, "[aaaa bbbb …");
+ line = mfree(line);
+
+ ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
+ ASSERT_TRUE(strv_equal(args, STRV_MAKE("[aaaa bbbb cccc]")));
+ args = strv_free(args);
+
+ /* Test with multiple arguments that do require quoting */
#define CMDLINE1 "foo\0'bar'\0\"bar$\"\0x y z\0!``\0"
#define EXPECT1 "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\""
#define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``'"
#define EXPECT1v STRV_MAKE("foo", "'bar'", "\"bar$\"", "x y z", "!``")
- ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
- ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE1, sizeof(CMDLINE1)), (ssize_t) sizeof(CMDLINE1));
- ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof(CMDLINE1)));
+ ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE1, sizeof(CMDLINE1)), (ssize_t) sizeof(CMDLINE1));
+ ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof(CMDLINE1)));
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
- log_debug("got: ==%s==", line);
- log_debug("exp: ==%s==", EXPECT1);
- ASSERT_STREQ(line, EXPECT1);
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
+ log_debug("got: ==%s==", line);
+ log_debug("exp: ==%s==", EXPECT1);
+ ASSERT_STREQ(line, EXPECT1);
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
- log_debug("got: ==%s==", line);
- log_debug("exp: ==%s==", EXPECT1p);
- ASSERT_STREQ(line, EXPECT1p);
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
+ log_debug("got: ==%s==", line);
+ log_debug("exp: ==%s==", EXPECT1p);
+ ASSERT_STREQ(line, EXPECT1p);
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
- ASSERT_TRUE(strv_equal(args, EXPECT1v));
- args = strv_free(args);
+ ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
+ ASSERT_TRUE(strv_equal(args, EXPECT1v));
+ args = strv_free(args);
#define CMDLINE2 "foo\0\1\2\3\0\0"
#define EXPECT2 "foo \"\\001\\002\\003\""
#define EXPECT2p "foo $'\\001\\002\\003'"
#define EXPECT2v STRV_MAKE("foo", "\1\2\3")
- ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
- ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE2, sizeof(CMDLINE2)), (ssize_t) sizeof(CMDLINE2));
- ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof CMDLINE2));
+ ASSERT_OK_ZERO_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE2, sizeof(CMDLINE2)), (ssize_t) sizeof(CMDLINE2));
+ ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof CMDLINE2));
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
- log_debug("got: ==%s==", line);
- log_debug("exp: ==%s==", EXPECT2);
- ASSERT_STREQ(line, EXPECT2);
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
+ log_debug("got: ==%s==", line);
+ log_debug("exp: ==%s==", EXPECT2);
+ ASSERT_STREQ(line, EXPECT2);
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
- log_debug("got: ==%s==", line);
- log_debug("exp: ==%s==", EXPECT2p);
- ASSERT_STREQ(line, EXPECT2p);
- line = mfree(line);
+ ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
+ log_debug("got: ==%s==", line);
+ log_debug("exp: ==%s==", EXPECT2p);
+ ASSERT_STREQ(line, EXPECT2p);
+ line = mfree(line);
- ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
- ASSERT_TRUE(strv_equal(args, EXPECT2v));
- args = strv_free(args);
+ ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
+ ASSERT_TRUE(strv_equal(args, EXPECT2v));
+ args = strv_free(args);
- safe_close(fd);
- _exit(EXIT_SUCCESS);
+ safe_close(fd);
+ _exit(EXIT_SUCCESS);
+ }
}
TEST(getpid_cached) {
- siginfo_t si;
- pid_t a, b, c, d, e, f, child;
+ pid_t a, b, c, d, e, f;
+ int r;
a = getpid();
b = getpid_cached();
ASSERT_EQ(a, b);
ASSERT_EQ(a, c);
- child = fork();
- ASSERT_OK_ERRNO(child);
+ r = ASSERT_OK(safe_fork("(getpid)", FORK_WAIT|FORK_LOG|FORK_DEATHSIG_SIGKILL, /* ret_pid= */ NULL));
- if (child == 0) {
+ if (r == 0) {
/* In child */
a = getpid();
b = getpid_cached();
ASSERT_EQ(a, d);
ASSERT_EQ(a, e);
ASSERT_EQ(a, f);
-
- ASSERT_OK(wait_for_terminate(child, &si));
- ASSERT_EQ(si.si_status, 0);
- ASSERT_EQ(si.si_code, CLD_EXITED);
}
TEST(getpid_measure) {
pid_t pid;
int r;
- BLOCK_SIGNALS(SIGCHLD);
-
r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &pid);
ASSERT_OK(r);
_exit(88);
}
- ASSERT_OK(wait_for_terminate(pid, &status));
+ _cleanup_(pidref_done) PidRef child = PIDREF_NULL;
+ ASSERT_OK(pidref_set_pid(&child, pid));
+
+ ASSERT_OK(pidref_wait_for_terminate(&child, &status));
ASSERT_EQ(status.si_code, CLD_EXITED);
ASSERT_EQ(status.si_status, 88);
- _cleanup_(pidref_done) PidRef child = PIDREF_NULL;
+ pidref_done(&child);
r = pidref_safe_fork("(test-child)", FORK_DETACH, &child);
if (r == 0) {
/* Don't freeze so this doesn't linger around forever in case something goes wrong. */
#include "locale-util.h"
#include "log.h"
#include "main-func.h"
+#include "pidref.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "stdio-util.h"
static int keyboard_load_and_wait(const char *vc, Context *c, bool utf8) {
const char* args[8];
unsigned i = 0;
- pid_t pid;
int r;
assert(vc);
log_debug("Executing \"%s\"...", strnull(cmd));
}
- r = safe_fork("(loadkeys)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork("(loadkeys)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
if (r < 0)
return r;
if (r == 0) {
_exit(EXIT_FAILURE);
}
- return wait_for_terminate_and_check(KBD_LOADKEYS, pid, WAIT_LOG);
+ return pidref_wait_for_terminate_and_check(KBD_LOADKEYS, &pidref, WAIT_LOG);
}
static int font_load_and_wait(const char *vc, Context *c) {
const char* args[9];
unsigned i = 0;
- pid_t pid;
int r;
assert(vc);
log_debug("Executing \"%s\"...", strnull(cmd));
}
- r = safe_fork("(setfont)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ r = pidref_safe_fork("(setfont)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
if (r < 0)
return r;
if (r == 0) {
/* setfont returns EX_OSERR when ioctl(KDFONTOP/PIO_FONTX/PIO_FONTX) fails. This might mean various
* things, but in particular lack of a graphical console. Let's be generous and not treat this as an
* error. */
- r = wait_for_terminate_and_check(KBD_SETFONT, pid, WAIT_LOG_ABNORMAL);
+ r = pidref_wait_for_terminate_and_check(KBD_SETFONT, &pidref, WAIT_LOG_ABNORMAL);
if (r == EX_OSERR)
log_notice(KBD_SETFONT " failed with a \"system error\" (EX_OSERR), ignoring.");
else if (r >= 0 && r != EXIT_SUCCESS)