diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-06-28 00:26:10 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-06-28 00:26:10 +0200 |
commit | d0a522eb312a0f6014e756d3fc066efc37fceaf7 (patch) | |
tree | 70c22872b026e41e96ce05ce9529997ba3ec5ad2 /src/logind.c | |
parent | 734b933ace7aac5d9c1d7507f9d30f73390ce102 (diff) |
logind: autospawn gettys when necessary
Diffstat (limited to 'src/logind.c')
-rw-r--r-- | src/logind.c | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/src/logind.c b/src/logind.c index 3100fd2517..701ef494e8 100644 --- a/src/logind.c +++ b/src/logind.c @@ -652,7 +652,13 @@ static int vt_is_busy(int vtnr) { assert(vtnr >= 1); - fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC); + /* 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; @@ -668,16 +674,61 @@ static int vt_is_busy(int vtnr) { 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); + dbus_error_init(&error); + r = vt_is_busy(vtnr); if (r != 0) return r; - /* ... */ + 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-getty@tty%i.service", vtnr) < 0) { + log_error("Could not allocate service name."); + r = -ENOMEM; + goto finish; + } - return 0; + 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; + } + + r = 0; + +finish: + free(name); + + if (message) + dbus_message_unref(message); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; } void manager_cgroup_notify_empty(Manager *m, const char *cgroup) { |