]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-util.c
util: rework rm_rf() logic
[thirdparty/systemd.git] / src / test / test-util.c
CommitLineData
539ad707
TA
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
23#include <string.h>
dbd73f9e
TA
24#include <unistd.h>
25#include <fcntl.h>
d6dd604b 26#include <locale.h>
2a371001 27#include <errno.h>
927be00c 28#include <signal.h>
8e211000 29#include <math.h>
8852362b 30#include <sys/wait.h>
539ad707
TA
31
32#include "util.h"
927be00c 33#include "mkdir.h"
c6878637 34#include "rm-rf.h"
893fa014 35#include "strv.h"
65b3903f
ZJS
36#include "def.h"
37#include "fileio.h"
9480794b 38#include "conf-parser.h"
0eb3cc88 39#include "virt.h"
539ad707
TA
40
41static void test_streq_ptr(void) {
8354c34e
TA
42 assert_se(streq_ptr(NULL, NULL));
43 assert_se(!streq_ptr("abc", "cdef"));
539ad707
TA
44}
45
625e870b
DH
46static void test_align_power2(void) {
47 unsigned long i, p2;
48
49 assert_se(ALIGN_POWER2(0) == 0);
50 assert_se(ALIGN_POWER2(1) == 1);
51 assert_se(ALIGN_POWER2(2) == 2);
52 assert_se(ALIGN_POWER2(3) == 4);
53 assert_se(ALIGN_POWER2(12) == 16);
54
55 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
56 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
57 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
58 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
59 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
60
61 for (i = 1; i < 131071; ++i) {
62 for (p2 = 1; p2 < i; p2 <<= 1)
63 /* empty */ ;
64
65 assert_se(ALIGN_POWER2(i) == p2);
66 }
67
68 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
69 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
70 /* empty */ ;
71
72 assert_se(ALIGN_POWER2(i) == p2);
73 }
74}
75
7242d742
DH
76static void test_max(void) {
77 static const struct {
78 int a;
79 int b[CONST_MAX(10, 100)];
80 } val1 = {
81 .a = CONST_MAX(10, 100),
82 };
83 int d = 0;
84
85 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
86
87 /* CONST_MAX returns (void) instead of a value if the passed arguments
88 * are not of the same type or not constant expressions. */
89 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
7242d742
DH
90 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
91
92 assert_se(val1.a == 100);
93 assert_se(MAX(++d, 0) == 1);
94 assert_se(d == 1);
40a1eebd
DH
95
96 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
97 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
98 assert_cc(MAXSIZE(char, long) == sizeof(long));
667a0377
DH
99
100 assert_se(MAX(-5, 5) == 5);
101 assert_se(MAX(5, 5) == 5);
102 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
103 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
104 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
105 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
106 assert_se(LESS_BY(8, 4) == 4);
107 assert_se(LESS_BY(8, 8) == 0);
108 assert_se(LESS_BY(4, 8) == 0);
109 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
110 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
111 assert_se(CLAMP(-5, 0, 1) == 0);
112 assert_se(CLAMP(5, 0, 1) == 1);
113 assert_se(CLAMP(5, -10, 1) == 1);
114 assert_se(CLAMP(5, -10, 10) == 5);
115 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
7242d742
DH
116}
117
fb835651
DH
118static void test_container_of(void) {
119 struct mytype {
120 uint8_t pad1[3];
121 uint64_t v1;
122 uint8_t pad2[2];
123 uint32_t v2;
124 } _packed_ myval = { };
125
126 assert_cc(sizeof(myval) == 17);
127 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
128 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
129 assert_se(container_of(&container_of(&myval.v2,
130 struct mytype,
131 v2)->v1,
132 struct mytype,
133 v1) == &myval);
134}
135
95d78c7e
DH
136static void test_alloca(void) {
137 static const uint8_t zero[997] = { };
138 char *t;
139
140 t = alloca_align(17, 512);
141 assert_se(!((uintptr_t)t & 0xff));
142 memzero(t, 17);
143
144 t = alloca0_align(997, 1024);
145 assert_se(!((uintptr_t)t & 0x1ff));
146 assert_se(!memcmp(t, zero, 997));
147}
148
180a60bc
DH
149static void test_div_round_up(void) {
150 int div;
151
152 /* basic tests */
153 assert_se(DIV_ROUND_UP(0, 8) == 0);
154 assert_se(DIV_ROUND_UP(1, 8) == 1);
155 assert_se(DIV_ROUND_UP(8, 8) == 1);
156 assert_se(DIV_ROUND_UP(12, 8) == 2);
157 assert_se(DIV_ROUND_UP(16, 8) == 2);
158
159 /* test multiple evaluation */
160 div = 0;
161 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
162 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
163 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
164 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
165
166 /* overflow test with exact division */
167 assert_se(sizeof(0U) == 4);
168 assert_se(0xfffffffaU % 10U == 0U);
169 assert_se(0xfffffffaU / 10U == 429496729U);
170 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
171 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
172 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
173
174 /* overflow test with rounded division */
175 assert_se(0xfffffffdU % 10U == 3U);
176 assert_se(0xfffffffdU / 10U == 429496729U);
177 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
178 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
179 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
180}
181
539ad707 182static void test_first_word(void) {
8354c34e
TA
183 assert_se(first_word("Hello", ""));
184 assert_se(first_word("Hello", "Hello"));
185 assert_se(first_word("Hello world", "Hello"));
186 assert_se(first_word("Hello\tworld", "Hello"));
187 assert_se(first_word("Hello\nworld", "Hello"));
188 assert_se(first_word("Hello\rworld", "Hello"));
189 assert_se(first_word("Hello ", "Hello"));
190
191 assert_se(!first_word("Hello", "Hellooo"));
192 assert_se(!first_word("Hello", "xxxxx"));
193 assert_se(!first_word("Hellooo", "Hello"));
194}
195
dbd73f9e
TA
196static void test_close_many(void) {
197 int fds[3];
198 char name0[] = "/tmp/test-close-many.XXXXXX";
199 char name1[] = "/tmp/test-close-many.XXXXXX";
200 char name2[] = "/tmp/test-close-many.XXXXXX";
201
2d5bdf5b
LP
202 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
203 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
204 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
dbd73f9e
TA
205
206 close_many(fds, 2);
207
208 assert_se(fcntl(fds[0], F_GETFD) == -1);
209 assert_se(fcntl(fds[1], F_GETFD) == -1);
210 assert_se(fcntl(fds[2], F_GETFD) >= 0);
211
03e334a1 212 safe_close(fds[2]);
dbd73f9e
TA
213
214 unlink(name0);
215 unlink(name1);
216 unlink(name2);
217}
218
8354c34e
TA
219static void test_parse_boolean(void) {
220 assert_se(parse_boolean("1") == 1);
221 assert_se(parse_boolean("y") == 1);
222 assert_se(parse_boolean("Y") == 1);
223 assert_se(parse_boolean("yes") == 1);
224 assert_se(parse_boolean("YES") == 1);
225 assert_se(parse_boolean("true") == 1);
226 assert_se(parse_boolean("TRUE") == 1);
227 assert_se(parse_boolean("on") == 1);
228 assert_se(parse_boolean("ON") == 1);
229
230 assert_se(parse_boolean("0") == 0);
231 assert_se(parse_boolean("n") == 0);
232 assert_se(parse_boolean("N") == 0);
233 assert_se(parse_boolean("no") == 0);
234 assert_se(parse_boolean("NO") == 0);
235 assert_se(parse_boolean("false") == 0);
236 assert_se(parse_boolean("FALSE") == 0);
237 assert_se(parse_boolean("off") == 0);
238 assert_se(parse_boolean("OFF") == 0);
239
240 assert_se(parse_boolean("garbage") < 0);
241 assert_se(parse_boolean("") < 0);
0f625d0b 242 assert_se(parse_boolean("full") < 0);
539ad707
TA
243}
244
8d99e5f5
TA
245static void test_parse_pid(void) {
246 int r;
247 pid_t pid;
248
249 r = parse_pid("100", &pid);
250 assert_se(r == 0);
251 assert_se(pid == 100);
252
253 r = parse_pid("0x7FFFFFFF", &pid);
254 assert_se(r == 0);
255 assert_se(pid == 2147483647);
256
257 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
258 r = parse_pid("0", &pid);
259 assert_se(r == -ERANGE);
260 assert_se(pid == 65);
261
262 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
263 r = parse_pid("-100", &pid);
264 assert_se(r == -ERANGE);
265 assert_se(pid == 65);
266
267 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
268 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
bdf7026e 269 assert_se(r == -ERANGE);
8d99e5f5
TA
270 assert_se(pid == 65);
271}
272
273static void test_parse_uid(void) {
274 int r;
275 uid_t uid;
276
277 r = parse_uid("100", &uid);
278 assert_se(r == 0);
279 assert_se(uid == 100);
280}
281
282static void test_safe_atolli(void) {
283 int r;
284 long long l;
285
286 r = safe_atolli("12345", &l);
287 assert_se(r == 0);
288 assert_se(l == 12345);
289
290 r = safe_atolli("junk", &l);
291 assert_se(r == -EINVAL);
292}
293
294static void test_safe_atod(void) {
295 int r;
296 double d;
d6dd604b
LP
297 char *e;
298
299 r = safe_atod("junk", &d);
300 assert_se(r == -EINVAL);
8d99e5f5
TA
301
302 r = safe_atod("0.2244", &d);
303 assert_se(r == 0);
8e211000 304 assert_se(fabs(d - 0.2244) < 0.000001);
8d99e5f5 305
d6dd604b 306 r = safe_atod("0,5", &d);
8d99e5f5 307 assert_se(r == -EINVAL);
d6dd604b
LP
308
309 errno = 0;
310 strtod("0,5", &e);
311 assert_se(*e == ',');
312
313 /* Check if this really is locale independent */
926446f4 314 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
d6dd604b 315
926446f4
DH
316 r = safe_atod("0.2244", &d);
317 assert_se(r == 0);
318 assert_se(fabs(d - 0.2244) < 0.000001);
d6dd604b 319
926446f4
DH
320 r = safe_atod("0,5", &d);
321 assert_se(r == -EINVAL);
d6dd604b 322
926446f4
DH
323 errno = 0;
324 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
325 }
d6dd604b
LP
326
327 /* And check again, reset */
926446f4 328 assert_se(setlocale(LC_NUMERIC, "C"));
d6dd604b
LP
329
330 r = safe_atod("0.2244", &d);
331 assert_se(r == 0);
8e211000 332 assert_se(fabs(d - 0.2244) < 0.000001);
d6dd604b
LP
333
334 r = safe_atod("0,5", &d);
335 assert_se(r == -EINVAL);
336
337 errno = 0;
338 strtod("0,5", &e);
339 assert_se(*e == ',');
8d99e5f5
TA
340}
341
dbd73f9e 342static void test_strappend(void) {
998b087f 343 _cleanup_free_ char *t1, *t2, *t3, *t4;
dbd73f9e 344
998b087f
TA
345 t1 = strappend(NULL, NULL);
346 assert_se(streq(t1, ""));
dbd73f9e 347
998b087f
TA
348 t2 = strappend(NULL, "suf");
349 assert_se(streq(t2, "suf"));
dbd73f9e 350
998b087f
TA
351 t3 = strappend("pre", NULL);
352 assert_se(streq(t3, "pre"));
dbd73f9e 353
998b087f
TA
354 t4 = strappend("pre", "suf");
355 assert_se(streq(t4, "presuf"));
dbd73f9e
TA
356}
357
1ef04f0b 358static void test_strstrip(void) {
998b087f
TA
359 char *r;
360 char input[] = " hello, waldo. ";
1ef04f0b 361
998b087f
TA
362 r = strstrip(input);
363 assert_se(streq(r, "hello, waldo."));
1ef04f0b
TA
364}
365
366static void test_delete_chars(void) {
998b087f
TA
367 char *r;
368 char input[] = " hello, waldo. abc";
1ef04f0b 369
998b087f
TA
370 r = delete_chars(input, WHITESPACE);
371 assert_se(streq(r, "hello,waldo.abc"));
1ef04f0b
TA
372}
373
374static void test_in_charset(void) {
998b087f
TA
375 assert_se(in_charset("dddaaabbbcccc", "abcd"));
376 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
1ef04f0b
TA
377}
378
44f4c86c
DB
379static void test_hexchar(void) {
380 assert_se(hexchar(0xa) == 'a');
381 assert_se(hexchar(0x0) == '0');
382}
383
384static void test_unhexchar(void) {
385 assert_se(unhexchar('a') == 0xA);
386 assert_se(unhexchar('A') == 0xA);
387 assert_se(unhexchar('0') == 0x0);
388}
389
390static void test_octchar(void) {
391 assert_se(octchar(00) == '0');
392 assert_se(octchar(07) == '7');
393}
394
395static void test_unoctchar(void) {
396 assert_se(unoctchar('0') == 00);
397 assert_se(unoctchar('7') == 07);
398}
399
400static void test_decchar(void) {
401 assert_se(decchar(0) == '0');
402 assert_se(decchar(9) == '9');
403}
404
405static void test_undecchar(void) {
406 assert_se(undecchar('0') == 0);
407 assert_se(undecchar('9') == 9);
408}
409
b4ecc959
TA
410static void test_cescape(void) {
411 _cleanup_free_ char *escaped;
e0a33e7b
LP
412
413 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
927be00c 414 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
b4ecc959
TA
415}
416
417static void test_cunescape(void) {
418 _cleanup_free_ char *unescaped;
e0a33e7b 419
7f769619
ZJS
420 unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00");
421 assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
422
423 /* incomplete sequences */
424 unescaped = cunescape("\\x0");
425 assert_se(streq_ptr(unescaped, "\\x0"));
426
427 unescaped = cunescape("\\x");
428 assert_se(streq_ptr(unescaped, "\\x"));
429
430 unescaped = cunescape("\\");
431 assert_se(streq_ptr(unescaped, "\\"));
432
433 unescaped = cunescape("\\11");
434 assert_se(streq_ptr(unescaped, "\\11"));
435
436 unescaped = cunescape("\\1");
437 assert_se(streq_ptr(unescaped, "\\1"));
b4ecc959
TA
438}
439
1ef04f0b 440static void test_foreach_word(void) {
a2a5291b 441 const char *word, *state;
1ef04f0b
TA
442 size_t l;
443 int i = 0;
444 const char test[] = "test abc d\te f ";
445 const char * const expected[] = {
446 "test",
447 "abc",
448 "d",
449 "e",
450 "f",
451 "",
452 NULL
453 };
454
a2a5291b
ZJS
455 FOREACH_WORD(word, l, test, state)
456 assert_se(strneq(expected[i++], word, l));
1ef04f0b
TA
457}
458
ba774317 459static void check(const char *test, char** expected, bool trailing) {
a2a5291b 460 const char *word, *state;
539ad707 461 size_t l;
1ef04f0b 462 int i = 0;
1ef04f0b 463
ba774317 464 printf("<<<%s>>>\n", test);
a2a5291b 465 FOREACH_WORD_QUOTED(word, l, test, state) {
1ef04f0b 466 _cleanup_free_ char *t = NULL;
539ad707 467
a2a5291b
ZJS
468 assert_se(t = strndup(word, l));
469 assert_se(strneq(expected[i++], word, l));
539ad707 470 printf("<%s>\n", t);
539ad707 471 }
ba774317 472 printf("<<<%s>>>\n", state);
e50221bf 473 assert_se(expected[i] == NULL);
ba774317
ZJS
474 assert_se(isempty(state) == !trailing);
475}
476
477static void test_foreach_word_quoted(void) {
478 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
479 STRV_MAKE("test",
480 "a",
481 "b",
482 "c",
483 "d",
484 "e",
485 "",
486 "",
487 "hhh",
488 "",
489 "",
490 "a b c"),
491 false);
492
493 check("test \"xxx",
494 STRV_MAKE("test"),
495 true);
496
497 check("test\\",
498 STRV_MAKE_EMPTY,
499 true);
539ad707
TA
500}
501
502static void test_default_term_for_tty(void) {
503 puts(default_term_for_tty("/dev/tty23"));
504 puts(default_term_for_tty("/dev/ttyS23"));
505 puts(default_term_for_tty("/dev/tty0"));
506 puts(default_term_for_tty("/dev/pty0"));
507 puts(default_term_for_tty("/dev/pts/0"));
508 puts(default_term_for_tty("/dev/console"));
509 puts(default_term_for_tty("tty23"));
510 puts(default_term_for_tty("ttyS23"));
511 puts(default_term_for_tty("tty0"));
512 puts(default_term_for_tty("pty0"));
513 puts(default_term_for_tty("pts/0"));
514 puts(default_term_for_tty("console"));
515}
516
0d585d82
TA
517static void test_memdup_multiply(void) {
518 int org[] = {1, 2, 3};
519 int *dup;
520
521 dup = (int*)memdup_multiply(org, sizeof(int), 3);
522
523 assert_se(dup);
524 assert_se(dup[0] == 1);
525 assert_se(dup[1] == 2);
526 assert_se(dup[2] == 3);
527 free(dup);
528}
529
aa3c5cf8 530static void test_hostname_is_valid(void) {
bdf7026e
TA
531 assert_se(hostname_is_valid("foobar"));
532 assert_se(hostname_is_valid("foobar.com"));
533 assert_se(!hostname_is_valid("fööbar"));
534 assert_se(!hostname_is_valid(""));
535 assert_se(!hostname_is_valid("."));
536 assert_se(!hostname_is_valid(".."));
537 assert_se(!hostname_is_valid("foobar."));
538 assert_se(!hostname_is_valid(".foobar"));
539 assert_se(!hostname_is_valid("foo..bar"));
540 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
aa3c5cf8
LP
541}
542
144e51ec 543static void test_u64log2(void) {
bdf7026e
TA
544 assert_se(u64log2(0) == 0);
545 assert_se(u64log2(8) == 3);
546 assert_se(u64log2(9) == 3);
547 assert_se(u64log2(15) == 3);
548 assert_se(u64log2(16) == 4);
549 assert_se(u64log2(1024*1024) == 20);
550 assert_se(u64log2(1024*1024+5) == 20);
144e51ec
CR
551}
552
49aa47c7 553static void test_get_process_comm(void) {
143bfdaf 554 struct stat st;
ad450c3e 555 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
c593bb36 556 _cleanup_free_ char *env = NULL;
49aa47c7
LP
557 pid_t e;
558 uid_t u;
559 gid_t g;
560 dev_t h;
561 int r;
ad450c3e 562 pid_t me;
49aa47c7 563
143bfdaf
HHPF
564 if (stat("/proc/1/comm", &st) == 0) {
565 assert_se(get_process_comm(1, &a) >= 0);
566 log_info("pid1 comm: '%s'", a);
567 } else {
568 log_warning("/proc/1/comm does not exist.");
569 }
49aa47c7 570
49aa47c7
LP
571 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
572 log_info("pid1 cmdline: '%s'", c);
573
574 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
575 log_info("pid1 cmdline truncated: '%s'", d);
576
577 assert_se(get_parent_of_pid(1, &e) >= 0);
de0671ee 578 log_info("pid1 ppid: "PID_FMT, e);
49aa47c7
LP
579 assert_se(e == 0);
580
581 assert_se(is_kernel_thread(1) == 0);
582
583 r = get_process_exe(1, &f);
584 assert_se(r >= 0 || r == -EACCES);
585 log_info("pid1 exe: '%s'", strna(f));
586
587 assert_se(get_process_uid(1, &u) == 0);
de0671ee 588 log_info("pid1 uid: "UID_FMT, u);
49aa47c7
LP
589 assert_se(u == 0);
590
591 assert_se(get_process_gid(1, &g) == 0);
de0671ee 592 log_info("pid1 gid: "GID_FMT, g);
49aa47c7
LP
593 assert_se(g == 0);
594
ad450c3e
JF
595 me = getpid();
596
597 r = get_process_cwd(me, &cwd);
598 assert_se(r >= 0 || r == -EACCES);
599 log_info("pid1 cwd: '%s'", cwd);
600
601 r = get_process_root(me, &root);
602 assert_se(r >= 0 || r == -EACCES);
603 log_info("pid1 root: '%s'", root);
604
c593bb36
JF
605 r = get_process_environ(me, &env);
606 assert_se(r >= 0 || r == -EACCES);
1fa2f38f 607 log_info("self strlen(environ): '%zu'", strlen(env));
c593bb36 608
0eb3cc88
JS
609 if (!detect_container(NULL))
610 assert_se(get_ctty_devnr(1, &h) == -ENOENT);
49aa47c7
LP
611
612 getenv_for_pid(1, "PATH", &i);
613 log_info("pid1 $PATH: '%s'", strna(i));
614}
615
2a371001
ZJS
616static void test_protect_errno(void) {
617 errno = 12;
618 {
619 PROTECT_ERRNO;
620 errno = 11;
621 }
bdf7026e 622 assert_se(errno == 12);
2a371001
ZJS
623}
624
5556b5fe 625static void test_parse_size(void) {
b32ff512
ZJS
626 off_t bytes;
627
5556b5fe 628 assert_se(parse_size("111", 1024, &bytes) == 0);
b32ff512
ZJS
629 assert_se(bytes == 111);
630
9480794b
ZJS
631 assert_se(parse_size("111.4", 1024, &bytes) == 0);
632 assert_se(bytes == 111);
633
5556b5fe 634 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
b32ff512
ZJS
635 assert_se(bytes == 112);
636
9480794b
ZJS
637 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
638 assert_se(bytes == 112);
639
640 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
641 assert_se(bytes == 3*1024 + 512);
642
643 assert_se(parse_size("3. K", 1024, &bytes) == 0);
644 assert_se(bytes == 3*1024);
645
646 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
b32ff512
ZJS
647 assert_se(bytes == 3*1024);
648
840292be 649 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
b32ff512 650
9480794b
ZJS
651 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
652 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
653
840292be
ZJS
654 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
655
656 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
9480794b 657 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
b32ff512 658
840292be
ZJS
659 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
660 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
661
662 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
663
664 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
665 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
666
667 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
b32ff512
ZJS
668 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
669
5556b5fe 670 assert_se(parse_size("12P", 1024, &bytes) == 0);
b32ff512
ZJS
671 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
672
840292be
ZJS
673 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
674
5556b5fe 675 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
b32ff512
ZJS
676 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
677
5556b5fe 678 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
b32ff512 679
9480794b
ZJS
680 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
681
682 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
683
5556b5fe
LP
684 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
685 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
686 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
b32ff512 687
5556b5fe 688 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
b32ff512 689
5556b5fe 690 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
b32ff512
ZJS
691}
692
9480794b
ZJS
693static void test_config_parse_iec_off(void) {
694 off_t offset = 0;
695 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
696 assert_se(offset == 4 * 1024 * 1024);
697
698 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
699}
700
b4ecc959
TA
701static void test_strextend(void) {
702 _cleanup_free_ char *str = strdup("0123");
703 strextend(&str, "456", "78", "9", NULL);
704 assert_se(streq(str, "0123456789"));
705}
706
707static void test_strrep(void) {
708 _cleanup_free_ char *one, *three, *zero;
709 one = strrep("waldo", 1);
710 three = strrep("waldo", 3);
711 zero = strrep("waldo", 0);
712
713 assert_se(streq(one, "waldo"));
714 assert_se(streq(three, "waldowaldowaldo"));
715 assert_se(streq(zero, ""));
716}
717
d4ac85c6
LP
718static void test_split_pair(void) {
719 _cleanup_free_ char *a = NULL, *b = NULL;
720
721 assert_se(split_pair("", "", &a, &b) == -EINVAL);
722 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
723 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
724 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
725 assert_se(streq(a, "foo"));
726 assert_se(streq(b, "bar"));
727 free(a);
728 free(b);
729 assert_se(split_pair("==", "==", &a, &b) >= 0);
730 assert_se(streq(a, ""));
731 assert_se(streq(b, ""));
732 free(a);
733 free(b);
734
735 assert_se(split_pair("===", "==", &a, &b) >= 0);
736 assert_se(streq(a, ""));
737 assert_se(streq(b, "="));
738}
739
22f5f628
DR
740static void test_fstab_node_to_udev_node(void) {
741 char *n;
742
743 n = fstab_node_to_udev_node("LABEL=applé/jack");
744 puts(n);
745 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
746 free(n);
747
748 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
749 puts(n);
750 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
751 free(n);
752
753 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
754 puts(n);
755 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
756 free(n);
757
758 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
759 puts(n);
760 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
761 free(n);
762
22f5f628
DR
763 n = fstab_node_to_udev_node("PONIES=awesome");
764 puts(n);
765 assert_se(streq(n, "PONIES=awesome"));
766 free(n);
767
768 n = fstab_node_to_udev_node("/dev/xda1");
769 puts(n);
770 assert_se(streq(n, "/dev/xda1"));
771 free(n);
772}
773
893fa014
ZJS
774static void test_get_files_in_directory(void) {
775 _cleanup_strv_free_ char **l = NULL, **t = NULL;
776
777 assert_se(get_files_in_directory("/tmp", &l) >= 0);
510b857f 778 assert_se(get_files_in_directory(".", &t) >= 0);
893fa014
ZJS
779 assert_se(get_files_in_directory(".", NULL) >= 0);
780}
781
cabb7806
LP
782static void test_in_set(void) {
783 assert_se(IN_SET(1, 1));
784 assert_se(IN_SET(1, 1, 2, 3, 4));
785 assert_se(IN_SET(2, 1, 2, 3, 4));
786 assert_se(IN_SET(3, 1, 2, 3, 4));
787 assert_se(IN_SET(4, 1, 2, 3, 4));
788 assert_se(!IN_SET(0, 1));
789 assert_se(!IN_SET(0, 1, 2, 3, 4));
790}
791
87b02843
ZJS
792static void test_writing_tmpfile(void) {
793 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
39883f62 794 _cleanup_free_ char *contents = NULL;
65b3903f
ZJS
795 size_t size;
796 int fd, r;
65b3903f 797 struct iovec iov[3];
39883f62 798
65b3903f
ZJS
799 IOVEC_SET_STRING(iov[0], "abc\n");
800 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
801 IOVEC_SET_STRING(iov[2], "");
802
2d5bdf5b 803 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
87b02843 804 printf("tmpfile: %s", name);
65b3903f 805
87b02843 806 r = writev(fd, iov, 3);
bdf7026e 807 assert_se(r >= 0);
65b3903f
ZJS
808
809 r = read_full_file(name, &contents, &size);
bdf7026e 810 assert_se(r == 0);
65b3903f 811 printf("contents: %s", contents);
bdf7026e 812 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
40edd236
RC
813
814 unlink(name);
65b3903f
ZJS
815}
816
29bfbcd6
LP
817static void test_hexdump(void) {
818 uint8_t data[146];
819 unsigned i;
820
821 hexdump(stdout, NULL, 0);
822 hexdump(stdout, "", 0);
823 hexdump(stdout, "", 1);
824 hexdump(stdout, "x", 1);
825 hexdump(stdout, "x", 2);
826 hexdump(stdout, "foobar", 7);
827 hexdump(stdout, "f\nobar", 7);
828 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
829
830 for (i = 0; i < ELEMENTSOF(data); i++)
831 data[i] = i*2;
832
833 hexdump(stdout, data, sizeof(data));
834}
835
8fe90522
ZJS
836static void test_log2i(void) {
837 assert_se(log2i(1) == 0);
838 assert_se(log2i(2) == 1);
839 assert_se(log2i(3) == 1);
840 assert_se(log2i(4) == 2);
841 assert_se(log2i(32) == 5);
842 assert_se(log2i(33) == 5);
843 assert_se(log2i(63) == 5);
844 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
845}
846
c4a7b2c5
LP
847static void test_foreach_string(void) {
848 const char * const t[] = {
849 "foo",
850 "bar",
851 "waldo",
852 NULL
853 };
854 const char *x;
855 unsigned i = 0;
856
857 FOREACH_STRING(x, "foo", "bar", "waldo")
858 assert_se(streq_ptr(t[i++], x));
859
860 assert_se(i == 3);
861
862 FOREACH_STRING(x, "zzz")
863 assert_se(streq(x, "zzz"));
864}
865
ae6c3cc0 866static void test_filename_is_valid(void) {
927be00c
RC
867 char foo[FILENAME_MAX+2];
868 int i;
869
ae6c3cc0
LP
870 assert_se(!filename_is_valid(""));
871 assert_se(!filename_is_valid("/bar/foo"));
872 assert_se(!filename_is_valid("/"));
873 assert_se(!filename_is_valid("."));
874 assert_se(!filename_is_valid(".."));
927be00c
RC
875
876 for (i=0; i<FILENAME_MAX+1; i++)
877 foo[i] = 'a';
878 foo[FILENAME_MAX+1] = '\0';
879
ae6c3cc0 880 assert_se(!filename_is_valid(foo));
927be00c 881
ae6c3cc0
LP
882 assert_se(filename_is_valid("foo_bar-333"));
883 assert_se(filename_is_valid("o.o"));
927be00c
RC
884}
885
1cb1767a
ZJS
886static void test_string_has_cc(void) {
887 assert_se(string_has_cc("abc\1", NULL));
888 assert_se(string_has_cc("abc\x7f", NULL));
889 assert_se(string_has_cc("abc\x7f", NULL));
890 assert_se(string_has_cc("abc\t\x7f", "\t"));
891 assert_se(string_has_cc("abc\t\x7f", "\t"));
892 assert_se(string_has_cc("\x7f", "\t"));
893 assert_se(string_has_cc("\x7f", "\t\a"));
894
895 assert_se(!string_has_cc("abc\t\t", "\t"));
896 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
897 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
898}
899
927be00c
RC
900static void test_ascii_strlower(void) {
901 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
902 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
903}
904
905static void test_files_same(void) {
906 _cleanup_close_ int fd = -1;
907 char name[] = "/tmp/test-files_same.XXXXXX";
908 char name_alias[] = "/tmp/test-files_same.alias";
909
910 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
911 assert_se(fd >= 0);
912 assert_se(symlink(name, name_alias) >= 0);
913
914 assert_se(files_same(name, name));
915 assert_se(files_same(name, name_alias));
916
917 unlink(name);
918 unlink(name_alias);
919}
920
921static void test_is_valid_documentation_url(void) {
a2e03378
LP
922 assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
923 assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
924 assert_se(documentation_url_is_valid("file:/foo/foo"));
925 assert_se(documentation_url_is_valid("man:systemd.special(7)"));
926 assert_se(documentation_url_is_valid("info:bar"));
927
928 assert_se(!documentation_url_is_valid("foo:"));
929 assert_se(!documentation_url_is_valid("info:"));
930 assert_se(!documentation_url_is_valid(""));
927be00c
RC
931}
932
933static void test_file_in_same_dir(void) {
eee84633
DH
934 char *t;
935
936 t = file_in_same_dir("/", "a");
937 assert_se(streq(t, "/a"));
938 free(t);
939
940 t = file_in_same_dir("/", "/a");
941 assert_se(streq(t, "/a"));
942 free(t);
943
944 t = file_in_same_dir("", "a");
945 assert_se(streq(t, "a"));
946 free(t);
947
948 t = file_in_same_dir("a/", "a");
949 assert_se(streq(t, "a/a"));
950 free(t);
951
952 t = file_in_same_dir("bar/foo", "bar");
953 assert_se(streq(t, "bar/bar"));
954 free(t);
927be00c
RC
955}
956
957static void test_endswith(void) {
958 assert_se(endswith("foobar", "bar"));
959 assert_se(endswith("foobar", ""));
960 assert_se(endswith("foobar", "foobar"));
961 assert_se(endswith("", ""));
962
963 assert_se(!endswith("foobar", "foo"));
964 assert_se(!endswith("foobar", "foobarfoofoo"));
965}
966
967static void test_close_nointr(void) {
968 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
969 int fd;
970
971 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
972 assert_se(fd >= 0);
973 assert_se(close_nointr(fd) >= 0);
974 assert_se(close_nointr(fd) < 0);
975
976 unlink(name);
977}
978
979
980static void test_unlink_noerrno(void) {
981 char name[] = "/tmp/test-close_nointr.XXXXXX";
982 int fd;
983
984 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
985 assert_se(fd >= 0);
986 assert_se(close_nointr(fd) >= 0);
987
988 {
989 PROTECT_ERRNO;
990 errno = -42;
991 assert_se(unlink_noerrno(name) >= 0);
992 assert_se(errno == -42);
993 assert_se(unlink_noerrno(name) < 0);
994 assert_se(errno == -42);
995 }
996}
997
998static void test_readlink_and_make_absolute(void) {
999 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
1000 char name[] = "/tmp/test-readlink_and_make_absolute/original";
1001 char name2[] = "test-readlink_and_make_absolute/original";
1002 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
1003 char *r = NULL;
1004
684fc892 1005 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
927be00c
RC
1006 assert_se(touch(name) >= 0);
1007
1008 assert_se(symlink(name, name_alias) >= 0);
1009 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1010 assert_se(streq(r, name));
1011 free(r);
1012 assert_se(unlink(name_alias) >= 0);
1013
1014 assert_se(chdir(tempdir) >= 0);
1015 assert_se(symlink(name2, name_alias) >= 0);
1016 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1017 assert_se(streq(r, name));
1018 free(r);
1019 assert_se(unlink(name_alias) >= 0);
1020
c6878637 1021 assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
927be00c
RC
1022}
1023
1024static void test_read_one_char(void) {
3f2e132a 1025 _cleanup_fclose_ FILE *file = NULL;
927be00c
RC
1026 char r;
1027 bool need_nl;
1028 char name[] = "/tmp/test-read_one_char.XXXXXX";
3f2e132a 1029 int fd;
927be00c
RC
1030
1031 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1032 assert_se(fd >= 0);
1033 file = fdopen(fd, "r+");
1034 assert_se(file);
1035 assert_se(fputs("c\n", file) >= 0);
1036 rewind(file);
1037
1038 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
1039 assert_se(!need_nl);
1040 assert_se(r == 'c');
1041 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1042
1043 rewind(file);
1044 assert_se(fputs("foobar\n", file) >= 0);
1045 rewind(file);
1046 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1047
1048 rewind(file);
1049 assert_se(fputs("\n", file) >= 0);
1050 rewind(file);
1051 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1052
1053 unlink(name);
1054}
1055
1056static void test_ignore_signals(void) {
1057 assert_se(ignore_signals(SIGINT, -1) >= 0);
1058 assert_se(kill(getpid(), SIGINT) >= 0);
1059 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1060 assert_se(kill(getpid(), SIGUSR1) >= 0);
1061 assert_se(kill(getpid(), SIGUSR2) >= 0);
1062 assert_se(kill(getpid(), SIGTERM) >= 0);
1063 assert_se(kill(getpid(), SIGPIPE) >= 0);
1064 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1065}
1066
1067static void test_strshorten(void) {
1068 char s[] = "foobar";
1069
1070 assert_se(strlen(strshorten(s, 6)) == 6);
1071 assert_se(strlen(strshorten(s, 12)) == 6);
1072 assert_se(strlen(strshorten(s, 2)) == 2);
1073 assert_se(strlen(strshorten(s, 0)) == 0);
1074}
1075
63c372cb 1076static void test_strjoina(void) {
8085f163
DR
1077 char *actual;
1078
63c372cb 1079 actual = strjoina("", "foo", "bar");
8085f163
DR
1080 assert_se(streq(actual, "foobar"));
1081
63c372cb 1082 actual = strjoina("foo", "bar", "baz");
8085f163
DR
1083 assert_se(streq(actual, "foobarbaz"));
1084
63c372cb 1085 actual = strjoina("foo", "", "bar", "baz");
8085f163 1086 assert_se(streq(actual, "foobarbaz"));
63c372cb
LP
1087
1088 actual = strjoina("foo");
1089 assert_se(streq(actual, "foo"));
1090
1091 actual = strjoina(NULL);
1092 assert_se(streq(actual, ""));
1093
1094 actual = strjoina(NULL, "foo");
1095 assert_se(streq(actual, ""));
1096
1097 actual = strjoina("foo", NULL, "bar");
1098 assert_se(streq(actual, "foo"));
8085f163
DR
1099}
1100
8852362b
RC
1101static void test_is_symlink(void) {
1102 char name[] = "/tmp/test-is_symlink.XXXXXX";
1103 char name_link[] = "/tmp/test-is_symlink.link";
1104 _cleanup_close_ int fd = -1;
1105
1106 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1107 assert_se(fd >= 0);
1108 assert_se(symlink(name, name_link) >= 0);
1109
1110 assert_se(is_symlink(name) == 0);
1111 assert_se(is_symlink(name_link) == 1);
1112 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1113
1114
1115 unlink(name);
1116 unlink(name_link);
1117}
1118
1119static void test_pid_is_unwaited(void) {
1120 pid_t pid;
1121
1122 pid = fork();
1123 assert_se(pid >= 0);
1124 if (pid == 0) {
1125 _exit(EXIT_SUCCESS);
1126 } else {
1127 int status;
1128
1129 waitpid(pid, &status, 0);
1130 assert_se(!pid_is_unwaited(pid));
1131 }
1132 assert_se(pid_is_unwaited(getpid()));
1133 assert_se(!pid_is_unwaited(-1));
1134}
1135
1136static void test_pid_is_alive(void) {
1137 pid_t pid;
1138
1139 pid = fork();
1140 assert_se(pid >= 0);
1141 if (pid == 0) {
1142 _exit(EXIT_SUCCESS);
1143 } else {
1144 int status;
1145
1146 waitpid(pid, &status, 0);
1147 assert_se(!pid_is_alive(pid));
1148 }
1149 assert_se(pid_is_alive(getpid()));
1150 assert_se(!pid_is_alive(-1));
1151}
1152
1153static void test_search_and_fopen(void) {
1154 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1155 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1156 int fd = -1;
1157 int r;
1158 FILE *f;
1159
1160 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1161 assert_se(fd >= 0);
1162 close(fd);
1163
1164 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1165 assert_se(r >= 0);
1166 fclose(f);
1167
1168 r = search_and_fopen(name, "r", NULL, dirs, &f);
1169 assert_se(r >= 0);
1170 fclose(f);
1171
1172 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1173 assert_se(r >= 0);
1174 fclose(f);
1175
1176 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1177 assert_se(r < 0);
1178 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1179 assert_se(r < 0);
1180
1181 r = unlink(name);
1182 assert_se(r == 0);
1183
1184 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1185 assert_se(r < 0);
1186}
1187
1188
1189static void test_search_and_fopen_nulstr(void) {
1190 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1191 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1192 int fd = -1;
1193 int r;
1194 FILE *f;
1195
1196 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1197 assert_se(fd >= 0);
1198 close(fd);
1199
1200 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1201 assert_se(r >= 0);
1202 fclose(f);
1203
1204 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1205 assert_se(r >= 0);
1206 fclose(f);
1207
1208 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1209 assert_se(r < 0);
1210 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1211 assert_se(r < 0);
1212
1213 r = unlink(name);
1214 assert_se(r == 0);
1215
1216 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1217 assert_se(r < 0);
1218}
1219
1220static void test_glob_exists(void) {
1221 char name[] = "/tmp/test-glob_exists.XXXXXX";
1222 int fd = -1;
1223 int r;
1224
1225 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1226 assert_se(fd >= 0);
1227 close(fd);
1228
1229 r = glob_exists("/tmp/test-glob_exists*");
1230 assert_se(r == 1);
1231
1232 r = unlink(name);
1233 assert_se(r == 0);
1234 r = glob_exists("/tmp/test-glob_exists*");
1235 assert_se(r == 0);
1236}
1237
1238static void test_execute_directory(void) {
aac7766c
ZJS
1239 char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1240 char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
76f282c6 1241 const char * dirs[] = {template_hi, template_lo, NULL};
aac7766c
ZJS
1242 const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
1243
1244 assert_se(mkdtemp(template_lo));
1245 assert_se(mkdtemp(template_hi));
1246
63c372cb
LP
1247 name = strjoina(template_lo, "/script");
1248 name2 = strjoina(template_hi, "/script2");
1249 name3 = strjoina(template_lo, "/useless");
1250 overridden = strjoina(template_lo, "/overridden");
1251 override = strjoina(template_hi, "/overridden");
1252 masked = strjoina(template_lo, "/masked");
1253 mask = strjoina(template_hi, "/masked");
e801700e
ZJS
1254
1255 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works") == 0);
1256 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2") == 0);
aac7766c
ZJS
1257 assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1258 assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0") == 0);
1259 assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1260 assert_se(symlink("/dev/null", mask) == 0);
8852362b
RC
1261 assert_se(chmod(name, 0755) == 0);
1262 assert_se(chmod(name2, 0755) == 0);
aac7766c
ZJS
1263 assert_se(chmod(overridden, 0755) == 0);
1264 assert_se(chmod(override, 0755) == 0);
1265 assert_se(chmod(masked, 0755) == 0);
8852362b
RC
1266 assert_se(touch(name3) >= 0);
1267
e801700e 1268 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
aac7766c 1269
0c0cdb06 1270 assert_se(chdir(template_lo) == 0);
e801700e 1271 assert_se(access("it_works", F_OK) >= 0);
aac7766c
ZJS
1272 assert_se(access("failed", F_OK) < 0);
1273
0c0cdb06 1274 assert_se(chdir(template_hi) == 0);
e801700e 1275 assert_se(access("it_works2", F_OK) >= 0);
aac7766c 1276 assert_se(access("failed", F_OK) < 0);
8852362b 1277
c6878637
LP
1278 (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
1279 (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
8852362b
RC
1280}
1281
7629889c
LP
1282static void test_unquote_first_word(void) {
1283 const char *p, *original;
1284 char *t;
1285
1286 p = original = "foobar waldo";
4034a06d 1287 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1288 assert_se(streq(t, "foobar"));
1289 free(t);
1290 assert_se(p == original + 7);
1291
4034a06d 1292 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1293 assert_se(streq(t, "waldo"));
1294 free(t);
1295 assert_se(p == original + 12);
1296
4034a06d 1297 assert_se(unquote_first_word(&p, &t, 0) == 0);
7629889c
LP
1298 assert_se(!t);
1299 assert_se(p == original + 12);
1300
1301 p = original = "\"foobar\" \'waldo\'";
4034a06d 1302 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1303 assert_se(streq(t, "foobar"));
1304 free(t);
1305 assert_se(p == original + 9);
1306
4034a06d 1307 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1308 assert_se(streq(t, "waldo"));
1309 free(t);
1310 assert_se(p == original + 16);
1311
4034a06d 1312 assert_se(unquote_first_word(&p, &t, 0) == 0);
7629889c
LP
1313 assert_se(!t);
1314 assert_se(p == original + 16);
1315
1316 p = original = "\"";
4034a06d 1317 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
7629889c
LP
1318 assert_se(p == original + 1);
1319
1320 p = original = "\'";
4034a06d 1321 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
7629889c
LP
1322 assert_se(p == original + 1);
1323
f32d2db1 1324 p = original = "\'fooo";
4034a06d 1325 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
f32d2db1
LP
1326 assert_se(p == original + 5);
1327
1328 p = original = "\'fooo";
4034a06d 1329 assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
f32d2db1 1330 assert_se(streq(t, "fooo"));
e1ba963f 1331 free(t);
f32d2db1
LP
1332 assert_se(p == original + 5);
1333
7629889c 1334 p = original = "yay\'foo\'bar";
4034a06d 1335 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1336 assert_se(streq(t, "yayfoobar"));
1337 free(t);
1338 assert_se(p == original + 11);
1339
1340 p = original = " foobar ";
4034a06d 1341 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1342 assert_se(streq(t, "foobar"));
1343 free(t);
1344 assert_se(p == original + 12);
4034a06d
LP
1345
1346 p = original = " foo\\ba\\x6ar ";
1347 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1348 assert_se(streq(t, "foo\ba\x6ar"));
1349 free(t);
1350 assert_se(p == original + 13);
1351
1352 p = original = " foo\\ba\\x6ar ";
1353 assert_se(unquote_first_word(&p, &t, 0) > 0);
1354 assert_se(streq(t, "foobax6ar"));
1355 free(t);
1356 assert_se(p == original + 13);
7629889c
LP
1357}
1358
1359static void test_unquote_many_words(void) {
1360 const char *p, *original;
1361 char *a, *b, *c;
1362
1363 p = original = "foobar waldi piep";
4034a06d 1364 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 3);
7629889c
LP
1365 assert_se(p == original + 17);
1366 assert_se(streq_ptr(a, "foobar"));
1367 assert_se(streq_ptr(b, "waldi"));
1368 assert_se(streq_ptr(c, "piep"));
1369 free(a);
1370 free(b);
1371 free(c);
1372
1373 p = original = "'foobar' wa\"ld\"i ";
4034a06d 1374 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 2);
7629889c
LP
1375 assert_se(p == original + 19);
1376 assert_se(streq_ptr(a, "foobar"));
1377 assert_se(streq_ptr(b, "waldi"));
1378 assert_se(streq_ptr(c, NULL));
1379 free(a);
1380 free(b);
1381
1382 p = original = "";
4034a06d 1383 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
7629889c
LP
1384 assert_se(p == original);
1385 assert_se(streq_ptr(a, NULL));
1386 assert_se(streq_ptr(b, NULL));
1387 assert_se(streq_ptr(c, NULL));
1388
1389 p = original = " ";
4034a06d 1390 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
7629889c
LP
1391 assert_se(p == original+2);
1392 assert_se(streq_ptr(a, NULL));
1393 assert_se(streq_ptr(b, NULL));
1394 assert_se(streq_ptr(c, NULL));
1395
1396 p = original = "foobar";
4034a06d 1397 assert_se(unquote_many_words(&p, 0, NULL) == 0);
7629889c
LP
1398 assert_se(p == original);
1399
1400 p = original = "foobar waldi";
4034a06d 1401 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
7629889c
LP
1402 assert_se(p == original+7);
1403 assert_se(streq_ptr(a, "foobar"));
eee84633 1404 free(a);
7629889c
LP
1405
1406 p = original = " foobar ";
4034a06d 1407 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
7629889c
LP
1408 assert_se(p == original+15);
1409 assert_se(streq_ptr(a, "foobar"));
eee84633 1410 free(a);
7629889c
LP
1411}
1412
f32d2db1
LP
1413static int parse_item(const char *key, const char *value) {
1414 assert_se(key);
1415
1416 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1417 return 0;
1418}
1419
1420static void test_parse_proc_cmdline(void) {
1421 assert_se(parse_proc_cmdline(parse_item) >= 0);
1422}
1423
ee05e779
ZJS
1424static void test_raw_clone(void) {
1425 pid_t parent, pid, pid2;
1426
1427 parent = getpid();
1428 log_info("before clone: getpid()→"PID_FMT, parent);
1429 assert_se(raw_getpid() == parent);
1430
1431 pid = raw_clone(0, NULL);
e50221bf 1432 assert_se(pid >= 0);
ee05e779
ZJS
1433
1434 pid2 = raw_getpid();
1435 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1436 pid, getpid(), pid2);
0289a5bc 1437 if (pid == 0) {
e50221bf 1438 assert_se(pid2 != parent);
0289a5bc
FB
1439 _exit(EXIT_SUCCESS);
1440 } else {
1441 int status;
1442
e50221bf 1443 assert_se(pid2 == parent);
0289a5bc
FB
1444 waitpid(pid, &status, __WCLONE);
1445 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1446 }
ee05e779
ZJS
1447}
1448
f7ad54a3
LP
1449static void test_same_fd(void) {
1450 _cleanup_close_pair_ int p[2] = { -1, -1 };
1451 _cleanup_close_ int a = -1, b = -1, c = -1;
1452
1453 assert_se(pipe2(p, O_CLOEXEC) >= 0);
1454 assert_se((a = dup(p[0])) >= 0);
1455 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1456 assert_se((c = dup(a)) >= 0);
1457
1458 assert_se(same_fd(p[0], p[0]) > 0);
1459 assert_se(same_fd(p[1], p[1]) > 0);
1460 assert_se(same_fd(a, a) > 0);
1461 assert_se(same_fd(b, b) > 0);
1462
1463 assert_se(same_fd(a, p[0]) > 0);
1464 assert_se(same_fd(p[0], a) > 0);
1465 assert_se(same_fd(c, p[0]) > 0);
1466 assert_se(same_fd(p[0], c) > 0);
1467 assert_se(same_fd(a, c) > 0);
1468 assert_se(same_fd(c, a) > 0);
1469
1470 assert_se(same_fd(p[0], p[1]) == 0);
1471 assert_se(same_fd(p[1], p[0]) == 0);
1472 assert_se(same_fd(p[0], b) == 0);
1473 assert_se(same_fd(b, p[0]) == 0);
1474 assert_se(same_fd(p[1], a) == 0);
1475 assert_se(same_fd(a, p[1]) == 0);
1476 assert_se(same_fd(p[1], b) == 0);
1477 assert_se(same_fd(b, p[1]) == 0);
1478
1479 assert_se(same_fd(a, b) == 0);
1480 assert_se(same_fd(b, a) == 0);
1481}
1482
8cb4ab00
LP
1483static void test_uid_ptr(void) {
1484
1485 assert_se(UID_TO_PTR(0) != NULL);
1486 assert_se(UID_TO_PTR(1000) != NULL);
1487
1488 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1489 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1490}
1491
ff6a7460
LP
1492static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
1493 char check[n];
1494
1495 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1496 assert_se(ftruncate(fd, 0) >= 0);
1497 assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
1498
1499 assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
1500 assert_se(ftruncate(fd, n) >= 0);
1501
1502 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1503 assert_se(read(fd, check, n) == (ssize_t) n);
1504
1505 assert_se(memcmp(buffer, check, n) == 0);
1506}
1507
1508static void test_sparse_write(void) {
1509 const char test_a[] = "test";
1510 const char test_b[] = "\0\0\0\0test\0\0\0\0";
1511 const char test_c[] = "\0\0test\0\0\0\0";
1512 const char test_d[] = "\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0\0\0\0";
1513 const char test_e[] = "test\0\0\0\0test";
1514 _cleanup_close_ int fd = -1;
1515 char fn[] = "/tmp/sparseXXXXXX";
1516
1517 fd = mkostemp(fn, O_CLOEXEC);
1518 assert_se(fd >= 0);
1519 unlink(fn);
1520
1521 test_sparse_write_one(fd, test_a, sizeof(test_a));
1522 test_sparse_write_one(fd, test_b, sizeof(test_b));
1523 test_sparse_write_one(fd, test_c, sizeof(test_c));
1524 test_sparse_write_one(fd, test_d, sizeof(test_d));
1525 test_sparse_write_one(fd, test_e, sizeof(test_e));
1526}
1527
539ad707 1528int main(int argc, char *argv[]) {
9480794b
ZJS
1529 log_parse_environment();
1530 log_open();
1531
539ad707 1532 test_streq_ptr();
625e870b 1533 test_align_power2();
7242d742 1534 test_max();
fb835651 1535 test_container_of();
95d78c7e 1536 test_alloca();
180a60bc 1537 test_div_round_up();
539ad707 1538 test_first_word();
dbd73f9e 1539 test_close_many();
8354c34e 1540 test_parse_boolean();
8d99e5f5
TA
1541 test_parse_pid();
1542 test_parse_uid();
1543 test_safe_atolli();
1544 test_safe_atod();
dbd73f9e 1545 test_strappend();
1ef04f0b
TA
1546 test_strstrip();
1547 test_delete_chars();
1548 test_in_charset();
44f4c86c
DB
1549 test_hexchar();
1550 test_unhexchar();
1551 test_octchar();
1552 test_unoctchar();
1553 test_decchar();
1554 test_undecchar();
b4ecc959
TA
1555 test_cescape();
1556 test_cunescape();
1ef04f0b 1557 test_foreach_word();
539ad707 1558 test_foreach_word_quoted();
1ef04f0b 1559 test_default_term_for_tty();
0d585d82 1560 test_memdup_multiply();
aa3c5cf8 1561 test_hostname_is_valid();
144e51ec 1562 test_u64log2();
49aa47c7 1563 test_get_process_comm();
2a371001 1564 test_protect_errno();
5556b5fe 1565 test_parse_size();
9480794b 1566 test_config_parse_iec_off();
b4ecc959
TA
1567 test_strextend();
1568 test_strrep();
d4ac85c6 1569 test_split_pair();
22f5f628 1570 test_fstab_node_to_udev_node();
893fa014 1571 test_get_files_in_directory();
cabb7806 1572 test_in_set();
87b02843 1573 test_writing_tmpfile();
29bfbcd6 1574 test_hexdump();
8fe90522 1575 test_log2i();
c4a7b2c5 1576 test_foreach_string();
ae6c3cc0 1577 test_filename_is_valid();
1cb1767a 1578 test_string_has_cc();
927be00c
RC
1579 test_ascii_strlower();
1580 test_files_same();
1581 test_is_valid_documentation_url();
1582 test_file_in_same_dir();
1583 test_endswith();
1584 test_close_nointr();
1585 test_unlink_noerrno();
1586 test_readlink_and_make_absolute();
1587 test_read_one_char();
1588 test_ignore_signals();
1589 test_strshorten();
63c372cb 1590 test_strjoina();
8852362b
RC
1591 test_is_symlink();
1592 test_pid_is_unwaited();
1593 test_pid_is_alive();
1594 test_search_and_fopen();
1595 test_search_and_fopen_nulstr();
1596 test_glob_exists();
1597 test_execute_directory();
7629889c
LP
1598 test_unquote_first_word();
1599 test_unquote_many_words();
f32d2db1 1600 test_parse_proc_cmdline();
ee05e779 1601 test_raw_clone();
f7ad54a3 1602 test_same_fd();
8cb4ab00 1603 test_uid_ptr();
ff6a7460 1604 test_sparse_write();
539ad707
TA
1605
1606 return 0;
1607}