- pid_is_unwaited() → pidref_is_unwaited()
- pid_is_alive() → pidref_is_alive()
- unit_watch_pid() → unit_watch_pidref()
- - actually wait for POLLIN on piref's pidfd in service logic
+ - actually wait for POLLIN on pidref's pidfd in service logic
- exec_spawn()
- serialization of control/main pid in service, socket, mount, swap units
- - unit_fork_and_watch_rm_rf()
- cg_pid_get_unit()
- openpt_allocate_in_namespace()
- scope dbus PIDs property needs to gain PIDFDs companion
static int mount_clean(Unit *u, ExecCleanMask mask) {
_cleanup_strv_free_ char **l = NULL;
Mount *m = MOUNT(u);
- pid_t pid;
int r;
assert(m);
if (r < 0)
goto fail;
- r = unit_fork_and_watch_rm_rf(u, l, &pid);
- if (r < 0)
- goto fail;
-
- r = pidref_set_pid(&m->control_pid, pid);
+ r = unit_fork_and_watch_rm_rf(u, l, &m->control_pid);
if (r < 0)
goto fail;
}
static int scope_enter_start_chown(Scope *s) {
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
Unit *u = UNIT(s);
- pid_t pid;
int r;
assert(s);
if (r < 0)
return r;
- r = unit_fork_helper_process(u, "(sd-chown-cgroup)", &pid);
+ r = unit_fork_helper_process(u, "(sd-chown-cgroup)", &pidref);
if (r < 0)
goto fail;
_exit(EXIT_SUCCESS);
}
- r = unit_watch_pid(UNIT(s), pid, true);
+ r = unit_watch_pid(UNIT(s), pidref.pid, /* exclusive= */ true);
if (r < 0)
goto fail;
_cleanup_strv_free_ char **l = NULL;
bool may_clean_fdstore = false;
Service *s = SERVICE(u);
- pid_t pid;
int r;
assert(s);
if (r < 0)
goto fail;
- r = unit_fork_and_watch_rm_rf(u, l, &pid);
- if (r < 0)
- goto fail;
-
- r = pidref_set_pid(&s->control_pid, pid);
+ r = unit_fork_and_watch_rm_rf(u, l, &s->control_pid);
if (r < 0)
goto fail;
const SocketAddress *address,
const char *label) {
+ _cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
_cleanup_close_pair_ int pair[2] = PIPE_EBADF;
int fd, r;
- pid_t pid;
assert(s);
assert(address);
fd = receive_one_fd(pair[0], 0);
/* We synchronously wait for the helper, as it shouldn't be slow */
- r = wait_for_terminate_and_check("(sd-listen)", pid, WAIT_LOG_ABNORMAL);
+ r = wait_for_terminate_and_check("(sd-listen)", pid.pid, WAIT_LOG_ABNORMAL);
if (r < 0) {
safe_close(fd);
return r;
}
static int socket_chown(Socket *s, PidRef *ret_pid) {
- _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
- pid_t pid;
+ _cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
int r;
assert(s);
_exit(EXIT_SUCCESS);
}
- r = pidref_set_pid(&pidref, pid);
- if (r < 0)
- return r;
-
- r = unit_watch_pid(UNIT(s), pidref.pid, /* exclusive= */ true);
+ r = unit_watch_pid(UNIT(s), pid.pid, /* exclusive= */ true);
if (r < 0)
return r;
- *ret_pid = TAKE_PIDREF(pidref);
+ *ret_pid = TAKE_PIDREF(pid);
return 0;
}
}
static int socket_accept_in_cgroup(Socket *s, SocketPort *p, int fd) {
+ _cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
_cleanup_close_pair_ int pair[2] = PIPE_EBADF;
int cfd, r;
- pid_t pid;
assert(s);
assert(p);
cfd = receive_one_fd(pair[0], 0);
/* We synchronously wait for the helper, as it shouldn't be slow */
- r = wait_for_terminate_and_check("(sd-accept)", pid, WAIT_LOG_ABNORMAL);
+ r = wait_for_terminate_and_check("(sd-accept)", pid.pid, WAIT_LOG_ABNORMAL);
if (r < 0) {
safe_close(cfd);
return r;
static int socket_clean(Unit *u, ExecCleanMask mask) {
_cleanup_strv_free_ char **l = NULL;
Socket *s = SOCKET(u);
- pid_t pid;
int r;
assert(s);
if (r < 0)
goto fail;
- r = unit_fork_and_watch_rm_rf(u, l, &pid);
- if (r < 0)
- goto fail;
-
- r = pidref_set_pid(&s->control_pid, pid);
+ r = unit_fork_and_watch_rm_rf(u, l, &s->control_pid);
if (r < 0)
goto fail;
static int swap_clean(Unit *u, ExecCleanMask mask) {
_cleanup_strv_free_ char **l = NULL;
Swap *s = SWAP(u);
- pid_t pid;
int r;
assert(s);
if (r < 0)
goto fail;
- r = unit_fork_and_watch_rm_rf(u, l, &pid);
- if (r < 0)
- goto fail;
-
- r = pidref_set_pid(&s->control_pid, pid);
+ r = unit_fork_and_watch_rm_rf(u, l, &s->control_pid);
if (r < 0)
goto fail;
return 0;
}
-int unit_fork_helper_process(Unit *u, const char *name, pid_t *ret) {
+int unit_fork_helper_process(Unit *u, const char *name, PidRef *ret) {
+ pid_t pid;
int r;
assert(u);
(void) unit_realize_cgroup(u);
- r = safe_fork(name, FORK_REOPEN_LOG|FORK_DEATHSIG, ret);
- if (r != 0)
+ r = safe_fork(name, FORK_REOPEN_LOG|FORK_DEATHSIG, &pid);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ int q;
+
+ /* Parent */
+
+ q = pidref_set_pid(&pidref, pid);
+ if (q < 0)
+ return q;
+
+ *ret = TAKE_PIDREF(pidref);
return r;
+ }
+
+ /* Child */
(void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE);
(void) ignore_signals(SIGPIPE);
return 0;
}
-int unit_fork_and_watch_rm_rf(Unit *u, char **paths, pid_t *ret_pid) {
- pid_t pid;
+int unit_fork_and_watch_rm_rf(Unit *u, char **paths, PidRef *ret_pid) {
+ _cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
int r;
assert(u);
_exit(ret);
}
- r = unit_watch_pid(u, pid, true);
+ r = unit_watch_pid(u, pid.pid, /* exclusive= */ true);
if (r < 0)
return r;
- *ret_pid = pid;
+ *ret_pid = TAKE_PIDREF(pid);
return 0;
}
int unit_set_exec_params(Unit *s, ExecParameters *p);
-int unit_fork_helper_process(Unit *u, const char *name, pid_t *ret);
-int unit_fork_and_watch_rm_rf(Unit *u, char **paths, pid_t *ret_pid);
+int unit_fork_helper_process(Unit *u, const char *name, PidRef *ret);
+int unit_fork_and_watch_rm_rf(Unit *u, char **paths, PidRef *ret);
void unit_remove_dependencies(Unit *u, UnitDependencyMask mask);