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