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