1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
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.
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.
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/>.
37 #include "conf-parser.h"
40 static void test_streq_ptr(void) {
41 assert_se(streq_ptr(NULL, NULL));
42 assert_se(!streq_ptr("abc", "cdef"));
45 static void test_align_power2(void) {
48 assert_se(ALIGN_POWER2(0) == 0);
49 assert_se(ALIGN_POWER2(1) == 1);
50 assert_se(ALIGN_POWER2(2) == 2);
51 assert_se(ALIGN_POWER2(3) == 4);
52 assert_se(ALIGN_POWER2(12) == 16);
54 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
55 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
56 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
57 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
58 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
60 for (i = 1; i < 131071; ++i) {
61 for (p2 = 1; p2 < i; p2 <<= 1)
64 assert_se(ALIGN_POWER2(i) == p2);
67 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
68 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
71 assert_se(ALIGN_POWER2(i) == p2);
75 static void test_max(void) {
78 int b[CONST_MAX(10, 100)];
80 .a = CONST_MAX(10, 100),
84 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
86 /* CONST_MAX returns (void) instead of a value if the passed arguments
87 * are not of the same type or not constant expressions. */
88 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
89 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
91 assert_se(val1.a == 100);
92 assert_se(MAX(++d, 0) == 1);
95 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
96 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
97 assert_cc(MAXSIZE(char, long) == sizeof(long));
99 assert_se(MAX(-5, 5) == 5);
100 assert_se(MAX(5, 5) == 5);
101 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
102 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
103 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
104 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
105 assert_se(LESS_BY(8, 4) == 4);
106 assert_se(LESS_BY(8, 8) == 0);
107 assert_se(LESS_BY(4, 8) == 0);
108 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
109 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
110 assert_se(CLAMP(-5, 0, 1) == 0);
111 assert_se(CLAMP(5, 0, 1) == 1);
112 assert_se(CLAMP(5, -10, 1) == 1);
113 assert_se(CLAMP(5, -10, 10) == 5);
114 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
117 static void test_container_of(void) {
123 } _packed_ myval = { };
125 assert_cc(sizeof(myval) == 17);
126 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
127 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
128 assert_se(container_of(&container_of(&myval.v2,
135 static void test_alloca(void) {
136 static const uint8_t zero[997] = { };
139 t = alloca_align(17, 512);
140 assert_se(!((uintptr_t)t & 0xff));
143 t = alloca0_align(997, 1024);
144 assert_se(!((uintptr_t)t & 0x1ff));
145 assert_se(!memcmp(t, zero, 997));
148 static void test_first_word(void) {
149 assert_se(first_word("Hello", ""));
150 assert_se(first_word("Hello", "Hello"));
151 assert_se(first_word("Hello world", "Hello"));
152 assert_se(first_word("Hello\tworld", "Hello"));
153 assert_se(first_word("Hello\nworld", "Hello"));
154 assert_se(first_word("Hello\rworld", "Hello"));
155 assert_se(first_word("Hello ", "Hello"));
157 assert_se(!first_word("Hello", "Hellooo"));
158 assert_se(!first_word("Hello", "xxxxx"));
159 assert_se(!first_word("Hellooo", "Hello"));
162 static void test_close_many(void) {
164 char name0[] = "/tmp/test-close-many.XXXXXX";
165 char name1[] = "/tmp/test-close-many.XXXXXX";
166 char name2[] = "/tmp/test-close-many.XXXXXX";
168 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
169 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
170 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
174 assert_se(fcntl(fds[0], F_GETFD) == -1);
175 assert_se(fcntl(fds[1], F_GETFD) == -1);
176 assert_se(fcntl(fds[2], F_GETFD) >= 0);
185 static void test_parse_boolean(void) {
186 assert_se(parse_boolean("1") == 1);
187 assert_se(parse_boolean("y") == 1);
188 assert_se(parse_boolean("Y") == 1);
189 assert_se(parse_boolean("yes") == 1);
190 assert_se(parse_boolean("YES") == 1);
191 assert_se(parse_boolean("true") == 1);
192 assert_se(parse_boolean("TRUE") == 1);
193 assert_se(parse_boolean("on") == 1);
194 assert_se(parse_boolean("ON") == 1);
196 assert_se(parse_boolean("0") == 0);
197 assert_se(parse_boolean("n") == 0);
198 assert_se(parse_boolean("N") == 0);
199 assert_se(parse_boolean("no") == 0);
200 assert_se(parse_boolean("NO") == 0);
201 assert_se(parse_boolean("false") == 0);
202 assert_se(parse_boolean("FALSE") == 0);
203 assert_se(parse_boolean("off") == 0);
204 assert_se(parse_boolean("OFF") == 0);
206 assert_se(parse_boolean("garbage") < 0);
207 assert_se(parse_boolean("") < 0);
208 assert_se(parse_boolean("full") < 0);
211 static void test_parse_pid(void) {
215 r = parse_pid("100", &pid);
217 assert_se(pid == 100);
219 r = parse_pid("0x7FFFFFFF", &pid);
221 assert_se(pid == 2147483647);
223 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
224 r = parse_pid("0", &pid);
225 assert_se(r == -ERANGE);
226 assert_se(pid == 65);
228 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
229 r = parse_pid("-100", &pid);
230 assert_se(r == -ERANGE);
231 assert_se(pid == 65);
233 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
234 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
235 assert_se(r == -ERANGE);
236 assert_se(pid == 65);
239 static void test_parse_uid(void) {
243 r = parse_uid("100", &uid);
245 assert_se(uid == 100);
248 static void test_safe_atolli(void) {
252 r = safe_atolli("12345", &l);
254 assert_se(l == 12345);
256 r = safe_atolli("junk", &l);
257 assert_se(r == -EINVAL);
260 static void test_safe_atod(void) {
265 r = safe_atod("junk", &d);
266 assert_se(r == -EINVAL);
268 r = safe_atod("0.2244", &d);
270 assert_se(fabs(d - 0.2244) < 0.000001);
272 r = safe_atod("0,5", &d);
273 assert_se(r == -EINVAL);
277 assert_se(*e == ',');
279 /* Check if this really is locale independent */
280 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
282 r = safe_atod("0.2244", &d);
284 assert_se(fabs(d - 0.2244) < 0.000001);
286 r = safe_atod("0,5", &d);
287 assert_se(r == -EINVAL);
290 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
293 /* And check again, reset */
294 assert_se(setlocale(LC_NUMERIC, "C"));
296 r = safe_atod("0.2244", &d);
298 assert_se(fabs(d - 0.2244) < 0.000001);
300 r = safe_atod("0,5", &d);
301 assert_se(r == -EINVAL);
305 assert_se(*e == ',');
308 static void test_strappend(void) {
309 _cleanup_free_ char *t1, *t2, *t3, *t4;
311 t1 = strappend(NULL, NULL);
312 assert_se(streq(t1, ""));
314 t2 = strappend(NULL, "suf");
315 assert_se(streq(t2, "suf"));
317 t3 = strappend("pre", NULL);
318 assert_se(streq(t3, "pre"));
320 t4 = strappend("pre", "suf");
321 assert_se(streq(t4, "presuf"));
324 static void test_strstrip(void) {
326 char input[] = " hello, waldo. ";
329 assert_se(streq(r, "hello, waldo."));
332 static void test_delete_chars(void) {
334 char input[] = " hello, waldo. abc";
336 r = delete_chars(input, WHITESPACE);
337 assert_se(streq(r, "hello,waldo.abc"));
340 static void test_in_charset(void) {
341 assert_se(in_charset("dddaaabbbcccc", "abcd"));
342 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
345 static void test_hexchar(void) {
346 assert_se(hexchar(0xa) == 'a');
347 assert_se(hexchar(0x0) == '0');
350 static void test_unhexchar(void) {
351 assert_se(unhexchar('a') == 0xA);
352 assert_se(unhexchar('A') == 0xA);
353 assert_se(unhexchar('0') == 0x0);
356 static void test_octchar(void) {
357 assert_se(octchar(00) == '0');
358 assert_se(octchar(07) == '7');
361 static void test_unoctchar(void) {
362 assert_se(unoctchar('0') == 00);
363 assert_se(unoctchar('7') == 07);
366 static void test_decchar(void) {
367 assert_se(decchar(0) == '0');
368 assert_se(decchar(9) == '9');
371 static void test_undecchar(void) {
372 assert_se(undecchar('0') == 0);
373 assert_se(undecchar('9') == 9);
376 static void test_cescape(void) {
377 _cleanup_free_ char *escaped;
379 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
380 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
383 static void test_cunescape(void) {
384 _cleanup_free_ char *unescaped;
386 assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
387 assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
390 static void test_foreach_word(void) {
391 const char *word, *state;
394 const char test[] = "test abc d\te f ";
395 const char * const expected[] = {
405 FOREACH_WORD(word, l, test, state)
406 assert_se(strneq(expected[i++], word, l));
409 static void check(const char *test, char** expected, bool trailing) {
410 const char *word, *state;
414 printf("<<<%s>>>\n", test);
415 FOREACH_WORD_QUOTED(word, l, test, state) {
416 _cleanup_free_ char *t = NULL;
418 assert_se(t = strndup(word, l));
419 assert_se(strneq(expected[i++], word, l));
422 printf("<<<%s>>>\n", state);
423 assert_se(expected[i] == NULL);
424 assert_se(isempty(state) == !trailing);
427 static void test_foreach_word_quoted(void) {
428 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
452 static void test_default_term_for_tty(void) {
453 puts(default_term_for_tty("/dev/tty23"));
454 puts(default_term_for_tty("/dev/ttyS23"));
455 puts(default_term_for_tty("/dev/tty0"));
456 puts(default_term_for_tty("/dev/pty0"));
457 puts(default_term_for_tty("/dev/pts/0"));
458 puts(default_term_for_tty("/dev/console"));
459 puts(default_term_for_tty("tty23"));
460 puts(default_term_for_tty("ttyS23"));
461 puts(default_term_for_tty("tty0"));
462 puts(default_term_for_tty("pty0"));
463 puts(default_term_for_tty("pts/0"));
464 puts(default_term_for_tty("console"));
467 static void test_memdup_multiply(void) {
468 int org[] = {1, 2, 3};
471 dup = (int*)memdup_multiply(org, sizeof(int), 3);
474 assert_se(dup[0] == 1);
475 assert_se(dup[1] == 2);
476 assert_se(dup[2] == 3);
480 static void test_hostname_is_valid(void) {
481 assert_se(hostname_is_valid("foobar"));
482 assert_se(hostname_is_valid("foobar.com"));
483 assert_se(!hostname_is_valid("fööbar"));
484 assert_se(!hostname_is_valid(""));
485 assert_se(!hostname_is_valid("."));
486 assert_se(!hostname_is_valid(".."));
487 assert_se(!hostname_is_valid("foobar."));
488 assert_se(!hostname_is_valid(".foobar"));
489 assert_se(!hostname_is_valid("foo..bar"));
490 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
493 static void test_u64log2(void) {
494 assert_se(u64log2(0) == 0);
495 assert_se(u64log2(8) == 3);
496 assert_se(u64log2(9) == 3);
497 assert_se(u64log2(15) == 3);
498 assert_se(u64log2(16) == 4);
499 assert_se(u64log2(1024*1024) == 20);
500 assert_se(u64log2(1024*1024+5) == 20);
503 static void test_get_process_comm(void) {
505 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
506 _cleanup_free_ char *env = NULL;
514 if (stat("/proc/1/comm", &st) == 0) {
515 assert_se(get_process_comm(1, &a) >= 0);
516 log_info("pid1 comm: '%s'", a);
518 log_warning("/proc/1/comm does not exist.");
521 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
522 log_info("pid1 cmdline: '%s'", c);
524 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
525 log_info("pid1 cmdline truncated: '%s'", d);
527 assert_se(get_parent_of_pid(1, &e) >= 0);
528 log_info("pid1 ppid: "PID_FMT, e);
531 assert_se(is_kernel_thread(1) == 0);
533 r = get_process_exe(1, &f);
534 assert_se(r >= 0 || r == -EACCES);
535 log_info("pid1 exe: '%s'", strna(f));
537 assert_se(get_process_uid(1, &u) == 0);
538 log_info("pid1 uid: "UID_FMT, u);
541 assert_se(get_process_gid(1, &g) == 0);
542 log_info("pid1 gid: "GID_FMT, g);
547 r = get_process_cwd(me, &cwd);
548 assert_se(r >= 0 || r == -EACCES);
549 log_info("pid1 cwd: '%s'", cwd);
551 r = get_process_root(me, &root);
552 assert_se(r >= 0 || r == -EACCES);
553 log_info("pid1 root: '%s'", root);
555 r = get_process_environ(me, &env);
556 assert_se(r >= 0 || r == -EACCES);
557 log_info("self strlen(environ): '%zd'", strlen(env));
559 if (!detect_container(NULL))
560 assert_se(get_ctty_devnr(1, &h) == -ENOENT);
562 getenv_for_pid(1, "PATH", &i);
563 log_info("pid1 $PATH: '%s'", strna(i));
566 static void test_protect_errno(void) {
572 assert_se(errno == 12);
575 static void test_parse_size(void) {
578 assert_se(parse_size("111", 1024, &bytes) == 0);
579 assert_se(bytes == 111);
581 assert_se(parse_size("111.4", 1024, &bytes) == 0);
582 assert_se(bytes == 111);
584 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
585 assert_se(bytes == 112);
587 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
588 assert_se(bytes == 112);
590 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
591 assert_se(bytes == 3*1024 + 512);
593 assert_se(parse_size("3. K", 1024, &bytes) == 0);
594 assert_se(bytes == 3*1024);
596 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
597 assert_se(bytes == 3*1024);
599 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
601 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
602 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
604 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
606 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
607 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
609 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
610 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
612 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
614 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
615 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
617 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
618 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
620 assert_se(parse_size("12P", 1024, &bytes) == 0);
621 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
623 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
625 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
626 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
628 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
630 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
632 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
634 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
635 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
636 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
638 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
640 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
643 static void test_config_parse_iec_off(void) {
645 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
646 assert_se(offset == 4 * 1024 * 1024);
648 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
651 static void test_strextend(void) {
652 _cleanup_free_ char *str = strdup("0123");
653 strextend(&str, "456", "78", "9", NULL);
654 assert_se(streq(str, "0123456789"));
657 static void test_strrep(void) {
658 _cleanup_free_ char *one, *three, *zero;
659 one = strrep("waldo", 1);
660 three = strrep("waldo", 3);
661 zero = strrep("waldo", 0);
663 assert_se(streq(one, "waldo"));
664 assert_se(streq(three, "waldowaldowaldo"));
665 assert_se(streq(zero, ""));
668 static void test_split_pair(void) {
669 _cleanup_free_ char *a = NULL, *b = NULL;
671 assert_se(split_pair("", "", &a, &b) == -EINVAL);
672 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
673 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
674 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
675 assert_se(streq(a, "foo"));
676 assert_se(streq(b, "bar"));
679 assert_se(split_pair("==", "==", &a, &b) >= 0);
680 assert_se(streq(a, ""));
681 assert_se(streq(b, ""));
685 assert_se(split_pair("===", "==", &a, &b) >= 0);
686 assert_se(streq(a, ""));
687 assert_se(streq(b, "="));
690 static void test_fstab_node_to_udev_node(void) {
693 n = fstab_node_to_udev_node("LABEL=applé/jack");
695 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
698 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
700 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
703 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
705 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
708 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
710 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
713 n = fstab_node_to_udev_node("PONIES=awesome");
715 assert_se(streq(n, "PONIES=awesome"));
718 n = fstab_node_to_udev_node("/dev/xda1");
720 assert_se(streq(n, "/dev/xda1"));
724 static void test_get_files_in_directory(void) {
725 _cleanup_strv_free_ char **l = NULL, **t = NULL;
727 assert_se(get_files_in_directory("/tmp", &l) >= 0);
728 assert_se(get_files_in_directory(".", &t) >= 0);
729 assert_se(get_files_in_directory(".", NULL) >= 0);
732 static void test_in_set(void) {
733 assert_se(IN_SET(1, 1));
734 assert_se(IN_SET(1, 1, 2, 3, 4));
735 assert_se(IN_SET(2, 1, 2, 3, 4));
736 assert_se(IN_SET(3, 1, 2, 3, 4));
737 assert_se(IN_SET(4, 1, 2, 3, 4));
738 assert_se(!IN_SET(0, 1));
739 assert_se(!IN_SET(0, 1, 2, 3, 4));
742 static void test_writing_tmpfile(void) {
743 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
744 _cleanup_free_ char *contents = NULL;
749 IOVEC_SET_STRING(iov[0], "abc\n");
750 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
751 IOVEC_SET_STRING(iov[2], "");
753 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
754 printf("tmpfile: %s", name);
756 r = writev(fd, iov, 3);
759 r = read_full_file(name, &contents, &size);
761 printf("contents: %s", contents);
762 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
767 static void test_hexdump(void) {
771 hexdump(stdout, NULL, 0);
772 hexdump(stdout, "", 0);
773 hexdump(stdout, "", 1);
774 hexdump(stdout, "x", 1);
775 hexdump(stdout, "x", 2);
776 hexdump(stdout, "foobar", 7);
777 hexdump(stdout, "f\nobar", 7);
778 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
780 for (i = 0; i < ELEMENTSOF(data); i++)
783 hexdump(stdout, data, sizeof(data));
786 static void test_log2i(void) {
787 assert_se(log2i(1) == 0);
788 assert_se(log2i(2) == 1);
789 assert_se(log2i(3) == 1);
790 assert_se(log2i(4) == 2);
791 assert_se(log2i(32) == 5);
792 assert_se(log2i(33) == 5);
793 assert_se(log2i(63) == 5);
794 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
797 static void test_foreach_string(void) {
798 const char * const t[] = {
807 FOREACH_STRING(x, "foo", "bar", "waldo")
808 assert_se(streq_ptr(t[i++], x));
812 FOREACH_STRING(x, "zzz")
813 assert_se(streq(x, "zzz"));
816 static void test_filename_is_valid(void) {
817 char foo[FILENAME_MAX+2];
820 assert_se(!filename_is_valid(""));
821 assert_se(!filename_is_valid("/bar/foo"));
822 assert_se(!filename_is_valid("/"));
823 assert_se(!filename_is_valid("."));
824 assert_se(!filename_is_valid(".."));
826 for (i=0; i<FILENAME_MAX+1; i++)
828 foo[FILENAME_MAX+1] = '\0';
830 assert_se(!filename_is_valid(foo));
832 assert_se(filename_is_valid("foo_bar-333"));
833 assert_se(filename_is_valid("o.o"));
836 static void test_string_has_cc(void) {
837 assert_se(string_has_cc("abc\1", NULL));
838 assert_se(string_has_cc("abc\x7f", NULL));
839 assert_se(string_has_cc("abc\x7f", NULL));
840 assert_se(string_has_cc("abc\t\x7f", "\t"));
841 assert_se(string_has_cc("abc\t\x7f", "\t"));
842 assert_se(string_has_cc("\x7f", "\t"));
843 assert_se(string_has_cc("\x7f", "\t\a"));
845 assert_se(!string_has_cc("abc\t\t", "\t"));
846 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
847 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
850 static void test_ascii_strlower(void) {
851 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
852 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
855 static void test_files_same(void) {
856 _cleanup_close_ int fd = -1;
857 char name[] = "/tmp/test-files_same.XXXXXX";
858 char name_alias[] = "/tmp/test-files_same.alias";
860 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
862 assert_se(symlink(name, name_alias) >= 0);
864 assert_se(files_same(name, name));
865 assert_se(files_same(name, name_alias));
871 static void test_is_valid_documentation_url(void) {
872 assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
873 assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
874 assert_se(is_valid_documentation_url("file:foo"));
875 assert_se(is_valid_documentation_url("man:systemd.special(7)"));
876 assert_se(is_valid_documentation_url("info:bar"));
878 assert_se(!is_valid_documentation_url("foo:"));
879 assert_se(!is_valid_documentation_url("info:"));
880 assert_se(!is_valid_documentation_url(""));
883 static void test_file_in_same_dir(void) {
886 t = file_in_same_dir("/", "a");
887 assert_se(streq(t, "/a"));
890 t = file_in_same_dir("/", "/a");
891 assert_se(streq(t, "/a"));
894 t = file_in_same_dir("", "a");
895 assert_se(streq(t, "a"));
898 t = file_in_same_dir("a/", "a");
899 assert_se(streq(t, "a/a"));
902 t = file_in_same_dir("bar/foo", "bar");
903 assert_se(streq(t, "bar/bar"));
907 static void test_endswith(void) {
908 assert_se(endswith("foobar", "bar"));
909 assert_se(endswith("foobar", ""));
910 assert_se(endswith("foobar", "foobar"));
911 assert_se(endswith("", ""));
913 assert_se(!endswith("foobar", "foo"));
914 assert_se(!endswith("foobar", "foobarfoofoo"));
917 static void test_close_nointr(void) {
918 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
921 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
923 assert_se(close_nointr(fd) >= 0);
924 assert_se(close_nointr(fd) < 0);
930 static void test_unlink_noerrno(void) {
931 char name[] = "/tmp/test-close_nointr.XXXXXX";
934 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
936 assert_se(close_nointr(fd) >= 0);
941 assert_se(unlink_noerrno(name) >= 0);
942 assert_se(errno == -42);
943 assert_se(unlink_noerrno(name) < 0);
944 assert_se(errno == -42);
948 static void test_readlink_and_make_absolute(void) {
949 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
950 char name[] = "/tmp/test-readlink_and_make_absolute/original";
951 char name2[] = "test-readlink_and_make_absolute/original";
952 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
955 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
956 assert_se(touch(name) >= 0);
958 assert_se(symlink(name, name_alias) >= 0);
959 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
960 assert_se(streq(r, name));
962 assert_se(unlink(name_alias) >= 0);
964 assert_se(chdir(tempdir) >= 0);
965 assert_se(symlink(name2, name_alias) >= 0);
966 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
967 assert_se(streq(r, name));
969 assert_se(unlink(name_alias) >= 0);
971 assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
974 static void test_read_one_char(void) {
975 _cleanup_fclose_ FILE *file = NULL;
978 char name[] = "/tmp/test-read_one_char.XXXXXX";
981 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
983 file = fdopen(fd, "r+");
985 assert_se(fputs("c\n", file) >= 0);
988 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
991 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
994 assert_se(fputs("foobar\n", file) >= 0);
996 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
999 assert_se(fputs("\n", file) >= 0);
1001 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1006 static void test_ignore_signals(void) {
1007 assert_se(ignore_signals(SIGINT, -1) >= 0);
1008 assert_se(kill(getpid(), SIGINT) >= 0);
1009 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1010 assert_se(kill(getpid(), SIGUSR1) >= 0);
1011 assert_se(kill(getpid(), SIGUSR2) >= 0);
1012 assert_se(kill(getpid(), SIGTERM) >= 0);
1013 assert_se(kill(getpid(), SIGPIPE) >= 0);
1014 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1017 static void test_strshorten(void) {
1018 char s[] = "foobar";
1020 assert_se(strlen(strshorten(s, 6)) == 6);
1021 assert_se(strlen(strshorten(s, 12)) == 6);
1022 assert_se(strlen(strshorten(s, 2)) == 2);
1023 assert_se(strlen(strshorten(s, 0)) == 0);
1026 static void test_strappenda(void) {
1029 actual = strappenda("", "foo", "bar");
1030 assert_se(streq(actual, "foobar"));
1032 actual = strappenda("foo", "bar", "baz");
1033 assert_se(streq(actual, "foobarbaz"));
1035 actual = strappenda("foo", "", "bar", "baz");
1036 assert_se(streq(actual, "foobarbaz"));
1039 static void test_is_symlink(void) {
1040 char name[] = "/tmp/test-is_symlink.XXXXXX";
1041 char name_link[] = "/tmp/test-is_symlink.link";
1042 _cleanup_close_ int fd = -1;
1044 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1046 assert_se(symlink(name, name_link) >= 0);
1048 assert_se(is_symlink(name) == 0);
1049 assert_se(is_symlink(name_link) == 1);
1050 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1057 static void test_pid_is_unwaited(void) {
1061 assert_se(pid >= 0);
1063 _exit(EXIT_SUCCESS);
1067 waitpid(pid, &status, 0);
1068 assert_se(!pid_is_unwaited(pid));
1070 assert_se(pid_is_unwaited(getpid()));
1071 assert_se(!pid_is_unwaited(-1));
1074 static void test_pid_is_alive(void) {
1078 assert_se(pid >= 0);
1080 _exit(EXIT_SUCCESS);
1084 waitpid(pid, &status, 0);
1085 assert_se(!pid_is_alive(pid));
1087 assert_se(pid_is_alive(getpid()));
1088 assert_se(!pid_is_alive(-1));
1091 static void test_search_and_fopen(void) {
1092 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1093 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1098 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1102 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1106 r = search_and_fopen(name, "r", NULL, dirs, &f);
1110 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1114 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1116 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1122 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1127 static void test_search_and_fopen_nulstr(void) {
1128 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1129 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1134 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1138 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1142 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1146 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1148 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1154 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1158 static void test_glob_exists(void) {
1159 char name[] = "/tmp/test-glob_exists.XXXXXX";
1163 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1167 r = glob_exists("/tmp/test-glob_exists*");
1172 r = glob_exists("/tmp/test-glob_exists*");
1176 static void test_execute_directory(void) {
1177 char name[] = "/tmp/test-execute_directory/script1";
1178 char name2[] = "/tmp/test-execute_directory/script2";
1179 char name3[] = "/tmp/test-execute_directory/useless";
1180 char tempdir[] = "/tmp/test-execute_directory/";
1182 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1183 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1184 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1185 assert_se(chmod(name, 0755) == 0);
1186 assert_se(chmod(name2, 0755) == 0);
1187 assert_se(touch(name3) >= 0);
1189 execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
1190 assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1191 assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1193 rm_rf_dangerous(tempdir, false, true, false);
1196 static void test_unquote_first_word(void) {
1197 const char *p, *original;
1200 p = original = "foobar waldo";
1201 assert_se(unquote_first_word(&p, &t, false) > 0);
1202 assert_se(streq(t, "foobar"));
1204 assert_se(p == original + 7);
1206 assert_se(unquote_first_word(&p, &t, false) > 0);
1207 assert_se(streq(t, "waldo"));
1209 assert_se(p == original + 12);
1211 assert_se(unquote_first_word(&p, &t, false) == 0);
1213 assert_se(p == original + 12);
1215 p = original = "\"foobar\" \'waldo\'";
1216 assert_se(unquote_first_word(&p, &t, false) > 0);
1217 assert_se(streq(t, "foobar"));
1219 assert_se(p == original + 9);
1221 assert_se(unquote_first_word(&p, &t, false) > 0);
1222 assert_se(streq(t, "waldo"));
1224 assert_se(p == original + 16);
1226 assert_se(unquote_first_word(&p, &t, false) == 0);
1228 assert_se(p == original + 16);
1230 p = original = "\"";
1231 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1232 assert_se(p == original + 1);
1234 p = original = "\'";
1235 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1236 assert_se(p == original + 1);
1238 p = original = "\'fooo";
1239 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1240 assert_se(p == original + 5);
1242 p = original = "\'fooo";
1243 assert_se(unquote_first_word(&p, &t, true) > 0);
1244 assert_se(streq(t, "fooo"));
1246 assert_se(p == original + 5);
1248 p = original = "yay\'foo\'bar";
1249 assert_se(unquote_first_word(&p, &t, false) > 0);
1250 assert_se(streq(t, "yayfoobar"));
1252 assert_se(p == original + 11);
1254 p = original = " foobar ";
1255 assert_se(unquote_first_word(&p, &t, false) > 0);
1256 assert_se(streq(t, "foobar"));
1258 assert_se(p == original + 12);
1261 static void test_unquote_many_words(void) {
1262 const char *p, *original;
1265 p = original = "foobar waldi piep";
1266 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1267 assert_se(p == original + 17);
1268 assert_se(streq_ptr(a, "foobar"));
1269 assert_se(streq_ptr(b, "waldi"));
1270 assert_se(streq_ptr(c, "piep"));
1275 p = original = "'foobar' wa\"ld\"i ";
1276 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1277 assert_se(p == original + 19);
1278 assert_se(streq_ptr(a, "foobar"));
1279 assert_se(streq_ptr(b, "waldi"));
1280 assert_se(streq_ptr(c, NULL));
1285 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1286 assert_se(p == original);
1287 assert_se(streq_ptr(a, NULL));
1288 assert_se(streq_ptr(b, NULL));
1289 assert_se(streq_ptr(c, NULL));
1292 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1293 assert_se(p == original+2);
1294 assert_se(streq_ptr(a, NULL));
1295 assert_se(streq_ptr(b, NULL));
1296 assert_se(streq_ptr(c, NULL));
1298 p = original = "foobar";
1299 assert_se(unquote_many_words(&p, NULL) == 0);
1300 assert_se(p == original);
1302 p = original = "foobar waldi";
1303 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1304 assert_se(p == original+7);
1305 assert_se(streq_ptr(a, "foobar"));
1308 p = original = " foobar ";
1309 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1310 assert_se(p == original+15);
1311 assert_se(streq_ptr(a, "foobar"));
1315 static int parse_item(const char *key, const char *value) {
1318 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1322 static void test_parse_proc_cmdline(void) {
1323 assert_se(parse_proc_cmdline(parse_item) >= 0);
1326 static void test_raw_clone(void) {
1327 pid_t parent, pid, pid2;
1330 log_info("before clone: getpid()→"PID_FMT, parent);
1331 assert_se(raw_getpid() == parent);
1333 pid = raw_clone(0, NULL);
1334 assert_se(pid >= 0);
1336 pid2 = raw_getpid();
1337 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1338 pid, getpid(), pid2);
1340 assert_se(pid2 != parent);
1341 _exit(EXIT_SUCCESS);
1345 assert_se(pid2 == parent);
1346 waitpid(pid, &status, __WCLONE);
1347 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1351 int main(int argc, char *argv[]) {
1352 log_parse_environment();
1356 test_align_power2();
1358 test_container_of();
1362 test_parse_boolean();
1369 test_delete_chars();
1379 test_foreach_word();
1380 test_foreach_word_quoted();
1381 test_default_term_for_tty();
1382 test_memdup_multiply();
1383 test_hostname_is_valid();
1385 test_get_process_comm();
1386 test_protect_errno();
1388 test_config_parse_iec_off();
1392 test_fstab_node_to_udev_node();
1393 test_get_files_in_directory();
1395 test_writing_tmpfile();
1398 test_foreach_string();
1399 test_filename_is_valid();
1400 test_string_has_cc();
1401 test_ascii_strlower();
1403 test_is_valid_documentation_url();
1404 test_file_in_same_dir();
1406 test_close_nointr();
1407 test_unlink_noerrno();
1408 test_readlink_and_make_absolute();
1409 test_read_one_char();
1410 test_ignore_signals();
1414 test_pid_is_unwaited();
1415 test_pid_is_alive();
1416 test_search_and_fopen();
1417 test_search_and_fopen_nulstr();
1419 test_execute_directory();
1420 test_unquote_first_word();
1421 test_unquote_many_words();
1422 test_parse_proc_cmdline();