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 test_foreach_word_quoted(void) {
410 const char *word, *state;
413 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
414 const char * const expected[] = {
430 printf("<%s>\n", test);
431 FOREACH_WORD_QUOTED(word, l, test, state) {
432 _cleanup_free_ char *t = NULL;
434 assert_se(t = strndup(word, l));
435 assert_se(strneq(expected[i++], word, l));
438 assert_se(isempty(state));
441 static void test_default_term_for_tty(void) {
442 puts(default_term_for_tty("/dev/tty23"));
443 puts(default_term_for_tty("/dev/ttyS23"));
444 puts(default_term_for_tty("/dev/tty0"));
445 puts(default_term_for_tty("/dev/pty0"));
446 puts(default_term_for_tty("/dev/pts/0"));
447 puts(default_term_for_tty("/dev/console"));
448 puts(default_term_for_tty("tty23"));
449 puts(default_term_for_tty("ttyS23"));
450 puts(default_term_for_tty("tty0"));
451 puts(default_term_for_tty("pty0"));
452 puts(default_term_for_tty("pts/0"));
453 puts(default_term_for_tty("console"));
456 static void test_memdup_multiply(void) {
457 int org[] = {1, 2, 3};
460 dup = (int*)memdup_multiply(org, sizeof(int), 3);
463 assert_se(dup[0] == 1);
464 assert_se(dup[1] == 2);
465 assert_se(dup[2] == 3);
469 static void test_hostname_is_valid(void) {
470 assert_se(hostname_is_valid("foobar"));
471 assert_se(hostname_is_valid("foobar.com"));
472 assert_se(!hostname_is_valid("fööbar"));
473 assert_se(!hostname_is_valid(""));
474 assert_se(!hostname_is_valid("."));
475 assert_se(!hostname_is_valid(".."));
476 assert_se(!hostname_is_valid("foobar."));
477 assert_se(!hostname_is_valid(".foobar"));
478 assert_se(!hostname_is_valid("foo..bar"));
479 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
482 static void test_u64log2(void) {
483 assert_se(u64log2(0) == 0);
484 assert_se(u64log2(8) == 3);
485 assert_se(u64log2(9) == 3);
486 assert_se(u64log2(15) == 3);
487 assert_se(u64log2(16) == 4);
488 assert_se(u64log2(1024*1024) == 20);
489 assert_se(u64log2(1024*1024+5) == 20);
492 static void test_get_process_comm(void) {
494 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
495 _cleanup_free_ char *env = NULL;
503 if (stat("/proc/1/comm", &st) == 0) {
504 assert_se(get_process_comm(1, &a) >= 0);
505 log_info("pid1 comm: '%s'", a);
507 log_warning("/proc/1/comm does not exist.");
510 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
511 log_info("pid1 cmdline: '%s'", c);
513 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
514 log_info("pid1 cmdline truncated: '%s'", d);
516 assert_se(get_parent_of_pid(1, &e) >= 0);
517 log_info("pid1 ppid: "PID_FMT, e);
520 assert_se(is_kernel_thread(1) == 0);
522 r = get_process_exe(1, &f);
523 assert_se(r >= 0 || r == -EACCES);
524 log_info("pid1 exe: '%s'", strna(f));
526 assert_se(get_process_uid(1, &u) == 0);
527 log_info("pid1 uid: "UID_FMT, u);
530 assert_se(get_process_gid(1, &g) == 0);
531 log_info("pid1 gid: "GID_FMT, g);
536 r = get_process_cwd(me, &cwd);
537 assert_se(r >= 0 || r == -EACCES);
538 log_info("pid1 cwd: '%s'", cwd);
540 r = get_process_root(me, &root);
541 assert_se(r >= 0 || r == -EACCES);
542 log_info("pid1 root: '%s'", root);
544 r = get_process_environ(me, &env);
545 assert_se(r >= 0 || r == -EACCES);
546 log_info("self strlen(environ): '%zd'", strlen(env));
548 if (!detect_container(NULL))
549 assert_se(get_ctty_devnr(1, &h) == -ENOENT);
551 getenv_for_pid(1, "PATH", &i);
552 log_info("pid1 $PATH: '%s'", strna(i));
555 static void test_protect_errno(void) {
561 assert_se(errno == 12);
564 static void test_parse_size(void) {
567 assert_se(parse_size("111", 1024, &bytes) == 0);
568 assert_se(bytes == 111);
570 assert_se(parse_size("111.4", 1024, &bytes) == 0);
571 assert_se(bytes == 111);
573 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
574 assert_se(bytes == 112);
576 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
577 assert_se(bytes == 112);
579 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
580 assert_se(bytes == 3*1024 + 512);
582 assert_se(parse_size("3. K", 1024, &bytes) == 0);
583 assert_se(bytes == 3*1024);
585 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
586 assert_se(bytes == 3*1024);
588 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
590 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
591 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
593 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
595 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
596 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
598 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
599 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
601 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
603 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
604 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
606 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
607 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
609 assert_se(parse_size("12P", 1024, &bytes) == 0);
610 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
612 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
614 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
615 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
617 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
619 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
621 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
623 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
624 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
625 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
627 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
629 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
632 static void test_config_parse_iec_off(void) {
634 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
635 assert_se(offset == 4 * 1024 * 1024);
637 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
640 static void test_strextend(void) {
641 _cleanup_free_ char *str = strdup("0123");
642 strextend(&str, "456", "78", "9", NULL);
643 assert_se(streq(str, "0123456789"));
646 static void test_strrep(void) {
647 _cleanup_free_ char *one, *three, *zero;
648 one = strrep("waldo", 1);
649 three = strrep("waldo", 3);
650 zero = strrep("waldo", 0);
652 assert_se(streq(one, "waldo"));
653 assert_se(streq(three, "waldowaldowaldo"));
654 assert_se(streq(zero, ""));
657 static void test_split_pair(void) {
658 _cleanup_free_ char *a = NULL, *b = NULL;
660 assert_se(split_pair("", "", &a, &b) == -EINVAL);
661 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
662 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
663 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
664 assert_se(streq(a, "foo"));
665 assert_se(streq(b, "bar"));
668 assert_se(split_pair("==", "==", &a, &b) >= 0);
669 assert_se(streq(a, ""));
670 assert_se(streq(b, ""));
674 assert_se(split_pair("===", "==", &a, &b) >= 0);
675 assert_se(streq(a, ""));
676 assert_se(streq(b, "="));
679 static void test_fstab_node_to_udev_node(void) {
682 n = fstab_node_to_udev_node("LABEL=applé/jack");
684 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
687 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
689 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
692 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
694 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
697 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
699 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
702 n = fstab_node_to_udev_node("PONIES=awesome");
704 assert_se(streq(n, "PONIES=awesome"));
707 n = fstab_node_to_udev_node("/dev/xda1");
709 assert_se(streq(n, "/dev/xda1"));
713 static void test_get_files_in_directory(void) {
714 _cleanup_strv_free_ char **l = NULL, **t = NULL;
716 assert_se(get_files_in_directory("/tmp", &l) >= 0);
717 assert_se(get_files_in_directory(".", &t) >= 0);
718 assert_se(get_files_in_directory(".", NULL) >= 0);
721 static void test_in_set(void) {
722 assert_se(IN_SET(1, 1));
723 assert_se(IN_SET(1, 1, 2, 3, 4));
724 assert_se(IN_SET(2, 1, 2, 3, 4));
725 assert_se(IN_SET(3, 1, 2, 3, 4));
726 assert_se(IN_SET(4, 1, 2, 3, 4));
727 assert_se(!IN_SET(0, 1));
728 assert_se(!IN_SET(0, 1, 2, 3, 4));
731 static void test_writing_tmpfile(void) {
732 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
733 _cleanup_free_ char *contents = NULL;
738 IOVEC_SET_STRING(iov[0], "abc\n");
739 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
740 IOVEC_SET_STRING(iov[2], "");
742 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
743 printf("tmpfile: %s", name);
745 r = writev(fd, iov, 3);
748 r = read_full_file(name, &contents, &size);
750 printf("contents: %s", contents);
751 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
756 static void test_hexdump(void) {
760 hexdump(stdout, NULL, 0);
761 hexdump(stdout, "", 0);
762 hexdump(stdout, "", 1);
763 hexdump(stdout, "x", 1);
764 hexdump(stdout, "x", 2);
765 hexdump(stdout, "foobar", 7);
766 hexdump(stdout, "f\nobar", 7);
767 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
769 for (i = 0; i < ELEMENTSOF(data); i++)
772 hexdump(stdout, data, sizeof(data));
775 static void test_log2i(void) {
776 assert_se(log2i(1) == 0);
777 assert_se(log2i(2) == 1);
778 assert_se(log2i(3) == 1);
779 assert_se(log2i(4) == 2);
780 assert_se(log2i(32) == 5);
781 assert_se(log2i(33) == 5);
782 assert_se(log2i(63) == 5);
783 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
786 static void test_foreach_string(void) {
787 const char * const t[] = {
796 FOREACH_STRING(x, "foo", "bar", "waldo")
797 assert_se(streq_ptr(t[i++], x));
801 FOREACH_STRING(x, "zzz")
802 assert_se(streq(x, "zzz"));
805 static void test_filename_is_safe(void) {
806 char foo[FILENAME_MAX+2];
809 assert_se(!filename_is_safe(""));
810 assert_se(!filename_is_safe("/bar/foo"));
811 assert_se(!filename_is_safe("/"));
812 assert_se(!filename_is_safe("."));
813 assert_se(!filename_is_safe(".."));
815 for (i=0; i<FILENAME_MAX+1; i++)
817 foo[FILENAME_MAX+1] = '\0';
819 assert_se(!filename_is_safe(foo));
821 assert_se(filename_is_safe("foo_bar-333"));
822 assert_se(filename_is_safe("o.o"));
825 static void test_string_has_cc(void) {
826 assert_se(string_has_cc("abc\1", NULL));
827 assert_se(string_has_cc("abc\x7f", NULL));
828 assert_se(string_has_cc("abc\x7f", NULL));
829 assert_se(string_has_cc("abc\t\x7f", "\t"));
830 assert_se(string_has_cc("abc\t\x7f", "\t"));
831 assert_se(string_has_cc("\x7f", "\t"));
832 assert_se(string_has_cc("\x7f", "\t\a"));
834 assert_se(!string_has_cc("abc\t\t", "\t"));
835 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
836 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
839 static void test_ascii_strlower(void) {
840 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
841 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
844 static void test_files_same(void) {
845 _cleanup_close_ int fd = -1;
846 char name[] = "/tmp/test-files_same.XXXXXX";
847 char name_alias[] = "/tmp/test-files_same.alias";
849 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
851 assert_se(symlink(name, name_alias) >= 0);
853 assert_se(files_same(name, name));
854 assert_se(files_same(name, name_alias));
860 static void test_is_valid_documentation_url(void) {
861 assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
862 assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
863 assert_se(is_valid_documentation_url("file:foo"));
864 assert_se(is_valid_documentation_url("man:systemd.special(7)"));
865 assert_se(is_valid_documentation_url("info:bar"));
867 assert_se(!is_valid_documentation_url("foo:"));
868 assert_se(!is_valid_documentation_url("info:"));
869 assert_se(!is_valid_documentation_url(""));
872 static void test_file_in_same_dir(void) {
875 t = file_in_same_dir("/", "a");
876 assert_se(streq(t, "/a"));
879 t = file_in_same_dir("/", "/a");
880 assert_se(streq(t, "/a"));
883 t = file_in_same_dir("", "a");
884 assert_se(streq(t, "a"));
887 t = file_in_same_dir("a/", "a");
888 assert_se(streq(t, "a/a"));
891 t = file_in_same_dir("bar/foo", "bar");
892 assert_se(streq(t, "bar/bar"));
896 static void test_endswith(void) {
897 assert_se(endswith("foobar", "bar"));
898 assert_se(endswith("foobar", ""));
899 assert_se(endswith("foobar", "foobar"));
900 assert_se(endswith("", ""));
902 assert_se(!endswith("foobar", "foo"));
903 assert_se(!endswith("foobar", "foobarfoofoo"));
906 static void test_close_nointr(void) {
907 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
910 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
912 assert_se(close_nointr(fd) >= 0);
913 assert_se(close_nointr(fd) < 0);
919 static void test_unlink_noerrno(void) {
920 char name[] = "/tmp/test-close_nointr.XXXXXX";
923 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
925 assert_se(close_nointr(fd) >= 0);
930 assert_se(unlink_noerrno(name) >= 0);
931 assert_se(errno == -42);
932 assert_se(unlink_noerrno(name) < 0);
933 assert_se(errno == -42);
937 static void test_readlink_and_make_absolute(void) {
938 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
939 char name[] = "/tmp/test-readlink_and_make_absolute/original";
940 char name2[] = "test-readlink_and_make_absolute/original";
941 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
944 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
945 assert_se(touch(name) >= 0);
947 assert_se(symlink(name, name_alias) >= 0);
948 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
949 assert_se(streq(r, name));
951 assert_se(unlink(name_alias) >= 0);
953 assert_se(chdir(tempdir) >= 0);
954 assert_se(symlink(name2, name_alias) >= 0);
955 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
956 assert_se(streq(r, name));
958 assert_se(unlink(name_alias) >= 0);
960 assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
963 static void test_read_one_char(void) {
964 _cleanup_fclose_ FILE *file = NULL;
967 char name[] = "/tmp/test-read_one_char.XXXXXX";
970 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
972 file = fdopen(fd, "r+");
974 assert_se(fputs("c\n", file) >= 0);
977 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
980 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
983 assert_se(fputs("foobar\n", file) >= 0);
985 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
988 assert_se(fputs("\n", file) >= 0);
990 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
995 static void test_ignore_signals(void) {
996 assert_se(ignore_signals(SIGINT, -1) >= 0);
997 assert_se(kill(getpid(), SIGINT) >= 0);
998 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
999 assert_se(kill(getpid(), SIGUSR1) >= 0);
1000 assert_se(kill(getpid(), SIGUSR2) >= 0);
1001 assert_se(kill(getpid(), SIGTERM) >= 0);
1002 assert_se(kill(getpid(), SIGPIPE) >= 0);
1003 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1006 static void test_strshorten(void) {
1007 char s[] = "foobar";
1009 assert_se(strlen(strshorten(s, 6)) == 6);
1010 assert_se(strlen(strshorten(s, 12)) == 6);
1011 assert_se(strlen(strshorten(s, 2)) == 2);
1012 assert_se(strlen(strshorten(s, 0)) == 0);
1015 static void test_strappenda(void) {
1018 actual = strappenda("", "foo", "bar");
1019 assert_se(streq(actual, "foobar"));
1021 actual = strappenda("foo", "bar", "baz");
1022 assert_se(streq(actual, "foobarbaz"));
1024 actual = strappenda("foo", "", "bar", "baz");
1025 assert_se(streq(actual, "foobarbaz"));
1028 static void test_is_symlink(void) {
1029 char name[] = "/tmp/test-is_symlink.XXXXXX";
1030 char name_link[] = "/tmp/test-is_symlink.link";
1031 _cleanup_close_ int fd = -1;
1033 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1035 assert_se(symlink(name, name_link) >= 0);
1037 assert_se(is_symlink(name) == 0);
1038 assert_se(is_symlink(name_link) == 1);
1039 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1046 static void test_pid_is_unwaited(void) {
1050 assert_se(pid >= 0);
1052 _exit(EXIT_SUCCESS);
1056 waitpid(pid, &status, 0);
1057 assert_se(!pid_is_unwaited(pid));
1059 assert_se(pid_is_unwaited(getpid()));
1060 assert_se(!pid_is_unwaited(-1));
1063 static void test_pid_is_alive(void) {
1067 assert_se(pid >= 0);
1069 _exit(EXIT_SUCCESS);
1073 waitpid(pid, &status, 0);
1074 assert_se(!pid_is_alive(pid));
1076 assert_se(pid_is_alive(getpid()));
1077 assert_se(!pid_is_alive(-1));
1080 static void test_search_and_fopen(void) {
1081 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1082 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1087 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1091 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1095 r = search_and_fopen(name, "r", NULL, dirs, &f);
1099 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1103 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1105 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1111 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1116 static void test_search_and_fopen_nulstr(void) {
1117 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1118 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1123 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1127 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1131 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1135 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1137 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1143 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1147 static void test_glob_exists(void) {
1148 char name[] = "/tmp/test-glob_exists.XXXXXX";
1152 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1156 r = glob_exists("/tmp/test-glob_exists*");
1161 r = glob_exists("/tmp/test-glob_exists*");
1165 static void test_execute_directory(void) {
1166 char name[] = "/tmp/test-execute_directory/script1";
1167 char name2[] = "/tmp/test-execute_directory/script2";
1168 char name3[] = "/tmp/test-execute_directory/useless";
1169 char tempdir[] = "/tmp/test-execute_directory/";
1171 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1172 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1173 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1174 assert_se(chmod(name, 0755) == 0);
1175 assert_se(chmod(name2, 0755) == 0);
1176 assert_se(touch(name3) >= 0);
1178 execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
1179 assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1180 assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1182 rm_rf_dangerous(tempdir, false, true, false);
1185 static void test_unquote_first_word(void) {
1186 const char *p, *original;
1189 p = original = "foobar waldo";
1190 assert_se(unquote_first_word(&p, &t, false) > 0);
1191 assert_se(streq(t, "foobar"));
1193 assert_se(p == original + 7);
1195 assert_se(unquote_first_word(&p, &t, false) > 0);
1196 assert_se(streq(t, "waldo"));
1198 assert_se(p == original + 12);
1200 assert_se(unquote_first_word(&p, &t, false) == 0);
1202 assert_se(p == original + 12);
1204 p = original = "\"foobar\" \'waldo\'";
1205 assert_se(unquote_first_word(&p, &t, false) > 0);
1206 assert_se(streq(t, "foobar"));
1208 assert_se(p == original + 9);
1210 assert_se(unquote_first_word(&p, &t, false) > 0);
1211 assert_se(streq(t, "waldo"));
1213 assert_se(p == original + 16);
1215 assert_se(unquote_first_word(&p, &t, false) == 0);
1217 assert_se(p == original + 16);
1219 p = original = "\"";
1220 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1221 assert_se(p == original + 1);
1223 p = original = "\'";
1224 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1225 assert_se(p == original + 1);
1227 p = original = "\'fooo";
1228 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1229 assert_se(p == original + 5);
1231 p = original = "\'fooo";
1232 assert_se(unquote_first_word(&p, &t, true) > 0);
1233 assert_se(streq(t, "fooo"));
1235 assert_se(p == original + 5);
1237 p = original = "yay\'foo\'bar";
1238 assert_se(unquote_first_word(&p, &t, false) > 0);
1239 assert_se(streq(t, "yayfoobar"));
1241 assert_se(p == original + 11);
1243 p = original = " foobar ";
1244 assert_se(unquote_first_word(&p, &t, false) > 0);
1245 assert_se(streq(t, "foobar"));
1247 assert_se(p == original + 12);
1250 static void test_unquote_many_words(void) {
1251 const char *p, *original;
1254 p = original = "foobar waldi piep";
1255 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1256 assert_se(p == original + 17);
1257 assert_se(streq_ptr(a, "foobar"));
1258 assert_se(streq_ptr(b, "waldi"));
1259 assert_se(streq_ptr(c, "piep"));
1264 p = original = "'foobar' wa\"ld\"i ";
1265 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1266 assert_se(p == original + 19);
1267 assert_se(streq_ptr(a, "foobar"));
1268 assert_se(streq_ptr(b, "waldi"));
1269 assert_se(streq_ptr(c, NULL));
1274 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1275 assert_se(p == original);
1276 assert_se(streq_ptr(a, NULL));
1277 assert_se(streq_ptr(b, NULL));
1278 assert_se(streq_ptr(c, NULL));
1281 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1282 assert_se(p == original+2);
1283 assert_se(streq_ptr(a, NULL));
1284 assert_se(streq_ptr(b, NULL));
1285 assert_se(streq_ptr(c, NULL));
1287 p = original = "foobar";
1288 assert_se(unquote_many_words(&p, NULL) == 0);
1289 assert_se(p == original);
1291 p = original = "foobar waldi";
1292 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1293 assert_se(p == original+7);
1294 assert_se(streq_ptr(a, "foobar"));
1297 p = original = " foobar ";
1298 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1299 assert_se(p == original+15);
1300 assert_se(streq_ptr(a, "foobar"));
1304 static int parse_item(const char *key, const char *value) {
1307 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1311 static void test_parse_proc_cmdline(void) {
1312 assert_se(parse_proc_cmdline(parse_item) >= 0);
1315 int main(int argc, char *argv[]) {
1316 log_parse_environment();
1320 test_align_power2();
1322 test_container_of();
1326 test_parse_boolean();
1333 test_delete_chars();
1343 test_foreach_word();
1344 test_foreach_word_quoted();
1345 test_default_term_for_tty();
1346 test_memdup_multiply();
1347 test_hostname_is_valid();
1349 test_get_process_comm();
1350 test_protect_errno();
1352 test_config_parse_iec_off();
1356 test_fstab_node_to_udev_node();
1357 test_get_files_in_directory();
1359 test_writing_tmpfile();
1362 test_foreach_string();
1363 test_filename_is_safe();
1364 test_string_has_cc();
1365 test_ascii_strlower();
1367 test_is_valid_documentation_url();
1368 test_file_in_same_dir();
1370 test_close_nointr();
1371 test_unlink_noerrno();
1372 test_readlink_and_make_absolute();
1373 test_read_one_char();
1374 test_ignore_signals();
1378 test_pid_is_unwaited();
1379 test_pid_is_alive();
1380 test_search_and_fopen();
1381 test_search_and_fopen_nulstr();
1383 test_execute_directory();
1384 test_unquote_first_word();
1385 test_unquote_many_words();
1386 test_parse_proc_cmdline();