<refname>sd_uid_get_sessions</refname>
<refname>sd_uid_get_seats</refname>
<refname>sd_uid_get_display</refname>
+ <refname>sd_uid_get_login_time</refname>
<refpurpose>Determine login state of a specific Unix user ID</refpurpose>
</refnamediv>
<paramdef>char **<parameter>session</parameter></paramdef>
</funcprototype>
</funcsynopsis>
+
+ <funcprototype>
+ <funcdef>int <function>sd_uid_get_login_time</function></funcdef>
+ <paramdef>uid_t <parameter>uid</parameter></paramdef>
+ <paramdef>uint64_t *<parameter>usec</parameter></paramdef>
+ </funcprototype>
</refsynopsisdiv>
<refsect1>
of the "primary" session of a user. If the user has graphical
sessions, it will be the oldest graphical session. Otherwise, it
will be the oldest open session.</para>
+
+ <para><function>sd_uid_get_login_time()</function> may be used to
+ determine the time the user's service manager has been invoked,
+ which is the time when the user's first active session, since which
+ they stayed logged in continuously, began. The <parameter>usec</parameter>
+ is in microseconds since the epoch (<constant>CLOCK_REALTIME</constant>).
+ This call will fail with <constant>-ENXIO</constant> if the user is not
+ currently logged in.</para>
</refsect1>
<refsect1>
<title>Return Value</title>
- <para>On success, <function>sd_uid_get_state()</function> returns 0 or a positive integer. If the test
- succeeds, <function>sd_uid_is_on_seat()</function> returns a positive integer; if it fails, 0.
- <function>sd_uid_get_sessions()</function> and <function>sd_uid_get_seats()</function> return the number
- of entries in the returned arrays. <function>sd_uid_get_display()</function> returns a non-negative code
- on success. On failure, these calls return a negative errno-style error code.</para>
+ <para>On success, <function>sd_uid_get_state()</function> and
+ <function>sd_uid_get_login_time()</function> returns 0 or a positive
+ integer. If the test succeeds, <function>sd_uid_is_on_seat()</function>
+ returns a positive integer; if it fails, 0. <function>sd_uid_get_sessions()</function>
+ and <function>sd_uid_get_seats()</function> return the number of entries
+ in the returned arrays. <function>sd_uid_get_display()</function>
+ returns a non-negative code on success. On failure, these calls return
+ a negative errno-style error code.</para>
<refsect2>
<title>Errors</title>
return 0;
}
+_public_ int sd_uid_get_login_time(uid_t uid, uint64_t *usec) {
+ _cleanup_free_ char *p = NULL, *s = NULL, *rt = NULL;
+ usec_t t;
+ int r;
+
+ assert_return(usec, -EINVAL);
+
+ r = file_of_uid(uid, &p);
+ if (r < 0)
+ return r;
+
+ r = parse_env_file(NULL, p, "STATE", &s, "REALTIME", &rt);
+ if (r == -ENOENT)
+ return -ENXIO;
+ if (r < 0)
+ return r;
+ if (isempty(s) || isempty(rt))
+ return -EIO;
+
+ if (!STR_IN_SET(s, "active", "online"))
+ return -ENXIO;
+
+ r = safe_atou64(rt, &t);
+ if (r < 0)
+ return r;
+
+ *usec = t;
+ return 0;
+}
+
static int file_of_seat(const char *seat, char **_p) {
char *p;
int r;
/* Return primary session of user, if there is any */
int sd_uid_get_display(uid_t uid, char **session);
+/* Determine the login time of user */
+int sd_uid_get_login_time(uid_t uid, uint64_t *usec);
+
/* Return 1 if UID has session on seat. If require_active is true, this will
* look for active sessions only. */
int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat);