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