sd-login: add sd_uid_get_login_time interface #26574

This commit is contained in:
Thorsten Kukuk
2023-02-24 09:47:52 +01:00
parent 9cddd36707
commit d622fefc00
4 changed files with 57 additions and 5 deletions

View File

@@ -22,6 +22,7 @@
<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>
@@ -62,6 +63,12 @@
<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>
@@ -126,16 +133,27 @@
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>

View File

@@ -817,4 +817,5 @@ LIBSYSTEMD_254 {
global:
sd_session_get_username;
sd_session_get_start_time;
sd_uid_get_login_time;
} LIBSYSTEMD_253;

View File

@@ -503,6 +503,36 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) {
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;

View File

@@ -130,6 +130,9 @@ int sd_uid_get_state(uid_t uid, char **state);
/* 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);