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