]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-util.c
build-sys: disable gc-sections for distcheck
[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"
958b66ea 41#include "hostname-util.h"
24882e06 42#include "signal-util.h"
539ad707
TA
43
44static void test_streq_ptr(void) {
8354c34e
TA
45 assert_se(streq_ptr(NULL, NULL));
46 assert_se(!streq_ptr("abc", "cdef"));
539ad707
TA
47}
48
625e870b
DH
49static void test_align_power2(void) {
50 unsigned long i, p2;
51
52 assert_se(ALIGN_POWER2(0) == 0);
53 assert_se(ALIGN_POWER2(1) == 1);
54 assert_se(ALIGN_POWER2(2) == 2);
55 assert_se(ALIGN_POWER2(3) == 4);
56 assert_se(ALIGN_POWER2(12) == 16);
57
58 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
59 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
60 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
61 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
62 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
63
64 for (i = 1; i < 131071; ++i) {
65 for (p2 = 1; p2 < i; p2 <<= 1)
66 /* empty */ ;
67
68 assert_se(ALIGN_POWER2(i) == p2);
69 }
70
71 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
72 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
73 /* empty */ ;
74
75 assert_se(ALIGN_POWER2(i) == p2);
76 }
77}
78
7242d742
DH
79static void test_max(void) {
80 static const struct {
81 int a;
82 int b[CONST_MAX(10, 100)];
83 } val1 = {
84 .a = CONST_MAX(10, 100),
85 };
86 int d = 0;
87
88 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
89
90 /* CONST_MAX returns (void) instead of a value if the passed arguments
91 * are not of the same type or not constant expressions. */
92 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
7242d742
DH
93 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
94
95 assert_se(val1.a == 100);
96 assert_se(MAX(++d, 0) == 1);
97 assert_se(d == 1);
40a1eebd
DH
98
99 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
100 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
101 assert_cc(MAXSIZE(char, long) == sizeof(long));
667a0377
DH
102
103 assert_se(MAX(-5, 5) == 5);
104 assert_se(MAX(5, 5) == 5);
105 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
106 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
107 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
108 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
109 assert_se(LESS_BY(8, 4) == 4);
110 assert_se(LESS_BY(8, 8) == 0);
111 assert_se(LESS_BY(4, 8) == 0);
112 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
113 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
114 assert_se(CLAMP(-5, 0, 1) == 0);
115 assert_se(CLAMP(5, 0, 1) == 1);
116 assert_se(CLAMP(5, -10, 1) == 1);
117 assert_se(CLAMP(5, -10, 10) == 5);
118 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
7242d742
DH
119}
120
fb835651
DH
121static void test_container_of(void) {
122 struct mytype {
123 uint8_t pad1[3];
124 uint64_t v1;
125 uint8_t pad2[2];
126 uint32_t v2;
127 } _packed_ myval = { };
128
129 assert_cc(sizeof(myval) == 17);
130 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
131 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
132 assert_se(container_of(&container_of(&myval.v2,
133 struct mytype,
134 v2)->v1,
135 struct mytype,
136 v1) == &myval);
137}
138
95d78c7e
DH
139static void test_alloca(void) {
140 static const uint8_t zero[997] = { };
141 char *t;
142
143 t = alloca_align(17, 512);
144 assert_se(!((uintptr_t)t & 0xff));
145 memzero(t, 17);
146
147 t = alloca0_align(997, 1024);
148 assert_se(!((uintptr_t)t & 0x1ff));
149 assert_se(!memcmp(t, zero, 997));
150}
151
180a60bc
DH
152static void test_div_round_up(void) {
153 int div;
154
155 /* basic tests */
156 assert_se(DIV_ROUND_UP(0, 8) == 0);
157 assert_se(DIV_ROUND_UP(1, 8) == 1);
158 assert_se(DIV_ROUND_UP(8, 8) == 1);
159 assert_se(DIV_ROUND_UP(12, 8) == 2);
160 assert_se(DIV_ROUND_UP(16, 8) == 2);
161
162 /* test multiple evaluation */
163 div = 0;
164 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
165 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
166 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
167 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
168
169 /* overflow test with exact division */
170 assert_se(sizeof(0U) == 4);
171 assert_se(0xfffffffaU % 10U == 0U);
172 assert_se(0xfffffffaU / 10U == 429496729U);
173 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
174 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
175 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
176
177 /* overflow test with rounded division */
178 assert_se(0xfffffffdU % 10U == 3U);
179 assert_se(0xfffffffdU / 10U == 429496729U);
180 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
181 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
182 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
183}
184
539ad707 185static void test_first_word(void) {
8354c34e
TA
186 assert_se(first_word("Hello", ""));
187 assert_se(first_word("Hello", "Hello"));
188 assert_se(first_word("Hello world", "Hello"));
189 assert_se(first_word("Hello\tworld", "Hello"));
190 assert_se(first_word("Hello\nworld", "Hello"));
191 assert_se(first_word("Hello\rworld", "Hello"));
192 assert_se(first_word("Hello ", "Hello"));
193
194 assert_se(!first_word("Hello", "Hellooo"));
195 assert_se(!first_word("Hello", "xxxxx"));
196 assert_se(!first_word("Hellooo", "Hello"));
197}
198
dbd73f9e
TA
199static void test_close_many(void) {
200 int fds[3];
201 char name0[] = "/tmp/test-close-many.XXXXXX";
202 char name1[] = "/tmp/test-close-many.XXXXXX";
203 char name2[] = "/tmp/test-close-many.XXXXXX";
204
2d5bdf5b
LP
205 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
206 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
207 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
dbd73f9e
TA
208
209 close_many(fds, 2);
210
211 assert_se(fcntl(fds[0], F_GETFD) == -1);
212 assert_se(fcntl(fds[1], F_GETFD) == -1);
213 assert_se(fcntl(fds[2], F_GETFD) >= 0);
214
03e334a1 215 safe_close(fds[2]);
dbd73f9e
TA
216
217 unlink(name0);
218 unlink(name1);
219 unlink(name2);
220}
221
8354c34e
TA
222static void test_parse_boolean(void) {
223 assert_se(parse_boolean("1") == 1);
224 assert_se(parse_boolean("y") == 1);
225 assert_se(parse_boolean("Y") == 1);
226 assert_se(parse_boolean("yes") == 1);
227 assert_se(parse_boolean("YES") == 1);
228 assert_se(parse_boolean("true") == 1);
229 assert_se(parse_boolean("TRUE") == 1);
230 assert_se(parse_boolean("on") == 1);
231 assert_se(parse_boolean("ON") == 1);
232
233 assert_se(parse_boolean("0") == 0);
234 assert_se(parse_boolean("n") == 0);
235 assert_se(parse_boolean("N") == 0);
236 assert_se(parse_boolean("no") == 0);
237 assert_se(parse_boolean("NO") == 0);
238 assert_se(parse_boolean("false") == 0);
239 assert_se(parse_boolean("FALSE") == 0);
240 assert_se(parse_boolean("off") == 0);
241 assert_se(parse_boolean("OFF") == 0);
242
243 assert_se(parse_boolean("garbage") < 0);
244 assert_se(parse_boolean("") < 0);
0f625d0b 245 assert_se(parse_boolean("full") < 0);
539ad707
TA
246}
247
8d99e5f5
TA
248static void test_parse_pid(void) {
249 int r;
250 pid_t pid;
251
252 r = parse_pid("100", &pid);
253 assert_se(r == 0);
254 assert_se(pid == 100);
255
256 r = parse_pid("0x7FFFFFFF", &pid);
257 assert_se(r == 0);
258 assert_se(pid == 2147483647);
259
260 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
261 r = parse_pid("0", &pid);
262 assert_se(r == -ERANGE);
263 assert_se(pid == 65);
264
265 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
266 r = parse_pid("-100", &pid);
267 assert_se(r == -ERANGE);
268 assert_se(pid == 65);
269
270 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
271 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
bdf7026e 272 assert_se(r == -ERANGE);
8d99e5f5
TA
273 assert_se(pid == 65);
274}
275
276static void test_parse_uid(void) {
277 int r;
278 uid_t uid;
279
280 r = parse_uid("100", &uid);
281 assert_se(r == 0);
282 assert_se(uid == 100);
283}
284
285static void test_safe_atolli(void) {
286 int r;
287 long long l;
288
289 r = safe_atolli("12345", &l);
290 assert_se(r == 0);
291 assert_se(l == 12345);
292
293 r = safe_atolli("junk", &l);
294 assert_se(r == -EINVAL);
295}
296
297static void test_safe_atod(void) {
298 int r;
299 double d;
d6dd604b
LP
300 char *e;
301
302 r = safe_atod("junk", &d);
303 assert_se(r == -EINVAL);
8d99e5f5
TA
304
305 r = safe_atod("0.2244", &d);
306 assert_se(r == 0);
8e211000 307 assert_se(fabs(d - 0.2244) < 0.000001);
8d99e5f5 308
d6dd604b 309 r = safe_atod("0,5", &d);
8d99e5f5 310 assert_se(r == -EINVAL);
d6dd604b
LP
311
312 errno = 0;
313 strtod("0,5", &e);
314 assert_se(*e == ',');
315
316 /* Check if this really is locale independent */
926446f4 317 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
d6dd604b 318
926446f4
DH
319 r = safe_atod("0.2244", &d);
320 assert_se(r == 0);
321 assert_se(fabs(d - 0.2244) < 0.000001);
d6dd604b 322
926446f4
DH
323 r = safe_atod("0,5", &d);
324 assert_se(r == -EINVAL);
d6dd604b 325
926446f4
DH
326 errno = 0;
327 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
328 }
d6dd604b
LP
329
330 /* And check again, reset */
926446f4 331 assert_se(setlocale(LC_NUMERIC, "C"));
d6dd604b
LP
332
333 r = safe_atod("0.2244", &d);
334 assert_se(r == 0);
8e211000 335 assert_se(fabs(d - 0.2244) < 0.000001);
d6dd604b
LP
336
337 r = safe_atod("0,5", &d);
338 assert_se(r == -EINVAL);
339
340 errno = 0;
341 strtod("0,5", &e);
342 assert_se(*e == ',');
8d99e5f5
TA
343}
344
dbd73f9e 345static void test_strappend(void) {
998b087f 346 _cleanup_free_ char *t1, *t2, *t3, *t4;
dbd73f9e 347
998b087f
TA
348 t1 = strappend(NULL, NULL);
349 assert_se(streq(t1, ""));
dbd73f9e 350
998b087f
TA
351 t2 = strappend(NULL, "suf");
352 assert_se(streq(t2, "suf"));
dbd73f9e 353
998b087f
TA
354 t3 = strappend("pre", NULL);
355 assert_se(streq(t3, "pre"));
dbd73f9e 356
998b087f
TA
357 t4 = strappend("pre", "suf");
358 assert_se(streq(t4, "presuf"));
dbd73f9e
TA
359}
360
1ef04f0b 361static void test_strstrip(void) {
998b087f
TA
362 char *r;
363 char input[] = " hello, waldo. ";
1ef04f0b 364
998b087f
TA
365 r = strstrip(input);
366 assert_se(streq(r, "hello, waldo."));
1ef04f0b
TA
367}
368
369static void test_delete_chars(void) {
998b087f
TA
370 char *r;
371 char input[] = " hello, waldo. abc";
1ef04f0b 372
998b087f
TA
373 r = delete_chars(input, WHITESPACE);
374 assert_se(streq(r, "hello,waldo.abc"));
1ef04f0b
TA
375}
376
377static void test_in_charset(void) {
998b087f
TA
378 assert_se(in_charset("dddaaabbbcccc", "abcd"));
379 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
1ef04f0b
TA
380}
381
44f4c86c
DB
382static void test_hexchar(void) {
383 assert_se(hexchar(0xa) == 'a');
384 assert_se(hexchar(0x0) == '0');
385}
386
387static void test_unhexchar(void) {
388 assert_se(unhexchar('a') == 0xA);
389 assert_se(unhexchar('A') == 0xA);
390 assert_se(unhexchar('0') == 0x0);
391}
392
393static void test_octchar(void) {
394 assert_se(octchar(00) == '0');
395 assert_se(octchar(07) == '7');
396}
397
398static void test_unoctchar(void) {
399 assert_se(unoctchar('0') == 00);
400 assert_se(unoctchar('7') == 07);
401}
402
403static void test_decchar(void) {
404 assert_se(decchar(0) == '0');
405 assert_se(decchar(9) == '9');
406}
407
408static void test_undecchar(void) {
409 assert_se(undecchar('0') == 0);
410 assert_se(undecchar('9') == 9);
411}
412
b4ecc959
TA
413static void test_cescape(void) {
414 _cleanup_free_ char *escaped;
e0a33e7b
LP
415
416 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
927be00c 417 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
b4ecc959
TA
418}
419
420static void test_cunescape(void) {
421 _cleanup_free_ char *unescaped;
e0a33e7b 422
527b7a42
LP
423 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped) < 0);
424 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX, &unescaped) >= 0);
f3ee6297 425 assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
527b7a42
LP
426 free(unescaped);
427 unescaped = NULL;
7f769619
ZJS
428
429 /* incomplete sequences */
527b7a42
LP
430 assert_se(cunescape("\\x0", 0, &unescaped) < 0);
431 assert_se(cunescape("\\x0", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 432 assert_se(streq_ptr(unescaped, "\\x0"));
527b7a42
LP
433 free(unescaped);
434 unescaped = NULL;
7f769619 435
527b7a42
LP
436 assert_se(cunescape("\\x", 0, &unescaped) < 0);
437 assert_se(cunescape("\\x", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 438 assert_se(streq_ptr(unescaped, "\\x"));
527b7a42
LP
439 free(unescaped);
440 unescaped = NULL;
7f769619 441
527b7a42
LP
442 assert_se(cunescape("\\", 0, &unescaped) < 0);
443 assert_se(cunescape("\\", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 444 assert_se(streq_ptr(unescaped, "\\"));
527b7a42
LP
445 free(unescaped);
446 unescaped = NULL;
7f769619 447
527b7a42
LP
448 assert_se(cunescape("\\11", 0, &unescaped) < 0);
449 assert_se(cunescape("\\11", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 450 assert_se(streq_ptr(unescaped, "\\11"));
527b7a42
LP
451 free(unescaped);
452 unescaped = NULL;
7f769619 453
527b7a42
LP
454 assert_se(cunescape("\\1", 0, &unescaped) < 0);
455 assert_se(cunescape("\\1", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 456 assert_se(streq_ptr(unescaped, "\\1"));
f3ee6297
LP
457 free(unescaped);
458 unescaped = NULL;
459
460 assert_se(cunescape("\\u0000", 0, &unescaped) < 0);
461 assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX, &unescaped) >= 0);
462 assert_se(streq_ptr(unescaped, "ßßΠA"));
b4ecc959
TA
463}
464
1ef04f0b 465static void test_foreach_word(void) {
a2a5291b 466 const char *word, *state;
1ef04f0b
TA
467 size_t l;
468 int i = 0;
469 const char test[] = "test abc d\te f ";
470 const char * const expected[] = {
471 "test",
472 "abc",
473 "d",
474 "e",
475 "f",
476 "",
477 NULL
478 };
479
a2a5291b
ZJS
480 FOREACH_WORD(word, l, test, state)
481 assert_se(strneq(expected[i++], word, l));
1ef04f0b
TA
482}
483
ba774317 484static void check(const char *test, char** expected, bool trailing) {
a2a5291b 485 const char *word, *state;
539ad707 486 size_t l;
1ef04f0b 487 int i = 0;
1ef04f0b 488
ba774317 489 printf("<<<%s>>>\n", test);
a2a5291b 490 FOREACH_WORD_QUOTED(word, l, test, state) {
1ef04f0b 491 _cleanup_free_ char *t = NULL;
539ad707 492
a2a5291b
ZJS
493 assert_se(t = strndup(word, l));
494 assert_se(strneq(expected[i++], word, l));
539ad707 495 printf("<%s>\n", t);
539ad707 496 }
ba774317 497 printf("<<<%s>>>\n", state);
e50221bf 498 assert_se(expected[i] == NULL);
ba774317
ZJS
499 assert_se(isempty(state) == !trailing);
500}
501
502static void test_foreach_word_quoted(void) {
503 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
504 STRV_MAKE("test",
505 "a",
506 "b",
507 "c",
508 "d",
509 "e",
510 "",
511 "",
512 "hhh",
513 "",
514 "",
515 "a b c"),
516 false);
517
518 check("test \"xxx",
519 STRV_MAKE("test"),
520 true);
521
522 check("test\\",
523 STRV_MAKE_EMPTY,
524 true);
539ad707
TA
525}
526
0d585d82
TA
527static void test_memdup_multiply(void) {
528 int org[] = {1, 2, 3};
529 int *dup;
530
531 dup = (int*)memdup_multiply(org, sizeof(int), 3);
532
533 assert_se(dup);
534 assert_se(dup[0] == 1);
535 assert_se(dup[1] == 2);
536 assert_se(dup[2] == 3);
537 free(dup);
538}
539
aa3c5cf8 540static void test_hostname_is_valid(void) {
bdf7026e
TA
541 assert_se(hostname_is_valid("foobar"));
542 assert_se(hostname_is_valid("foobar.com"));
543 assert_se(!hostname_is_valid("fööbar"));
544 assert_se(!hostname_is_valid(""));
545 assert_se(!hostname_is_valid("."));
546 assert_se(!hostname_is_valid(".."));
547 assert_se(!hostname_is_valid("foobar."));
548 assert_se(!hostname_is_valid(".foobar"));
549 assert_se(!hostname_is_valid("foo..bar"));
550 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
aa3c5cf8
LP
551}
552
139e5336
MP
553static void test_read_hostname_config(void) {
554 char path[] = "/tmp/hostname.XXXXXX";
555 char *hostname;
556 int fd;
557
558 fd = mkostemp_safe(path, O_RDWR|O_CLOEXEC);
559 assert(fd > 0);
560 close(fd);
561
562 /* simple hostname */
563 write_string_file(path, "foo");
564 assert_se(read_hostname_config(path, &hostname) == 0);
565 assert_se(streq(hostname, "foo"));
566 free(hostname);
e136009d 567 hostname = NULL;
139e5336
MP
568
569 /* with comment */
570 write_string_file(path, "# comment\nfoo");
571 assert_se(read_hostname_config(path, &hostname) == 0);
e136009d 572 assert_se(hostname);
139e5336
MP
573 assert_se(streq(hostname, "foo"));
574 free(hostname);
e136009d 575 hostname = NULL;
139e5336
MP
576
577 /* with comment and extra whitespace */
578 write_string_file(path, "# comment\n\n foo ");
579 assert_se(read_hostname_config(path, &hostname) == 0);
e136009d 580 assert_se(hostname);
139e5336
MP
581 assert_se(streq(hostname, "foo"));
582 free(hostname);
e136009d 583 hostname = NULL;
139e5336
MP
584
585 /* cleans up name */
586 write_string_file(path, "!foo/bar.com");
587 assert_se(read_hostname_config(path, &hostname) == 0);
e136009d 588 assert_se(hostname);
139e5336
MP
589 assert_se(streq(hostname, "foobar.com"));
590 free(hostname);
e136009d 591 hostname = NULL;
139e5336
MP
592
593 /* no value set */
594 hostname = (char*) 0x1234;
595 write_string_file(path, "# nothing here\n");
596 assert_se(read_hostname_config(path, &hostname) == -ENOENT);
597 assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */
598
599 /* nonexisting file */
600 assert_se(read_hostname_config("/non/existing", &hostname) == -ENOENT);
601 assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */
602
603 unlink(path);
604}
605
144e51ec 606static void test_u64log2(void) {
bdf7026e
TA
607 assert_se(u64log2(0) == 0);
608 assert_se(u64log2(8) == 3);
609 assert_se(u64log2(9) == 3);
610 assert_se(u64log2(15) == 3);
611 assert_se(u64log2(16) == 4);
612 assert_se(u64log2(1024*1024) == 20);
613 assert_se(u64log2(1024*1024+5) == 20);
144e51ec
CR
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
927be00c
RC
1024static void test_ignore_signals(void) {
1025 assert_se(ignore_signals(SIGINT, -1) >= 0);
1026 assert_se(kill(getpid(), SIGINT) >= 0);
1027 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1028 assert_se(kill(getpid(), SIGUSR1) >= 0);
1029 assert_se(kill(getpid(), SIGUSR2) >= 0);
1030 assert_se(kill(getpid(), SIGTERM) >= 0);
1031 assert_se(kill(getpid(), SIGPIPE) >= 0);
1032 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1033}
1034
1035static void test_strshorten(void) {
1036 char s[] = "foobar";
1037
1038 assert_se(strlen(strshorten(s, 6)) == 6);
1039 assert_se(strlen(strshorten(s, 12)) == 6);
1040 assert_se(strlen(strshorten(s, 2)) == 2);
1041 assert_se(strlen(strshorten(s, 0)) == 0);
1042}
1043
63c372cb 1044static void test_strjoina(void) {
8085f163
DR
1045 char *actual;
1046
63c372cb 1047 actual = strjoina("", "foo", "bar");
8085f163
DR
1048 assert_se(streq(actual, "foobar"));
1049
63c372cb 1050 actual = strjoina("foo", "bar", "baz");
8085f163
DR
1051 assert_se(streq(actual, "foobarbaz"));
1052
63c372cb 1053 actual = strjoina("foo", "", "bar", "baz");
8085f163 1054 assert_se(streq(actual, "foobarbaz"));
63c372cb
LP
1055
1056 actual = strjoina("foo");
1057 assert_se(streq(actual, "foo"));
1058
1059 actual = strjoina(NULL);
1060 assert_se(streq(actual, ""));
1061
1062 actual = strjoina(NULL, "foo");
1063 assert_se(streq(actual, ""));
1064
1065 actual = strjoina("foo", NULL, "bar");
1066 assert_se(streq(actual, "foo"));
8085f163
DR
1067}
1068
8852362b
RC
1069static void test_is_symlink(void) {
1070 char name[] = "/tmp/test-is_symlink.XXXXXX";
1071 char name_link[] = "/tmp/test-is_symlink.link";
1072 _cleanup_close_ int fd = -1;
1073
1074 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1075 assert_se(fd >= 0);
1076 assert_se(symlink(name, name_link) >= 0);
1077
1078 assert_se(is_symlink(name) == 0);
1079 assert_se(is_symlink(name_link) == 1);
1080 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1081
1082
1083 unlink(name);
1084 unlink(name_link);
1085}
1086
8852362b
RC
1087static void test_search_and_fopen(void) {
1088 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1089 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1090 int fd = -1;
1091 int r;
1092 FILE *f;
1093
1094 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1095 assert_se(fd >= 0);
1096 close(fd);
1097
1098 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1099 assert_se(r >= 0);
1100 fclose(f);
1101
1102 r = search_and_fopen(name, "r", NULL, dirs, &f);
1103 assert_se(r >= 0);
1104 fclose(f);
1105
1106 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1107 assert_se(r >= 0);
1108 fclose(f);
1109
1110 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1111 assert_se(r < 0);
1112 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1113 assert_se(r < 0);
1114
1115 r = unlink(name);
1116 assert_se(r == 0);
1117
1118 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1119 assert_se(r < 0);
1120}
1121
1122
1123static void test_search_and_fopen_nulstr(void) {
1124 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1125 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1126 int fd = -1;
1127 int r;
1128 FILE *f;
1129
1130 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1131 assert_se(fd >= 0);
1132 close(fd);
1133
1134 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1135 assert_se(r >= 0);
1136 fclose(f);
1137
1138 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1139 assert_se(r >= 0);
1140 fclose(f);
1141
1142 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1143 assert_se(r < 0);
1144 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1145 assert_se(r < 0);
1146
1147 r = unlink(name);
1148 assert_se(r == 0);
1149
1150 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1151 assert_se(r < 0);
1152}
1153
1154static void test_glob_exists(void) {
1155 char name[] = "/tmp/test-glob_exists.XXXXXX";
1156 int fd = -1;
1157 int r;
1158
1159 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1160 assert_se(fd >= 0);
1161 close(fd);
1162
1163 r = glob_exists("/tmp/test-glob_exists*");
1164 assert_se(r == 1);
1165
1166 r = unlink(name);
1167 assert_se(r == 0);
1168 r = glob_exists("/tmp/test-glob_exists*");
1169 assert_se(r == 0);
1170}
1171
1172static void test_execute_directory(void) {
aac7766c
ZJS
1173 char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1174 char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
76f282c6 1175 const char * dirs[] = {template_hi, template_lo, NULL};
aac7766c
ZJS
1176 const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
1177
1178 assert_se(mkdtemp(template_lo));
1179 assert_se(mkdtemp(template_hi));
1180
63c372cb
LP
1181 name = strjoina(template_lo, "/script");
1182 name2 = strjoina(template_hi, "/script2");
1183 name3 = strjoina(template_lo, "/useless");
1184 overridden = strjoina(template_lo, "/overridden");
1185 override = strjoina(template_hi, "/overridden");
1186 masked = strjoina(template_lo, "/masked");
1187 mask = strjoina(template_hi, "/masked");
e801700e
ZJS
1188
1189 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works") == 0);
1190 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2") == 0);
aac7766c
ZJS
1191 assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1192 assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0") == 0);
1193 assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1194 assert_se(symlink("/dev/null", mask) == 0);
8852362b
RC
1195 assert_se(chmod(name, 0755) == 0);
1196 assert_se(chmod(name2, 0755) == 0);
aac7766c
ZJS
1197 assert_se(chmod(overridden, 0755) == 0);
1198 assert_se(chmod(override, 0755) == 0);
1199 assert_se(chmod(masked, 0755) == 0);
8852362b
RC
1200 assert_se(touch(name3) >= 0);
1201
e801700e 1202 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
aac7766c 1203
0c0cdb06 1204 assert_se(chdir(template_lo) == 0);
e801700e 1205 assert_se(access("it_works", F_OK) >= 0);
aac7766c
ZJS
1206 assert_se(access("failed", F_OK) < 0);
1207
0c0cdb06 1208 assert_se(chdir(template_hi) == 0);
e801700e 1209 assert_se(access("it_works2", F_OK) >= 0);
aac7766c 1210 assert_se(access("failed", F_OK) < 0);
8852362b 1211
c6878637
LP
1212 (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
1213 (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
8852362b
RC
1214}
1215
7629889c
LP
1216static void test_unquote_first_word(void) {
1217 const char *p, *original;
1218 char *t;
1219
1220 p = original = "foobar waldo";
4034a06d 1221 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1222 assert_se(streq(t, "foobar"));
1223 free(t);
1224 assert_se(p == original + 7);
1225
4034a06d 1226 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1227 assert_se(streq(t, "waldo"));
1228 free(t);
1229 assert_se(p == original + 12);
1230
4034a06d 1231 assert_se(unquote_first_word(&p, &t, 0) == 0);
7629889c
LP
1232 assert_se(!t);
1233 assert_se(p == original + 12);
1234
1235 p = original = "\"foobar\" \'waldo\'";
4034a06d 1236 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1237 assert_se(streq(t, "foobar"));
1238 free(t);
1239 assert_se(p == original + 9);
1240
4034a06d 1241 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1242 assert_se(streq(t, "waldo"));
1243 free(t);
1244 assert_se(p == original + 16);
1245
4034a06d 1246 assert_se(unquote_first_word(&p, &t, 0) == 0);
7629889c
LP
1247 assert_se(!t);
1248 assert_se(p == original + 16);
1249
1250 p = original = "\"";
4034a06d 1251 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
7629889c
LP
1252 assert_se(p == original + 1);
1253
1254 p = original = "\'";
4034a06d 1255 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
7629889c
LP
1256 assert_se(p == original + 1);
1257
f32d2db1 1258 p = original = "\'fooo";
4034a06d 1259 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
f32d2db1
LP
1260 assert_se(p == original + 5);
1261
1262 p = original = "\'fooo";
4034a06d 1263 assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
f32d2db1 1264 assert_se(streq(t, "fooo"));
e1ba963f 1265 free(t);
f32d2db1
LP
1266 assert_se(p == original + 5);
1267
7629889c 1268 p = original = "yay\'foo\'bar";
4034a06d 1269 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1270 assert_se(streq(t, "yayfoobar"));
1271 free(t);
1272 assert_se(p == original + 11);
1273
1274 p = original = " foobar ";
4034a06d 1275 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1276 assert_se(streq(t, "foobar"));
1277 free(t);
1278 assert_se(p == original + 12);
4034a06d
LP
1279
1280 p = original = " foo\\ba\\x6ar ";
1281 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1282 assert_se(streq(t, "foo\ba\x6ar"));
1283 free(t);
1284 assert_se(p == original + 13);
1285
1286 p = original = " foo\\ba\\x6ar ";
1287 assert_se(unquote_first_word(&p, &t, 0) > 0);
1288 assert_se(streq(t, "foobax6ar"));
1289 free(t);
1290 assert_se(p == original + 13);
8ebac1f9
LP
1291
1292 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
1293 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1294 assert_se(streq(t, "föo"));
1295 free(t);
1296 assert_se(p == original + 13);
1297
1298 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1299 assert_se(streq(t, "pi\360\237\222\251le"));
1300 free(t);
1301 assert_se(p == original + 32);
7629889c
LP
1302}
1303
1304static void test_unquote_many_words(void) {
1305 const char *p, *original;
1306 char *a, *b, *c;
1307
1308 p = original = "foobar waldi piep";
4034a06d 1309 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 3);
7629889c
LP
1310 assert_se(p == original + 17);
1311 assert_se(streq_ptr(a, "foobar"));
1312 assert_se(streq_ptr(b, "waldi"));
1313 assert_se(streq_ptr(c, "piep"));
1314 free(a);
1315 free(b);
1316 free(c);
1317
1318 p = original = "'foobar' wa\"ld\"i ";
4034a06d 1319 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 2);
7629889c
LP
1320 assert_se(p == original + 19);
1321 assert_se(streq_ptr(a, "foobar"));
1322 assert_se(streq_ptr(b, "waldi"));
1323 assert_se(streq_ptr(c, NULL));
1324 free(a);
1325 free(b);
1326
1327 p = original = "";
4034a06d 1328 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
7629889c
LP
1329 assert_se(p == original);
1330 assert_se(streq_ptr(a, NULL));
1331 assert_se(streq_ptr(b, NULL));
1332 assert_se(streq_ptr(c, NULL));
1333
1334 p = original = " ";
4034a06d 1335 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
7629889c
LP
1336 assert_se(p == original+2);
1337 assert_se(streq_ptr(a, NULL));
1338 assert_se(streq_ptr(b, NULL));
1339 assert_se(streq_ptr(c, NULL));
1340
1341 p = original = "foobar";
4034a06d 1342 assert_se(unquote_many_words(&p, 0, NULL) == 0);
7629889c
LP
1343 assert_se(p == original);
1344
1345 p = original = "foobar waldi";
4034a06d 1346 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
7629889c
LP
1347 assert_se(p == original+7);
1348 assert_se(streq_ptr(a, "foobar"));
eee84633 1349 free(a);
7629889c
LP
1350
1351 p = original = " foobar ";
4034a06d 1352 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
7629889c
LP
1353 assert_se(p == original+15);
1354 assert_se(streq_ptr(a, "foobar"));
eee84633 1355 free(a);
7629889c
LP
1356}
1357
f32d2db1
LP
1358static int parse_item(const char *key, const char *value) {
1359 assert_se(key);
1360
1361 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1362 return 0;
1363}
1364
1365static void test_parse_proc_cmdline(void) {
1366 assert_se(parse_proc_cmdline(parse_item) >= 0);
1367}
1368
ee05e779
ZJS
1369static void test_raw_clone(void) {
1370 pid_t parent, pid, pid2;
1371
1372 parent = getpid();
1373 log_info("before clone: getpid()→"PID_FMT, parent);
1374 assert_se(raw_getpid() == parent);
1375
1376 pid = raw_clone(0, NULL);
e50221bf 1377 assert_se(pid >= 0);
ee05e779
ZJS
1378
1379 pid2 = raw_getpid();
1380 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1381 pid, getpid(), pid2);
0289a5bc 1382 if (pid == 0) {
e50221bf 1383 assert_se(pid2 != parent);
0289a5bc
FB
1384 _exit(EXIT_SUCCESS);
1385 } else {
1386 int status;
1387
e50221bf 1388 assert_se(pid2 == parent);
0289a5bc
FB
1389 waitpid(pid, &status, __WCLONE);
1390 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1391 }
ee05e779
ZJS
1392}
1393
f7ad54a3
LP
1394static void test_same_fd(void) {
1395 _cleanup_close_pair_ int p[2] = { -1, -1 };
1396 _cleanup_close_ int a = -1, b = -1, c = -1;
1397
1398 assert_se(pipe2(p, O_CLOEXEC) >= 0);
1399 assert_se((a = dup(p[0])) >= 0);
1400 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1401 assert_se((c = dup(a)) >= 0);
1402
1403 assert_se(same_fd(p[0], p[0]) > 0);
1404 assert_se(same_fd(p[1], p[1]) > 0);
1405 assert_se(same_fd(a, a) > 0);
1406 assert_se(same_fd(b, b) > 0);
1407
1408 assert_se(same_fd(a, p[0]) > 0);
1409 assert_se(same_fd(p[0], a) > 0);
1410 assert_se(same_fd(c, p[0]) > 0);
1411 assert_se(same_fd(p[0], c) > 0);
1412 assert_se(same_fd(a, c) > 0);
1413 assert_se(same_fd(c, a) > 0);
1414
1415 assert_se(same_fd(p[0], p[1]) == 0);
1416 assert_se(same_fd(p[1], p[0]) == 0);
1417 assert_se(same_fd(p[0], b) == 0);
1418 assert_se(same_fd(b, p[0]) == 0);
1419 assert_se(same_fd(p[1], a) == 0);
1420 assert_se(same_fd(a, p[1]) == 0);
1421 assert_se(same_fd(p[1], b) == 0);
1422 assert_se(same_fd(b, p[1]) == 0);
1423
1424 assert_se(same_fd(a, b) == 0);
1425 assert_se(same_fd(b, a) == 0);
1426}
1427
8cb4ab00
LP
1428static void test_uid_ptr(void) {
1429
1430 assert_se(UID_TO_PTR(0) != NULL);
1431 assert_se(UID_TO_PTR(1000) != NULL);
1432
1433 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1434 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1435}
1436
ff6a7460
LP
1437static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
1438 char check[n];
1439
1440 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1441 assert_se(ftruncate(fd, 0) >= 0);
1442 assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
1443
1444 assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
1445 assert_se(ftruncate(fd, n) >= 0);
1446
1447 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1448 assert_se(read(fd, check, n) == (ssize_t) n);
1449
1450 assert_se(memcmp(buffer, check, n) == 0);
1451}
1452
1453static void test_sparse_write(void) {
1454 const char test_a[] = "test";
1455 const char test_b[] = "\0\0\0\0test\0\0\0\0";
1456 const char test_c[] = "\0\0test\0\0\0\0";
1457 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";
1458 const char test_e[] = "test\0\0\0\0test";
1459 _cleanup_close_ int fd = -1;
1460 char fn[] = "/tmp/sparseXXXXXX";
1461
1462 fd = mkostemp(fn, O_CLOEXEC);
1463 assert_se(fd >= 0);
1464 unlink(fn);
1465
1466 test_sparse_write_one(fd, test_a, sizeof(test_a));
1467 test_sparse_write_one(fd, test_b, sizeof(test_b));
1468 test_sparse_write_one(fd, test_c, sizeof(test_c));
1469 test_sparse_write_one(fd, test_d, sizeof(test_d));
1470 test_sparse_write_one(fd, test_e, sizeof(test_e));
1471}
1472
019c7fba
LP
1473static void test_shell_maybe_quote_one(const char *s, const char *expected) {
1474 _cleanup_free_ char *r;
1475
1476 assert_se(r = shell_maybe_quote(s));
1477 assert_se(streq(r, expected));
1478}
1479
1480static void test_shell_maybe_quote(void) {
1481
1482 test_shell_maybe_quote_one("", "");
1483 test_shell_maybe_quote_one("\\", "\"\\\\\"");
1484 test_shell_maybe_quote_one("\"", "\"\\\"\"");
1485 test_shell_maybe_quote_one("foobar", "foobar");
1486 test_shell_maybe_quote_one("foo bar", "\"foo bar\"");
1487 test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\"");
1488 test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
1489}
1490
2ff7b0a5
LP
1491static void test_parse_mode(void) {
1492 mode_t m;
1493
1494 assert_se(parse_mode("-1", &m) < 0);
1495 assert_se(parse_mode("", &m) < 0);
1496 assert_se(parse_mode("888", &m) < 0);
1497 assert_se(parse_mode("77777", &m) < 0);
1498
1499 assert_se(parse_mode("544", &m) >= 0 && m == 0544);
1500 assert_se(parse_mode("777", &m) >= 0 && m == 0777);
1501 assert_se(parse_mode("7777", &m) >= 0 && m == 07777);
1502 assert_se(parse_mode("0", &m) >= 0 && m == 0);
1503}
1504
539ad707 1505int main(int argc, char *argv[]) {
9480794b
ZJS
1506 log_parse_environment();
1507 log_open();
1508
539ad707 1509 test_streq_ptr();
625e870b 1510 test_align_power2();
7242d742 1511 test_max();
fb835651 1512 test_container_of();
95d78c7e 1513 test_alloca();
180a60bc 1514 test_div_round_up();
539ad707 1515 test_first_word();
dbd73f9e 1516 test_close_many();
8354c34e 1517 test_parse_boolean();
8d99e5f5
TA
1518 test_parse_pid();
1519 test_parse_uid();
1520 test_safe_atolli();
1521 test_safe_atod();
dbd73f9e 1522 test_strappend();
1ef04f0b
TA
1523 test_strstrip();
1524 test_delete_chars();
1525 test_in_charset();
44f4c86c
DB
1526 test_hexchar();
1527 test_unhexchar();
1528 test_octchar();
1529 test_unoctchar();
1530 test_decchar();
1531 test_undecchar();
b4ecc959
TA
1532 test_cescape();
1533 test_cunescape();
1ef04f0b 1534 test_foreach_word();
539ad707 1535 test_foreach_word_quoted();
0d585d82 1536 test_memdup_multiply();
aa3c5cf8 1537 test_hostname_is_valid();
139e5336 1538 test_read_hostname_config();
144e51ec 1539 test_u64log2();
2a371001 1540 test_protect_errno();
5556b5fe 1541 test_parse_size();
9480794b 1542 test_config_parse_iec_off();
b4ecc959
TA
1543 test_strextend();
1544 test_strrep();
d4ac85c6 1545 test_split_pair();
22f5f628 1546 test_fstab_node_to_udev_node();
893fa014 1547 test_get_files_in_directory();
cabb7806 1548 test_in_set();
87b02843 1549 test_writing_tmpfile();
29bfbcd6 1550 test_hexdump();
8fe90522 1551 test_log2i();
c4a7b2c5 1552 test_foreach_string();
ae6c3cc0 1553 test_filename_is_valid();
1cb1767a 1554 test_string_has_cc();
927be00c
RC
1555 test_ascii_strlower();
1556 test_files_same();
1557 test_is_valid_documentation_url();
1558 test_file_in_same_dir();
1559 test_endswith();
1560 test_close_nointr();
1561 test_unlink_noerrno();
1562 test_readlink_and_make_absolute();
927be00c
RC
1563 test_ignore_signals();
1564 test_strshorten();
63c372cb 1565 test_strjoina();
8852362b 1566 test_is_symlink();
8852362b
RC
1567 test_search_and_fopen();
1568 test_search_and_fopen_nulstr();
1569 test_glob_exists();
1570 test_execute_directory();
7629889c
LP
1571 test_unquote_first_word();
1572 test_unquote_many_words();
f32d2db1 1573 test_parse_proc_cmdline();
ee05e779 1574 test_raw_clone();
f7ad54a3 1575 test_same_fd();
8cb4ab00 1576 test_uid_ptr();
ff6a7460 1577 test_sparse_write();
019c7fba 1578 test_shell_maybe_quote();
2ff7b0a5 1579 test_parse_mode();
539ad707
TA
1580
1581 return 0;
1582}