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