X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Flogind-core.c;h=440c32aa2cd2284e042f41bb2e834e0a2af0d241;hb=8af9597bdb2f17e0220c90299a322cfff3c4195f;hp=67b03623acccb20dd24f11a0a9053403e94bc864;hpb=08e1896fb7a00a758c3a71a99e54f0ff69da2fbd;p=elogind.git diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 67b03623a..440c32aa2 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -31,6 +31,7 @@ #include "bus-error.h" #include "udev-util.h" #include "logind.h" +#include "terminal-util.h" int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) { Device *d; @@ -311,24 +312,49 @@ int manager_process_button_device(Manager *m, struct udev_device *d) { } int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { + _cleanup_free_ char *unit = NULL; + Session *s; + int r; + assert(m); assert(session); - /* Without cgroups, we have no way to map from pid to - session. */ - return 0; + if (pid < 1) + return -EINVAL; + + r = cg_pid_get_unit(pid, &unit); + if (r < 0) + return 0; + + s = hashmap_get(m->session_units, unit); + if (!s) + return 0; + + *session = s; + return 1; } int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { + _cleanup_free_ char *unit = NULL; + User *u; + int r; + assert(m); assert(user); if (pid < 1) return -EINVAL; - /* Without cgroups, we have no way to map from pid to - user. */ - return 0; + r = cg_pid_get_slice(pid, &unit); + if (r < 0) + return 0; + + u = hashmap_get(m->user_units, unit); + if (!u) + return 0; + + *user = u; + return 1; } int manager_get_idle_hint(Manager *m, dual_timestamp *t) { @@ -411,6 +437,46 @@ static int vt_is_busy(unsigned int vtnr) { return r; } +int manager_spawn_autovt(Manager *m, unsigned int vtnr) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + char name[sizeof("autovt@tty.service") + DECIMAL_STR_MAX(unsigned int)]; + int r; + + assert(m); + assert(vtnr >= 1); + + if (vtnr > m->n_autovts && + vtnr != m->reserve_vt) + return 0; + + if (vtnr != m->reserve_vt) { + /* If this is the reserved TTY, we'll start the getty + * on it in any case, but otherwise only if it is not + * busy. */ + + r = vt_is_busy(vtnr); + if (r < 0) + return r; + else if (r > 0) + return -EBUSY; + } + + snprintf(name, sizeof(name), "autovt@tty%u.service", vtnr); + r = sd_bus_call_method( + m->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartUnit", + &error, + NULL, + "ss", name, "fail"); + if (r < 0) + log_error("Failed to start %s: %s", name, bus_error_message(&error, r)); + + return r; +} + bool manager_is_docked(Manager *m) { Iterator i; Button *b;