sd_bus_error *error) {
Manager *m = userdata;
- dual_timestamp t;
+ dual_timestamp t = DUAL_TIMESTAMP_NULL;
assert(bus);
assert(reply);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
+static int property_get_docked(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Manager *m = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(m);
+
+ return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
+}
+
static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Manager *m = userdata;
return r;
}
- manager_get_session_by_pid(m, leader, &session);
- if (session) {
- _cleanup_free_ char *path = NULL;
- _cleanup_close_ int fifo_fd = -1;
-
- /* Session already exists, client is probably
- * something like "su" which changes uid but is still
- * the same session */
-
- fifo_fd = session_create_fifo(session);
- if (fifo_fd < 0)
- return fifo_fd;
-
- path = session_bus_path(session);
- if (!path)
- return -ENOMEM;
-
- log_debug("Sending reply about an existing session: "
- "id=%s object_path=%s uid=%u runtime_path=%s "
- "session_fd=%d seat=%s vtnr=%u",
- session->id,
- path,
- (uint32_t) session->user->uid,
- session->user->runtime_path,
- fifo_fd,
- session->seat ? session->seat->id : "",
- (uint32_t) session->vtnr);
-
- return sd_bus_reply_method_return(
- message, "soshusub",
- session->id,
- path,
- session->user->runtime_path,
- fifo_fd,
- (uint32_t) session->user->uid,
- session->seat ? session->seat->id : "",
- (uint32_t) session->vtnr,
- true);
- }
+ r = manager_get_session_by_pid(m, leader, NULL);
+ if (r > 0)
+ return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session");
+
+ /*
+ * Old gdm and lightdm start the user-session on the same VT as
+ * the greeter session. But they destroy the greeter session
+ * after the user-session and want the user-session to take
+ * over the VT. We need to support this for
+ * backwards-compatibility, so make sure we allow new sessions
+ * on a VT that a greeter is running on.
+ */
+ if (vtnr > 0 &&
+ vtnr < m->seat0->position_count &&
+ m->seat0->positions[vtnr] &&
+ m->seat0->positions[vtnr]->class != SESSION_GREETER)
+ return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
audit_session_from_pid(leader, &audit_id);
if (audit_id > 0) {
if (!t)
return -ENOMEM;
- write_string_file(t, "change");
+ write_string_file(t, "change", WRITE_STRING_FILE_CREATE);
}
return 0;
log_info("Creating /run/nologin, blocking further logins...");
- r = write_string_file_atomic("/run/nologin", "System is going down.");
+ r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_ATOMIC);
if (r < 0)
log_error_errno(r, "Failed to create /run/nologin: %m");
else
SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
+ SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),