chiark / gitweb /
a37316b9cb2bd124e2bb1273f7f3ecedff0f18fd
[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_strappenda(void) {
1076         char *actual;
1077
1078         actual = strappenda("", "foo", "bar");
1079         assert_se(streq(actual, "foobar"));
1080
1081         actual = strappenda("foo", "bar", "baz");
1082         assert_se(streq(actual, "foobarbaz"));
1083
1084         actual = strappenda("foo", "", "bar", "baz");
1085         assert_se(streq(actual, "foobarbaz"));
1086 }
1087
1088 static void test_is_symlink(void) {
1089         char name[] = "/tmp/test-is_symlink.XXXXXX";
1090         char name_link[] = "/tmp/test-is_symlink.link";
1091         _cleanup_close_ int fd = -1;
1092
1093         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1094         assert_se(fd >= 0);
1095         assert_se(symlink(name, name_link) >= 0);
1096
1097         assert_se(is_symlink(name) == 0);
1098         assert_se(is_symlink(name_link) == 1);
1099         assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1100
1101
1102         unlink(name);
1103         unlink(name_link);
1104 }
1105
1106 static void test_pid_is_unwaited(void) {
1107         pid_t pid;
1108
1109         pid = fork();
1110         assert_se(pid >= 0);
1111         if (pid == 0) {
1112                 _exit(EXIT_SUCCESS);
1113         } else {
1114                 int status;
1115
1116                 waitpid(pid, &status, 0);
1117                 assert_se(!pid_is_unwaited(pid));
1118         }
1119         assert_se(pid_is_unwaited(getpid()));
1120         assert_se(!pid_is_unwaited(-1));
1121 }
1122
1123 static void test_pid_is_alive(void) {
1124         pid_t pid;
1125
1126         pid = fork();
1127         assert_se(pid >= 0);
1128         if (pid == 0) {
1129                 _exit(EXIT_SUCCESS);
1130         } else {
1131                 int status;
1132
1133                 waitpid(pid, &status, 0);
1134                 assert_se(!pid_is_alive(pid));
1135         }
1136         assert_se(pid_is_alive(getpid()));
1137         assert_se(!pid_is_alive(-1));
1138 }
1139
1140 static void test_search_and_fopen(void) {
1141         const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1142         char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1143         int fd = -1;
1144         int r;
1145         FILE *f;
1146
1147         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1148         assert_se(fd >= 0);
1149         close(fd);
1150
1151         r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1152         assert_se(r >= 0);
1153         fclose(f);
1154
1155         r = search_and_fopen(name, "r", NULL, dirs, &f);
1156         assert_se(r >= 0);
1157         fclose(f);
1158
1159         r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1160         assert_se(r >= 0);
1161         fclose(f);
1162
1163         r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1164         assert_se(r < 0);
1165         r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1166         assert_se(r < 0);
1167
1168         r = unlink(name);
1169         assert_se(r == 0);
1170
1171         r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1172         assert_se(r < 0);
1173 }
1174
1175
1176 static void test_search_and_fopen_nulstr(void) {
1177         const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1178         char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1179         int fd = -1;
1180         int r;
1181         FILE *f;
1182
1183         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1184         assert_se(fd >= 0);
1185         close(fd);
1186
1187         r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1188         assert_se(r >= 0);
1189         fclose(f);
1190
1191         r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1192         assert_se(r >= 0);
1193         fclose(f);
1194
1195         r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1196         assert_se(r < 0);
1197         r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1198         assert_se(r < 0);
1199
1200         r = unlink(name);
1201         assert_se(r == 0);
1202
1203         r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1204         assert_se(r < 0);
1205 }
1206
1207 static void test_glob_exists(void) {
1208         char name[] = "/tmp/test-glob_exists.XXXXXX";
1209         int fd = -1;
1210         int r;
1211
1212         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1213         assert_se(fd >= 0);
1214         close(fd);
1215
1216         r = glob_exists("/tmp/test-glob_exists*");
1217         assert_se(r == 1);
1218
1219         r = unlink(name);
1220         assert_se(r == 0);
1221         r = glob_exists("/tmp/test-glob_exists*");
1222         assert_se(r == 0);
1223 }
1224
1225 static void test_execute_directory(void) {
1226         char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1227         char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
1228         const char const* dirs[] = {template_hi, template_lo, NULL};
1229         const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
1230
1231         assert_se(mkdtemp(template_lo));
1232         assert_se(mkdtemp(template_hi));
1233
1234         name = strappenda(template_lo, "/script");
1235         name2 = strappenda(template_hi, "/script2");
1236         name3 = strappenda(template_lo, "/useless");
1237         overridden = strappenda(template_lo, "/overridden");
1238         override = strappenda(template_hi, "/overridden");
1239         masked = strappenda(template_lo, "/masked");
1240         mask = strappenda(template_hi, "/masked");
1241
1242         assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works") == 0);
1243         assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2") == 0);
1244         assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1245         assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0") == 0);
1246         assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1247         assert_se(symlink("/dev/null", mask) == 0);
1248         assert_se(chmod(name, 0755) == 0);
1249         assert_se(chmod(name2, 0755) == 0);
1250         assert_se(chmod(overridden, 0755) == 0);
1251         assert_se(chmod(override, 0755) == 0);
1252         assert_se(chmod(masked, 0755) == 0);
1253         assert_se(touch(name3) >= 0);
1254
1255         execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
1256
1257         assert(chdir(template_lo) == 0);
1258         assert_se(access("it_works", F_OK) >= 0);
1259         assert_se(access("failed", F_OK) < 0);
1260
1261         assert(chdir(template_hi) == 0);
1262         assert_se(access("it_works2", F_OK) >= 0);
1263         assert_se(access("failed", F_OK) < 0);
1264
1265         rm_rf_dangerous(template_lo, false, true, false);
1266         rm_rf_dangerous(template_hi, false, true, false);
1267 }
1268
1269 static void test_unquote_first_word(void) {
1270         const char *p, *original;
1271         char *t;
1272
1273         p = original = "foobar waldo";
1274         assert_se(unquote_first_word(&p, &t, false) > 0);
1275         assert_se(streq(t, "foobar"));
1276         free(t);
1277         assert_se(p == original + 7);
1278
1279         assert_se(unquote_first_word(&p, &t, false) > 0);
1280         assert_se(streq(t, "waldo"));
1281         free(t);
1282         assert_se(p == original + 12);
1283
1284         assert_se(unquote_first_word(&p, &t, false) == 0);
1285         assert_se(!t);
1286         assert_se(p == original + 12);
1287
1288         p = original = "\"foobar\" \'waldo\'";
1289         assert_se(unquote_first_word(&p, &t, false) > 0);
1290         assert_se(streq(t, "foobar"));
1291         free(t);
1292         assert_se(p == original + 9);
1293
1294         assert_se(unquote_first_word(&p, &t, false) > 0);
1295         assert_se(streq(t, "waldo"));
1296         free(t);
1297         assert_se(p == original + 16);
1298
1299         assert_se(unquote_first_word(&p, &t, false) == 0);
1300         assert_se(!t);
1301         assert_se(p == original + 16);
1302
1303         p = original = "\"";
1304         assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1305         assert_se(p == original + 1);
1306
1307         p = original = "\'";
1308         assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1309         assert_se(p == original + 1);
1310
1311         p = original = "\'fooo";
1312         assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1313         assert_se(p == original + 5);
1314
1315         p = original = "\'fooo";
1316         assert_se(unquote_first_word(&p, &t, true) > 0);
1317         assert_se(streq(t, "fooo"));
1318         free(t);
1319         assert_se(p == original + 5);
1320
1321         p = original = "yay\'foo\'bar";
1322         assert_se(unquote_first_word(&p, &t, false) > 0);
1323         assert_se(streq(t, "yayfoobar"));
1324         free(t);
1325         assert_se(p == original + 11);
1326
1327         p = original = "   foobar   ";
1328         assert_se(unquote_first_word(&p, &t, false) > 0);
1329         assert_se(streq(t, "foobar"));
1330         free(t);
1331         assert_se(p == original + 12);
1332 }
1333
1334 static void test_unquote_many_words(void) {
1335         const char *p, *original;
1336         char *a, *b, *c;
1337
1338         p = original = "foobar waldi piep";
1339         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1340         assert_se(p == original + 17);
1341         assert_se(streq_ptr(a, "foobar"));
1342         assert_se(streq_ptr(b, "waldi"));
1343         assert_se(streq_ptr(c, "piep"));
1344         free(a);
1345         free(b);
1346         free(c);
1347
1348         p = original = "'foobar' wa\"ld\"i   ";
1349         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1350         assert_se(p == original + 19);
1351         assert_se(streq_ptr(a, "foobar"));
1352         assert_se(streq_ptr(b, "waldi"));
1353         assert_se(streq_ptr(c, NULL));
1354         free(a);
1355         free(b);
1356
1357         p = original = "";
1358         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1359         assert_se(p == original);
1360         assert_se(streq_ptr(a, NULL));
1361         assert_se(streq_ptr(b, NULL));
1362         assert_se(streq_ptr(c, NULL));
1363
1364         p = original = "  ";
1365         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1366         assert_se(p == original+2);
1367         assert_se(streq_ptr(a, NULL));
1368         assert_se(streq_ptr(b, NULL));
1369         assert_se(streq_ptr(c, NULL));
1370
1371         p = original = "foobar";
1372         assert_se(unquote_many_words(&p, NULL) == 0);
1373         assert_se(p == original);
1374
1375         p = original = "foobar waldi";
1376         assert_se(unquote_many_words(&p, &a, NULL) == 1);
1377         assert_se(p == original+7);
1378         assert_se(streq_ptr(a, "foobar"));
1379         free(a);
1380
1381         p = original = "     foobar    ";
1382         assert_se(unquote_many_words(&p, &a, NULL) == 1);
1383         assert_se(p == original+15);
1384         assert_se(streq_ptr(a, "foobar"));
1385         free(a);
1386 }
1387
1388 static int parse_item(const char *key, const char *value) {
1389         assert_se(key);
1390
1391         log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1392         return 0;
1393 }
1394
1395 static void test_parse_proc_cmdline(void) {
1396         assert_se(parse_proc_cmdline(parse_item) >= 0);
1397 }
1398
1399 static void test_raw_clone(void) {
1400         pid_t parent, pid, pid2;
1401
1402         parent = getpid();
1403         log_info("before clone: getpid()→"PID_FMT, parent);
1404         assert_se(raw_getpid() == parent);
1405
1406         pid = raw_clone(0, NULL);
1407         assert_se(pid >= 0);
1408
1409         pid2 = raw_getpid();
1410         log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1411                  pid, getpid(), pid2);
1412         if (pid == 0) {
1413                 assert_se(pid2 != parent);
1414                 _exit(EXIT_SUCCESS);
1415         } else {
1416                 int status;
1417
1418                 assert_se(pid2 == parent);
1419                 waitpid(pid, &status, __WCLONE);
1420                 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1421         }
1422 }
1423
1424 static void test_same_fd(void) {
1425         _cleanup_close_pair_ int p[2] = { -1, -1 };
1426         _cleanup_close_ int a = -1, b = -1, c = -1;
1427
1428         assert_se(pipe2(p, O_CLOEXEC) >= 0);
1429         assert_se((a = dup(p[0])) >= 0);
1430         assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1431         assert_se((c = dup(a)) >= 0);
1432
1433         assert_se(same_fd(p[0], p[0]) > 0);
1434         assert_se(same_fd(p[1], p[1]) > 0);
1435         assert_se(same_fd(a, a) > 0);
1436         assert_se(same_fd(b, b) > 0);
1437
1438         assert_se(same_fd(a, p[0]) > 0);
1439         assert_se(same_fd(p[0], a) > 0);
1440         assert_se(same_fd(c, p[0]) > 0);
1441         assert_se(same_fd(p[0], c) > 0);
1442         assert_se(same_fd(a, c) > 0);
1443         assert_se(same_fd(c, a) > 0);
1444
1445         assert_se(same_fd(p[0], p[1]) == 0);
1446         assert_se(same_fd(p[1], p[0]) == 0);
1447         assert_se(same_fd(p[0], b) == 0);
1448         assert_se(same_fd(b, p[0]) == 0);
1449         assert_se(same_fd(p[1], a) == 0);
1450         assert_se(same_fd(a, p[1]) == 0);
1451         assert_se(same_fd(p[1], b) == 0);
1452         assert_se(same_fd(b, p[1]) == 0);
1453
1454         assert_se(same_fd(a, b) == 0);
1455         assert_se(same_fd(b, a) == 0);
1456 }
1457
1458 static void test_uid_ptr(void) {
1459
1460         assert_se(UID_TO_PTR(0) != NULL);
1461         assert_se(UID_TO_PTR(1000) != NULL);
1462
1463         assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1464         assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1465 }
1466
1467 static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
1468         char check[n];
1469
1470         assert_se(lseek(fd, 0, SEEK_SET) == 0);
1471         assert_se(ftruncate(fd, 0) >= 0);
1472         assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
1473
1474         assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
1475         assert_se(ftruncate(fd, n) >= 0);
1476
1477         assert_se(lseek(fd, 0, SEEK_SET) == 0);
1478         assert_se(read(fd, check, n) == (ssize_t) n);
1479
1480         assert_se(memcmp(buffer, check, n) == 0);
1481 }
1482
1483 static void test_sparse_write(void) {
1484         const char test_a[] = "test";
1485         const char test_b[] = "\0\0\0\0test\0\0\0\0";
1486         const char test_c[] = "\0\0test\0\0\0\0";
1487         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";
1488         const char test_e[] = "test\0\0\0\0test";
1489         _cleanup_close_ int fd = -1;
1490         char fn[] = "/tmp/sparseXXXXXX";
1491
1492         fd = mkostemp(fn, O_CLOEXEC);
1493         assert_se(fd >= 0);
1494         unlink(fn);
1495
1496         test_sparse_write_one(fd, test_a, sizeof(test_a));
1497         test_sparse_write_one(fd, test_b, sizeof(test_b));
1498         test_sparse_write_one(fd, test_c, sizeof(test_c));
1499         test_sparse_write_one(fd, test_d, sizeof(test_d));
1500         test_sparse_write_one(fd, test_e, sizeof(test_e));
1501 }
1502
1503 int main(int argc, char *argv[]) {
1504         log_parse_environment();
1505         log_open();
1506
1507         test_streq_ptr();
1508         test_align_power2();
1509         test_max();
1510         test_container_of();
1511         test_alloca();
1512         test_div_round_up();
1513         test_first_word();
1514         test_close_many();
1515         test_parse_boolean();
1516         test_parse_pid();
1517         test_parse_uid();
1518         test_safe_atolli();
1519         test_safe_atod();
1520         test_strappend();
1521         test_strstrip();
1522         test_delete_chars();
1523         test_in_charset();
1524         test_hexchar();
1525         test_unhexchar();
1526         test_octchar();
1527         test_unoctchar();
1528         test_decchar();
1529         test_undecchar();
1530         test_cescape();
1531         test_cunescape();
1532         test_foreach_word();
1533         test_foreach_word_quoted();
1534         test_default_term_for_tty();
1535         test_memdup_multiply();
1536         test_hostname_is_valid();
1537         test_u64log2();
1538         test_get_process_comm();
1539         test_protect_errno();
1540         test_parse_size();
1541         test_config_parse_iec_off();
1542         test_strextend();
1543         test_strrep();
1544         test_split_pair();
1545         test_fstab_node_to_udev_node();
1546         test_get_files_in_directory();
1547         test_in_set();
1548         test_writing_tmpfile();
1549         test_hexdump();
1550         test_log2i();
1551         test_foreach_string();
1552         test_filename_is_valid();
1553         test_string_has_cc();
1554         test_ascii_strlower();
1555         test_files_same();
1556         test_is_valid_documentation_url();
1557         test_file_in_same_dir();
1558         test_endswith();
1559         test_close_nointr();
1560         test_unlink_noerrno();
1561         test_readlink_and_make_absolute();
1562         test_read_one_char();
1563         test_ignore_signals();
1564         test_strshorten();
1565         test_strappenda();
1566         test_is_symlink();
1567         test_pid_is_unwaited();
1568         test_pid_is_alive();
1569         test_search_and_fopen();
1570         test_search_and_fopen_nulstr();
1571         test_glob_exists();
1572         test_execute_directory();
1573         test_unquote_first_word();
1574         test_unquote_many_words();
1575         test_parse_proc_cmdline();
1576         test_raw_clone();
1577         test_same_fd();
1578         test_uid_ptr();
1579         test_sparse_write();
1580
1581         return 0;
1582 }