chiark / gitweb /
sd-rtnl: fix bogus warning about dropping 20 bytes from multi-part messages
[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         unsigned long long b;
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_starttime_of_pid(1, &b) >= 0);
511         log_info("pid1 starttime: '%llu'", b);
512
513         assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
514         log_info("pid1 cmdline: '%s'", c);
515
516         assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
517         log_info("pid1 cmdline truncated: '%s'", d);
518
519         assert_se(get_parent_of_pid(1, &e) >= 0);
520         log_info("pid1 ppid: "PID_FMT, e);
521         assert_se(e == 0);
522
523         assert_se(is_kernel_thread(1) == 0);
524
525         r = get_process_exe(1, &f);
526         assert_se(r >= 0 || r == -EACCES);
527         log_info("pid1 exe: '%s'", strna(f));
528
529         assert_se(get_process_uid(1, &u) == 0);
530         log_info("pid1 uid: "UID_FMT, u);
531         assert_se(u == 0);
532
533         assert_se(get_process_gid(1, &g) == 0);
534         log_info("pid1 gid: "GID_FMT, g);
535         assert_se(g == 0);
536
537         me = getpid();
538
539         r = get_process_cwd(me, &cwd);
540         assert_se(r >= 0 || r == -EACCES);
541         log_info("pid1 cwd: '%s'", cwd);
542
543         r = get_process_root(me, &root);
544         assert_se(r >= 0 || r == -EACCES);
545         log_info("pid1 root: '%s'", root);
546
547         r = get_process_environ(me, &env);
548         assert_se(r >= 0 || r == -EACCES);
549         log_info("self strlen(environ): '%zd'", strlen(env));
550
551         assert_se(get_ctty_devnr(1, &h) == -ENOENT);
552
553         getenv_for_pid(1, "PATH", &i);
554         log_info("pid1 $PATH: '%s'", strna(i));
555 }
556
557 static void test_protect_errno(void) {
558         errno = 12;
559         {
560                 PROTECT_ERRNO;
561                 errno = 11;
562         }
563         assert_se(errno == 12);
564 }
565
566 static void test_parse_size(void) {
567         off_t bytes;
568
569         assert_se(parse_size("111", 1024, &bytes) == 0);
570         assert_se(bytes == 111);
571
572         assert_se(parse_size("111.4", 1024, &bytes) == 0);
573         assert_se(bytes == 111);
574
575         assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
576         assert_se(bytes == 112);
577
578         assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
579         assert_se(bytes == 112);
580
581         assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
582         assert_se(bytes == 3*1024 + 512);
583
584         assert_se(parse_size("3. K", 1024, &bytes) == 0);
585         assert_se(bytes == 3*1024);
586
587         assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
588         assert_se(bytes == 3*1024);
589
590         assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
591
592         assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
593         assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
594
595         assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
596
597         assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
598         assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
599
600         assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
601         assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
602
603         assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
604
605         assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
606         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
607
608         assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
609         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
610
611         assert_se(parse_size("12P", 1024, &bytes) == 0);
612         assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
613
614         assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
615
616         assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
617         assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
618
619         assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
620
621         assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
622
623         assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
624
625         assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
626         assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
627         assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
628
629         assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
630
631         assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
632 }
633
634 static void test_config_parse_iec_off(void) {
635         off_t offset = 0;
636         assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
637         assert_se(offset == 4 * 1024 * 1024);
638
639         assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
640 }
641
642 static void test_strextend(void) {
643         _cleanup_free_ char *str = strdup("0123");
644         strextend(&str, "456", "78", "9", NULL);
645         assert_se(streq(str, "0123456789"));
646 }
647
648 static void test_strrep(void) {
649         _cleanup_free_ char *one, *three, *zero;
650         one = strrep("waldo", 1);
651         three = strrep("waldo", 3);
652         zero = strrep("waldo", 0);
653
654         assert_se(streq(one, "waldo"));
655         assert_se(streq(three, "waldowaldowaldo"));
656         assert_se(streq(zero, ""));
657 }
658
659 static void test_split_pair(void) {
660         _cleanup_free_ char *a = NULL, *b = NULL;
661
662         assert_se(split_pair("", "", &a, &b) == -EINVAL);
663         assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
664         assert_se(split_pair("", "=", &a, &b) == -EINVAL);
665         assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
666         assert_se(streq(a, "foo"));
667         assert_se(streq(b, "bar"));
668         free(a);
669         free(b);
670         assert_se(split_pair("==", "==", &a, &b) >= 0);
671         assert_se(streq(a, ""));
672         assert_se(streq(b, ""));
673         free(a);
674         free(b);
675
676         assert_se(split_pair("===", "==", &a, &b) >= 0);
677         assert_se(streq(a, ""));
678         assert_se(streq(b, "="));
679 }
680
681 static void test_fstab_node_to_udev_node(void) {
682         char *n;
683
684         n = fstab_node_to_udev_node("LABEL=applé/jack");
685         puts(n);
686         assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
687         free(n);
688
689         n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
690         puts(n);
691         assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
692         free(n);
693
694         n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
695         puts(n);
696         assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
697         free(n);
698
699         n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
700         puts(n);
701         assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
702         free(n);
703
704         n = fstab_node_to_udev_node("PONIES=awesome");
705         puts(n);
706         assert_se(streq(n, "PONIES=awesome"));
707         free(n);
708
709         n = fstab_node_to_udev_node("/dev/xda1");
710         puts(n);
711         assert_se(streq(n, "/dev/xda1"));
712         free(n);
713 }
714
715 static void test_get_files_in_directory(void) {
716         _cleanup_strv_free_ char **l = NULL, **t = NULL;
717
718         assert_se(get_files_in_directory("/tmp", &l) >= 0);
719         assert_se(get_files_in_directory(".", &t) >= 0);
720         assert_se(get_files_in_directory(".", NULL) >= 0);
721 }
722
723 static void test_in_set(void) {
724         assert_se(IN_SET(1, 1));
725         assert_se(IN_SET(1, 1, 2, 3, 4));
726         assert_se(IN_SET(2, 1, 2, 3, 4));
727         assert_se(IN_SET(3, 1, 2, 3, 4));
728         assert_se(IN_SET(4, 1, 2, 3, 4));
729         assert_se(!IN_SET(0, 1));
730         assert_se(!IN_SET(0, 1, 2, 3, 4));
731 }
732
733 static void test_writing_tmpfile(void) {
734         char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
735         _cleanup_free_ char *contents = NULL;
736         size_t size;
737         int fd, r;
738         struct iovec iov[3];
739
740         IOVEC_SET_STRING(iov[0], "abc\n");
741         IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
742         IOVEC_SET_STRING(iov[2], "");
743
744         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
745         printf("tmpfile: %s", name);
746
747         r = writev(fd, iov, 3);
748         assert_se(r >= 0);
749
750         r = read_full_file(name, &contents, &size);
751         assert_se(r == 0);
752         printf("contents: %s", contents);
753         assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
754
755         unlink(name);
756 }
757
758 static void test_hexdump(void) {
759         uint8_t data[146];
760         unsigned i;
761
762         hexdump(stdout, NULL, 0);
763         hexdump(stdout, "", 0);
764         hexdump(stdout, "", 1);
765         hexdump(stdout, "x", 1);
766         hexdump(stdout, "x", 2);
767         hexdump(stdout, "foobar", 7);
768         hexdump(stdout, "f\nobar", 7);
769         hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
770
771         for (i = 0; i < ELEMENTSOF(data); i++)
772                 data[i] = i*2;
773
774         hexdump(stdout, data, sizeof(data));
775 }
776
777 static void test_log2i(void) {
778         assert_se(log2i(1) == 0);
779         assert_se(log2i(2) == 1);
780         assert_se(log2i(3) == 1);
781         assert_se(log2i(4) == 2);
782         assert_se(log2i(32) == 5);
783         assert_se(log2i(33) == 5);
784         assert_se(log2i(63) == 5);
785         assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
786 }
787
788 static void test_foreach_string(void) {
789         const char * const t[] = {
790                 "foo",
791                 "bar",
792                 "waldo",
793                 NULL
794         };
795         const char *x;
796         unsigned i = 0;
797
798         FOREACH_STRING(x, "foo", "bar", "waldo")
799                 assert_se(streq_ptr(t[i++], x));
800
801         assert_se(i == 3);
802
803         FOREACH_STRING(x, "zzz")
804                 assert_se(streq(x, "zzz"));
805 }
806
807 static void test_filename_is_safe(void) {
808         char foo[FILENAME_MAX+2];
809         int i;
810
811         assert_se(!filename_is_safe(""));
812         assert_se(!filename_is_safe("/bar/foo"));
813         assert_se(!filename_is_safe("/"));
814         assert_se(!filename_is_safe("."));
815         assert_se(!filename_is_safe(".."));
816
817         for (i=0; i<FILENAME_MAX+1; i++)
818                 foo[i] = 'a';
819         foo[FILENAME_MAX+1] = '\0';
820
821         assert_se(!filename_is_safe(foo));
822
823         assert_se(filename_is_safe("foo_bar-333"));
824         assert_se(filename_is_safe("o.o"));
825 }
826
827 static void test_string_has_cc(void) {
828         assert_se(string_has_cc("abc\1", NULL));
829         assert_se(string_has_cc("abc\x7f", NULL));
830         assert_se(string_has_cc("abc\x7f", NULL));
831         assert_se(string_has_cc("abc\t\x7f", "\t"));
832         assert_se(string_has_cc("abc\t\x7f", "\t"));
833         assert_se(string_has_cc("\x7f", "\t"));
834         assert_se(string_has_cc("\x7f", "\t\a"));
835
836         assert_se(!string_has_cc("abc\t\t", "\t"));
837         assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
838         assert_se(!string_has_cc("a\ab\tc", "\t\a"));
839 }
840
841 static void test_ascii_strlower(void) {
842         char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
843         assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
844 }
845
846 static void test_files_same(void) {
847         _cleanup_close_ int fd = -1;
848         char name[] = "/tmp/test-files_same.XXXXXX";
849         char name_alias[] = "/tmp/test-files_same.alias";
850
851         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
852         assert_se(fd >= 0);
853         assert_se(symlink(name, name_alias) >= 0);
854
855         assert_se(files_same(name, name));
856         assert_se(files_same(name, name_alias));
857
858         unlink(name);
859         unlink(name_alias);
860 }
861
862 static void test_is_valid_documentation_url(void) {
863         assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
864         assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
865         assert_se(is_valid_documentation_url("file:foo"));
866         assert_se(is_valid_documentation_url("man:systemd.special(7)"));
867         assert_se(is_valid_documentation_url("info:bar"));
868
869         assert_se(!is_valid_documentation_url("foo:"));
870         assert_se(!is_valid_documentation_url("info:"));
871         assert_se(!is_valid_documentation_url(""));
872 }
873
874 static void test_file_in_same_dir(void) {
875         char *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");
886         assert_se(streq(t, "a"));
887         free(t);
888
889         t = file_in_same_dir("a/", "a");
890         assert_se(streq(t, "a/a"));
891         free(t);
892
893         t = file_in_same_dir("bar/foo", "bar");
894         assert_se(streq(t, "bar/bar"));
895         free(t);
896 }
897
898 static void test_endswith(void) {
899         assert_se(endswith("foobar", "bar"));
900         assert_se(endswith("foobar", ""));
901         assert_se(endswith("foobar", "foobar"));
902         assert_se(endswith("", ""));
903
904         assert_se(!endswith("foobar", "foo"));
905         assert_se(!endswith("foobar", "foobarfoofoo"));
906 }
907
908 static void test_close_nointr(void) {
909         char name[] = "/tmp/test-test-close_nointr.XXXXXX";
910         int fd;
911
912         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
913         assert_se(fd >= 0);
914         assert_se(close_nointr(fd) >= 0);
915         assert_se(close_nointr(fd) < 0);
916
917         unlink(name);
918 }
919
920
921 static void test_unlink_noerrno(void) {
922         char name[] = "/tmp/test-close_nointr.XXXXXX";
923         int fd;
924
925         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
926         assert_se(fd >= 0);
927         assert_se(close_nointr(fd) >= 0);
928
929         {
930                 PROTECT_ERRNO;
931                 errno = -42;
932                 assert_se(unlink_noerrno(name) >= 0);
933                 assert_se(errno == -42);
934                 assert_se(unlink_noerrno(name) < 0);
935                 assert_se(errno == -42);
936         }
937 }
938
939 static void test_readlink_and_make_absolute(void) {
940         char tempdir[] = "/tmp/test-readlink_and_make_absolute";
941         char name[] = "/tmp/test-readlink_and_make_absolute/original";
942         char name2[] = "test-readlink_and_make_absolute/original";
943         char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
944         char *r = NULL;
945
946         assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
947         assert_se(touch(name) >= 0);
948
949         assert_se(symlink(name, name_alias) >= 0);
950         assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
951         assert_se(streq(r, name));
952         free(r);
953         assert_se(unlink(name_alias) >= 0);
954
955         assert_se(chdir(tempdir) >= 0);
956         assert_se(symlink(name2, name_alias) >= 0);
957         assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
958         assert_se(streq(r, name));
959         free(r);
960         assert_se(unlink(name_alias) >= 0);
961
962         assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
963 }
964
965 static void test_read_one_char(void) {
966         _cleanup_fclose_ FILE *file = NULL;
967         char r;
968         bool need_nl;
969         char name[] = "/tmp/test-read_one_char.XXXXXX";
970         int fd;
971
972         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
973         assert_se(fd >= 0);
974         file = fdopen(fd, "r+");
975         assert_se(file);
976         assert_se(fputs("c\n", file) >= 0);
977         rewind(file);
978
979         assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
980         assert_se(!need_nl);
981         assert_se(r == 'c');
982         assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
983
984         rewind(file);
985         assert_se(fputs("foobar\n", file) >= 0);
986         rewind(file);
987         assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
988
989         rewind(file);
990         assert_se(fputs("\n", file) >= 0);
991         rewind(file);
992         assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
993
994         unlink(name);
995 }
996
997 static void test_ignore_signals(void) {
998         assert_se(ignore_signals(SIGINT, -1) >= 0);
999         assert_se(kill(getpid(), SIGINT) >= 0);
1000         assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1001         assert_se(kill(getpid(), SIGUSR1) >= 0);
1002         assert_se(kill(getpid(), SIGUSR2) >= 0);
1003         assert_se(kill(getpid(), SIGTERM) >= 0);
1004         assert_se(kill(getpid(), SIGPIPE) >= 0);
1005         assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1006 }
1007
1008 static void test_strshorten(void) {
1009         char s[] = "foobar";
1010
1011         assert_se(strlen(strshorten(s, 6)) == 6);
1012         assert_se(strlen(strshorten(s, 12)) == 6);
1013         assert_se(strlen(strshorten(s, 2)) == 2);
1014         assert_se(strlen(strshorten(s, 0)) == 0);
1015 }
1016
1017 static void test_strappenda(void) {
1018         char *actual;
1019
1020         actual = strappenda("", "foo", "bar");
1021         assert_se(streq(actual, "foobar"));
1022
1023         actual = strappenda("foo", "bar", "baz");
1024         assert_se(streq(actual, "foobarbaz"));
1025
1026         actual = strappenda("foo", "", "bar", "baz");
1027         assert_se(streq(actual, "foobarbaz"));
1028 }
1029
1030 static void test_is_symlink(void) {
1031         char name[] = "/tmp/test-is_symlink.XXXXXX";
1032         char name_link[] = "/tmp/test-is_symlink.link";
1033         _cleanup_close_ int fd = -1;
1034
1035         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1036         assert_se(fd >= 0);
1037         assert_se(symlink(name, name_link) >= 0);
1038
1039         assert_se(is_symlink(name) == 0);
1040         assert_se(is_symlink(name_link) == 1);
1041         assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1042
1043
1044         unlink(name);
1045         unlink(name_link);
1046 }
1047
1048 static void test_pid_is_unwaited(void) {
1049         pid_t pid;
1050
1051         pid = fork();
1052         assert_se(pid >= 0);
1053         if (pid == 0) {
1054                 _exit(EXIT_SUCCESS);
1055         } else {
1056                 int status;
1057
1058                 waitpid(pid, &status, 0);
1059                 assert_se(!pid_is_unwaited(pid));
1060         }
1061         assert_se(pid_is_unwaited(getpid()));
1062         assert_se(!pid_is_unwaited(-1));
1063 }
1064
1065 static void test_pid_is_alive(void) {
1066         pid_t pid;
1067
1068         pid = fork();
1069         assert_se(pid >= 0);
1070         if (pid == 0) {
1071                 _exit(EXIT_SUCCESS);
1072         } else {
1073                 int status;
1074
1075                 waitpid(pid, &status, 0);
1076                 assert_se(!pid_is_alive(pid));
1077         }
1078         assert_se(pid_is_alive(getpid()));
1079         assert_se(!pid_is_alive(-1));
1080 }
1081
1082 static void test_search_and_fopen(void) {
1083         const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1084         char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1085         int fd = -1;
1086         int r;
1087         FILE *f;
1088
1089         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1090         assert_se(fd >= 0);
1091         close(fd);
1092
1093         r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1094         assert_se(r >= 0);
1095         fclose(f);
1096
1097         r = search_and_fopen(name, "r", NULL, dirs, &f);
1098         assert_se(r >= 0);
1099         fclose(f);
1100
1101         r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1102         assert_se(r >= 0);
1103         fclose(f);
1104
1105         r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1106         assert_se(r < 0);
1107         r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1108         assert_se(r < 0);
1109
1110         r = unlink(name);
1111         assert_se(r == 0);
1112
1113         r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1114         assert_se(r < 0);
1115 }
1116
1117
1118 static void test_search_and_fopen_nulstr(void) {
1119         const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1120         char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1121         int fd = -1;
1122         int r;
1123         FILE *f;
1124
1125         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1126         assert_se(fd >= 0);
1127         close(fd);
1128
1129         r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1130         assert_se(r >= 0);
1131         fclose(f);
1132
1133         r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1134         assert_se(r >= 0);
1135         fclose(f);
1136
1137         r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1138         assert_se(r < 0);
1139         r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1140         assert_se(r < 0);
1141
1142         r = unlink(name);
1143         assert_se(r == 0);
1144
1145         r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1146         assert_se(r < 0);
1147 }
1148
1149 static void test_glob_exists(void) {
1150         char name[] = "/tmp/test-glob_exists.XXXXXX";
1151         int fd = -1;
1152         int r;
1153
1154         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1155         assert_se(fd >= 0);
1156         close(fd);
1157
1158         r = glob_exists("/tmp/test-glob_exists*");
1159         assert_se(r == 1);
1160
1161         r = unlink(name);
1162         assert_se(r == 0);
1163         r = glob_exists("/tmp/test-glob_exists*");
1164         assert_se(r == 0);
1165 }
1166
1167 static void test_execute_directory(void) {
1168         char name[] = "/tmp/test-execute_directory/script1";
1169         char name2[] = "/tmp/test-execute_directory/script2";
1170         char name3[] = "/tmp/test-execute_directory/useless";
1171         char tempdir[] = "/tmp/test-execute_directory/";
1172
1173         assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1174         assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1175         assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1176         assert_se(chmod(name, 0755) == 0);
1177         assert_se(chmod(name2, 0755) == 0);
1178         assert_se(touch(name3) >= 0);
1179
1180         execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
1181         assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1182         assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1183
1184         rm_rf_dangerous(tempdir, false, true, false);
1185 }
1186
1187 static void test_unquote_first_word(void) {
1188         const char *p, *original;
1189         char *t;
1190
1191         p = original = "foobar waldo";
1192         assert_se(unquote_first_word(&p, &t, false) > 0);
1193         assert_se(streq(t, "foobar"));
1194         free(t);
1195         assert_se(p == original + 7);
1196
1197         assert_se(unquote_first_word(&p, &t, false) > 0);
1198         assert_se(streq(t, "waldo"));
1199         free(t);
1200         assert_se(p == original + 12);
1201
1202         assert_se(unquote_first_word(&p, &t, false) == 0);
1203         assert_se(!t);
1204         assert_se(p == original + 12);
1205
1206         p = original = "\"foobar\" \'waldo\'";
1207         assert_se(unquote_first_word(&p, &t, false) > 0);
1208         assert_se(streq(t, "foobar"));
1209         free(t);
1210         assert_se(p == original + 9);
1211
1212         assert_se(unquote_first_word(&p, &t, false) > 0);
1213         assert_se(streq(t, "waldo"));
1214         free(t);
1215         assert_se(p == original + 16);
1216
1217         assert_se(unquote_first_word(&p, &t, false) == 0);
1218         assert_se(!t);
1219         assert_se(p == original + 16);
1220
1221         p = original = "\"";
1222         assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1223         assert_se(p == original + 1);
1224
1225         p = original = "\'";
1226         assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1227         assert_se(p == original + 1);
1228
1229         p = original = "\'fooo";
1230         assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1231         assert_se(p == original + 5);
1232
1233         p = original = "\'fooo";
1234         assert_se(unquote_first_word(&p, &t, true) > 0);
1235         assert_se(streq(t, "fooo"));
1236         free(t);
1237         assert_se(p == original + 5);
1238
1239         p = original = "yay\'foo\'bar";
1240         assert_se(unquote_first_word(&p, &t, false) > 0);
1241         assert_se(streq(t, "yayfoobar"));
1242         free(t);
1243         assert_se(p == original + 11);
1244
1245         p = original = "   foobar   ";
1246         assert_se(unquote_first_word(&p, &t, false) > 0);
1247         assert_se(streq(t, "foobar"));
1248         free(t);
1249         assert_se(p == original + 12);
1250 }
1251
1252 static void test_unquote_many_words(void) {
1253         const char *p, *original;
1254         char *a, *b, *c;
1255
1256         p = original = "foobar waldi piep";
1257         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1258         assert_se(p == original + 17);
1259         assert_se(streq_ptr(a, "foobar"));
1260         assert_se(streq_ptr(b, "waldi"));
1261         assert_se(streq_ptr(c, "piep"));
1262         free(a);
1263         free(b);
1264         free(c);
1265
1266         p = original = "'foobar' wa\"ld\"i   ";
1267         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1268         assert_se(p == original + 19);
1269         assert_se(streq_ptr(a, "foobar"));
1270         assert_se(streq_ptr(b, "waldi"));
1271         assert_se(streq_ptr(c, NULL));
1272         free(a);
1273         free(b);
1274
1275         p = original = "";
1276         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1277         assert_se(p == original);
1278         assert_se(streq_ptr(a, NULL));
1279         assert_se(streq_ptr(b, NULL));
1280         assert_se(streq_ptr(c, NULL));
1281
1282         p = original = "  ";
1283         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1284         assert_se(p == original+2);
1285         assert_se(streq_ptr(a, NULL));
1286         assert_se(streq_ptr(b, NULL));
1287         assert_se(streq_ptr(c, NULL));
1288
1289         p = original = "foobar";
1290         assert_se(unquote_many_words(&p, NULL) == 0);
1291         assert_se(p == original);
1292
1293         p = original = "foobar waldi";
1294         assert_se(unquote_many_words(&p, &a, NULL) == 1);
1295         assert_se(p == original+7);
1296         assert_se(streq_ptr(a, "foobar"));
1297         free(a);
1298
1299         p = original = "     foobar    ";
1300         assert_se(unquote_many_words(&p, &a, NULL) == 1);
1301         assert_se(p == original+15);
1302         assert_se(streq_ptr(a, "foobar"));
1303         free(a);
1304 }
1305
1306 static int parse_item(const char *key, const char *value) {
1307         assert_se(key);
1308
1309         log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1310         return 0;
1311 }
1312
1313 static void test_parse_proc_cmdline(void) {
1314         assert_se(parse_proc_cmdline(parse_item) >= 0);
1315 }
1316
1317 int main(int argc, char *argv[]) {
1318         log_parse_environment();
1319         log_open();
1320
1321         test_streq_ptr();
1322         test_align_power2();
1323         test_max();
1324         test_container_of();
1325         test_alloca();
1326         test_first_word();
1327         test_close_many();
1328         test_parse_boolean();
1329         test_parse_pid();
1330         test_parse_uid();
1331         test_safe_atolli();
1332         test_safe_atod();
1333         test_strappend();
1334         test_strstrip();
1335         test_delete_chars();
1336         test_in_charset();
1337         test_hexchar();
1338         test_unhexchar();
1339         test_octchar();
1340         test_unoctchar();
1341         test_decchar();
1342         test_undecchar();
1343         test_cescape();
1344         test_cunescape();
1345         test_foreach_word();
1346         test_foreach_word_quoted();
1347         test_default_term_for_tty();
1348         test_memdup_multiply();
1349         test_hostname_is_valid();
1350         test_u64log2();
1351         test_get_process_comm();
1352         test_protect_errno();
1353         test_parse_size();
1354         test_config_parse_iec_off();
1355         test_strextend();
1356         test_strrep();
1357         test_split_pair();
1358         test_fstab_node_to_udev_node();
1359         test_get_files_in_directory();
1360         test_in_set();
1361         test_writing_tmpfile();
1362         test_hexdump();
1363         test_log2i();
1364         test_foreach_string();
1365         test_filename_is_safe();
1366         test_string_has_cc();
1367         test_ascii_strlower();
1368         test_files_same();
1369         test_is_valid_documentation_url();
1370         test_file_in_same_dir();
1371         test_endswith();
1372         test_close_nointr();
1373         test_unlink_noerrno();
1374         test_readlink_and_make_absolute();
1375         test_read_one_char();
1376         test_ignore_signals();
1377         test_strshorten();
1378         test_strappenda();
1379         test_is_symlink();
1380         test_pid_is_unwaited();
1381         test_pid_is_alive();
1382         test_search_and_fopen();
1383         test_search_and_fopen_nulstr();
1384         test_glob_exists();
1385         test_execute_directory();
1386         test_unquote_first_word();
1387         test_unquote_many_words();
1388         test_parse_proc_cmdline();
1389
1390         return 0;
1391 }