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