chiark / gitweb /
d529a213cc24fec7aa6890c4b36ec415ae578b7b
[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 name[] = "/tmp/test-execute_directory/script1";
1211         char name2[] = "/tmp/test-execute_directory/script2";
1212         char name3[] = "/tmp/test-execute_directory/useless";
1213         char tempdir[] = "/tmp/test-execute_directory/";
1214
1215         assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1216         assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1217         assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1218         assert_se(chmod(name, 0755) == 0);
1219         assert_se(chmod(name2, 0755) == 0);
1220         assert_se(touch(name3) >= 0);
1221
1222         execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
1223         assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1224         assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1225
1226         rm_rf_dangerous(tempdir, false, true, false);
1227 }
1228
1229 static void test_unquote_first_word(void) {
1230         const char *p, *original;
1231         char *t;
1232
1233         p = original = "foobar waldo";
1234         assert_se(unquote_first_word(&p, &t, false) > 0);
1235         assert_se(streq(t, "foobar"));
1236         free(t);
1237         assert_se(p == original + 7);
1238
1239         assert_se(unquote_first_word(&p, &t, false) > 0);
1240         assert_se(streq(t, "waldo"));
1241         free(t);
1242         assert_se(p == original + 12);
1243
1244         assert_se(unquote_first_word(&p, &t, false) == 0);
1245         assert_se(!t);
1246         assert_se(p == original + 12);
1247
1248         p = original = "\"foobar\" \'waldo\'";
1249         assert_se(unquote_first_word(&p, &t, false) > 0);
1250         assert_se(streq(t, "foobar"));
1251         free(t);
1252         assert_se(p == original + 9);
1253
1254         assert_se(unquote_first_word(&p, &t, false) > 0);
1255         assert_se(streq(t, "waldo"));
1256         free(t);
1257         assert_se(p == original + 16);
1258
1259         assert_se(unquote_first_word(&p, &t, false) == 0);
1260         assert_se(!t);
1261         assert_se(p == original + 16);
1262
1263         p = original = "\"";
1264         assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1265         assert_se(p == original + 1);
1266
1267         p = original = "\'";
1268         assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1269         assert_se(p == original + 1);
1270
1271         p = original = "\'fooo";
1272         assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1273         assert_se(p == original + 5);
1274
1275         p = original = "\'fooo";
1276         assert_se(unquote_first_word(&p, &t, true) > 0);
1277         assert_se(streq(t, "fooo"));
1278         free(t);
1279         assert_se(p == original + 5);
1280
1281         p = original = "yay\'foo\'bar";
1282         assert_se(unquote_first_word(&p, &t, false) > 0);
1283         assert_se(streq(t, "yayfoobar"));
1284         free(t);
1285         assert_se(p == original + 11);
1286
1287         p = original = "   foobar   ";
1288         assert_se(unquote_first_word(&p, &t, false) > 0);
1289         assert_se(streq(t, "foobar"));
1290         free(t);
1291         assert_se(p == original + 12);
1292 }
1293
1294 static void test_unquote_many_words(void) {
1295         const char *p, *original;
1296         char *a, *b, *c;
1297
1298         p = original = "foobar waldi piep";
1299         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1300         assert_se(p == original + 17);
1301         assert_se(streq_ptr(a, "foobar"));
1302         assert_se(streq_ptr(b, "waldi"));
1303         assert_se(streq_ptr(c, "piep"));
1304         free(a);
1305         free(b);
1306         free(c);
1307
1308         p = original = "'foobar' wa\"ld\"i   ";
1309         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1310         assert_se(p == original + 19);
1311         assert_se(streq_ptr(a, "foobar"));
1312         assert_se(streq_ptr(b, "waldi"));
1313         assert_se(streq_ptr(c, NULL));
1314         free(a);
1315         free(b);
1316
1317         p = original = "";
1318         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1319         assert_se(p == original);
1320         assert_se(streq_ptr(a, NULL));
1321         assert_se(streq_ptr(b, NULL));
1322         assert_se(streq_ptr(c, NULL));
1323
1324         p = original = "  ";
1325         assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1326         assert_se(p == original+2);
1327         assert_se(streq_ptr(a, NULL));
1328         assert_se(streq_ptr(b, NULL));
1329         assert_se(streq_ptr(c, NULL));
1330
1331         p = original = "foobar";
1332         assert_se(unquote_many_words(&p, NULL) == 0);
1333         assert_se(p == original);
1334
1335         p = original = "foobar waldi";
1336         assert_se(unquote_many_words(&p, &a, NULL) == 1);
1337         assert_se(p == original+7);
1338         assert_se(streq_ptr(a, "foobar"));
1339         free(a);
1340
1341         p = original = "     foobar    ";
1342         assert_se(unquote_many_words(&p, &a, NULL) == 1);
1343         assert_se(p == original+15);
1344         assert_se(streq_ptr(a, "foobar"));
1345         free(a);
1346 }
1347
1348 static int parse_item(const char *key, const char *value) {
1349         assert_se(key);
1350
1351         log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1352         return 0;
1353 }
1354
1355 static void test_parse_proc_cmdline(void) {
1356         assert_se(parse_proc_cmdline(parse_item) >= 0);
1357 }
1358
1359 static void test_raw_clone(void) {
1360         pid_t parent, pid, pid2;
1361
1362         parent = getpid();
1363         log_info("before clone: getpid()→"PID_FMT, parent);
1364         assert_se(raw_getpid() == parent);
1365
1366         pid = raw_clone(0, NULL);
1367         assert_se(pid >= 0);
1368
1369         pid2 = raw_getpid();
1370         log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1371                  pid, getpid(), pid2);
1372         if (pid == 0) {
1373                 assert_se(pid2 != parent);
1374                 _exit(EXIT_SUCCESS);
1375         } else {
1376                 int status;
1377
1378                 assert_se(pid2 == parent);
1379                 waitpid(pid, &status, __WCLONE);
1380                 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1381         }
1382 }
1383
1384 static void test_same_fd(void) {
1385         _cleanup_close_pair_ int p[2] = { -1, -1 };
1386         _cleanup_close_ int a = -1, b = -1, c = -1;
1387
1388         assert_se(pipe2(p, O_CLOEXEC) >= 0);
1389         assert_se((a = dup(p[0])) >= 0);
1390         assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1391         assert_se((c = dup(a)) >= 0);
1392
1393         assert_se(same_fd(p[0], p[0]) > 0);
1394         assert_se(same_fd(p[1], p[1]) > 0);
1395         assert_se(same_fd(a, a) > 0);
1396         assert_se(same_fd(b, b) > 0);
1397
1398         assert_se(same_fd(a, p[0]) > 0);
1399         assert_se(same_fd(p[0], a) > 0);
1400         assert_se(same_fd(c, p[0]) > 0);
1401         assert_se(same_fd(p[0], c) > 0);
1402         assert_se(same_fd(a, c) > 0);
1403         assert_se(same_fd(c, a) > 0);
1404
1405         assert_se(same_fd(p[0], p[1]) == 0);
1406         assert_se(same_fd(p[1], p[0]) == 0);
1407         assert_se(same_fd(p[0], b) == 0);
1408         assert_se(same_fd(b, p[0]) == 0);
1409         assert_se(same_fd(p[1], a) == 0);
1410         assert_se(same_fd(a, p[1]) == 0);
1411         assert_se(same_fd(p[1], b) == 0);
1412         assert_se(same_fd(b, p[1]) == 0);
1413
1414         assert_se(same_fd(a, b) == 0);
1415         assert_se(same_fd(b, a) == 0);
1416 }
1417
1418 static void test_uid_ptr(void) {
1419
1420         assert_se(UID_TO_PTR(0) != NULL);
1421         assert_se(UID_TO_PTR(1000) != NULL);
1422
1423         assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1424         assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1425 }
1426
1427 int main(int argc, char *argv[]) {
1428         log_parse_environment();
1429         log_open();
1430
1431         test_streq_ptr();
1432         test_align_power2();
1433         test_max();
1434         test_container_of();
1435         test_alloca();
1436         test_div_round_up();
1437         test_first_word();
1438         test_close_many();
1439         test_parse_boolean();
1440         test_parse_pid();
1441         test_parse_uid();
1442         test_safe_atolli();
1443         test_safe_atod();
1444         test_strappend();
1445         test_strstrip();
1446         test_delete_chars();
1447         test_in_charset();
1448         test_hexchar();
1449         test_unhexchar();
1450         test_octchar();
1451         test_unoctchar();
1452         test_decchar();
1453         test_undecchar();
1454         test_cescape();
1455         test_cunescape();
1456         test_foreach_word();
1457         test_foreach_word_quoted();
1458         test_default_term_for_tty();
1459         test_memdup_multiply();
1460         test_hostname_is_valid();
1461         test_u64log2();
1462         test_get_process_comm();
1463         test_protect_errno();
1464         test_parse_size();
1465         test_config_parse_iec_off();
1466         test_strextend();
1467         test_strrep();
1468         test_split_pair();
1469         test_fstab_node_to_udev_node();
1470         test_get_files_in_directory();
1471         test_in_set();
1472         test_writing_tmpfile();
1473         test_hexdump();
1474         test_log2i();
1475         test_foreach_string();
1476         test_filename_is_valid();
1477         test_string_has_cc();
1478         test_ascii_strlower();
1479         test_files_same();
1480         test_is_valid_documentation_url();
1481         test_file_in_same_dir();
1482         test_endswith();
1483         test_close_nointr();
1484         test_unlink_noerrno();
1485         test_readlink_and_make_absolute();
1486         test_read_one_char();
1487         test_ignore_signals();
1488         test_strshorten();
1489         test_strappenda();
1490         test_is_symlink();
1491         test_pid_is_unwaited();
1492         test_pid_is_alive();
1493         test_search_and_fopen();
1494         test_search_and_fopen_nulstr();
1495         test_glob_exists();
1496         test_execute_directory();
1497         test_unquote_first_word();
1498         test_unquote_many_words();
1499         test_parse_proc_cmdline();
1500         test_raw_clone();
1501         test_same_fd();
1502         test_uid_ptr();
1503
1504         return 0;
1505 }