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