s->exec_context.std_output = u->manager->default_std_output;
s->exec_context.std_error = u->manager->default_std_error;
+ s->control_pid = PIDREF_NULL;
s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
s->trigger_limit.interval = USEC_INFINITY;
static void socket_unwatch_control_pid(Socket *s) {
assert(s);
- if (s->control_pid <= 0)
+ if (!pidref_is_set(&s->control_pid))
return;
- unit_unwatch_pid(UNIT(s), TAKE_PID(s->control_pid));
+ unit_unwatch_pid(UNIT(s), s->control_pid.pid);
+ pidref_done(&s->control_pid);
}
static void socket_cleanup_fd_list(SocketPort *p) {
"%sTimestamping: %s\n",
prefix, socket_timestamping_to_string(s->timestamping));
- if (s->control_pid > 0)
+ if (pidref_is_set(&s->control_pid))
fprintf(f,
"%sControl PID: "PID_FMT"\n",
- prefix, s->control_pid);
+ prefix, s->control_pid.pid);
if (s->bind_to_device)
fprintf(f,
if (s->deserialized_state == s->state)
return 0;
- if (s->control_pid > 0 &&
- pid_is_unwaited(s->control_pid) &&
+ if (pidref_is_set(&s->control_pid) &&
+ pid_is_unwaited(s->control_pid.pid) &&
IN_SET(s->deserialized_state,
SOCKET_START_PRE,
SOCKET_START_CHOWN,
SOCKET_FINAL_SIGKILL,
SOCKET_CLEANING)) {
- r = unit_watch_pid(UNIT(s), s->control_pid, false);
+ r = unit_watch_pid(UNIT(s), s->control_pid.pid, /* exclusive= */ false);
if (r < 0)
return r;
return 0;
}
-static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
+static int socket_spawn(Socket *s, ExecCommand *c, PidRef *ret_pid) {
_cleanup_(exec_params_clear) ExecParameters exec_params = {
.flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
.stderr_fd = -EBADF,
.exec_fd = -EBADF,
};
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
pid_t pid;
int r;
assert(s);
assert(c);
- assert(_pid);
+ assert(ret_pid);
r = unit_prepare_exec(UNIT(s));
if (r < 0)
if (r < 0)
return r;
- r = unit_watch_pid(UNIT(s), pid, true);
+ r = pidref_set_pid(&pidref, pid);
if (r < 0)
return r;
- *_pid = pid;
+ r = unit_watch_pid(UNIT(s), pidref.pid, /* exclusive= */ true);
+ if (r < 0)
+ return r;
+ *ret_pid = TAKE_PIDREF(pidref);
return 0;
}
-static int socket_chown(Socket *s, pid_t *_pid) {
+static int socket_chown(Socket *s, PidRef *ret_pid) {
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
pid_t pid;
int r;
+ assert(s);
+
r = socket_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_usec));
if (r < 0)
goto fail;
_exit(EXIT_SUCCESS);
}
- r = unit_watch_pid(UNIT(s), pid, true);
+ r = pidref_set_pid(&pidref, pid);
+ if (r < 0)
+ goto fail;
+
+ r = unit_watch_pid(UNIT(s), pidref.pid, /* exclusive= */ true);
if (r < 0)
goto fail;
- *_pid = pid;
+ *ret_pid = TAKE_PIDREF(pidref);
return 0;
fail:
s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST];
if (s->control_command) {
+ pidref_done(&s->control_pid);
+
r = socket_spawn(s, s->control_command, &s->control_pid);
if (r < 0)
goto fail;
&s->kill_context,
state_to_kill_operation(s, state),
-1,
- s->control_pid,
+ s->control_pid.pid,
false);
if (r < 0)
goto fail;
s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE];
if (s->control_command) {
+ pidref_done(&s->control_pid);
+
r = socket_spawn(s, s->control_command, &s->control_pid);
if (r < 0)
goto fail;
s->control_command = s->exec_command[SOCKET_EXEC_START_POST];
if (s->control_command) {
+ pidref_done(&s->control_pid);
+
r = socket_spawn(s, s->control_command, &s->control_pid);
if (r < 0) {
log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-post' task: %m");
s->control_command = s->exec_command[SOCKET_EXEC_START_PRE];
if (s->control_command) {
+ pidref_done(&s->control_pid);
+
r = socket_spawn(s, s->control_command, &s->control_pid);
if (r < 0) {
log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-pre' task: %m");
s->control_command = s->control_command->command_next;
+ pidref_done(&s->control_pid);
+
r = socket_spawn(s, s->control_command, &s->control_pid);
if (r < 0)
goto fail;
(void) serialize_item_format(f, "n-accepted", "%u", s->n_accepted);
(void) serialize_item_format(f, "n-refused", "%u", s->n_refused);
- if (s->control_pid > 0)
- (void) serialize_item_format(f, "control-pid", PID_FMT, s->control_pid);
+ if (pidref_is_set(&s->control_pid))
+ (void) serialize_item_format(f, "control-pid", PID_FMT, s->control_pid.pid);
if (s->control_command_id >= 0)
(void) serialize_item(f, "control-command", socket_exec_command_to_string(s->control_command_id));
else
s->n_refused += k;
} else if (streq(key, "control-pid")) {
- pid_t pid;
-
- if (parse_pid(value, &pid) < 0)
- log_unit_debug(u, "Failed to parse control-pid value: %s", value);
- else
- s->control_pid = pid;
+ pidref_done(&s->control_pid);
+ r = pidref_set_pidstr(&s->control_pid, value);
+ if (r < 0)
+ log_debug_errno(r, "Failed to pin control PID '%s', ignoring: %m", value);
} else if (streq(key, "control-command")) {
SocketExecCommand id;
assert(s);
assert(pid >= 0);
- if (pid != s->control_pid)
+ if (pid != s->control_pid.pid)
return;
- s->control_pid = 0;
+ pidref_done(&s->control_pid);
if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL))
f = SOCKET_SUCCESS;
}
static int socket_kill(Unit *u, KillWho who, int signo, int code, int value, sd_bus_error *error) {
- return unit_kill_common(u, who, signo, code, value, -1, SOCKET(u)->control_pid, error);
+ return unit_kill_common(u, who, signo, code, value, -1, SOCKET(u)->control_pid.pid, error);
}
static int socket_get_timeout(Unit *u, usec_t *timeout) {
assert(s);
- return s->control_pid;
+ return s->control_pid.pid;
}
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, &s->control_pid);
+ r = unit_fork_and_watch_rm_rf(u, l, &pid);
if (r < 0)
goto fail;
- socket_set_state(s, SOCKET_CLEANING);
+ r = pidref_set_pid(&s->control_pid, pid);
+ if (r < 0)
+ goto fail;
+ socket_set_state(s, SOCKET_CLEANING);
return 0;
fail: