- while ((de = readdir(d))) {
- struct Session *s;
- int k;
-
- if (!dirent_is_file(de))
- continue;
-
- s = hashmap_get(m->sessions, de->d_name);
- if (!s) {
- unlinkat(dirfd(d), de->d_name, 0);
- continue;
- }
-
- k = session_load(s);
- if (k < 0)
- r = k;
- }
-
- closedir(d);
-
- return r;
-}
-
-int manager_enumerate_inhibitors(Manager *m) {
- DIR *d;
- struct dirent *de;
- int r = 0;
-
- assert(m);
-
- d = opendir("/run/systemd/inhibit");
- if (!d) {
- if (errno == ENOENT)
- return 0;
-
- log_error("Failed to open /run/systemd/inhibit: %m");
- return -errno;
- }
-
- while ((de = readdir(d))) {
- int k;
- Inhibitor *i;
-
- if (!dirent_is_file(de))
- continue;
-
- k = manager_add_inhibitor(m, de->d_name, &i);
- if (k < 0) {
- log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
- r = k;
- continue;
- }
-
- k = inhibitor_load(i);
- if (k < 0)
- r = k;
- }
-
- closedir(d);
-
- return r;
-}
-
-int manager_dispatch_seat_udev(Manager *m) {
- struct udev_device *d;
- int r;
-
- assert(m);
-
- d = udev_monitor_receive_device(m->udev_seat_monitor);
- if (!d)
- return -ENOMEM;
-
- r = manager_process_seat_device(m, d);
- udev_device_unref(d);
-
- return r;
-}
-
-int manager_dispatch_vcsa_udev(Manager *m) {
- struct udev_device *d;
- int r = 0;
- const char *name;
-
- assert(m);
-
- d = udev_monitor_receive_device(m->udev_vcsa_monitor);
- if (!d)
- return -ENOMEM;
-
- name = udev_device_get_sysname(d);
-
- /* Whenever a VCSA device is removed try to reallocate our
- * VTs, to make sure our auto VTs never go away. */
-
- if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
- r = seat_preallocate_vts(m->vtconsole);
-
- udev_device_unref(d);
-
- return r;
-}
-
-int manager_dispatch_button_udev(Manager *m) {
- struct udev_device *d;
- int r;
-
- assert(m);
-
- d = udev_monitor_receive_device(m->udev_button_monitor);
- if (!d)
- return -ENOMEM;
-
- r = manager_process_button_device(m, d);
- udev_device_unref(d);
-
- return r;
-}
-
-int manager_dispatch_console(Manager *m) {
- assert(m);
-
- if (m->vtconsole)
- seat_read_active_vt(m->vtconsole);
-
- return 0;
-}
-
-static int vt_is_busy(int vtnr) {
- struct vt_stat vt_stat;
- int r = 0, fd;
-
- assert(vtnr >= 1);
-
- /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
- * we'd open the latter we'd open the foreground tty which
- * hence would be unconditionally busy. By opening /dev/tty1
- * we avoid this. Since tty1 is special and needs to be an
- * explicitly loaded getty or DM this is safe. */
-
- fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return -errno;
-
- if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
- r = -errno;
- else
- r = !!(vt_stat.v_state & (1 << vtnr));
-
- close_nointr_nofail(fd);
-
- return r;
-}
-
-int manager_spawn_autovt(Manager *m, int vtnr) {
- int r;
- DBusMessage *message = NULL, *reply = NULL;
- char *name = NULL;
- const char *mode = "fail";
- DBusError error;
-
- assert(m);
- assert(vtnr >= 1);
-
- dbus_error_init(&error);
-
- if ((unsigned) vtnr > m->n_autovts)
- return 0;
-
- r = vt_is_busy(vtnr);
- if (r < 0)
- return r;
- else if (r > 0)
- return -EBUSY;
-
- message = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit");
- if (!message) {
- log_error("Could not allocate message.");
- r = -ENOMEM;
- goto finish;
- }
-
- if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
- log_error("Could not allocate service name.");
- r = -ENOMEM;
- goto finish;
- }
-
- if (!dbus_message_append_args(message,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_STRING, &mode,
- DBUS_TYPE_INVALID)) {
- log_error("Could not attach target and flag information to message.");
- r = -ENOMEM;
- goto finish;
- }
-
- reply = dbus_connection_send_with_reply_and_block(m->bus, message, -1, &error);
- if (!reply) {
- log_error("Failed to start unit: %s", bus_error_message(&error));
- goto finish;
- }