]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #27740 from dtardon/list-sessions-idle
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 24 May 2023 11:03:39 +0000 (20:03 +0900)
committerGitHub <noreply@github.com>
Wed, 24 May 2023 11:03:39 +0000 (20:03 +0900)
Show idle status in `loginctl list-sessions`

1  2 
src/login/loginctl.c

diff --combined src/login/loginctl.c
index 29fc14b5718b3883fc5e142d01195be5407f0f4d,28f4231ac1fa5a1d2fcb36c32a10ca6f9dabd1c8..d7db518bf995e59d2e2e038a3d572b4c78ba0413
@@@ -54,6 -54,29 +54,29 @@@ static OutputMode arg_output = OUTPUT_S
  
  STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep);
  
+ typedef struct SessionStatusInfo {
+         const char *id;
+         uid_t uid;
+         const char *name;
+         struct dual_timestamp timestamp;
+         unsigned vtnr;
+         const char *seat;
+         const char *tty;
+         const char *display;
+         bool remote;
+         const char *remote_host;
+         const char *remote_user;
+         const char *service;
+         pid_t leader;
+         const char *type;
+         const char *class;
+         const char *state;
+         const char *scope;
+         const char *desktop;
+         bool idle_hint;
+         dual_timestamp idle_hint_timestamp;
+ } SessionStatusInfo;
  static OutputFlags get_output_flags(void) {
  
          return
@@@ -115,6 -138,15 +138,15 @@@ static int show_table(Table *table, con
  }
  
  static int list_sessions(int argc, char *argv[], void *userdata) {
+         static const struct bus_properties_map map[]  = {
+                 { "IdleHint",               "b",    NULL,   offsetof(SessionStatusInfo, idle_hint)                      },
+                 { "IdleSinceHintMonotonic", "t",    NULL,   offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic)  },
+                 { "State",                  "s",    NULL,   offsetof(SessionStatusInfo, state)                          },
+                 { "TTY",                    "s",    NULL,   offsetof(SessionStatusInfo, tty)                            },
+                 {},
+         };
          _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
          _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
          _cleanup_(table_unrefp) Table *table = NULL;
          if (r < 0)
                  return bus_log_parse_error(r);
  
-         table = table_new("session", "uid", "user", "seat", "tty", "state");
+         table = table_new("session", "uid", "user", "seat", "tty", "state", "idle", "since");
          if (!table)
                  return log_oom();
  
          (void) table_set_align_percent(table, TABLE_HEADER_CELL(1), 100);
  
          for (;;) {
-                 _cleanup_(sd_bus_error_free) sd_bus_error error_property = SD_BUS_ERROR_NULL;
-                 _cleanup_free_ char *tty = NULL, *state = NULL;
+                 _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
                  const char *id, *user, *seat, *object;
                  uint32_t uid;
+                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+                 SessionStatusInfo i = {};
  
                  r = sd_bus_message_read(reply, "(susso)", &id, &uid, &user, &seat, &object);
                  if (r < 0)
                  if (r == 0)
                          break;
  
-                 r = sd_bus_get_property_string(bus,
-                                                "org.freedesktop.login1",
-                                                object,
-                                                "org.freedesktop.login1.Session",
-                                                "TTY",
-                                                &error_property,
-                                                &tty);
-                 if (r < 0) {
-                         if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
-                                 /* The session is already closed when we're querying the property */
-                                 continue;
-                         log_warning_errno(r, "Failed to get TTY for session %s, ignoring: %s",
-                                           id, bus_error_message(&error_property, r));
-                         sd_bus_error_free(&error_property);
-                 }
-                 r = sd_bus_get_property_string(bus,
-                                                "org.freedesktop.login1",
-                                                object,
-                                                "org.freedesktop.login1.Session",
-                                                "State",
-                                                &error_property,
-                                                &state);
+                 r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i);
                  if (r < 0) {
-                         if (sd_bus_error_has_name(&error_property, SD_BUS_ERROR_UNKNOWN_OBJECT))
-                                 /* The session is already closed when we're querying the property */
-                                 continue;
-                         return log_error_errno(r, "Failed to get state for session %s: %s",
-                                                id, bus_error_message(&error_property, r));
+                         log_full_errno(sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT) ? LOG_DEBUG : LOG_WARNING,
+                                        r,
+                                        "Failed to get properties of session %s, ignoring: %s",
+                                        id, bus_error_message(&e, r));
+                         continue;
                  }
  
                  r = table_add_many(table,
                                     TABLE_UID, (uid_t) uid,
                                     TABLE_STRING, user,
                                     TABLE_STRING, seat,
-                                    TABLE_STRING, strna(tty),
-                                    TABLE_STRING, state);
+                                    TABLE_STRING, strna(i.tty),
+                                    TABLE_STRING, i.state,
+                                    TABLE_BOOLEAN, i.idle_hint);
+                 if (r < 0)
+                         return table_log_add_error(r);
+                 if (i.idle_hint)
+                         r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic);
+                 else
+                         r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
                  if (r < 0)
                          return table_log_add_error(r);
          }
@@@ -376,27 -392,6 +392,6 @@@ static int show_unit_cgroup(sd_bus *bus
          return 0;
  }
  
- typedef struct SessionStatusInfo {
-         const char *id;
-         uid_t uid;
-         const char *name;
-         struct dual_timestamp timestamp;
-         unsigned vtnr;
-         const char *seat;
-         const char *tty;
-         const char *display;
-         bool remote;
-         const char *remote_host;
-         const char *remote_user;
-         const char *service;
-         pid_t leader;
-         const char *type;
-         const char *class;
-         const char *state;
-         const char *scope;
-         const char *desktop;
- } SessionStatusInfo;
  typedef struct UserStatusInfo {
          uid_t uid;
          bool linger;
@@@ -917,7 -912,14 +912,7 @@@ static int show_user(int argc, char *ar
                  if (r < 0)
                          return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
  
 -                r = sd_bus_call_method(
 -                                bus,
 -                                "org.freedesktop.login1",
 -                                "/org/freedesktop/login1",
 -                                "org.freedesktop.login1.Manager",
 -                                "GetUser",
 -                                &error, &reply,
 -                                "u", (uint32_t) uid);
 +                r = bus_call_method(bus, bus_login_mgr, "GetUser", &error, &reply, "u", (uint32_t) uid);
                  if (r < 0)
                          return log_error_errno(r, "Failed to get user: %s", bus_error_message(&error, r));