]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-util.c
util: rework rm_rf() logic
[thirdparty/systemd.git] / src / test / test-util.c
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>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <locale.h>
27 #include <errno.h>
28 #include <signal.h>
29 #include <math.h>
30 #include <sys/wait.h>
31
32 #include "util.h"
33 #include "mkdir.h"
34 #include "rm-rf.h"
35 #include "strv.h"
36 #include "def.h"
37 #include "fileio.h"
38 #include "conf-parser.h"
39 #include "virt.h"
40
41 static void test_streq_ptr(void) {
42 assert_se(streq_ptr(NULL, NULL));
43 assert_se(!streq_ptr("abc", "cdef"));
44 }
45
46 static void test_align_power2(void) {
47 unsigned long i, p2;
48
49 assert_se(ALIGN_POWER2(0) == 0);
50 assert_se(ALIGN_POWER2(1) == 1);
51 assert_se(ALIGN_POWER2(2) == 2);
52 assert_se(ALIGN_POWER2(3) == 4);
53 assert_se(ALIGN_POWER2(12) == 16);
54
55 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
56 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
57 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
58 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
59 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
60
61 for (i = 1; i < 131071; ++i) {
62 for (p2 = 1; p2 < i; p2 <<= 1)
63 /* empty */ ;
64
65 assert_se(ALIGN_POWER2(i) == p2);
66 }
67
68 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
69 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
70 /* empty */ ;
71
72 assert_se(ALIGN_POWER2(i) == p2);
73 }
74 }
75
76 static void test_max(void) {
77 static const struct {
78 int a;
79 int b[CONST_MAX(10, 100)];
80 } val1 = {
81 .a = CONST_MAX(10, 100),
82 };
83 int d = 0;
84
85 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
86
87 /* CONST_MAX returns (void) instead of a value if the passed arguments
88 * are not of the same type or not constant expressions. */
89 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
90 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
91
92 assert_se(val1.a == 100);
93 assert_se(MAX(++d, 0) == 1);
94 assert_se(d == 1);
95
96 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
97 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
98 assert_cc(MAXSIZE(char, long) == sizeof(long));
99
100 assert_se(MAX(-5, 5) == 5);
101 assert_se(MAX(5, 5) == 5);
102 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
103 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
104 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
105 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
106 assert_se(LESS_BY(8, 4) == 4);
107 assert_se(LESS_BY(8, 8) == 0);
108 assert_se(LESS_BY(4, 8) == 0);
109 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
110 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
111 assert_se(CLAMP(-5, 0, 1) == 0);
112 assert_se(CLAMP(5, 0, 1) == 1);
113 assert_se(CLAMP(5, -10, 1) == 1);
114 assert_se(CLAMP(5, -10, 10) == 5);
115 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
116 }
117
118 static void test_container_of(void) {
119 struct mytype {
120 uint8_t pad1[3];
121 uint64_t v1;
122 uint8_t pad2[2];
123 uint32_t v2;
124 } _packed_ myval = { };
125
126 assert_cc(sizeof(myval) == 17);
127 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
128 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
129 assert_se(container_of(&container_of(&myval.v2,
130 struct mytype,
131 v2)->v1,
132 struct mytype,
133 v1) == &myval);
134 }
135
136 static void test_alloca(void) {
137 static const uint8_t zero[997] = { };
138 char *t;
139
140 t = alloca_align(17, 512);
141 assert_se(!((uintptr_t)t & 0xff));
142 memzero(t, 17);
143
144 t = alloca0_align(997, 1024);
145 assert_se(!((uintptr_t)t & 0x1ff));
146 assert_se(!memcmp(t, zero, 997));
147 }
148
149 static void test_div_round_up(void) {
150 int div;
151
152 /* basic tests */
153 assert_se(DIV_ROUND_UP(0, 8) == 0);
154 assert_se(DIV_ROUND_UP(1, 8) == 1);
155 assert_se(DIV_ROUND_UP(8, 8) == 1);
156 assert_se(DIV_ROUND_UP(12, 8) == 2);
157 assert_se(DIV_ROUND_UP(16, 8) == 2);
158
159 /* test multiple evaluation */
160 div = 0;
161 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
162 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
163 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
164 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
165
166 /* overflow test with exact division */
167 assert_se(sizeof(0U) == 4);
168 assert_se(0xfffffffaU % 10U == 0U);
169 assert_se(0xfffffffaU / 10U == 429496729U);
170 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
171 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
172 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
173
174 /* overflow test with rounded division */
175 assert_se(0xfffffffdU % 10U == 3U);
176 assert_se(0xfffffffdU / 10U == 429496729U);
177 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
178 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
179 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
180 }
181
182 static void test_first_word(void) {
183 assert_se(first_word("Hello", ""));
184 assert_se(first_word("Hello", "Hello"));
185 assert_se(first_word("Hello world", "Hello"));
186 assert_se(first_word("Hello\tworld", "Hello"));
187 assert_se(first_word("Hello\nworld", "Hello"));
188 assert_se(first_word("Hello\rworld", "Hello"));
189 assert_se(first_word("Hello ", "Hello"));
190
191 assert_se(!first_word("Hello", "Hellooo"));
192 assert_se(!first_word("Hello", "xxxxx"));
193 assert_se(!first_word("Hellooo", "Hello"));
194 }
195
196 static void test_close_many(void) {
197 int fds[3];
198 char name0[] = "/tmp/test-close-many.XXXXXX";
199 char name1[] = "/tmp/test-close-many.XXXXXX";
200 char name2[] = "/tmp/test-close-many.XXXXXX";
201
202 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
203 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
204 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
205
206 close_many(fds, 2);
207
208 assert_se(fcntl(fds[0], F_GETFD) == -1);
209 assert_se(fcntl(fds[1], F_GETFD) == -1);
210 assert_se(fcntl(fds[2], F_GETFD) >= 0);
211
212 safe_close(fds[2]);
213
214 unlink(name0);
215 unlink(name1);
216 unlink(name2);
217 }
218
219 static void test_parse_boolean(void) {
220 assert_se(parse_boolean("1") == 1);
221 assert_se(parse_boolean("y") == 1);
222 assert_se(parse_boolean("Y") == 1);
223 assert_se(parse_boolean("yes") == 1);
224 assert_se(parse_boolean("YES") == 1);
225 assert_se(parse_boolean("true") == 1);
226 assert_se(parse_boolean("TRUE") == 1);
227 assert_se(parse_boolean("on") == 1);
228 assert_se(parse_boolean("ON") == 1);
229
230 assert_se(parse_boolean("0") == 0);
231 assert_se(parse_boolean("n") == 0);
232 assert_se(parse_boolean("N") == 0);
233 assert_se(parse_boolean("no") == 0);
234 assert_se(parse_boolean("NO") == 0);
235 assert_se(parse_boolean("false") == 0);
236 assert_se(parse_boolean("FALSE") == 0);
237 assert_se(parse_boolean("off") == 0);
238 assert_se(parse_boolean("OFF") == 0);
239
240 assert_se(parse_boolean("garbage") < 0);
241 assert_se(parse_boolean("") < 0);
242 assert_se(parse_boolean("full") < 0);
243 }
244
245 static void test_parse_pid(void) {
246 int r;
247 pid_t pid;
248
249 r = parse_pid("100", &pid);
250 assert_se(r == 0);
251 assert_se(pid == 100);
252
253 r = parse_pid("0x7FFFFFFF", &pid);
254 assert_se(r == 0);
255 assert_se(pid == 2147483647);
256
257 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
258 r = parse_pid("0", &pid);
259 assert_se(r == -ERANGE);
260 assert_se(pid == 65);
261
262 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
263 r = parse_pid("-100", &pid);
264 assert_se(r == -ERANGE);
265 assert_se(pid == 65);
266
267 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
268 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
269 assert_se(r == -ERANGE);
270 assert_se(pid == 65);
271 }
272
273 static void test_parse_uid(void) {
274 int r;
275 uid_t uid;
276
277 r = parse_uid("100", &uid);
278 assert_se(r == 0);
279 assert_se(uid == 100);
280 }
281
282 static void test_safe_atolli(void) {
283 int r;
284 long long l;
285
286 r = safe_atolli("12345", &l);
287 assert_se(r == 0);
288 assert_se(l == 12345);
289
290 r = safe_atolli("junk", &l);
291 assert_se(r == -EINVAL);
292 }
293
294 static void test_safe_atod(void) {
295 int r;
296 double d;
297 char *e;
298
299 r = safe_atod("junk", &d);
300 assert_se(r == -EINVAL);
301
302 r = safe_atod("0.2244", &d);
303 assert_se(r == 0);
304 assert_se(fabs(d - 0.2244) < 0.000001);
305
306 r = safe_atod("0,5", &d);
307 assert_se(r == -EINVAL);
308
309 errno = 0;
310 strtod("0,5", &e);
311 assert_se(*e == ',');
312
313 /* Check if this really is locale independent */
314 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
315
316 r = safe_atod("0.2244", &d);
317 assert_se(r == 0);
318 assert_se(fabs(d - 0.2244) < 0.000001);
319
320 r = safe_atod("0,5", &d);
321 assert_se(r == -EINVAL);
322
323 errno = 0;
324 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
325 }
326
327 /* And check again, reset */
328 assert_se(setlocale(LC_NUMERIC, "C"));
329
330 r = safe_atod("0.2244", &d);
331 assert_se(r == 0);
332 assert_se(fabs(d - 0.2244) < 0.000001);
333
334 r = safe_atod("0,5", &d);
335 assert_se(r == -EINVAL);
336
337 errno = 0;
338 strtod("0,5", &e);
339 assert_se(*e == ',');
340 }
341
342 static void test_strappend(void) {
343 _cleanup_free_ char *t1, *t2, *t3, *t4;
344
345 t1 = strappend(NULL, NULL);
346 assert_se(streq(t1, ""));
347
348 t2 = strappend(NULL, "suf");
349 assert_se(streq(t2, "suf"));
350
351 t3 = strappend("pre", NULL);
352 assert_se(streq(t3, "pre"));
353
354 t4 = strappend("pre", "suf");
355 assert_se(streq(t4, "presuf"));
356 }
357
358 static void test_strstrip(void) {
359 char *r;
360 char input[] = " hello, waldo. ";
361
362 r = strstrip(input);
363 assert_se(streq(r, "hello, waldo."));
364 }
365
366 static void test_delete_chars(void) {
367 char *r;
368 char input[] = " hello, waldo. abc";
369
370 r = delete_chars(input, WHITESPACE);
371 assert_se(streq(r, "hello,waldo.abc"));
372 }
373
374 static void test_in_charset(void) {
375 assert_se(in_charset("dddaaabbbcccc", "abcd"));
376 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
377 }
378
379 static void test_hexchar(void) {
380 assert_se(hexchar(0xa) == 'a');
381 assert_se(hexchar(0x0) == '0');
382 }
383
384 static void test_unhexchar(void) {
385 assert_se(unhexchar('a') == 0xA);
386 assert_se(unhexchar('A') == 0xA);
387 assert_se(unhexchar('0') == 0x0);
388 }
389
390 static void test_octchar(void) {
391 assert_se(octchar(00) == '0');
392 assert_se(octchar(07) == '7');
393 }
394
395 static void test_unoctchar(void) {
396 assert_se(unoctchar('0') == 00);
397 assert_se(unoctchar('7') == 07);
398 }
399
400 static void test_decchar(void) {
401 assert_se(decchar(0) == '0');
402 assert_se(decchar(9) == '9');
403 }
404
405 static void test_undecchar(void) {
406 assert_se(undecchar('0') == 0);
407 assert_se(undecchar('9') == 9);
408 }
409
410 static void test_cescape(void) {
411 _cleanup_free_ char *escaped;
412
413 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
414 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
415 }
416
417 static void test_cunescape(void) {
418 _cleanup_free_ char *unescaped;
419
420 unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00");
421 assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
422
423 /* incomplete sequences */
424 unescaped = cunescape("\\x0");
425 assert_se(streq_ptr(unescaped, "\\x0"));
426
427 unescaped = cunescape("\\x");
428 assert_se(streq_ptr(unescaped, "\\x"));
429
430 unescaped = cunescape("\\");
431 assert_se(streq_ptr(unescaped, "\\"));
432
433 unescaped = cunescape("\\11");
434 assert_se(streq_ptr(unescaped, "\\11"));
435
436 unescaped = cunescape("\\1");
437 assert_se(streq_ptr(unescaped, "\\1"));
438 }
439
440 static void test_foreach_word(void) {
441 const char *word, *state;
442 size_t l;
443 int i = 0;
444 const char test[] = "test abc d\te f ";
445 const char * const expected[] = {
446 "test",
447 "abc",
448 "d",
449 "e",
450 "f",
451 "",
452 NULL
453 };
454
455 FOREACH_WORD(word, l, test, state)
456 assert_se(strneq(expected[i++], word, l));
457 }
458
459 static void check(const char *test, char** expected, bool trailing) {
460 const char *word, *state;
461 size_t l;
462 int i = 0;
463
464 printf("<<<%s>>>\n", test);
465 FOREACH_WORD_QUOTED(word, l, test, state) {
466 _cleanup_free_ char *t = NULL;
467
468 assert_se(t = strndup(word, l));
469 assert_se(strneq(expected[i++], word, l));
470 printf("<%s>\n", t);
471 }
472 printf("<<<%s>>>\n", state);
473 assert_se(expected[i] == NULL);
474 assert_se(isempty(state) == !trailing);
475 }
476
477 static void test_foreach_word_quoted(void) {
478 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
479 STRV_MAKE("test",
480 "a",
481 "b",
482 "c",
483 "d",
484 "e",
485 "",
486 "",
487 "hhh",
488 "",
489 "",
490 "a b c"),
491 false);
492
493 check("test \"xxx",
494 STRV_MAKE("test"),
495 true);
496
497 check("test\\",
498 STRV_MAKE_EMPTY,
499 true);
500 }
501
502 static void test_default_term_for_tty(void) {
503 puts(default_term_for_tty("/dev/tty23"));
504 puts(default_term_for_tty("/dev/ttyS23"));
505 puts(default_term_for_tty("/dev/tty0"));
506 puts(default_term_for_tty("/dev/pty0"));
507 puts(default_term_for_tty("/dev/pts/0"));
508 puts(default_term_for_tty("/dev/console"));
509 puts(default_term_for_tty("tty23"));
510 puts(default_term_for_tty("ttyS23"));
511 puts(default_term_for_tty("tty0"));
512 puts(default_term_for_tty("pty0"));
513 puts(default_term_for_tty("pts/0"));
514 puts(default_term_for_tty("console"));
515 }
516
517 static void test_memdup_multiply(void) {
518 int org[] = {1, 2, 3};
519 int *dup;
520
521 dup = (int*)memdup_multiply(org, sizeof(int), 3);
522
523 assert_se(dup);
524 assert_se(dup[0] == 1);
525 assert_se(dup[1] == 2);
526 assert_se(dup[2] == 3);
527 free(dup);
528 }
529
530 static void test_hostname_is_valid(void) {
531 assert_se(hostname_is_valid("foobar"));
532 assert_se(hostname_is_valid("foobar.com"));
533 assert_se(!hostname_is_valid("fööbar"));
534 assert_se(!hostname_is_valid(""));
535 assert_se(!hostname_is_valid("."));
536 assert_se(!hostname_is_valid(".."));
537 assert_se(!hostname_is_valid("foobar."));
538 assert_se(!hostname_is_valid(".foobar"));
539 assert_se(!hostname_is_valid("foo..bar"));
540 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
541 }
542
543 static void test_u64log2(void) {
544 assert_se(u64log2(0) == 0);
545 assert_se(u64log2(8) == 3);
546 assert_se(u64log2(9) == 3);
547 assert_se(u64log2(15) == 3);
548 assert_se(u64log2(16) == 4);
549 assert_se(u64log2(1024*1024) == 20);
550 assert_se(u64log2(1024*1024+5) == 20);
551 }
552
553 static void test_get_process_comm(void) {
554 struct stat st;
555 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
556 _cleanup_free_ char *env = NULL;
557 pid_t e;
558 uid_t u;
559 gid_t g;
560 dev_t h;
561 int r;
562 pid_t me;
563
564 if (stat("/proc/1/comm", &st) == 0) {
565 assert_se(get_process_comm(1, &a) >= 0);
566 log_info("pid1 comm: '%s'", a);
567 } else {
568 log_warning("/proc/1/comm does not exist.");
569 }
570
571 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
572 log_info("pid1 cmdline: '%s'", c);
573
574 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
575 log_info("pid1 cmdline truncated: '%s'", d);
576
577 assert_se(get_parent_of_pid(1, &e) >= 0);
578 log_info("pid1 ppid: "PID_FMT, e);
579 assert_se(e == 0);
580
581 assert_se(is_kernel_thread(1) == 0);
582
583 r = get_process_exe(1, &f);
584 assert_se(r >= 0 || r == -EACCES);
585 log_info("pid1 exe: '%s'", strna(f));
586
587 assert_se(get_process_uid(1, &u) == 0);
588 log_info("pid1 uid: "UID_FMT, u);
589 assert_se(u == 0);
590
591 assert_se(get_process_gid(1, &g) == 0);
592 log_info("pid1 gid: "GID_FMT, g);
593 assert_se(g == 0);
594
595 me = getpid();
596
597 r = get_process_cwd(me, &cwd);
598 assert_se(r >= 0 || r == -EACCES);
599 log_info("pid1 cwd: '%s'", cwd);
600
601 r = get_process_root(me, &root);
602 assert_se(r >= 0 || r == -EACCES);
603 log_info("pid1 root: '%s'", root);
604
605 r = get_process_environ(me, &env);
606 assert_se(r >= 0 || r == -EACCES);
607 log_info("self strlen(environ): '%zu'", strlen(env));
608
609 if (!detect_container(NULL))
610 assert_se(get_ctty_devnr(1, &h) == -ENOENT);
611
612 getenv_for_pid(1, "PATH", &i);
613 log_info("pid1 $PATH: '%s'", strna(i));
614 }
615
616 static void test_protect_errno(void) {
617 errno = 12;
618 {
619 PROTECT_ERRNO;
620 errno = 11;
621 }
622 assert_se(errno == 12);
623 }
624
625 static void test_parse_size(void) {
626 off_t bytes;
627
628 assert_se(parse_size("111", 1024, &bytes) == 0);
629 assert_se(bytes == 111);
630
631 assert_se(parse_size("111.4", 1024, &bytes) == 0);
632 assert_se(bytes == 111);
633
634 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
635 assert_se(bytes == 112);
636
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);
647 assert_se(bytes == 3*1024);
648
649 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
650
651 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
652 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
653
654 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
655
656 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
657 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
658
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);
668 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
669
670 assert_se(parse_size("12P", 1024, &bytes) == 0);
671 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
672
673 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
674
675 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
676 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
677
678 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
679
680 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
681
682 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
683
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);
687
688 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
689
690 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
691 }
692
693 static 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
701 static 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
707 static 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
718 static 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
740 static 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
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
774 static 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);
778 assert_se(get_files_in_directory(".", &t) >= 0);
779 assert_se(get_files_in_directory(".", NULL) >= 0);
780 }
781
782 static 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
792 static void test_writing_tmpfile(void) {
793 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
794 _cleanup_free_ char *contents = NULL;
795 size_t size;
796 int fd, r;
797 struct iovec iov[3];
798
799 IOVEC_SET_STRING(iov[0], "abc\n");
800 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
801 IOVEC_SET_STRING(iov[2], "");
802
803 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
804 printf("tmpfile: %s", name);
805
806 r = writev(fd, iov, 3);
807 assert_se(r >= 0);
808
809 r = read_full_file(name, &contents, &size);
810 assert_se(r == 0);
811 printf("contents: %s", contents);
812 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
813
814 unlink(name);
815 }
816
817 static 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
836 static 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
847 static 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
866 static void test_filename_is_valid(void) {
867 char foo[FILENAME_MAX+2];
868 int i;
869
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(".."));
875
876 for (i=0; i<FILENAME_MAX+1; i++)
877 foo[i] = 'a';
878 foo[FILENAME_MAX+1] = '\0';
879
880 assert_se(!filename_is_valid(foo));
881
882 assert_se(filename_is_valid("foo_bar-333"));
883 assert_se(filename_is_valid("o.o"));
884 }
885
886 static 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
900 static 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
905 static 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
921 static void test_is_valid_documentation_url(void) {
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(""));
931 }
932
933 static void test_file_in_same_dir(void) {
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);
955 }
956
957 static 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
967 static 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
980 static 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
998 static 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
1005 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
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
1021 assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
1022 }
1023
1024 static void test_read_one_char(void) {
1025 _cleanup_fclose_ FILE *file = NULL;
1026 char r;
1027 bool need_nl;
1028 char name[] = "/tmp/test-read_one_char.XXXXXX";
1029 int fd;
1030
1031 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1032 assert_se(fd >= 0);
1033 file = fdopen(fd, "r+");
1034 assert_se(file);
1035 assert_se(fputs("c\n", file) >= 0);
1036 rewind(file);
1037
1038 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
1039 assert_se(!need_nl);
1040 assert_se(r == 'c');
1041 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1042
1043 rewind(file);
1044 assert_se(fputs("foobar\n", file) >= 0);
1045 rewind(file);
1046 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1047
1048 rewind(file);
1049 assert_se(fputs("\n", file) >= 0);
1050 rewind(file);
1051 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1052
1053 unlink(name);
1054 }
1055
1056 static void test_ignore_signals(void) {
1057 assert_se(ignore_signals(SIGINT, -1) >= 0);
1058 assert_se(kill(getpid(), SIGINT) >= 0);
1059 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1060 assert_se(kill(getpid(), SIGUSR1) >= 0);
1061 assert_se(kill(getpid(), SIGUSR2) >= 0);
1062 assert_se(kill(getpid(), SIGTERM) >= 0);
1063 assert_se(kill(getpid(), SIGPIPE) >= 0);
1064 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1065 }
1066
1067 static void test_strshorten(void) {
1068 char s[] = "foobar";
1069
1070 assert_se(strlen(strshorten(s, 6)) == 6);
1071 assert_se(strlen(strshorten(s, 12)) == 6);
1072 assert_se(strlen(strshorten(s, 2)) == 2);
1073 assert_se(strlen(strshorten(s, 0)) == 0);
1074 }
1075
1076 static void test_strjoina(void) {
1077 char *actual;
1078
1079 actual = strjoina("", "foo", "bar");
1080 assert_se(streq(actual, "foobar"));
1081
1082 actual = strjoina("foo", "bar", "baz");
1083 assert_se(streq(actual, "foobarbaz"));
1084
1085 actual = strjoina("foo", "", "bar", "baz");
1086 assert_se(streq(actual, "foobarbaz"));
1087
1088 actual = strjoina("foo");
1089 assert_se(streq(actual, "foo"));
1090
1091 actual = strjoina(NULL);
1092 assert_se(streq(actual, ""));
1093
1094 actual = strjoina(NULL, "foo");
1095 assert_se(streq(actual, ""));
1096
1097 actual = strjoina("foo", NULL, "bar");
1098 assert_se(streq(actual, "foo"));
1099 }
1100
1101 static void test_is_symlink(void) {
1102 char name[] = "/tmp/test-is_symlink.XXXXXX";
1103 char name_link[] = "/tmp/test-is_symlink.link";
1104 _cleanup_close_ int fd = -1;
1105
1106 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1107 assert_se(fd >= 0);
1108 assert_se(symlink(name, name_link) >= 0);
1109
1110 assert_se(is_symlink(name) == 0);
1111 assert_se(is_symlink(name_link) == 1);
1112 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1113
1114
1115 unlink(name);
1116 unlink(name_link);
1117 }
1118
1119 static void test_pid_is_unwaited(void) {
1120 pid_t pid;
1121
1122 pid = fork();
1123 assert_se(pid >= 0);
1124 if (pid == 0) {
1125 _exit(EXIT_SUCCESS);
1126 } else {
1127 int status;
1128
1129 waitpid(pid, &status, 0);
1130 assert_se(!pid_is_unwaited(pid));
1131 }
1132 assert_se(pid_is_unwaited(getpid()));
1133 assert_se(!pid_is_unwaited(-1));
1134 }
1135
1136 static void test_pid_is_alive(void) {
1137 pid_t pid;
1138
1139 pid = fork();
1140 assert_se(pid >= 0);
1141 if (pid == 0) {
1142 _exit(EXIT_SUCCESS);
1143 } else {
1144 int status;
1145
1146 waitpid(pid, &status, 0);
1147 assert_se(!pid_is_alive(pid));
1148 }
1149 assert_se(pid_is_alive(getpid()));
1150 assert_se(!pid_is_alive(-1));
1151 }
1152
1153 static void test_search_and_fopen(void) {
1154 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1155 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1156 int fd = -1;
1157 int r;
1158 FILE *f;
1159
1160 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1161 assert_se(fd >= 0);
1162 close(fd);
1163
1164 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1165 assert_se(r >= 0);
1166 fclose(f);
1167
1168 r = search_and_fopen(name, "r", NULL, dirs, &f);
1169 assert_se(r >= 0);
1170 fclose(f);
1171
1172 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1173 assert_se(r >= 0);
1174 fclose(f);
1175
1176 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1177 assert_se(r < 0);
1178 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1179 assert_se(r < 0);
1180
1181 r = unlink(name);
1182 assert_se(r == 0);
1183
1184 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1185 assert_se(r < 0);
1186 }
1187
1188
1189 static void test_search_and_fopen_nulstr(void) {
1190 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1191 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1192 int fd = -1;
1193 int r;
1194 FILE *f;
1195
1196 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1197 assert_se(fd >= 0);
1198 close(fd);
1199
1200 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1201 assert_se(r >= 0);
1202 fclose(f);
1203
1204 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1205 assert_se(r >= 0);
1206 fclose(f);
1207
1208 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1209 assert_se(r < 0);
1210 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1211 assert_se(r < 0);
1212
1213 r = unlink(name);
1214 assert_se(r == 0);
1215
1216 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1217 assert_se(r < 0);
1218 }
1219
1220 static void test_glob_exists(void) {
1221 char name[] = "/tmp/test-glob_exists.XXXXXX";
1222 int fd = -1;
1223 int r;
1224
1225 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1226 assert_se(fd >= 0);
1227 close(fd);
1228
1229 r = glob_exists("/tmp/test-glob_exists*");
1230 assert_se(r == 1);
1231
1232 r = unlink(name);
1233 assert_se(r == 0);
1234 r = glob_exists("/tmp/test-glob_exists*");
1235 assert_se(r == 0);
1236 }
1237
1238 static void test_execute_directory(void) {
1239 char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1240 char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
1241 const char * dirs[] = {template_hi, template_lo, NULL};
1242 const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
1243
1244 assert_se(mkdtemp(template_lo));
1245 assert_se(mkdtemp(template_hi));
1246
1247 name = strjoina(template_lo, "/script");
1248 name2 = strjoina(template_hi, "/script2");
1249 name3 = strjoina(template_lo, "/useless");
1250 overridden = strjoina(template_lo, "/overridden");
1251 override = strjoina(template_hi, "/overridden");
1252 masked = strjoina(template_lo, "/masked");
1253 mask = strjoina(template_hi, "/masked");
1254
1255 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works") == 0);
1256 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2") == 0);
1257 assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1258 assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0") == 0);
1259 assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1260 assert_se(symlink("/dev/null", mask) == 0);
1261 assert_se(chmod(name, 0755) == 0);
1262 assert_se(chmod(name2, 0755) == 0);
1263 assert_se(chmod(overridden, 0755) == 0);
1264 assert_se(chmod(override, 0755) == 0);
1265 assert_se(chmod(masked, 0755) == 0);
1266 assert_se(touch(name3) >= 0);
1267
1268 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
1269
1270 assert_se(chdir(template_lo) == 0);
1271 assert_se(access("it_works", F_OK) >= 0);
1272 assert_se(access("failed", F_OK) < 0);
1273
1274 assert_se(chdir(template_hi) == 0);
1275 assert_se(access("it_works2", F_OK) >= 0);
1276 assert_se(access("failed", F_OK) < 0);
1277
1278 (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
1279 (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
1280 }
1281
1282 static void test_unquote_first_word(void) {
1283 const char *p, *original;
1284 char *t;
1285
1286 p = original = "foobar waldo";
1287 assert_se(unquote_first_word(&p, &t, 0) > 0);
1288 assert_se(streq(t, "foobar"));
1289 free(t);
1290 assert_se(p == original + 7);
1291
1292 assert_se(unquote_first_word(&p, &t, 0) > 0);
1293 assert_se(streq(t, "waldo"));
1294 free(t);
1295 assert_se(p == original + 12);
1296
1297 assert_se(unquote_first_word(&p, &t, 0) == 0);
1298 assert_se(!t);
1299 assert_se(p == original + 12);
1300
1301 p = original = "\"foobar\" \'waldo\'";
1302 assert_se(unquote_first_word(&p, &t, 0) > 0);
1303 assert_se(streq(t, "foobar"));
1304 free(t);
1305 assert_se(p == original + 9);
1306
1307 assert_se(unquote_first_word(&p, &t, 0) > 0);
1308 assert_se(streq(t, "waldo"));
1309 free(t);
1310 assert_se(p == original + 16);
1311
1312 assert_se(unquote_first_word(&p, &t, 0) == 0);
1313 assert_se(!t);
1314 assert_se(p == original + 16);
1315
1316 p = original = "\"";
1317 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
1318 assert_se(p == original + 1);
1319
1320 p = original = "\'";
1321 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
1322 assert_se(p == original + 1);
1323
1324 p = original = "\'fooo";
1325 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
1326 assert_se(p == original + 5);
1327
1328 p = original = "\'fooo";
1329 assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
1330 assert_se(streq(t, "fooo"));
1331 free(t);
1332 assert_se(p == original + 5);
1333
1334 p = original = "yay\'foo\'bar";
1335 assert_se(unquote_first_word(&p, &t, 0) > 0);
1336 assert_se(streq(t, "yayfoobar"));
1337 free(t);
1338 assert_se(p == original + 11);
1339
1340 p = original = " foobar ";
1341 assert_se(unquote_first_word(&p, &t, 0) > 0);
1342 assert_se(streq(t, "foobar"));
1343 free(t);
1344 assert_se(p == original + 12);
1345
1346 p = original = " foo\\ba\\x6ar ";
1347 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1348 assert_se(streq(t, "foo\ba\x6ar"));
1349 free(t);
1350 assert_se(p == original + 13);
1351
1352 p = original = " foo\\ba\\x6ar ";
1353 assert_se(unquote_first_word(&p, &t, 0) > 0);
1354 assert_se(streq(t, "foobax6ar"));
1355 free(t);
1356 assert_se(p == original + 13);
1357 }
1358
1359 static void test_unquote_many_words(void) {
1360 const char *p, *original;
1361 char *a, *b, *c;
1362
1363 p = original = "foobar waldi piep";
1364 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 3);
1365 assert_se(p == original + 17);
1366 assert_se(streq_ptr(a, "foobar"));
1367 assert_se(streq_ptr(b, "waldi"));
1368 assert_se(streq_ptr(c, "piep"));
1369 free(a);
1370 free(b);
1371 free(c);
1372
1373 p = original = "'foobar' wa\"ld\"i ";
1374 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 2);
1375 assert_se(p == original + 19);
1376 assert_se(streq_ptr(a, "foobar"));
1377 assert_se(streq_ptr(b, "waldi"));
1378 assert_se(streq_ptr(c, NULL));
1379 free(a);
1380 free(b);
1381
1382 p = original = "";
1383 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
1384 assert_se(p == original);
1385 assert_se(streq_ptr(a, NULL));
1386 assert_se(streq_ptr(b, NULL));
1387 assert_se(streq_ptr(c, NULL));
1388
1389 p = original = " ";
1390 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
1391 assert_se(p == original+2);
1392 assert_se(streq_ptr(a, NULL));
1393 assert_se(streq_ptr(b, NULL));
1394 assert_se(streq_ptr(c, NULL));
1395
1396 p = original = "foobar";
1397 assert_se(unquote_many_words(&p, 0, NULL) == 0);
1398 assert_se(p == original);
1399
1400 p = original = "foobar waldi";
1401 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
1402 assert_se(p == original+7);
1403 assert_se(streq_ptr(a, "foobar"));
1404 free(a);
1405
1406 p = original = " foobar ";
1407 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
1408 assert_se(p == original+15);
1409 assert_se(streq_ptr(a, "foobar"));
1410 free(a);
1411 }
1412
1413 static int parse_item(const char *key, const char *value) {
1414 assert_se(key);
1415
1416 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1417 return 0;
1418 }
1419
1420 static void test_parse_proc_cmdline(void) {
1421 assert_se(parse_proc_cmdline(parse_item) >= 0);
1422 }
1423
1424 static void test_raw_clone(void) {
1425 pid_t parent, pid, pid2;
1426
1427 parent = getpid();
1428 log_info("before clone: getpid()→"PID_FMT, parent);
1429 assert_se(raw_getpid() == parent);
1430
1431 pid = raw_clone(0, NULL);
1432 assert_se(pid >= 0);
1433
1434 pid2 = raw_getpid();
1435 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1436 pid, getpid(), pid2);
1437 if (pid == 0) {
1438 assert_se(pid2 != parent);
1439 _exit(EXIT_SUCCESS);
1440 } else {
1441 int status;
1442
1443 assert_se(pid2 == parent);
1444 waitpid(pid, &status, __WCLONE);
1445 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1446 }
1447 }
1448
1449 static void test_same_fd(void) {
1450 _cleanup_close_pair_ int p[2] = { -1, -1 };
1451 _cleanup_close_ int a = -1, b = -1, c = -1;
1452
1453 assert_se(pipe2(p, O_CLOEXEC) >= 0);
1454 assert_se((a = dup(p[0])) >= 0);
1455 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1456 assert_se((c = dup(a)) >= 0);
1457
1458 assert_se(same_fd(p[0], p[0]) > 0);
1459 assert_se(same_fd(p[1], p[1]) > 0);
1460 assert_se(same_fd(a, a) > 0);
1461 assert_se(same_fd(b, b) > 0);
1462
1463 assert_se(same_fd(a, p[0]) > 0);
1464 assert_se(same_fd(p[0], a) > 0);
1465 assert_se(same_fd(c, p[0]) > 0);
1466 assert_se(same_fd(p[0], c) > 0);
1467 assert_se(same_fd(a, c) > 0);
1468 assert_se(same_fd(c, a) > 0);
1469
1470 assert_se(same_fd(p[0], p[1]) == 0);
1471 assert_se(same_fd(p[1], p[0]) == 0);
1472 assert_se(same_fd(p[0], b) == 0);
1473 assert_se(same_fd(b, p[0]) == 0);
1474 assert_se(same_fd(p[1], a) == 0);
1475 assert_se(same_fd(a, p[1]) == 0);
1476 assert_se(same_fd(p[1], b) == 0);
1477 assert_se(same_fd(b, p[1]) == 0);
1478
1479 assert_se(same_fd(a, b) == 0);
1480 assert_se(same_fd(b, a) == 0);
1481 }
1482
1483 static void test_uid_ptr(void) {
1484
1485 assert_se(UID_TO_PTR(0) != NULL);
1486 assert_se(UID_TO_PTR(1000) != NULL);
1487
1488 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1489 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1490 }
1491
1492 static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
1493 char check[n];
1494
1495 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1496 assert_se(ftruncate(fd, 0) >= 0);
1497 assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
1498
1499 assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
1500 assert_se(ftruncate(fd, n) >= 0);
1501
1502 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1503 assert_se(read(fd, check, n) == (ssize_t) n);
1504
1505 assert_se(memcmp(buffer, check, n) == 0);
1506 }
1507
1508 static void test_sparse_write(void) {
1509 const char test_a[] = "test";
1510 const char test_b[] = "\0\0\0\0test\0\0\0\0";
1511 const char test_c[] = "\0\0test\0\0\0\0";
1512 const char test_d[] = "\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0\0\0\0";
1513 const char test_e[] = "test\0\0\0\0test";
1514 _cleanup_close_ int fd = -1;
1515 char fn[] = "/tmp/sparseXXXXXX";
1516
1517 fd = mkostemp(fn, O_CLOEXEC);
1518 assert_se(fd >= 0);
1519 unlink(fn);
1520
1521 test_sparse_write_one(fd, test_a, sizeof(test_a));
1522 test_sparse_write_one(fd, test_b, sizeof(test_b));
1523 test_sparse_write_one(fd, test_c, sizeof(test_c));
1524 test_sparse_write_one(fd, test_d, sizeof(test_d));
1525 test_sparse_write_one(fd, test_e, sizeof(test_e));
1526 }
1527
1528 int main(int argc, char *argv[]) {
1529 log_parse_environment();
1530 log_open();
1531
1532 test_streq_ptr();
1533 test_align_power2();
1534 test_max();
1535 test_container_of();
1536 test_alloca();
1537 test_div_round_up();
1538 test_first_word();
1539 test_close_many();
1540 test_parse_boolean();
1541 test_parse_pid();
1542 test_parse_uid();
1543 test_safe_atolli();
1544 test_safe_atod();
1545 test_strappend();
1546 test_strstrip();
1547 test_delete_chars();
1548 test_in_charset();
1549 test_hexchar();
1550 test_unhexchar();
1551 test_octchar();
1552 test_unoctchar();
1553 test_decchar();
1554 test_undecchar();
1555 test_cescape();
1556 test_cunescape();
1557 test_foreach_word();
1558 test_foreach_word_quoted();
1559 test_default_term_for_tty();
1560 test_memdup_multiply();
1561 test_hostname_is_valid();
1562 test_u64log2();
1563 test_get_process_comm();
1564 test_protect_errno();
1565 test_parse_size();
1566 test_config_parse_iec_off();
1567 test_strextend();
1568 test_strrep();
1569 test_split_pair();
1570 test_fstab_node_to_udev_node();
1571 test_get_files_in_directory();
1572 test_in_set();
1573 test_writing_tmpfile();
1574 test_hexdump();
1575 test_log2i();
1576 test_foreach_string();
1577 test_filename_is_valid();
1578 test_string_has_cc();
1579 test_ascii_strlower();
1580 test_files_same();
1581 test_is_valid_documentation_url();
1582 test_file_in_same_dir();
1583 test_endswith();
1584 test_close_nointr();
1585 test_unlink_noerrno();
1586 test_readlink_and_make_absolute();
1587 test_read_one_char();
1588 test_ignore_signals();
1589 test_strshorten();
1590 test_strjoina();
1591 test_is_symlink();
1592 test_pid_is_unwaited();
1593 test_pid_is_alive();
1594 test_search_and_fopen();
1595 test_search_and_fopen_nulstr();
1596 test_glob_exists();
1597 test_execute_directory();
1598 test_unquote_first_word();
1599 test_unquote_many_words();
1600 test_parse_proc_cmdline();
1601 test_raw_clone();
1602 test_same_fd();
1603 test_uid_ptr();
1604 test_sparse_write();
1605
1606 return 0;
1607 }