manager_is_inhibited(m, inhibit_operation, INHIBIT_BLOCK, NULL, false, false, 0, &offending)) {
_cleanup_free_ char *comm = NULL, *u = NULL;
- (void) get_process_comm(offending->pid, &comm);
+ (void) get_process_comm(offending->pid.pid, &comm);
u = uid_to_name(offending->uid);
/* If this is just a recheck of the lid switch then don't warn about anything */
handle_action_to_string(handle),
inhibit_what_to_string(inhibit_operation),
offending->uid, strna(u),
- offending->pid, strna(comm));
+ offending->pid.pid, strna(comm));
return is_edge ? -EPERM : 0;
}
strempty(inhibitor->why),
strempty(inhibit_mode_to_string(inhibitor->mode)),
(uint32_t) inhibitor->uid,
- (uint32_t) inhibitor->pid);
+ (uint32_t) inhibitor->pid.pid);
if (r < 0)
return r;
}
if (!timeout)
return 0;
- (void) get_process_comm(offending->pid, &comm);
+ (void) get_process_comm(offending->pid.pid, &comm);
u = uid_to_name(offending->uid);
log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
offending->uid, strna(u),
- offending->pid, strna(comm));
+ offending->pid.pid, strna(comm));
}
/* Actually do the operation */
static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
const char *who, *why, *what, *mode;
_cleanup_free_ char *id = NULL;
_cleanup_close_ int fifo_fd = -EBADF;
if (r < 0)
return r;
+ r = pidref_set_pid(&pidref, pid);
+ if (r < 0)
+ return sd_bus_error_set_errnof(error, r, "Failed pin source process "PID_FMT": %m", pid);
+
if (hashmap_size(m->inhibitors) >= m->inhibitors_max)
return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED,
"Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.",
i->what = w;
i->mode = mm;
- i->pid = pid;
+ i->pid = TAKE_PIDREF(pidref);
i->uid = uid;
i->why = strdup(why);
i->who = strdup(who);
.mode = _INHIBIT_MODE_INVALID,
.uid = UID_INVALID,
.fifo_fd = -EBADF,
+ .pid = PIDREF_NULL,
};
i->state_file = path_join("/run/systemd/inhibit", id);
free(i->state_file);
free(i->fifo_path);
+ pidref_done(&i->pid);
+
return mfree(i);
}
inhibit_what_to_string(i->what),
inhibit_mode_to_string(i->mode),
i->uid,
- i->pid);
+ i->pid.pid);
if (i->who) {
_cleanup_free_ char *cc = NULL;
log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s started.",
strna(i->who), strna(i->why),
- i->pid, i->uid,
+ i->pid.pid, i->uid,
inhibit_mode_to_string(i->mode));
i->started = true;
if (i->started)
log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s stopped.",
strna(i->who), strna(i->why),
- i->pid, i->uid,
+ i->pid.pid, i->uid,
inhibit_mode_to_string(i->mode));
inhibitor_remove_fifo(i);
}
if (pid) {
- r = parse_pid(pid, &i->pid);
+ pidref_done(&i->pid);
+ r = pidref_set_pidstr(&i->pid, pid);
if (r < 0)
log_debug_errno(r, "Failed to parse PID of inhibitor: %s", pid);
}
if (i->mode != mm)
continue;
- if (ignore_inactive && pid_is_active(m, i->pid) <= 0)
+ if (ignore_inactive && pid_is_active(m, i->pid.pid) <= 0)
continue;
if (ignore_uid && i->uid == uid)
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "pidref.h"
+
typedef struct Inhibitor Inhibitor;
typedef enum InhibitWhat {
char *why;
InhibitMode mode;
- pid_t pid;
+ PidRef pid;
uid_t uid;
dual_timestamp since;
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader.pid), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST),
.vtfd = -EBADF,
.audit_id = AUDIT_SESSION_INVALID,
.tty_validity = _TTY_VALIDITY_INVALID,
+ .leader = PIDREF_NULL,
};
s->state_file = path_join("/run/systemd/sessions", id);
free(s->scope);
}
- if (pid_is_valid(s->leader))
- (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s);
+ if (pidref_is_set(&s->leader)) {
+ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader.pid), s);
+ pidref_done(&s->leader);
+ }
free(s->scope_job);
}
int session_set_leader(Session *s, pid_t pid) {
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
int r;
assert(s);
if (!pid_is_valid(pid))
return -EINVAL;
- if (s->leader == pid)
+ if (s->leader.pid == pid)
return 0;
- r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pid), s);
+ r = pidref_set_pid(&pidref, pid);
if (r < 0)
return r;
- if (pid_is_valid(s->leader))
- (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s);
+ r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pidref.pid), s);
+ if (r < 0)
+ return r;
+
+ if (pidref_is_set(&s->leader)) {
+ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader.pid), s);
+ pidref_done(&s->leader);
+ }
- s->leader = pid;
- (void) audit_session_from_pid(pid, &s->audit_id);
+ s->leader = TAKE_PIDREF(pidref);
+ (void) audit_session_from_pid(s->leader.pid, &s->audit_id);
return 1;
}
if (!s->vtnr)
fprintf(f, "POSITION=%u\n", s->position);
- if (pid_is_valid(s->leader))
- fprintf(f, "LEADER="PID_FMT"\n", s->leader);
+ if (pidref_is_set(&s->leader))
+ fprintf(f, "LEADER="PID_FMT"\n", s->leader.pid);
if (audit_session_is_valid(s->audit_id))
fprintf(f, "AUDIT=%"PRIu32"\n", s->audit_id);
r = manager_start_scope(
s->manager,
scope,
- s->leader,
+ s->leader.pid,
s->user->slice,
description,
/* These two have StopWhenUnneeded= set, hence add a dep towards them */
"MESSAGE_ID=" SD_MESSAGE_SESSION_START_STR,
"SESSION_ID=%s", s->id,
"USER_ID=%s", s->user->user_record->user_name,
- "LEADER="PID_FMT, s->leader,
+ "LEADER="PID_FMT, s->leader.pid,
LOG_MESSAGE("New session %s of user %s.", s->id, s->user->user_record->user_name));
if (!dual_timestamp_is_set(&s->timestamp))
log_struct(s->class == SESSION_BACKGROUND ? LOG_DEBUG : LOG_INFO,
"SESSION_ID=%s", s->id,
"USER_ID=%s", s->user->user_record->user_name,
- "LEADER="PID_FMT, s->leader,
+ "LEADER="PID_FMT, s->leader.pid,
LOG_MESSAGE("Session %s logged out. Waiting for processes to exit.", s->id));
}
"MESSAGE_ID=" SD_MESSAGE_SESSION_STOP_STR,
"SESSION_ID=%s", s->id,
"USER_ID=%s", s->user->user_record->user_name,
- "LEADER="PID_FMT, s->leader,
+ "LEADER="PID_FMT, s->leader.pid,
LOG_MESSAGE("Removed session %s.", s->id));
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
/* For sessions with a leader but no explicitly configured tty, let's check the controlling tty of
* the leader */
- if (pid_is_valid(s->leader)) {
- r = get_process_ctty_atime(s->leader, &atime);
+ if (pidref_is_set(&s->leader)) {
+ r = get_process_ctty_atime(s->leader.pid, &atime);
if (r >= 0)
goto found_atime;
}
#include "list.h"
#include "login-util.h"
#include "logind-user.h"
+#include "pidref.h"
#include "string-util.h"
typedef enum SessionState {
unsigned vtnr;
int vtfd;
- pid_t leader;
+ PidRef leader;
uint32_t audit_id;
int fifo_fd;