logind-session.c revision baccf3e40bab6c0b69992ae29c396930de4660c9
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen This file is part of systemd.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen Copyright 2011 Lennart Poettering
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen systemd is free software; you can redistribute it and/or modify it
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen under the terms of the GNU Lesser General Public License as published by
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen (at your option) any later version.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen systemd is distributed in the hope that it will be useful, but
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen Lesser General Public License for more details.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen You should have received a copy of the GNU Lesser General Public License
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersenstatic unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersenstatic int devt_compare_func(const void *_a, const void *_b) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom GundersenSession* session_new(Manager *m, const char *id) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen s->state_file = strappend("/run/systemd/sessions/", id);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen s->devices = hashmap_new(devt_hash_func, devt_compare_func);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen LIST_REMOVE(gc_queue, s->manager->session_gc_queue, s);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen s->timer_event_source = sd_event_source_unref(s->timer_event_source);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen LIST_REMOVE(sessions_by_user, s->user->sessions, s);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen LIST_REMOVE(sessions_by_seat, s->seat->sessions, s);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen hashmap_remove(s->manager->session_units, s->scope);
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen s->vt_source = sd_event_source_unref(s->vt_source);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen LIST_PREPEND(sessions_by_user, u->sessions, s);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen r = fopen_temporary(s->state_file, &f, &temp_path);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen "# This is private data. Do not parse.\n"
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen "ACTIVE=%i\n"
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen "REMOTE=%i\n",
s->remote);
if (s->type >= 0)
if (s->class >= 0)
if (s->scope)
if (s->scope_job)
if (s->fifo_path)
if (s->seat)
if (s->tty)
if (s->display)
if (s->remote_host) {
if (!escaped) {
r = -ENOMEM;
goto finish;
if (s->remote_user) {
if (!escaped) {
r = -ENOMEM;
goto finish;
if (s->service) {
if (!escaped) {
r = -ENOMEM;
goto finish;
if (s->desktop) {
if (!escaped) {
r = -ENOMEM;
goto finish;
if (!s->vtnr)
if (s->leader > 0)
if (s->audit_id > 0)
fprintf(f,
if (s->controller)
fflush(f);
r = -errno;
assert(s);
NULL);
if (!s->user) {
uid_t u;
if (!uid) {
return -ENOENT;
if (!user) {
return -ENOENT;
if (remote) {
s->remote = k;
if (vtnr)
Seat *o;
r = seat_attach_session(o, s);
s->vtnr = 0;
unsigned int npos;
if (leader) {
if (type) {
SessionType t;
s->type = t;
if (class) {
SessionClass c;
s->class = c;
if (s->fifo_path) {
int fd;
if (realtime) {
if (monotonic) {
if (controller) {
unsigned int num_pending;
assert(s);
if (!s->seat)
return -ENOTSUP;
if (!s->vtnr)
return -ENOTSUP;
if (!num_pending)
assert(s);
if (!s->scope) {
if (!description)
return log_oom();
if (!scope)
return log_oom();
r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-logind.service", "systemd-user-sessions.service", &error, &job);
if (s->scope)
assert(s);
if (!s->user)
return -ESTALE;
if (s->started)
r = session_start_scope(s);
NULL);
if (s->seat)
s->started = true;
session_save(s);
if (s->seat)
session_send_signal(s, true);
if (s->seat) {
assert(s);
if (!s->scope)
assert(s);
if (!s->user)
return -ESTALE;
s->stopping = true;
session_save(s);
assert(s);
if (!s->user)
return -ESTALE;
if (s->started)
NULL);
if (s->started) {
session_send_signal(s, false);
s->started = false;
if (s->seat) {
assert(s);
session_stop(s, false);
assert(s);
if (!s->timer_event_source)
&s->timer_event_source,
assert(s);
if (!s->seat)
return -ENOMEM;
tty = p;
return -ENOENT;
return -errno;
assert(s);
if (s->idle_hint) {
*t = s->idle_hint_timestamp;
return s->idle_hint;
if (s->display)
goto dont_know;
if (s->tty) {
goto found_atime;
if (s->leader > 0) {
goto found_atime;
*t = s->idle_hint_timestamp;
assert(s);
if (s->idle_hint == b)
s->idle_hint = b;
if (s->seat)
assert(s);
session_stop(s, false);
assert(s);
if (!s->fifo_path) {
return -ENOMEM;
return -errno;
if (s->fifo_fd < 0) {
if (s->fifo_fd < 0)
return -errno;
if (!s->fifo_event_source) {
r = sd_event_add_io(s->manager->event, &s->fifo_event_source, s->fifo_fd, 0, session_dispatch_fifo, s);
return -errno;
assert(s);
if (s->fifo_path) {
assert(s);
if (!s->user)
if (s->fifo_fd >= 0) {
assert(s);
if (s->in_gc_queue)
s->in_gc_queue = true;
assert(s);
return SESSION_CLOSING;
return SESSION_OPENING;
if (session_is_active(s))
return SESSION_ACTIVE;
return SESSION_ONLINE;
assert(s);
if (!s->scope)
return -ESRCH;
return -ENODEV;
if (s->vtfd >= 0)
return s->vtfd;
if (s->vtfd < 0) {
return -errno;
return s->vtfd;
if (s->vtfd >= 0)
int vt, r;
if (vt < 0)
return vt;
r = -errno;
goto error;
r = -errno;
goto error;
r = -errno;
goto error;
goto error;
r = -errno;
goto error;
if (vt < 0)
assert(s);
if (s->controller) {
if (!name)
session_save(s);
assert(s);
return -EBUSY;
return -ENOMEM;
free(t);
r = session_prepare_vt(s);
session_swap_controller(s, t);
assert(s);
if (!s->controller)