]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-util.c
Merge pull request #208 from poettering/btrfs-rec-snapshot
[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"));
602ee553
TA
463 free(unescaped);
464 unescaped = NULL;
3b51f8dd
DM
465
466 assert_se(cunescape("\\073", 0, &unescaped) >= 0);
467 assert_se(streq_ptr(unescaped, ";"));
b4ecc959
TA
468}
469
1ef04f0b 470static void test_foreach_word(void) {
a2a5291b 471 const char *word, *state;
1ef04f0b
TA
472 size_t l;
473 int i = 0;
474 const char test[] = "test abc d\te f ";
475 const char * const expected[] = {
476 "test",
477 "abc",
478 "d",
479 "e",
480 "f",
481 "",
482 NULL
483 };
484
a2a5291b
ZJS
485 FOREACH_WORD(word, l, test, state)
486 assert_se(strneq(expected[i++], word, l));
1ef04f0b
TA
487}
488
ba774317 489static void check(const char *test, char** expected, bool trailing) {
a2a5291b 490 const char *word, *state;
539ad707 491 size_t l;
1ef04f0b 492 int i = 0;
1ef04f0b 493
ba774317 494 printf("<<<%s>>>\n", test);
a2a5291b 495 FOREACH_WORD_QUOTED(word, l, test, state) {
1ef04f0b 496 _cleanup_free_ char *t = NULL;
539ad707 497
a2a5291b
ZJS
498 assert_se(t = strndup(word, l));
499 assert_se(strneq(expected[i++], word, l));
539ad707 500 printf("<%s>\n", t);
539ad707 501 }
ba774317 502 printf("<<<%s>>>\n", state);
e50221bf 503 assert_se(expected[i] == NULL);
ba774317
ZJS
504 assert_se(isempty(state) == !trailing);
505}
506
507static void test_foreach_word_quoted(void) {
508 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
509 STRV_MAKE("test",
510 "a",
511 "b",
512 "c",
513 "d",
514 "e",
515 "",
516 "",
517 "hhh",
518 "",
519 "",
520 "a b c"),
521 false);
522
523 check("test \"xxx",
524 STRV_MAKE("test"),
525 true);
526
527 check("test\\",
528 STRV_MAKE_EMPTY,
529 true);
539ad707
TA
530}
531
0d585d82
TA
532static void test_memdup_multiply(void) {
533 int org[] = {1, 2, 3};
534 int *dup;
535
536 dup = (int*)memdup_multiply(org, sizeof(int), 3);
537
538 assert_se(dup);
539 assert_se(dup[0] == 1);
540 assert_se(dup[1] == 2);
541 assert_se(dup[2] == 3);
542 free(dup);
543}
544
aa3c5cf8 545static void test_hostname_is_valid(void) {
bdf7026e
TA
546 assert_se(hostname_is_valid("foobar"));
547 assert_se(hostname_is_valid("foobar.com"));
548 assert_se(!hostname_is_valid("fööbar"));
549 assert_se(!hostname_is_valid(""));
550 assert_se(!hostname_is_valid("."));
551 assert_se(!hostname_is_valid(".."));
552 assert_se(!hostname_is_valid("foobar."));
553 assert_se(!hostname_is_valid(".foobar"));
554 assert_se(!hostname_is_valid("foo..bar"));
555 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
aa3c5cf8
LP
556}
557
139e5336
MP
558static void test_read_hostname_config(void) {
559 char path[] = "/tmp/hostname.XXXXXX";
560 char *hostname;
561 int fd;
562
563 fd = mkostemp_safe(path, O_RDWR|O_CLOEXEC);
564 assert(fd > 0);
565 close(fd);
566
567 /* simple hostname */
568 write_string_file(path, "foo");
569 assert_se(read_hostname_config(path, &hostname) == 0);
570 assert_se(streq(hostname, "foo"));
571 free(hostname);
e136009d 572 hostname = NULL;
139e5336
MP
573
574 /* with comment */
575 write_string_file(path, "# comment\nfoo");
576 assert_se(read_hostname_config(path, &hostname) == 0);
e136009d 577 assert_se(hostname);
139e5336
MP
578 assert_se(streq(hostname, "foo"));
579 free(hostname);
e136009d 580 hostname = NULL;
139e5336
MP
581
582 /* with comment and extra whitespace */
583 write_string_file(path, "# comment\n\n foo ");
584 assert_se(read_hostname_config(path, &hostname) == 0);
e136009d 585 assert_se(hostname);
139e5336
MP
586 assert_se(streq(hostname, "foo"));
587 free(hostname);
e136009d 588 hostname = NULL;
139e5336
MP
589
590 /* cleans up name */
591 write_string_file(path, "!foo/bar.com");
592 assert_se(read_hostname_config(path, &hostname) == 0);
e136009d 593 assert_se(hostname);
139e5336
MP
594 assert_se(streq(hostname, "foobar.com"));
595 free(hostname);
e136009d 596 hostname = NULL;
139e5336
MP
597
598 /* no value set */
599 hostname = (char*) 0x1234;
600 write_string_file(path, "# nothing here\n");
601 assert_se(read_hostname_config(path, &hostname) == -ENOENT);
602 assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */
603
604 /* nonexisting file */
605 assert_se(read_hostname_config("/non/existing", &hostname) == -ENOENT);
606 assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */
607
608 unlink(path);
609}
610
144e51ec 611static void test_u64log2(void) {
bdf7026e
TA
612 assert_se(u64log2(0) == 0);
613 assert_se(u64log2(8) == 3);
614 assert_se(u64log2(9) == 3);
615 assert_se(u64log2(15) == 3);
616 assert_se(u64log2(16) == 4);
617 assert_se(u64log2(1024*1024) == 20);
618 assert_se(u64log2(1024*1024+5) == 20);
144e51ec
CR
619}
620
2a371001
ZJS
621static void test_protect_errno(void) {
622 errno = 12;
623 {
624 PROTECT_ERRNO;
625 errno = 11;
626 }
bdf7026e 627 assert_se(errno == 12);
2a371001
ZJS
628}
629
5556b5fe 630static void test_parse_size(void) {
b32ff512
ZJS
631 off_t bytes;
632
5556b5fe 633 assert_se(parse_size("111", 1024, &bytes) == 0);
b32ff512
ZJS
634 assert_se(bytes == 111);
635
9480794b
ZJS
636 assert_se(parse_size("111.4", 1024, &bytes) == 0);
637 assert_se(bytes == 111);
638
5556b5fe 639 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
b32ff512
ZJS
640 assert_se(bytes == 112);
641
9480794b
ZJS
642 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
643 assert_se(bytes == 112);
644
645 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
646 assert_se(bytes == 3*1024 + 512);
647
648 assert_se(parse_size("3. K", 1024, &bytes) == 0);
649 assert_se(bytes == 3*1024);
650
651 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
b32ff512
ZJS
652 assert_se(bytes == 3*1024);
653
840292be 654 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
b32ff512 655
9480794b
ZJS
656 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
657 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
658
840292be
ZJS
659 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
660
661 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
9480794b 662 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
b32ff512 663
840292be
ZJS
664 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
665 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
666
667 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
668
669 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
670 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
671
672 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
b32ff512
ZJS
673 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
674
5556b5fe 675 assert_se(parse_size("12P", 1024, &bytes) == 0);
b32ff512
ZJS
676 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
677
840292be
ZJS
678 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
679
5556b5fe 680 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
b32ff512
ZJS
681 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
682
5556b5fe 683 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
b32ff512 684
9480794b
ZJS
685 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
686
687 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
688
5556b5fe
LP
689 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
690 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
691 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
b32ff512 692
5556b5fe 693 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
b32ff512 694
5556b5fe 695 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
b32ff512
ZJS
696}
697
9480794b
ZJS
698static void test_config_parse_iec_off(void) {
699 off_t offset = 0;
700 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
701 assert_se(offset == 4 * 1024 * 1024);
702
703 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
704}
705
b4ecc959
TA
706static void test_strextend(void) {
707 _cleanup_free_ char *str = strdup("0123");
708 strextend(&str, "456", "78", "9", NULL);
709 assert_se(streq(str, "0123456789"));
710}
711
712static void test_strrep(void) {
713 _cleanup_free_ char *one, *three, *zero;
714 one = strrep("waldo", 1);
715 three = strrep("waldo", 3);
716 zero = strrep("waldo", 0);
717
718 assert_se(streq(one, "waldo"));
719 assert_se(streq(three, "waldowaldowaldo"));
720 assert_se(streq(zero, ""));
721}
722
d4ac85c6
LP
723static void test_split_pair(void) {
724 _cleanup_free_ char *a = NULL, *b = NULL;
725
726 assert_se(split_pair("", "", &a, &b) == -EINVAL);
727 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
728 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
729 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
730 assert_se(streq(a, "foo"));
731 assert_se(streq(b, "bar"));
732 free(a);
733 free(b);
734 assert_se(split_pair("==", "==", &a, &b) >= 0);
735 assert_se(streq(a, ""));
736 assert_se(streq(b, ""));
737 free(a);
738 free(b);
739
740 assert_se(split_pair("===", "==", &a, &b) >= 0);
741 assert_se(streq(a, ""));
742 assert_se(streq(b, "="));
743}
744
22f5f628
DR
745static void test_fstab_node_to_udev_node(void) {
746 char *n;
747
748 n = fstab_node_to_udev_node("LABEL=applé/jack");
749 puts(n);
750 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
751 free(n);
752
753 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
754 puts(n);
755 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
756 free(n);
757
758 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
759 puts(n);
760 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
761 free(n);
762
763 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
764 puts(n);
765 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
766 free(n);
767
22f5f628
DR
768 n = fstab_node_to_udev_node("PONIES=awesome");
769 puts(n);
770 assert_se(streq(n, "PONIES=awesome"));
771 free(n);
772
773 n = fstab_node_to_udev_node("/dev/xda1");
774 puts(n);
775 assert_se(streq(n, "/dev/xda1"));
776 free(n);
777}
778
893fa014
ZJS
779static void test_get_files_in_directory(void) {
780 _cleanup_strv_free_ char **l = NULL, **t = NULL;
781
782 assert_se(get_files_in_directory("/tmp", &l) >= 0);
510b857f 783 assert_se(get_files_in_directory(".", &t) >= 0);
893fa014
ZJS
784 assert_se(get_files_in_directory(".", NULL) >= 0);
785}
786
cabb7806
LP
787static void test_in_set(void) {
788 assert_se(IN_SET(1, 1));
789 assert_se(IN_SET(1, 1, 2, 3, 4));
790 assert_se(IN_SET(2, 1, 2, 3, 4));
791 assert_se(IN_SET(3, 1, 2, 3, 4));
792 assert_se(IN_SET(4, 1, 2, 3, 4));
793 assert_se(!IN_SET(0, 1));
794 assert_se(!IN_SET(0, 1, 2, 3, 4));
795}
796
87b02843
ZJS
797static void test_writing_tmpfile(void) {
798 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
39883f62 799 _cleanup_free_ char *contents = NULL;
65b3903f
ZJS
800 size_t size;
801 int fd, r;
65b3903f 802 struct iovec iov[3];
39883f62 803
65b3903f
ZJS
804 IOVEC_SET_STRING(iov[0], "abc\n");
805 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
806 IOVEC_SET_STRING(iov[2], "");
807
2d5bdf5b 808 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
87b02843 809 printf("tmpfile: %s", name);
65b3903f 810
87b02843 811 r = writev(fd, iov, 3);
bdf7026e 812 assert_se(r >= 0);
65b3903f
ZJS
813
814 r = read_full_file(name, &contents, &size);
bdf7026e 815 assert_se(r == 0);
65b3903f 816 printf("contents: %s", contents);
bdf7026e 817 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
40edd236
RC
818
819 unlink(name);
65b3903f
ZJS
820}
821
29bfbcd6
LP
822static void test_hexdump(void) {
823 uint8_t data[146];
824 unsigned i;
825
826 hexdump(stdout, NULL, 0);
827 hexdump(stdout, "", 0);
828 hexdump(stdout, "", 1);
829 hexdump(stdout, "x", 1);
830 hexdump(stdout, "x", 2);
831 hexdump(stdout, "foobar", 7);
832 hexdump(stdout, "f\nobar", 7);
833 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
834
835 for (i = 0; i < ELEMENTSOF(data); i++)
836 data[i] = i*2;
837
838 hexdump(stdout, data, sizeof(data));
839}
840
8fe90522
ZJS
841static void test_log2i(void) {
842 assert_se(log2i(1) == 0);
843 assert_se(log2i(2) == 1);
844 assert_se(log2i(3) == 1);
845 assert_se(log2i(4) == 2);
846 assert_se(log2i(32) == 5);
847 assert_se(log2i(33) == 5);
848 assert_se(log2i(63) == 5);
849 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
850}
851
c4a7b2c5
LP
852static void test_foreach_string(void) {
853 const char * const t[] = {
854 "foo",
855 "bar",
856 "waldo",
857 NULL
858 };
859 const char *x;
860 unsigned i = 0;
861
862 FOREACH_STRING(x, "foo", "bar", "waldo")
863 assert_se(streq_ptr(t[i++], x));
864
865 assert_se(i == 3);
866
867 FOREACH_STRING(x, "zzz")
868 assert_se(streq(x, "zzz"));
869}
870
ae6c3cc0 871static void test_filename_is_valid(void) {
927be00c
RC
872 char foo[FILENAME_MAX+2];
873 int i;
874
ae6c3cc0
LP
875 assert_se(!filename_is_valid(""));
876 assert_se(!filename_is_valid("/bar/foo"));
877 assert_se(!filename_is_valid("/"));
878 assert_se(!filename_is_valid("."));
879 assert_se(!filename_is_valid(".."));
927be00c
RC
880
881 for (i=0; i<FILENAME_MAX+1; i++)
882 foo[i] = 'a';
883 foo[FILENAME_MAX+1] = '\0';
884
ae6c3cc0 885 assert_se(!filename_is_valid(foo));
927be00c 886
ae6c3cc0
LP
887 assert_se(filename_is_valid("foo_bar-333"));
888 assert_se(filename_is_valid("o.o"));
927be00c
RC
889}
890
1cb1767a
ZJS
891static void test_string_has_cc(void) {
892 assert_se(string_has_cc("abc\1", NULL));
893 assert_se(string_has_cc("abc\x7f", NULL));
894 assert_se(string_has_cc("abc\x7f", NULL));
895 assert_se(string_has_cc("abc\t\x7f", "\t"));
896 assert_se(string_has_cc("abc\t\x7f", "\t"));
897 assert_se(string_has_cc("\x7f", "\t"));
898 assert_se(string_has_cc("\x7f", "\t\a"));
899
900 assert_se(!string_has_cc("abc\t\t", "\t"));
901 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
902 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
903}
904
927be00c
RC
905static void test_ascii_strlower(void) {
906 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
907 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
908}
909
910static void test_files_same(void) {
911 _cleanup_close_ int fd = -1;
912 char name[] = "/tmp/test-files_same.XXXXXX";
913 char name_alias[] = "/tmp/test-files_same.alias";
914
915 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
916 assert_se(fd >= 0);
917 assert_se(symlink(name, name_alias) >= 0);
918
919 assert_se(files_same(name, name));
920 assert_se(files_same(name, name_alias));
921
922 unlink(name);
923 unlink(name_alias);
924}
925
926static void test_is_valid_documentation_url(void) {
a2e03378
LP
927 assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
928 assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
929 assert_se(documentation_url_is_valid("file:/foo/foo"));
930 assert_se(documentation_url_is_valid("man:systemd.special(7)"));
931 assert_se(documentation_url_is_valid("info:bar"));
932
933 assert_se(!documentation_url_is_valid("foo:"));
934 assert_se(!documentation_url_is_valid("info:"));
935 assert_se(!documentation_url_is_valid(""));
927be00c
RC
936}
937
938static void test_file_in_same_dir(void) {
eee84633
DH
939 char *t;
940
941 t = file_in_same_dir("/", "a");
942 assert_se(streq(t, "/a"));
943 free(t);
944
945 t = file_in_same_dir("/", "/a");
946 assert_se(streq(t, "/a"));
947 free(t);
948
949 t = file_in_same_dir("", "a");
950 assert_se(streq(t, "a"));
951 free(t);
952
953 t = file_in_same_dir("a/", "a");
954 assert_se(streq(t, "a/a"));
955 free(t);
956
957 t = file_in_same_dir("bar/foo", "bar");
958 assert_se(streq(t, "bar/bar"));
959 free(t);
927be00c
RC
960}
961
962static void test_endswith(void) {
963 assert_se(endswith("foobar", "bar"));
964 assert_se(endswith("foobar", ""));
965 assert_se(endswith("foobar", "foobar"));
966 assert_se(endswith("", ""));
967
968 assert_se(!endswith("foobar", "foo"));
969 assert_se(!endswith("foobar", "foobarfoofoo"));
970}
971
972static void test_close_nointr(void) {
973 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
974 int fd;
975
976 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
977 assert_se(fd >= 0);
978 assert_se(close_nointr(fd) >= 0);
979 assert_se(close_nointr(fd) < 0);
980
981 unlink(name);
982}
983
984
985static void test_unlink_noerrno(void) {
986 char name[] = "/tmp/test-close_nointr.XXXXXX";
987 int fd;
988
989 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
990 assert_se(fd >= 0);
991 assert_se(close_nointr(fd) >= 0);
992
993 {
994 PROTECT_ERRNO;
995 errno = -42;
996 assert_se(unlink_noerrno(name) >= 0);
997 assert_se(errno == -42);
998 assert_se(unlink_noerrno(name) < 0);
999 assert_se(errno == -42);
1000 }
1001}
1002
1003static void test_readlink_and_make_absolute(void) {
1004 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
1005 char name[] = "/tmp/test-readlink_and_make_absolute/original";
1006 char name2[] = "test-readlink_and_make_absolute/original";
1007 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
1008 char *r = NULL;
1009
684fc892 1010 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
927be00c
RC
1011 assert_se(touch(name) >= 0);
1012
1013 assert_se(symlink(name, name_alias) >= 0);
1014 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1015 assert_se(streq(r, name));
1016 free(r);
1017 assert_se(unlink(name_alias) >= 0);
1018
1019 assert_se(chdir(tempdir) >= 0);
1020 assert_se(symlink(name2, name_alias) >= 0);
1021 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1022 assert_se(streq(r, name));
1023 free(r);
1024 assert_se(unlink(name_alias) >= 0);
1025
c6878637 1026 assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
927be00c
RC
1027}
1028
927be00c
RC
1029static void test_ignore_signals(void) {
1030 assert_se(ignore_signals(SIGINT, -1) >= 0);
1031 assert_se(kill(getpid(), SIGINT) >= 0);
1032 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1033 assert_se(kill(getpid(), SIGUSR1) >= 0);
1034 assert_se(kill(getpid(), SIGUSR2) >= 0);
1035 assert_se(kill(getpid(), SIGTERM) >= 0);
1036 assert_se(kill(getpid(), SIGPIPE) >= 0);
1037 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1038}
1039
1040static void test_strshorten(void) {
1041 char s[] = "foobar";
1042
1043 assert_se(strlen(strshorten(s, 6)) == 6);
1044 assert_se(strlen(strshorten(s, 12)) == 6);
1045 assert_se(strlen(strshorten(s, 2)) == 2);
1046 assert_se(strlen(strshorten(s, 0)) == 0);
1047}
1048
63c372cb 1049static void test_strjoina(void) {
8085f163
DR
1050 char *actual;
1051
63c372cb 1052 actual = strjoina("", "foo", "bar");
8085f163
DR
1053 assert_se(streq(actual, "foobar"));
1054
63c372cb 1055 actual = strjoina("foo", "bar", "baz");
8085f163
DR
1056 assert_se(streq(actual, "foobarbaz"));
1057
63c372cb 1058 actual = strjoina("foo", "", "bar", "baz");
8085f163 1059 assert_se(streq(actual, "foobarbaz"));
63c372cb
LP
1060
1061 actual = strjoina("foo");
1062 assert_se(streq(actual, "foo"));
1063
1064 actual = strjoina(NULL);
1065 assert_se(streq(actual, ""));
1066
1067 actual = strjoina(NULL, "foo");
1068 assert_se(streq(actual, ""));
1069
1070 actual = strjoina("foo", NULL, "bar");
1071 assert_se(streq(actual, "foo"));
8085f163
DR
1072}
1073
8852362b
RC
1074static void test_is_symlink(void) {
1075 char name[] = "/tmp/test-is_symlink.XXXXXX";
1076 char name_link[] = "/tmp/test-is_symlink.link";
1077 _cleanup_close_ int fd = -1;
1078
1079 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1080 assert_se(fd >= 0);
1081 assert_se(symlink(name, name_link) >= 0);
1082
1083 assert_se(is_symlink(name) == 0);
1084 assert_se(is_symlink(name_link) == 1);
1085 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1086
1087
1088 unlink(name);
1089 unlink(name_link);
1090}
1091
8852362b
RC
1092static void test_search_and_fopen(void) {
1093 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1094 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1095 int fd = -1;
1096 int r;
1097 FILE *f;
1098
1099 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1100 assert_se(fd >= 0);
1101 close(fd);
1102
1103 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1104 assert_se(r >= 0);
1105 fclose(f);
1106
1107 r = search_and_fopen(name, "r", NULL, dirs, &f);
1108 assert_se(r >= 0);
1109 fclose(f);
1110
1111 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1112 assert_se(r >= 0);
1113 fclose(f);
1114
1115 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1116 assert_se(r < 0);
1117 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1118 assert_se(r < 0);
1119
1120 r = unlink(name);
1121 assert_se(r == 0);
1122
1123 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1124 assert_se(r < 0);
1125}
1126
1127
1128static void test_search_and_fopen_nulstr(void) {
1129 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1130 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1131 int fd = -1;
1132 int r;
1133 FILE *f;
1134
1135 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1136 assert_se(fd >= 0);
1137 close(fd);
1138
1139 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1140 assert_se(r >= 0);
1141 fclose(f);
1142
1143 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1144 assert_se(r >= 0);
1145 fclose(f);
1146
1147 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1148 assert_se(r < 0);
1149 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1150 assert_se(r < 0);
1151
1152 r = unlink(name);
1153 assert_se(r == 0);
1154
1155 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1156 assert_se(r < 0);
1157}
1158
1159static void test_glob_exists(void) {
1160 char name[] = "/tmp/test-glob_exists.XXXXXX";
1161 int fd = -1;
1162 int r;
1163
1164 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1165 assert_se(fd >= 0);
1166 close(fd);
1167
1168 r = glob_exists("/tmp/test-glob_exists*");
1169 assert_se(r == 1);
1170
1171 r = unlink(name);
1172 assert_se(r == 0);
1173 r = glob_exists("/tmp/test-glob_exists*");
1174 assert_se(r == 0);
1175}
1176
1177static void test_execute_directory(void) {
aac7766c
ZJS
1178 char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1179 char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
76f282c6 1180 const char * dirs[] = {template_hi, template_lo, NULL};
aac7766c
ZJS
1181 const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
1182
1183 assert_se(mkdtemp(template_lo));
1184 assert_se(mkdtemp(template_hi));
1185
63c372cb
LP
1186 name = strjoina(template_lo, "/script");
1187 name2 = strjoina(template_hi, "/script2");
1188 name3 = strjoina(template_lo, "/useless");
1189 overridden = strjoina(template_lo, "/overridden");
1190 override = strjoina(template_hi, "/overridden");
1191 masked = strjoina(template_lo, "/masked");
1192 mask = strjoina(template_hi, "/masked");
e801700e
ZJS
1193
1194 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works") == 0);
1195 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2") == 0);
aac7766c
ZJS
1196 assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1197 assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0") == 0);
1198 assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1199 assert_se(symlink("/dev/null", mask) == 0);
8852362b
RC
1200 assert_se(chmod(name, 0755) == 0);
1201 assert_se(chmod(name2, 0755) == 0);
aac7766c
ZJS
1202 assert_se(chmod(overridden, 0755) == 0);
1203 assert_se(chmod(override, 0755) == 0);
1204 assert_se(chmod(masked, 0755) == 0);
8852362b
RC
1205 assert_se(touch(name3) >= 0);
1206
e801700e 1207 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
aac7766c 1208
0c0cdb06 1209 assert_se(chdir(template_lo) == 0);
e801700e 1210 assert_se(access("it_works", F_OK) >= 0);
aac7766c
ZJS
1211 assert_se(access("failed", F_OK) < 0);
1212
0c0cdb06 1213 assert_se(chdir(template_hi) == 0);
e801700e 1214 assert_se(access("it_works2", F_OK) >= 0);
aac7766c 1215 assert_se(access("failed", F_OK) < 0);
8852362b 1216
c6878637
LP
1217 (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
1218 (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
8852362b
RC
1219}
1220
7629889c
LP
1221static void test_unquote_first_word(void) {
1222 const char *p, *original;
1223 char *t;
1224
1225 p = original = "foobar waldo";
4034a06d 1226 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1227 assert_se(streq(t, "foobar"));
1228 free(t);
1229 assert_se(p == original + 7);
1230
4034a06d 1231 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1232 assert_se(streq(t, "waldo"));
1233 free(t);
1234 assert_se(p == original + 12);
1235
4034a06d 1236 assert_se(unquote_first_word(&p, &t, 0) == 0);
7629889c
LP
1237 assert_se(!t);
1238 assert_se(p == original + 12);
1239
1240 p = original = "\"foobar\" \'waldo\'";
4034a06d 1241 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1242 assert_se(streq(t, "foobar"));
1243 free(t);
1244 assert_se(p == original + 9);
1245
4034a06d 1246 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1247 assert_se(streq(t, "waldo"));
1248 free(t);
1249 assert_se(p == original + 16);
1250
4034a06d 1251 assert_se(unquote_first_word(&p, &t, 0) == 0);
7629889c
LP
1252 assert_se(!t);
1253 assert_se(p == original + 16);
1254
1255 p = original = "\"";
4034a06d 1256 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
7629889c
LP
1257 assert_se(p == original + 1);
1258
1259 p = original = "\'";
4034a06d 1260 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
7629889c
LP
1261 assert_se(p == original + 1);
1262
f32d2db1 1263 p = original = "\'fooo";
4034a06d 1264 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
f32d2db1
LP
1265 assert_se(p == original + 5);
1266
1267 p = original = "\'fooo";
4034a06d 1268 assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
f32d2db1 1269 assert_se(streq(t, "fooo"));
e1ba963f 1270 free(t);
f32d2db1
LP
1271 assert_se(p == original + 5);
1272
7629889c 1273 p = original = "yay\'foo\'bar";
4034a06d 1274 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1275 assert_se(streq(t, "yayfoobar"));
1276 free(t);
1277 assert_se(p == original + 11);
1278
1279 p = original = " foobar ";
4034a06d 1280 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1281 assert_se(streq(t, "foobar"));
1282 free(t);
1283 assert_se(p == original + 12);
4034a06d
LP
1284
1285 p = original = " foo\\ba\\x6ar ";
1286 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1287 assert_se(streq(t, "foo\ba\x6ar"));
1288 free(t);
1289 assert_se(p == original + 13);
1290
1291 p = original = " foo\\ba\\x6ar ";
1292 assert_se(unquote_first_word(&p, &t, 0) > 0);
1293 assert_se(streq(t, "foobax6ar"));
1294 free(t);
1295 assert_se(p == original + 13);
8ebac1f9
LP
1296
1297 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
1298 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1299 assert_se(streq(t, "föo"));
1300 free(t);
1301 assert_se(p == original + 13);
1302
1303 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1304 assert_se(streq(t, "pi\360\237\222\251le"));
1305 free(t);
1306 assert_se(p == original + 32);
7629889c
LP
1307}
1308
1309static void test_unquote_many_words(void) {
1310 const char *p, *original;
1311 char *a, *b, *c;
1312
1313 p = original = "foobar waldi piep";
4034a06d 1314 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 3);
7629889c
LP
1315 assert_se(p == original + 17);
1316 assert_se(streq_ptr(a, "foobar"));
1317 assert_se(streq_ptr(b, "waldi"));
1318 assert_se(streq_ptr(c, "piep"));
1319 free(a);
1320 free(b);
1321 free(c);
1322
1323 p = original = "'foobar' wa\"ld\"i ";
4034a06d 1324 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 2);
7629889c
LP
1325 assert_se(p == original + 19);
1326 assert_se(streq_ptr(a, "foobar"));
1327 assert_se(streq_ptr(b, "waldi"));
1328 assert_se(streq_ptr(c, NULL));
1329 free(a);
1330 free(b);
1331
1332 p = original = "";
4034a06d 1333 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
7629889c
LP
1334 assert_se(p == original);
1335 assert_se(streq_ptr(a, NULL));
1336 assert_se(streq_ptr(b, NULL));
1337 assert_se(streq_ptr(c, NULL));
1338
1339 p = original = " ";
4034a06d 1340 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
7629889c
LP
1341 assert_se(p == original+2);
1342 assert_se(streq_ptr(a, NULL));
1343 assert_se(streq_ptr(b, NULL));
1344 assert_se(streq_ptr(c, NULL));
1345
1346 p = original = "foobar";
4034a06d 1347 assert_se(unquote_many_words(&p, 0, NULL) == 0);
7629889c
LP
1348 assert_se(p == original);
1349
1350 p = original = "foobar waldi";
4034a06d 1351 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
7629889c
LP
1352 assert_se(p == original+7);
1353 assert_se(streq_ptr(a, "foobar"));
eee84633 1354 free(a);
7629889c
LP
1355
1356 p = original = " foobar ";
4034a06d 1357 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
7629889c
LP
1358 assert_se(p == original+15);
1359 assert_se(streq_ptr(a, "foobar"));
eee84633 1360 free(a);
7629889c
LP
1361}
1362
f32d2db1
LP
1363static int parse_item(const char *key, const char *value) {
1364 assert_se(key);
1365
1366 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1367 return 0;
1368}
1369
1370static void test_parse_proc_cmdline(void) {
1371 assert_se(parse_proc_cmdline(parse_item) >= 0);
1372}
1373
ee05e779
ZJS
1374static void test_raw_clone(void) {
1375 pid_t parent, pid, pid2;
1376
1377 parent = getpid();
1378 log_info("before clone: getpid()→"PID_FMT, parent);
1379 assert_se(raw_getpid() == parent);
1380
1381 pid = raw_clone(0, NULL);
e50221bf 1382 assert_se(pid >= 0);
ee05e779
ZJS
1383
1384 pid2 = raw_getpid();
1385 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1386 pid, getpid(), pid2);
0289a5bc 1387 if (pid == 0) {
e50221bf 1388 assert_se(pid2 != parent);
0289a5bc
FB
1389 _exit(EXIT_SUCCESS);
1390 } else {
1391 int status;
1392
e50221bf 1393 assert_se(pid2 == parent);
0289a5bc
FB
1394 waitpid(pid, &status, __WCLONE);
1395 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1396 }
ee05e779
ZJS
1397}
1398
f7ad54a3
LP
1399static void test_same_fd(void) {
1400 _cleanup_close_pair_ int p[2] = { -1, -1 };
1401 _cleanup_close_ int a = -1, b = -1, c = -1;
1402
1403 assert_se(pipe2(p, O_CLOEXEC) >= 0);
1404 assert_se((a = dup(p[0])) >= 0);
1405 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1406 assert_se((c = dup(a)) >= 0);
1407
1408 assert_se(same_fd(p[0], p[0]) > 0);
1409 assert_se(same_fd(p[1], p[1]) > 0);
1410 assert_se(same_fd(a, a) > 0);
1411 assert_se(same_fd(b, b) > 0);
1412
1413 assert_se(same_fd(a, p[0]) > 0);
1414 assert_se(same_fd(p[0], a) > 0);
1415 assert_se(same_fd(c, p[0]) > 0);
1416 assert_se(same_fd(p[0], c) > 0);
1417 assert_se(same_fd(a, c) > 0);
1418 assert_se(same_fd(c, a) > 0);
1419
1420 assert_se(same_fd(p[0], p[1]) == 0);
1421 assert_se(same_fd(p[1], p[0]) == 0);
1422 assert_se(same_fd(p[0], b) == 0);
1423 assert_se(same_fd(b, p[0]) == 0);
1424 assert_se(same_fd(p[1], a) == 0);
1425 assert_se(same_fd(a, p[1]) == 0);
1426 assert_se(same_fd(p[1], b) == 0);
1427 assert_se(same_fd(b, p[1]) == 0);
1428
1429 assert_se(same_fd(a, b) == 0);
1430 assert_se(same_fd(b, a) == 0);
1431}
1432
8cb4ab00
LP
1433static void test_uid_ptr(void) {
1434
1435 assert_se(UID_TO_PTR(0) != NULL);
1436 assert_se(UID_TO_PTR(1000) != NULL);
1437
1438 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1439 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1440}
1441
ff6a7460
LP
1442static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
1443 char check[n];
1444
1445 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1446 assert_se(ftruncate(fd, 0) >= 0);
1447 assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
1448
1449 assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
1450 assert_se(ftruncate(fd, n) >= 0);
1451
1452 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1453 assert_se(read(fd, check, n) == (ssize_t) n);
1454
1455 assert_se(memcmp(buffer, check, n) == 0);
1456}
1457
1458static void test_sparse_write(void) {
1459 const char test_a[] = "test";
1460 const char test_b[] = "\0\0\0\0test\0\0\0\0";
1461 const char test_c[] = "\0\0test\0\0\0\0";
1462 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";
1463 const char test_e[] = "test\0\0\0\0test";
1464 _cleanup_close_ int fd = -1;
1465 char fn[] = "/tmp/sparseXXXXXX";
1466
1467 fd = mkostemp(fn, O_CLOEXEC);
1468 assert_se(fd >= 0);
1469 unlink(fn);
1470
1471 test_sparse_write_one(fd, test_a, sizeof(test_a));
1472 test_sparse_write_one(fd, test_b, sizeof(test_b));
1473 test_sparse_write_one(fd, test_c, sizeof(test_c));
1474 test_sparse_write_one(fd, test_d, sizeof(test_d));
1475 test_sparse_write_one(fd, test_e, sizeof(test_e));
1476}
1477
019c7fba
LP
1478static void test_shell_maybe_quote_one(const char *s, const char *expected) {
1479 _cleanup_free_ char *r;
1480
1481 assert_se(r = shell_maybe_quote(s));
1482 assert_se(streq(r, expected));
1483}
1484
1485static void test_shell_maybe_quote(void) {
1486
1487 test_shell_maybe_quote_one("", "");
1488 test_shell_maybe_quote_one("\\", "\"\\\\\"");
1489 test_shell_maybe_quote_one("\"", "\"\\\"\"");
1490 test_shell_maybe_quote_one("foobar", "foobar");
1491 test_shell_maybe_quote_one("foo bar", "\"foo bar\"");
1492 test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\"");
1493 test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
1494}
1495
2ff7b0a5
LP
1496static void test_parse_mode(void) {
1497 mode_t m;
1498
1499 assert_se(parse_mode("-1", &m) < 0);
1500 assert_se(parse_mode("", &m) < 0);
1501 assert_se(parse_mode("888", &m) < 0);
1502 assert_se(parse_mode("77777", &m) < 0);
1503
1504 assert_se(parse_mode("544", &m) >= 0 && m == 0544);
1505 assert_se(parse_mode("777", &m) >= 0 && m == 0777);
1506 assert_se(parse_mode("7777", &m) >= 0 && m == 07777);
1507 assert_se(parse_mode("0", &m) >= 0 && m == 0);
1508}
1509
539ad707 1510int main(int argc, char *argv[]) {
9480794b
ZJS
1511 log_parse_environment();
1512 log_open();
1513
539ad707 1514 test_streq_ptr();
625e870b 1515 test_align_power2();
7242d742 1516 test_max();
fb835651 1517 test_container_of();
95d78c7e 1518 test_alloca();
180a60bc 1519 test_div_round_up();
539ad707 1520 test_first_word();
dbd73f9e 1521 test_close_many();
8354c34e 1522 test_parse_boolean();
8d99e5f5
TA
1523 test_parse_pid();
1524 test_parse_uid();
1525 test_safe_atolli();
1526 test_safe_atod();
dbd73f9e 1527 test_strappend();
1ef04f0b
TA
1528 test_strstrip();
1529 test_delete_chars();
1530 test_in_charset();
44f4c86c
DB
1531 test_hexchar();
1532 test_unhexchar();
1533 test_octchar();
1534 test_unoctchar();
1535 test_decchar();
1536 test_undecchar();
b4ecc959
TA
1537 test_cescape();
1538 test_cunescape();
1ef04f0b 1539 test_foreach_word();
539ad707 1540 test_foreach_word_quoted();
0d585d82 1541 test_memdup_multiply();
aa3c5cf8 1542 test_hostname_is_valid();
139e5336 1543 test_read_hostname_config();
144e51ec 1544 test_u64log2();
2a371001 1545 test_protect_errno();
5556b5fe 1546 test_parse_size();
9480794b 1547 test_config_parse_iec_off();
b4ecc959
TA
1548 test_strextend();
1549 test_strrep();
d4ac85c6 1550 test_split_pair();
22f5f628 1551 test_fstab_node_to_udev_node();
893fa014 1552 test_get_files_in_directory();
cabb7806 1553 test_in_set();
87b02843 1554 test_writing_tmpfile();
29bfbcd6 1555 test_hexdump();
8fe90522 1556 test_log2i();
c4a7b2c5 1557 test_foreach_string();
ae6c3cc0 1558 test_filename_is_valid();
1cb1767a 1559 test_string_has_cc();
927be00c
RC
1560 test_ascii_strlower();
1561 test_files_same();
1562 test_is_valid_documentation_url();
1563 test_file_in_same_dir();
1564 test_endswith();
1565 test_close_nointr();
1566 test_unlink_noerrno();
1567 test_readlink_and_make_absolute();
927be00c
RC
1568 test_ignore_signals();
1569 test_strshorten();
63c372cb 1570 test_strjoina();
8852362b 1571 test_is_symlink();
8852362b
RC
1572 test_search_and_fopen();
1573 test_search_and_fopen_nulstr();
1574 test_glob_exists();
1575 test_execute_directory();
7629889c
LP
1576 test_unquote_first_word();
1577 test_unquote_many_words();
f32d2db1 1578 test_parse_proc_cmdline();
ee05e779 1579 test_raw_clone();
f7ad54a3 1580 test_same_fd();
8cb4ab00 1581 test_uid_ptr();
ff6a7460 1582 test_sparse_write();
019c7fba 1583 test_shell_maybe_quote();
2ff7b0a5 1584 test_parse_mode();
539ad707
TA
1585
1586 return 0;
1587}