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