diff --git a/Makefile.am b/Makefile.am
index 66670962cc..6b418dc7b1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6128,10 +6128,10 @@ test_login_tables_LDADD = \
liblogind-core.la
manual_tests += \
- test-login \
test-inhibit
tests += \
+ test-login \
test-login-tables \
test-login-shared
diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml
index 806cff34e4..0c135ba871 100644
--- a/man/sd_pid_get_session.xml
+++ b/man/sd_pid_get_session.xml
@@ -177,7 +177,7 @@
processes, user processes that are shared between multiple
sessions of the same user, or kernel threads). For processes not
being part of a login session, this function will fail with
- -ENODATA. The returned string needs to be freed with the libc
+ -ENODATA. The returned string needs to be freed with the libc
free3
call after use.
@@ -189,7 +189,7 @@
paths. Note that not all processes are part of a system
unit/service (e.g. user processes, or kernel threads). For
processes not being part of a systemd system unit, this function
- will fail with -ENODATA. (More specifically, this call will not
+ will fail with -ENODATA. (More specifically, this call will not
work for kernel threads.) The returned string needs to be freed
with the libc free3
@@ -208,7 +208,7 @@
multiple login sessions of the same user, whereas
sd_pid_get_session() will fail. For processes
not being part of a login session and not being a shared process
- of a user, this function will fail with -ENODATA.
+ of a user, this function will fail with -ENODATA.
sd_pid_get_machine_name() may be used
to determine the name of the VM or container is a member of. The
@@ -217,7 +217,7 @@
free3
call after use. For processes not part of a VM or containers, this
- function fails with -ENODATA.
+ function fails with -ENODATA.
sd_pid_get_slice() may be used to
determine the slice unit the process is a member of. See
diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml
index c5e6ddab02..3dd461f83f 100644
--- a/man/sd_seat_get_active.xml
+++ b/man/sd_seat_get_active.xml
@@ -105,8 +105,9 @@
one (NULL terminated) with the session
identifiers of the sessions and one with the user identifiers of
the Unix users the sessions belong to. An additional parameter may
- be used to return the number of entries in the latter array. The
- two arrays and the latter parameter may be passed as
+ be used to return the number of entries in the latter array. This
+ value is the same the return value, if the latter is nonnegative.
+ The two arrays and the last parameter may be passed as
NULL in case these values need not to be
determined. The arrays and the strings referenced by them need to
be freed with the libc
diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
index a6076b177a..f95e74ead6 100644
--- a/man/sd_session_is_active.xml
+++ b/man/sd_session_is_active.xml
@@ -184,8 +184,9 @@
sd_session_get_seat() may be used to
determine the seat identifier of the seat the session identified
by the specified session identifier belongs to. Note that not all
- sessions are attached to a seat, this call will fail for them. The
- returned string needs to be freed with the libc
+ sessions are attached to a seat, this call will fail (returning
+ -ENODATA) for them. The returned string needs
+ to be freed with the libc
free3
call after use.
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index d2cfbdf5b0..25dff7738f 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -56,27 +56,33 @@
*/
_public_ int sd_pid_get_session(pid_t pid, char **session) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(session, -EINVAL);
- return cg_pid_get_session(pid, session);
+ r = cg_pid_get_session(pid, session);
+ return r == -ENXIO ? -ENODATA : r;
}
_public_ int sd_pid_get_unit(pid_t pid, char **unit) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(unit, -EINVAL);
- return cg_pid_get_unit(pid, unit);
+ r = cg_pid_get_unit(pid, unit);
+ return r == -ENXIO ? -ENODATA : r;
}
_public_ int sd_pid_get_user_unit(pid_t pid, char **unit) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(unit, -EINVAL);
- return cg_pid_get_user_unit(pid, unit);
+ r = cg_pid_get_user_unit(pid, unit);
+ return r == -ENXIO ? -ENODATA : r;
}
_public_ int sd_pid_get_machine_name(pid_t pid, char **name) {
@@ -687,7 +693,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui
r = parse_env_file(p, NEWLINE,
"SESSIONS", &s,
- "ACTIVE_SESSIONS", &t,
+ "UIDS", &t,
NULL);
if (r == -ENOENT)
return -ENXIO;
@@ -723,7 +729,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui
r = parse_uid(k, b + i);
if (r < 0)
- continue;
+ return r;
i++;
}
@@ -848,6 +854,10 @@ _public_ int sd_get_machine_names(char ***machines) {
assert_return(machines, -EINVAL);
r = get_files_in_directory("/run/systemd/machines/", &l);
+ if (r == -ENOENT) {
+ *machines = NULL;
+ return 0;
+ }
if (r < 0)
return r;
diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
index 9de33d85db..6889d2f0b4 100644
--- a/src/libsystemd/sd-login/test-login.c
+++ b/src/libsystemd/sd-login/test-login.c
@@ -25,173 +25,198 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "format-util.h"
+#include "log.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
+static char* format_uids(char **buf, uid_t* uids, int count) {
+ int pos = 0, k, inc;
+ size_t size = (DECIMAL_STR_MAX(uid_t) + 1) * count + 1;
+
+ assert_se(*buf = malloc(size));
+
+ for (k = 0; k < count; k++) {
+ sprintf(*buf + pos, "%s"UID_FMT"%n", k > 0 ? " " : "", uids[k], &inc);
+ pos += inc;
+ }
+
+ assert_se(pos < size);
+ (*buf)[pos] = '\0';
+
+ return *buf;
+}
+
static void test_login(void) {
_cleanup_close_pair_ int pair[2] = { -1, -1 };
- _cleanup_free_ char *pp = NULL, *qq = NULL;
+ _cleanup_free_ char *pp = NULL, *qq = NULL,
+ *display_session = NULL, *cgroup = NULL,
+ *display = NULL, *remote_user = NULL, *remote_host = NULL,
+ *type = NULL, *class = NULL, *state = NULL, *state2 = NULL,
+ *seat = NULL, *session = NULL,
+ *unit = NULL, *user_unit = NULL, *slice = NULL;
int r, k;
uid_t u, u2;
- char *seat, *type, *class, *display, *remote_user, *remote_host, *display_session, *cgroup;
- char *session;
- char *state;
- char *session2;
- char *t;
- char **seats, **sessions, **machines;
- uid_t *uids;
- unsigned n;
- struct pollfd pollfd;
- sd_login_monitor *m = NULL;
+ char *t, **seats, **sessions;
- assert_se(sd_pid_get_session(0, &session) == 0);
- printf("session = %s\n", session);
-
- assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
- printf("user = "UID_FMT"\n", u2);
-
- assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
- printf("cgroup = %s\n", cgroup);
- free(cgroup);
-
- display_session = NULL;
- r = sd_uid_get_display(u2, &display_session);
+ r = sd_pid_get_unit(0, &unit);
assert_se(r >= 0 || r == -ENODATA);
- printf("user's display session = %s\n", strna(display_session));
- free(display_session);
+ log_info("sd_pid_get_unit(0, …) → \"%s\"", unit);
- assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
- sd_peer_get_session(pair[0], &pp);
- sd_peer_get_session(pair[1], &qq);
- assert_se(streq_ptr(pp, qq));
-
- r = sd_uid_get_sessions(u2, false, &sessions);
- assert_se(r >= 0);
- assert_se(r == (int) strv_length(sessions));
- assert_se(t = strv_join(sessions, ", "));
- strv_free(sessions);
- printf("sessions = %s\n", t);
- free(t);
-
- assert_se(r == sd_uid_get_sessions(u2, false, NULL));
-
- r = sd_uid_get_seats(u2, false, &seats);
- assert_se(r >= 0);
- assert_se(r == (int) strv_length(seats));
- assert_se(t = strv_join(seats, ", "));
- strv_free(seats);
- printf("seats = %s\n", t);
- free(t);
-
- assert_se(r == sd_uid_get_seats(u2, false, NULL));
-
- r = sd_session_is_active(session);
- assert_se(r >= 0);
- printf("active = %s\n", yes_no(r));
-
- r = sd_session_is_remote(session);
- assert_se(r >= 0);
- printf("remote = %s\n", yes_no(r));
-
- r = sd_session_get_state(session, &state);
- assert_se(r >= 0);
- printf("state = %s\n", state);
- free(state);
-
- assert_se(sd_session_get_uid(session, &u) >= 0);
- printf("uid = "UID_FMT"\n", u);
- assert_se(u == u2);
-
- assert_se(sd_session_get_type(session, &type) >= 0);
- printf("type = %s\n", type);
- free(type);
-
- assert_se(sd_session_get_class(session, &class) >= 0);
- printf("class = %s\n", class);
- free(class);
-
- display = NULL;
- r = sd_session_get_display(session, &display);
+ r = sd_pid_get_user_unit(0, &user_unit);
assert_se(r >= 0 || r == -ENODATA);
- printf("display = %s\n", strna(display));
- free(display);
+ log_info("sd_pid_get_user_unit(0, …) → \"%s\"", user_unit);
- remote_user = NULL;
- r = sd_session_get_remote_user(session, &remote_user);
- assert_se(r >= 0 || r == -ENODATA);
- printf("remote_user = %s\n", strna(remote_user));
- free(remote_user);
+ assert_se(sd_pid_get_slice(0, &slice) >= 0);
+ log_info("sd_pid_get_slice(0, …) → \"%s\"", slice);
- remote_host = NULL;
- r = sd_session_get_remote_host(session, &remote_host);
- assert_se(r >= 0 || r == -ENODATA);
- printf("remote_host = %s\n", strna(remote_host));
- free(remote_host);
+ r = sd_pid_get_session(0, &session);
+ if (r < 0) {
+ log_warning_errno(r, "sd_pid_get_session(0, …): %m");
+ if (r == -ENODATA)
+ log_info("Seems we are not running in a session, skipping some tests.");
+ } else {
+ log_info("sd_pid_get_session(0, …) → \"%s\"", session);
- assert_se(sd_session_get_seat(session, &seat) >= 0);
- printf("seat = %s\n", seat);
+ assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
+ log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2);
- r = sd_seat_can_multi_session(seat);
- assert_se(r >= 0);
- printf("can do multi session = %s\n", yes_no(r));
+ assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
+ log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup);
- r = sd_seat_can_tty(seat);
- assert_se(r >= 0);
- printf("can do tty = %s\n", yes_no(r));
+ r = sd_uid_get_display(u2, &display_session);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_uid_get_display("UID_FMT", …) → \"%s\"",
+ u2, strnull(display_session));
- r = sd_seat_can_graphical(seat);
- assert_se(r >= 0);
- printf("can do graphical = %s\n", yes_no(r));
+ assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
+ sd_peer_get_session(pair[0], &pp);
+ sd_peer_get_session(pair[1], &qq);
+ assert_se(streq_ptr(pp, qq));
- assert_se(sd_uid_get_state(u, &state) >= 0);
- printf("state = %s\n", state);
+ r = sd_uid_get_sessions(u2, false, &sessions);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(sessions));
+ assert_se(t = strv_join(sessions, " "));
+ strv_free(sessions);
+ log_info("sd_uid_get_sessions("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
+ free(t);
- assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
+ assert_se(r == sd_uid_get_sessions(u2, false, NULL));
- k = sd_uid_is_on_seat(u, 1, seat);
- assert_se(k >= 0);
- assert_se(!!r == !!r);
+ r = sd_uid_get_seats(u2, false, &seats);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(seats));
+ assert_se(t = strv_join(seats, " "));
+ strv_free(seats);
+ log_info("sd_uid_get_seats("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
+ free(t);
- assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
- printf("session2 = %s\n", session2);
- printf("uid2 = "UID_FMT"\n", u2);
+ assert_se(r == sd_uid_get_seats(u2, false, NULL));
+ }
- r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
- assert_se(r >= 0);
- printf("n_sessions = %i\n", r);
- assert_se(r == (int) strv_length(sessions));
- assert_se(t = strv_join(sessions, ", "));
- strv_free(sessions);
- printf("sessions = %s\n", t);
- free(t);
- printf("uids =");
- for (k = 0; k < (int) n; k++)
- printf(" "UID_FMT, uids[k]);
- printf("\n");
- free(uids);
+ if (session) {
+ r = sd_session_is_active(session);
+ assert_se(r >= 0);
+ log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
- assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
+ r = sd_session_is_remote(session);
+ assert_se(r >= 0);
+ log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
- free(session);
- free(state);
- free(session2);
- free(seat);
+ r = sd_session_get_state(session, &state);
+ assert_se(r >= 0);
+ log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
+
+ assert_se(sd_session_get_uid(session, &u) >= 0);
+ log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
+ assert_se(u == u2);
+
+ assert_se(sd_session_get_type(session, &type) >= 0);
+ log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
+
+ assert_se(sd_session_get_class(session, &class) >= 0);
+ log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
+
+ r = sd_session_get_display(session, &display);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
+
+ r = sd_session_get_remote_user(session, &remote_user);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
+ session, strna(remote_user));
+
+ r = sd_session_get_remote_host(session, &remote_host);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
+ session, strna(remote_host));
+
+ r = sd_session_get_seat(session, &seat);
+ if (r >= 0) {
+ assert_se(seat);
+
+ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, seat);
+
+ r = sd_seat_can_multi_session(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
+
+ r = sd_seat_can_tty(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
+
+ r = sd_seat_can_graphical(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
+ } else {
+ log_info_errno(r, "sd_session_get_display(\"%s\"): %m", session);
+ assert_se(r == -ENODATA);
+ }
+
+ assert_se(sd_uid_get_state(u, &state2) >= 0);
+ log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
+ }
+
+ if (seat) {
+ _cleanup_free_ char *session2 = NULL, *buf = NULL;
+ _cleanup_free_ uid_t *uids = NULL;
+ unsigned n;
+
+ assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
+
+ k = sd_uid_is_on_seat(u, 1, seat);
+ assert_se(k >= 0);
+ assert_se(!!k == !!r);
+
+ assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
+ log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT, seat, session2, u2);
+
+ r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(sessions));
+ assert_se(t = strv_join(sessions, " "));
+ strv_free(sessions);
+ log_info("sd_seat_get_sessions(\"%s\", …) → %i, \"%s\", [%i] {%s}",
+ seat, r, t, n, format_uids(&buf, uids, n));
+ free(t);
+
+ assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
+ }
r = sd_get_seats(&seats);
assert_se(r >= 0);
assert_se(r == (int) strv_length(seats));
assert_se(t = strv_join(seats, ", "));
strv_free(seats);
- printf("n_seats = %i\n", r);
- printf("seats = %s\n", t);
- free(t);
+ log_info("sd_get_seats(…) → [%i] \"%s\"", r, t);
+ t = mfree(t);
assert_se(sd_get_seats(NULL) == r);
r = sd_seat_get_active(NULL, &t, NULL);
- assert_se(r >= 0);
- printf("active session on current seat = %s\n", t);
+ assert_se(IN_SET(r, 0, -ENODATA));
+ log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s", strnull(t));
free(t);
r = sd_get_sessions(&sessions);
@@ -199,40 +224,47 @@ static void test_login(void) {
assert_se(r == (int) strv_length(sessions));
assert_se(t = strv_join(sessions, ", "));
strv_free(sessions);
- printf("n_sessions = %i\n", r);
- printf("sessions = %s\n", t);
+ log_info("sd_get_sessions(…) → [%i] \"%s\"", r, t);
free(t);
assert_se(sd_get_sessions(NULL) == r);
- r = sd_get_uids(&uids);
- assert_se(r >= 0);
+ {
+ _cleanup_free_ uid_t *uids = NULL;
+ _cleanup_free_ char *buf = NULL;
- printf("uids =");
- for (k = 0; k < r; k++)
- printf(" "UID_FMT, uids[k]);
- printf("\n");
- free(uids);
+ r = sd_get_uids(&uids);
+ assert_se(r >= 0);
+ log_info("sd_get_uids(…) → [%i] {%s}", r, format_uids(&buf, uids, r));
- printf("n_uids = %i\n", r);
- assert_se(sd_get_uids(NULL) == r);
+ assert_se(sd_get_uids(NULL) == r);
+ }
- r = sd_get_machine_names(&machines);
- assert_se(r >= 0);
- assert_se(r == (int) strv_length(machines));
- assert_se(t = strv_join(machines, ", "));
- strv_free(machines);
- printf("n_machines = %i\n", r);
- printf("machines = %s\n", t);
- free(t);
+ {
+ _cleanup_strv_free_ char **machines = NULL;
+ _cleanup_free_ char *buf = NULL;
+
+ r = sd_get_machine_names(&machines);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(machines));
+ assert_se(buf = strv_join(machines, " "));
+
+ log_info("sd_get_machines(…) → [%i] \"%s\"", r, buf);
+ }
+}
+
+static void test_monitor(void) {
+ sd_login_monitor *m = NULL;
+ unsigned n;
+ int r;
r = sd_login_monitor_new("session", &m);
assert_se(r >= 0);
for (n = 0; n < 5; n++) {
+ struct pollfd pollfd = {};
usec_t timeout, nw;
- zero(pollfd);
assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0);
assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0);
@@ -258,7 +290,12 @@ int main(int argc, char* argv[]) {
log_parse_environment();
log_open();
+ log_info("/* Information printed is from the live system */");
+
test_login();
+ if (streq_ptr(argv[1], "-m"))
+ test_monitor();
+
return 0;
}
diff --git a/src/test/meson.build b/src/test/meson.build
index 0324e3451a..892d2929ee 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -790,8 +790,7 @@ tests += [
[['src/libsystemd/sd-login/test-login.c'],
[],
- [],
- '', 'manual'],
+ []],
]
if cxx.found()