X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogin%2Flogind-core.c;h=a128246d1ab0de09a2afc8260779a28e1be64bba;hp=107b3243a5a1701f1e2ac9ed017eaaf9dd0aa740;hb=48a439f2dac67302f3e7d1ccb21bd93e919efd02;hpb=1b99ea27bc3ffa1fc6f7cfe89563d891a9aed4c5 diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 107b3243a..a128246d1 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -19,19 +19,22 @@ along with systemd; If not, see . ***/ -#include -#include #include #include +#include +#include #include -#include "strv.h" -#include "cgroup-util.h" -#include "bus-util.h" +#include "alloc-util.h" #include "bus-error.h" -#include "udev-util.h" +#include "bus-util.h" +#include "cgroup-util.h" +#include "fd-util.h" #include "logind.h" +#include "strv.h" #include "terminal-util.h" +#include "udev-util.h" +#include "user-util.h" int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) { Device *d; @@ -95,15 +98,16 @@ int manager_add_session(Manager *m, const char *id, Session **_session) { int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) { User *u; + int r; assert(m); assert(name); u = hashmap_get(m->users, UID_TO_PTR(uid)); if (!u) { - u = user_new(m, uid, gid, name); - if (!u) - return -ENOMEM; + r = user_new(&u, m, uid, gid, name); + if (r < 0) + return r; } if (_user) @@ -113,8 +117,8 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User ** } int manager_add_user_by_name(Manager *m, const char *name, User **_user) { - uid_t uid; - gid_t gid; + uid_t uid = 1000; + gid_t gid = 1000; int r; assert(m); @@ -274,31 +278,50 @@ int manager_process_button_device(Manager *m, struct udev_device *d) { } int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { +#if 0 /// elogind does not support systemd units, but its own session system _cleanup_free_ char *unit = NULL; +#else + _cleanup_free_ char *session_name = NULL; +#endif // 0 Session *s; int r; assert(m); - assert(session); if (pid < 1) return -EINVAL; +#if 0 /// elogind does not support systemd units, but its own session system r = cg_pid_get_unit(pid, &unit); if (r < 0) return 0; s = hashmap_get(m->session_units, unit); +#else + log_debug_elogind("Searching session for PID %u", pid); + r = cg_pid_get_session(pid, &session_name); + if (r < 0) + return 0; + + s = hashmap_get(m->sessions, session_name); + log_debug_elogind("Session Name \"%s\" -> Session \"%s\"", + session_name, s && s->id ? s->id : "NULL"); +#endif // 0 if (!s) return 0; - *session = s; + if (session) + *session = s; return 1; } int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { +#if 0 /// elogind does not support systemd units, but its own session system _cleanup_free_ char *unit = NULL; User *u; +#else + Session *s; +#endif // 0 int r; assert(m); @@ -307,6 +330,7 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { if (pid < 1) return -EINVAL; +#if 0 /// elogind does not support systemd units, but its own session system r = cg_pid_get_slice(pid, &unit); if (r < 0) return 0; @@ -316,13 +340,21 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) { return 0; *user = u; +#else + r = manager_get_session_by_pid (m, pid, &s); + if (r <= 0) + return r; + + *user = s->user; +#endif // 0 + return 1; } int manager_get_idle_hint(Manager *m, dual_timestamp *t) { Session *s; bool idle_hint; - dual_timestamp ts = { 0, 0 }; + dual_timestamp ts = DUAL_TIMESTAMP_NULL; Iterator i; assert(m); @@ -374,6 +406,7 @@ bool manager_shall_kill(Manager *m, const char *user) { return strv_contains(m->kill_only_users, user); } +#if 0 /// UNNEEDED by elogind static int vt_is_busy(unsigned int vtnr) { struct vt_stat vt_stat; int r = 0; @@ -438,8 +471,9 @@ int manager_spawn_autovt(Manager *m, unsigned int vtnr) { return r; } +#endif // 0 -bool manager_is_docked(Manager *m) { +static bool manager_is_docked(Manager *m) { Iterator i; Button *b; @@ -450,7 +484,7 @@ bool manager_is_docked(Manager *m) { return false; } -int manager_count_displays(Manager *m) { +static int manager_count_external_displays(Manager *m) { _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; struct udev_list_entry *item = NULL, *first = NULL; int r; @@ -472,7 +506,8 @@ int manager_count_displays(Manager *m) { udev_list_entry_foreach(item, first) { _cleanup_udev_device_unref_ struct udev_device *d = NULL; struct udev_device *p; - const char *status; + const char *status, *enabled, *dash, *nn, *i; + bool external = false; d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item)); if (!d) @@ -488,6 +523,40 @@ int manager_count_displays(Manager *m) { if (!streq_ptr(udev_device_get_subsystem(p), "drm")) continue; + nn = udev_device_get_sysname(d); + if (!nn) + continue; + + /* Ignore internal displays: the type is encoded in + * the sysfs name, as the second dash seperated item + * (the first is the card name, the last the connector + * number). We implement a whitelist of external + * displays here, rather than a whitelist, to ensure + * we don't block suspends too eagerly. */ + dash = strchr(nn, '-'); + if (!dash) + continue; + + dash++; + FOREACH_STRING(i, "VGA-", "DVI-I-", "DVI-D-", "DVI-A-" + "Composite-", "SVIDEO-", "Component-", + "DIN-", "DP-", "HDMI-A-", "HDMI-B-", "TV-") { + + if (startswith(dash, i)) { + external = true; + break; + } + } + if (!external) + continue; + + /* Ignore ports that are not enabled */ + enabled = udev_device_get_sysattr_value(d, "enabled"); + if (!enabled) + continue; + if (!streq_ptr(enabled, "enabled")) + continue; + /* We count any connector which is not explicitly * "disconnected" as connected. */ status = udev_device_get_sysattr_value(d, "status"); @@ -498,7 +567,7 @@ int manager_count_displays(Manager *m) { return n; } -bool manager_is_docked_or_multiple_displays(Manager *m) { +bool manager_is_docked_or_external_displays(Manager *m) { int n; /* If we are docked don't react to lid closing */ @@ -509,11 +578,11 @@ bool manager_is_docked_or_multiple_displays(Manager *m) { /* If we have more than one display connected, * assume that we are docked. */ - n = manager_count_displays(m); + n = manager_count_external_displays(m); if (n < 0) log_warning_errno(n, "Display counting failed: %m"); - else if (n > 1) { - log_debug("Multiple (%i) displays connected.", n); + else if (n >= 1) { + log_debug("External (%i) displays connected.", n); return true; }