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