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