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=2b4d6ff0b37b74eb44da7ddc28b4a19e3ae7750f;hb=48a439f2dac67302f3e7d1ccb21bd93e919efd02;hpb=c6999740c1a68767c5397306b8d7e14e08533111
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index 2b4d6ff0b..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,8 +278,7 @@ int manager_process_button_device(Manager *m, struct udev_device *d) {
}
int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
-/// elogind does not support systemd units, but its own session system
-#if 0
+#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;
@@ -288,8 +291,7 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
if (pid < 1)
return -EINVAL;
-/// elogind does not support systemd units, but its own session system
-#if 0
+#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;
@@ -314,8 +316,7 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
}
int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
-/// elogind does not support systemd units, but its own session system
-#if 0
+#if 0 /// elogind does not support systemd units, but its own session system
_cleanup_free_ char *unit = NULL;
User *u;
#else
@@ -329,8 +330,7 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
if (pid < 1)
return -EINVAL;
-/// elogind does not support systemd units, but its own session system
-#if 0
+#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;
@@ -354,7 +354,7 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
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);
@@ -406,8 +406,7 @@ bool manager_shall_kill(Manager *m, const char *user) {
return strv_contains(m->kill_only_users, user);
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
static int vt_is_busy(unsigned int vtnr) {
struct vt_stat vt_stat;
int r = 0;
@@ -474,7 +473,7 @@ int manager_spawn_autovt(Manager *m, unsigned int vtnr) {
}
#endif // 0
-bool manager_is_docked(Manager *m) {
+static bool manager_is_docked(Manager *m) {
Iterator i;
Button *b;
@@ -485,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;
@@ -507,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)
@@ -523,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");
@@ -533,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 */
@@ -544,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;
}