chiark / gitweb /
Prep v236 : Add missing SPDX-License-Identifier (4/9) src/libelogind
[elogind.git] / src / libelogind / sd-login / test-login.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3   This file is part of systemd.
4
5   Copyright 2011 Lennart Poettering
6
7   systemd is free software; you can redistribute it and/or modify it
8   under the terms of the GNU Lesser General Public License as published by
9   the Free Software Foundation; either version 2.1 of the License, or
10   (at your option) any later version.
11
12   systemd is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <poll.h>
22 #include <string.h>
23
24 #include "sd-login.h"
25
26 #include "alloc-util.h"
27 #include "fd-util.h"
28 #include "format-util.h"
29 #include "log.h"
30 #include "string-util.h"
31 #include "strv.h"
32 #include "util.h"
33
34 /// Additional includes needed by elogind
35 #include "musl_missing.h"
36 static char* format_uids(char **buf, uid_t* uids, int count) {
37         int pos = 0, k, inc;
38         size_t size = (DECIMAL_STR_MAX(uid_t) + 1) * count + 1;
39
40         assert_se(*buf = malloc(size));
41
42         for (k = 0; k < count; k++) {
43                 sprintf(*buf + pos, "%s"UID_FMT"%n", k > 0 ? " " : "", uids[k], &inc);
44                 pos += inc;
45         }
46
47         assert_se(pos < (ssize_t)size);
48         (*buf)[pos] = '\0';
49
50         return *buf;
51 }
52
53 static void test_login(void) {
54         _cleanup_close_pair_ int pair[2] = { -1, -1 };
55         _cleanup_free_ char *pp = NULL, *qq = NULL,
56                 *display_session = NULL, *cgroup = NULL,
57                 *display = NULL, *remote_user = NULL, *remote_host = NULL,
58                 *type = NULL, *class = NULL, *state = NULL, *state2 = NULL,
59                 *seat = NULL, *session = NULL,
60                 *unit = NULL, *user_unit = NULL, *slice = NULL;
61         int r;
62         uid_t u, u2;
63         char *t, **seats, **sessions;
64
65 #if 0 /// elogind does not support systemd units
66         r = sd_pid_get_unit(0, &unit);
67         assert_se(r >= 0 || r == -ENODATA);
68         log_info("sd_pid_get_unit(0, …) → \"%s\"", strna(unit));
69
70         r = sd_pid_get_user_unit(0, &user_unit);
71         assert_se(r >= 0 || r == -ENODATA);
72         log_info("sd_pid_get_user_unit(0, …) → \"%s\"", strna(user_unit));
73 #endif // 0
74
75         r = sd_pid_get_slice(0, &slice);
76         assert_se(r >= 0 || r == -ENODATA);
77         log_info("sd_pid_get_slice(0, …) → \"%s\"", strna(slice));
78
79         r = sd_pid_get_session(0, &session);
80         if (r < 0) {
81                 log_warning_errno(r, "sd_pid_get_session(0, …): %m");
82                 if (r == -ENODATA)
83                         log_info("Seems we are not running in a session, skipping some tests.");
84         } else {
85                 log_info("sd_pid_get_session(0, …) → \"%s\"", session);
86
87                 assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
88                 log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2);
89
90                 assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
91                 log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup);
92
93                 r = sd_uid_get_display(u2, &display_session);
94                 assert_se(r >= 0 || r == -ENODATA);
95                 log_info("sd_uid_get_display("UID_FMT", …) → \"%s\"",
96                          u2, strnull(display_session));
97
98                 assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
99                 sd_peer_get_session(pair[0], &pp);
100                 sd_peer_get_session(pair[1], &qq);
101                 assert_se(streq_ptr(pp, qq));
102
103                 r = sd_uid_get_sessions(u2, false, &sessions);
104                 assert_se(r >= 0);
105                 assert_se(r == (int) strv_length(sessions));
106                 assert_se(t = strv_join(sessions, " "));
107                 strv_free(sessions);
108                 log_info("sd_uid_get_sessions("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
109                 free(t);
110
111                 assert_se(r == sd_uid_get_sessions(u2, false, NULL));
112
113                 r = sd_uid_get_seats(u2, false, &seats);
114                 assert_se(r >= 0);
115                 assert_se(r == (int) strv_length(seats));
116                 assert_se(t = strv_join(seats, " "));
117                 strv_free(seats);
118                 log_info("sd_uid_get_seats("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
119                 free(t);
120
121                 assert_se(r == sd_uid_get_seats(u2, false, NULL));
122         }
123
124         if (session) {
125                 r = sd_session_is_active(session);
126                 assert_se(r >= 0);
127                 log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
128
129                 r = sd_session_is_remote(session);
130                 assert_se(r >= 0);
131                 log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
132
133                 r = sd_session_get_state(session, &state);
134                 assert_se(r >= 0);
135                 log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
136
137                 assert_se(sd_session_get_uid(session, &u) >= 0);
138                 log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
139                 assert_se(u == u2);
140
141                 assert_se(sd_session_get_type(session, &type) >= 0);
142                 log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
143
144                 assert_se(sd_session_get_class(session, &class) >= 0);
145                 log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
146
147                 r = sd_session_get_display(session, &display);
148                 assert_se(r >= 0 || r == -ENODATA);
149                 log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
150
151                 r = sd_session_get_remote_user(session, &remote_user);
152                 assert_se(r >= 0 || r == -ENODATA);
153                 log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
154                          session, strna(remote_user));
155
156                 r = sd_session_get_remote_host(session, &remote_host);
157                 assert_se(r >= 0 || r == -ENODATA);
158                 log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
159                          session, strna(remote_host));
160
161                 r = sd_session_get_seat(session, &seat);
162                 if (r >= 0) {
163                         assert_se(seat);
164
165                         log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat);
166
167                         r = sd_seat_can_multi_session(seat);
168                         assert_se(r >= 0);
169                         log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
170
171                         r = sd_seat_can_tty(seat);
172                         assert_se(r >= 0);
173                         log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
174
175                         r = sd_seat_can_graphical(seat);
176                         assert_se(r >= 0);
177                         log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
178                 } else {
179                         log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session);
180                         assert_se(r == -ENODATA);
181                 }
182
183                 assert_se(sd_uid_get_state(u, &state2) >= 0);
184                 log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
185         }
186
187         if (seat) {
188                 _cleanup_free_ char *session2 = NULL, *buf = NULL;
189                 _cleanup_free_ uid_t *uids = NULL;
190                 unsigned n;
191
192                 assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
193
194                 r = sd_seat_get_active(seat, &session2, &u2);
195                 assert_se(r >= 0);
196                 log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT, seat, session2, u2);
197
198                 r = sd_uid_is_on_seat(u, 1, seat);
199                 assert_se(r >= 0);
200                 assert_se(!!r == streq(session, session2));
201
202                 r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
203                 assert_se(r >= 0);
204                 assert_se(r == (int) strv_length(sessions));
205                 assert_se(t = strv_join(sessions, " "));
206                 strv_free(sessions);
207                 log_info("sd_seat_get_sessions(\"%s\", …) → %i, \"%s\", [%i] {%s}",
208                          seat, r, t, n, format_uids(&buf, uids, n));
209                 free(t);
210
211                 assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
212         }
213
214         r = sd_get_seats(&seats);
215         assert_se(r >= 0);
216         assert_se(r == (int) strv_length(seats));
217         assert_se(t = strv_join(seats, ", "));
218         strv_free(seats);
219         log_info("sd_get_seats(…) → [%i] \"%s\"", r, t);
220         t = mfree(t);
221
222         assert_se(sd_get_seats(NULL) == r);
223
224         r = sd_seat_get_active(NULL, &t, NULL);
225         assert_se(IN_SET(r, 0, -ENODATA));
226         log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s", strnull(t));
227         free(t);
228
229         r = sd_get_sessions(&sessions);
230         assert_se(r >= 0);
231         assert_se(r == (int) strv_length(sessions));
232         assert_se(t = strv_join(sessions, ", "));
233         strv_free(sessions);
234         log_info("sd_get_sessions(…) → [%i] \"%s\"", r, t);
235         free(t);
236
237         assert_se(sd_get_sessions(NULL) == r);
238
239         {
240                 _cleanup_free_ uid_t *uids = NULL;
241                 _cleanup_free_ char *buf = NULL;
242
243                 r = sd_get_uids(&uids);
244                 assert_se(r >= 0);
245                 log_info("sd_get_uids(…) → [%i] {%s}", r, format_uids(&buf, uids, r));
246
247                 assert_se(sd_get_uids(NULL) == r);
248         }
249
250         {
251                 _cleanup_strv_free_ char **machines = NULL;
252                 _cleanup_free_ char *buf = NULL;
253
254                 r = sd_get_machine_names(&machines);
255                 assert_se(r >= 0);
256                 assert_se(r == (int) strv_length(machines));
257                 assert_se(buf = strv_join(machines, " "));
258                 log_info("sd_get_machines(…) → [%i] \"%s\"", r, buf);
259
260                 assert_se(sd_get_machine_names(NULL) == r);
261         }
262 }
263
264 static void test_monitor(void) {
265         sd_login_monitor *m = NULL;
266         unsigned n;
267         int r;
268
269         r = sd_login_monitor_new("session", &m);
270         assert_se(r >= 0);
271
272         for (n = 0; n < 5; n++) {
273                 struct pollfd pollfd = {};
274                 usec_t timeout, nw;
275
276                 assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0);
277                 assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0);
278
279                 assert_se(sd_login_monitor_get_timeout(m, &timeout) >= 0);
280
281                 nw = now(CLOCK_MONOTONIC);
282
283                 r = poll(&pollfd, 1,
284                          timeout == (uint64_t) -1 ? -1 :
285                          timeout > nw ? (int) ((timeout - nw) / 1000) :
286                          0);
287
288                 assert_se(r >= 0);
289
290                 sd_login_monitor_flush(m);
291                 printf("Wake!\n");
292         }
293
294         sd_login_monitor_unref(m);
295 }
296
297 int main(int argc, char* argv[]) {
298         log_parse_environment();
299         log_open();
300
301         log_info("/* Information printed is from the live system */");
302
303         test_login();
304
305         if (streq_ptr(argv[1], "-m"))
306                 test_monitor();
307
308         return 0;
309 }