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