***/
#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <pwd.h>
-#include <unistd.h>
#include <linux/vt.h>
#include "strv.h"
#include "cgroup-util.h"
-#include "audit.h"
#include "bus-util.h"
#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;
assert(sysfs);
d = hashmap_get(m->devices, sysfs);
- if (d) {
- if (_device)
- *_device = d;
-
+ if (d)
/* we support adding master-flags, but not removing them */
d->master = d->master || master;
-
- return 0;
+ else {
+ d = device_new(m, sysfs, master);
+ if (!d)
+ return -ENOMEM;
}
- d = device_new(m, sysfs, master);
- if (!d)
- return -ENOMEM;
-
if (_device)
*_device = d;
assert(id);
s = hashmap_get(m->seats, id);
- if (s) {
- if (_seat)
- *_seat = s;
-
- return 0;
+ if (!s) {
+ s = seat_new(m, id);
+ if (!s)
+ return -ENOMEM;
}
- s = seat_new(m, id);
- if (!s)
- return -ENOMEM;
-
if (_seat)
*_seat = s;
assert(id);
s = hashmap_get(m->sessions, id);
- if (s) {
- if (_session)
- *_session = s;
-
- return 0;
+ if (!s) {
+ s = session_new(m, id);
+ if (!s)
+ return -ENOMEM;
}
- s = session_new(m, id);
- if (!s)
- return -ENOMEM;
-
if (_session)
*_session = s;
assert(m);
assert(name);
- u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
- if (u) {
- if (_user)
- *_user = u;
-
- return 0;
+ u = hashmap_get(m->users, UID_TO_PTR(uid));
+ if (!u) {
+ u = user_new(m, uid, gid, name);
+ if (!u)
+ return -ENOMEM;
}
- u = user_new(m, uid, gid, name);
- if (!u)
- return -ENOMEM;
-
if (_user)
*_user = u;
assert(name);
b = hashmap_get(m->buttons, name);
- if (b) {
- if (_button)
- *_button = b;
-
- return 0;
+ if (!b) {
+ b = button_new(m, name);
+ if (!b)
+ return -ENOMEM;
}
- b = button_new(m, name);
- if (!b)
- return -ENOMEM;
-
if (_button)
*_button = b;
return 0;
}
-int manager_watch_busname(Manager *m, const char *name) {
- char *n;
- int r;
-
- assert(m);
- assert(name);
-
- if (set_get(m->busnames, (char*) name))
- return 0;
-
- n = strdup(name);
- if (!n)
- return -ENOMEM;
-
- r = set_put(m->busnames, n);
- if (r < 0) {
- free(n);
- return r;
- }
-
- return 0;
-}
-
-void manager_drop_busname(Manager *m, const char *name) {
- Session *session;
- Iterator i;
-
- assert(m);
- assert(name);
-
- /* keep it if the name still owns a controller */
- HASHMAP_FOREACH(session, m->sessions, i)
- if (session_is_controller(session, name))
- return;
-
- free(set_remove(m->busnames, (char*) name));
-}
-
int manager_process_seat_device(Manager *m, struct udev_device *d) {
Device *device;
int r;
static int vt_is_busy(unsigned int vtnr) {
struct vt_stat vt_stat;
- int r = 0, fd;
+ int r = 0;
+ _cleanup_close_ int fd;
assert(vtnr >= 1);
else
r = !!(vt_stat.v_state & (1 << vtnr));
- close_nointr_nofail(fd);
-
return r;
}
int manager_spawn_autovt(Manager *m, unsigned int vtnr) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *name = NULL;
+ char name[sizeof("autovt@tty.service") + DECIMAL_STR_MAX(unsigned int)];
int r;
assert(m);
return -EBUSY;
}
- if (asprintf(&name, "autovt@tty%u.service", vtnr) < 0)
- return log_oom();
-
+ snprintf(name, sizeof(name), "autovt@tty%u.service", vtnr);
r = sd_bus_call_method(
m->bus,
"org.freedesktop.systemd1",
p = udev_device_get_parent(d);
if (!p)
- return -ENOMEM;
+ continue;
/* If the parent shares the same subsystem as the
* device we are looking at then it is a connector,
return n;
}
+
+bool manager_is_docked_or_multiple_displays(Manager *m) {
+ int n;
+
+ /* If we are docked don't react to lid closing */
+ if (manager_is_docked(m)) {
+ log_debug("System is docked.");
+ return true;
+ }
+
+ /* If we have more than one display connected,
+ * assume that we are docked. */
+ n = manager_count_displays(m);
+ if (n < 0)
+ log_warning_errno(n, "Display counting failed: %m");
+ else if (n > 1) {
+ log_debug("Multiple (%i) displays connected.", n);
+ return true;
+ }
+
+ return false;
+}