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"
39 static void test_streq_ptr(void) {
40 assert_se(streq_ptr(NULL, NULL));
41 assert_se(!streq_ptr("abc", "cdef"));
44 static void test_align_power2(void) {
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);
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);
59 for (i = 1; i < 131071; ++i) {
60 for (p2 = 1; p2 < i; p2 <<= 1)
63 assert_se(ALIGN_POWER2(i) == p2);
66 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
67 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
70 assert_se(ALIGN_POWER2(i) == p2);
74 static void test_max(void) {
77 int b[CONST_MAX(10, 100)];
79 .a = CONST_MAX(10, 100),
83 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
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));
90 assert_se(val1.a == 100);
91 assert_se(MAX(++d, 0) == 1);
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));
98 assert_se(MAX(-5, 5) == 5);
99 assert_se(MAX(5, 5) == 5);
100 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
101 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
102 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
103 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
104 assert_se(LESS_BY(8, 4) == 4);
105 assert_se(LESS_BY(8, 8) == 0);
106 assert_se(LESS_BY(4, 8) == 0);
107 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
108 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
109 assert_se(CLAMP(-5, 0, 1) == 0);
110 assert_se(CLAMP(5, 0, 1) == 1);
111 assert_se(CLAMP(5, -10, 1) == 1);
112 assert_se(CLAMP(5, -10, 10) == 5);
113 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
116 static void test_container_of(void) {
122 } _packed_ myval = { };
124 assert_cc(sizeof(myval) == 17);
125 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
126 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
127 assert_se(container_of(&container_of(&myval.v2,
134 static void test_alloca(void) {
135 static const uint8_t zero[997] = { };
138 t = alloca_align(17, 512);
139 assert_se(!((uintptr_t)t & 0xff));
142 t = alloca0_align(997, 1024);
143 assert_se(!((uintptr_t)t & 0x1ff));
144 assert_se(!memcmp(t, zero, 997));
147 static void test_first_word(void) {
148 assert_se(first_word("Hello", ""));
149 assert_se(first_word("Hello", "Hello"));
150 assert_se(first_word("Hello world", "Hello"));
151 assert_se(first_word("Hello\tworld", "Hello"));
152 assert_se(first_word("Hello\nworld", "Hello"));
153 assert_se(first_word("Hello\rworld", "Hello"));
154 assert_se(first_word("Hello ", "Hello"));
156 assert_se(!first_word("Hello", "Hellooo"));
157 assert_se(!first_word("Hello", "xxxxx"));
158 assert_se(!first_word("Hellooo", "Hello"));
161 static void test_close_many(void) {
163 char name0[] = "/tmp/test-close-many.XXXXXX";
164 char name1[] = "/tmp/test-close-many.XXXXXX";
165 char name2[] = "/tmp/test-close-many.XXXXXX";
167 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
168 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
169 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
173 assert_se(fcntl(fds[0], F_GETFD) == -1);
174 assert_se(fcntl(fds[1], F_GETFD) == -1);
175 assert_se(fcntl(fds[2], F_GETFD) >= 0);
184 static void test_parse_boolean(void) {
185 assert_se(parse_boolean("1") == 1);
186 assert_se(parse_boolean("y") == 1);
187 assert_se(parse_boolean("Y") == 1);
188 assert_se(parse_boolean("yes") == 1);
189 assert_se(parse_boolean("YES") == 1);
190 assert_se(parse_boolean("true") == 1);
191 assert_se(parse_boolean("TRUE") == 1);
192 assert_se(parse_boolean("on") == 1);
193 assert_se(parse_boolean("ON") == 1);
195 assert_se(parse_boolean("0") == 0);
196 assert_se(parse_boolean("n") == 0);
197 assert_se(parse_boolean("N") == 0);
198 assert_se(parse_boolean("no") == 0);
199 assert_se(parse_boolean("NO") == 0);
200 assert_se(parse_boolean("false") == 0);
201 assert_se(parse_boolean("FALSE") == 0);
202 assert_se(parse_boolean("off") == 0);
203 assert_se(parse_boolean("OFF") == 0);
205 assert_se(parse_boolean("garbage") < 0);
206 assert_se(parse_boolean("") < 0);
207 assert_se(parse_boolean("full") < 0);
210 static void test_parse_pid(void) {
214 r = parse_pid("100", &pid);
216 assert_se(pid == 100);
218 r = parse_pid("0x7FFFFFFF", &pid);
220 assert_se(pid == 2147483647);
222 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
223 r = parse_pid("0", &pid);
224 assert_se(r == -ERANGE);
225 assert_se(pid == 65);
227 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
228 r = parse_pid("-100", &pid);
229 assert_se(r == -ERANGE);
230 assert_se(pid == 65);
232 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
233 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
234 assert_se(r == -ERANGE);
235 assert_se(pid == 65);
238 static void test_parse_uid(void) {
242 r = parse_uid("100", &uid);
244 assert_se(uid == 100);
247 static void test_safe_atolli(void) {
251 r = safe_atolli("12345", &l);
253 assert_se(l == 12345);
255 r = safe_atolli("junk", &l);
256 assert_se(r == -EINVAL);
259 static void test_safe_atod(void) {
264 r = safe_atod("junk", &d);
265 assert_se(r == -EINVAL);
267 r = safe_atod("0.2244", &d);
269 assert_se(fabs(d - 0.2244) < 0.000001);
271 r = safe_atod("0,5", &d);
272 assert_se(r == -EINVAL);
276 assert_se(*e == ',');
278 /* Check if this really is locale independent */
279 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
281 r = safe_atod("0.2244", &d);
283 assert_se(fabs(d - 0.2244) < 0.000001);
285 r = safe_atod("0,5", &d);
286 assert_se(r == -EINVAL);
289 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
292 /* And check again, reset */
293 assert_se(setlocale(LC_NUMERIC, "C"));
295 r = safe_atod("0.2244", &d);
297 assert_se(fabs(d - 0.2244) < 0.000001);
299 r = safe_atod("0,5", &d);
300 assert_se(r == -EINVAL);
304 assert_se(*e == ',');
307 static void test_strappend(void) {
308 _cleanup_free_ char *t1, *t2, *t3, *t4;
310 t1 = strappend(NULL, NULL);
311 assert_se(streq(t1, ""));
313 t2 = strappend(NULL, "suf");
314 assert_se(streq(t2, "suf"));
316 t3 = strappend("pre", NULL);
317 assert_se(streq(t3, "pre"));
319 t4 = strappend("pre", "suf");
320 assert_se(streq(t4, "presuf"));
323 static void test_strstrip(void) {
325 char input[] = " hello, waldo. ";
328 assert_se(streq(r, "hello, waldo."));
331 static void test_delete_chars(void) {
333 char input[] = " hello, waldo. abc";
335 r = delete_chars(input, WHITESPACE);
336 assert_se(streq(r, "hello,waldo.abc"));
339 static void test_in_charset(void) {
340 assert_se(in_charset("dddaaabbbcccc", "abcd"));
341 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
344 static void test_hexchar(void) {
345 assert_se(hexchar(0xa) == 'a');
346 assert_se(hexchar(0x0) == '0');
349 static void test_unhexchar(void) {
350 assert_se(unhexchar('a') == 0xA);
351 assert_se(unhexchar('A') == 0xA);
352 assert_se(unhexchar('0') == 0x0);
355 static void test_octchar(void) {
356 assert_se(octchar(00) == '0');
357 assert_se(octchar(07) == '7');
360 static void test_unoctchar(void) {
361 assert_se(unoctchar('0') == 00);
362 assert_se(unoctchar('7') == 07);
365 static void test_decchar(void) {
366 assert_se(decchar(0) == '0');
367 assert_se(decchar(9) == '9');
370 static void test_undecchar(void) {
371 assert_se(undecchar('0') == 0);
372 assert_se(undecchar('9') == 9);
375 static void test_cescape(void) {
376 _cleanup_free_ char *escaped;
378 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
379 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
382 static void test_cunescape(void) {
383 _cleanup_free_ char *unescaped;
385 assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
386 assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
389 static void test_foreach_word(void) {
390 const char *word, *state;
393 const char test[] = "test abc d\te f ";
394 const char * const expected[] = {
404 FOREACH_WORD(word, l, test, state)
405 assert_se(strneq(expected[i++], word, l));
408 static void test_foreach_word_quoted(void) {
409 const char *word, *state;
412 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
413 const char * const expected[] = {
429 printf("<%s>\n", test);
430 FOREACH_WORD_QUOTED(word, l, test, state) {
431 _cleanup_free_ char *t = NULL;
433 assert_se(t = strndup(word, l));
434 assert_se(strneq(expected[i++], word, l));
437 assert_se(isempty(state));
440 static void test_default_term_for_tty(void) {
441 puts(default_term_for_tty("/dev/tty23"));
442 puts(default_term_for_tty("/dev/ttyS23"));
443 puts(default_term_for_tty("/dev/tty0"));
444 puts(default_term_for_tty("/dev/pty0"));
445 puts(default_term_for_tty("/dev/pts/0"));
446 puts(default_term_for_tty("/dev/console"));
447 puts(default_term_for_tty("tty23"));
448 puts(default_term_for_tty("ttyS23"));
449 puts(default_term_for_tty("tty0"));
450 puts(default_term_for_tty("pty0"));
451 puts(default_term_for_tty("pts/0"));
452 puts(default_term_for_tty("console"));
455 static void test_memdup_multiply(void) {
456 int org[] = {1, 2, 3};
459 dup = (int*)memdup_multiply(org, sizeof(int), 3);
462 assert_se(dup[0] == 1);
463 assert_se(dup[1] == 2);
464 assert_se(dup[2] == 3);
468 static void test_hostname_is_valid(void) {
469 assert_se(hostname_is_valid("foobar"));
470 assert_se(hostname_is_valid("foobar.com"));
471 assert_se(!hostname_is_valid("fööbar"));
472 assert_se(!hostname_is_valid(""));
473 assert_se(!hostname_is_valid("."));
474 assert_se(!hostname_is_valid(".."));
475 assert_se(!hostname_is_valid("foobar."));
476 assert_se(!hostname_is_valid(".foobar"));
477 assert_se(!hostname_is_valid("foo..bar"));
478 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
481 static void test_u64log2(void) {
482 assert_se(u64log2(0) == 0);
483 assert_se(u64log2(8) == 3);
484 assert_se(u64log2(9) == 3);
485 assert_se(u64log2(15) == 3);
486 assert_se(u64log2(16) == 4);
487 assert_se(u64log2(1024*1024) == 20);
488 assert_se(u64log2(1024*1024+5) == 20);
491 static void test_get_process_comm(void) {
493 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
494 _cleanup_free_ char *env = NULL;
502 if (stat("/proc/1/comm", &st) == 0) {
503 assert_se(get_process_comm(1, &a) >= 0);
504 log_info("pid1 comm: '%s'", a);
506 log_warning("/proc/1/comm does not exist.");
509 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
510 log_info("pid1 cmdline: '%s'", c);
512 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
513 log_info("pid1 cmdline truncated: '%s'", d);
515 assert_se(get_parent_of_pid(1, &e) >= 0);
516 log_info("pid1 ppid: "PID_FMT, e);
519 assert_se(is_kernel_thread(1) == 0);
521 r = get_process_exe(1, &f);
522 assert_se(r >= 0 || r == -EACCES);
523 log_info("pid1 exe: '%s'", strna(f));
525 assert_se(get_process_uid(1, &u) == 0);
526 log_info("pid1 uid: "UID_FMT, u);
529 assert_se(get_process_gid(1, &g) == 0);
530 log_info("pid1 gid: "GID_FMT, g);
535 r = get_process_cwd(me, &cwd);
536 assert_se(r >= 0 || r == -EACCES);
537 log_info("pid1 cwd: '%s'", cwd);
539 r = get_process_root(me, &root);
540 assert_se(r >= 0 || r == -EACCES);
541 log_info("pid1 root: '%s'", root);
543 r = get_process_environ(me, &env);
544 assert_se(r >= 0 || r == -EACCES);
545 log_info("self strlen(environ): '%zd'", strlen(env));
547 assert_se(get_ctty_devnr(1, &h) == -ENOENT);
549 getenv_for_pid(1, "PATH", &i);
550 log_info("pid1 $PATH: '%s'", strna(i));
553 static void test_protect_errno(void) {
559 assert_se(errno == 12);
562 static void test_parse_size(void) {
565 assert_se(parse_size("111", 1024, &bytes) == 0);
566 assert_se(bytes == 111);
568 assert_se(parse_size("111.4", 1024, &bytes) == 0);
569 assert_se(bytes == 111);
571 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
572 assert_se(bytes == 112);
574 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
575 assert_se(bytes == 112);
577 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
578 assert_se(bytes == 3*1024 + 512);
580 assert_se(parse_size("3. K", 1024, &bytes) == 0);
581 assert_se(bytes == 3*1024);
583 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
584 assert_se(bytes == 3*1024);
586 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
588 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
589 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
591 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
593 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
594 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
596 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
597 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
599 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
601 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
602 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
604 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
605 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
607 assert_se(parse_size("12P", 1024, &bytes) == 0);
608 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
610 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
612 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
613 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
615 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
617 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
619 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
621 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
622 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
623 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
625 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
627 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
630 static void test_config_parse_iec_off(void) {
632 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
633 assert_se(offset == 4 * 1024 * 1024);
635 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
638 static void test_strextend(void) {
639 _cleanup_free_ char *str = strdup("0123");
640 strextend(&str, "456", "78", "9", NULL);
641 assert_se(streq(str, "0123456789"));
644 static void test_strrep(void) {
645 _cleanup_free_ char *one, *three, *zero;
646 one = strrep("waldo", 1);
647 three = strrep("waldo", 3);
648 zero = strrep("waldo", 0);
650 assert_se(streq(one, "waldo"));
651 assert_se(streq(three, "waldowaldowaldo"));
652 assert_se(streq(zero, ""));
655 static void test_split_pair(void) {
656 _cleanup_free_ char *a = NULL, *b = NULL;
658 assert_se(split_pair("", "", &a, &b) == -EINVAL);
659 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
660 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
661 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
662 assert_se(streq(a, "foo"));
663 assert_se(streq(b, "bar"));
666 assert_se(split_pair("==", "==", &a, &b) >= 0);
667 assert_se(streq(a, ""));
668 assert_se(streq(b, ""));
672 assert_se(split_pair("===", "==", &a, &b) >= 0);
673 assert_se(streq(a, ""));
674 assert_se(streq(b, "="));
677 static void test_fstab_node_to_udev_node(void) {
680 n = fstab_node_to_udev_node("LABEL=applé/jack");
682 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
685 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
687 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
690 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
692 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
695 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
697 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
700 n = fstab_node_to_udev_node("PONIES=awesome");
702 assert_se(streq(n, "PONIES=awesome"));
705 n = fstab_node_to_udev_node("/dev/xda1");
707 assert_se(streq(n, "/dev/xda1"));
711 static void test_get_files_in_directory(void) {
712 _cleanup_strv_free_ char **l = NULL, **t = NULL;
714 assert_se(get_files_in_directory("/tmp", &l) >= 0);
715 assert_se(get_files_in_directory(".", &t) >= 0);
716 assert_se(get_files_in_directory(".", NULL) >= 0);
719 static void test_in_set(void) {
720 assert_se(IN_SET(1, 1));
721 assert_se(IN_SET(1, 1, 2, 3, 4));
722 assert_se(IN_SET(2, 1, 2, 3, 4));
723 assert_se(IN_SET(3, 1, 2, 3, 4));
724 assert_se(IN_SET(4, 1, 2, 3, 4));
725 assert_se(!IN_SET(0, 1));
726 assert_se(!IN_SET(0, 1, 2, 3, 4));
729 static void test_writing_tmpfile(void) {
730 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
731 _cleanup_free_ char *contents = NULL;
736 IOVEC_SET_STRING(iov[0], "abc\n");
737 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
738 IOVEC_SET_STRING(iov[2], "");
740 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
741 printf("tmpfile: %s", name);
743 r = writev(fd, iov, 3);
746 r = read_full_file(name, &contents, &size);
748 printf("contents: %s", contents);
749 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
754 static void test_hexdump(void) {
758 hexdump(stdout, NULL, 0);
759 hexdump(stdout, "", 0);
760 hexdump(stdout, "", 1);
761 hexdump(stdout, "x", 1);
762 hexdump(stdout, "x", 2);
763 hexdump(stdout, "foobar", 7);
764 hexdump(stdout, "f\nobar", 7);
765 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
767 for (i = 0; i < ELEMENTSOF(data); i++)
770 hexdump(stdout, data, sizeof(data));
773 static void test_log2i(void) {
774 assert_se(log2i(1) == 0);
775 assert_se(log2i(2) == 1);
776 assert_se(log2i(3) == 1);
777 assert_se(log2i(4) == 2);
778 assert_se(log2i(32) == 5);
779 assert_se(log2i(33) == 5);
780 assert_se(log2i(63) == 5);
781 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
784 static void test_foreach_string(void) {
785 const char * const t[] = {
794 FOREACH_STRING(x, "foo", "bar", "waldo")
795 assert_se(streq_ptr(t[i++], x));
799 FOREACH_STRING(x, "zzz")
800 assert_se(streq(x, "zzz"));
803 static void test_filename_is_safe(void) {
804 char foo[FILENAME_MAX+2];
807 assert_se(!filename_is_safe(""));
808 assert_se(!filename_is_safe("/bar/foo"));
809 assert_se(!filename_is_safe("/"));
810 assert_se(!filename_is_safe("."));
811 assert_se(!filename_is_safe(".."));
813 for (i=0; i<FILENAME_MAX+1; i++)
815 foo[FILENAME_MAX+1] = '\0';
817 assert_se(!filename_is_safe(foo));
819 assert_se(filename_is_safe("foo_bar-333"));
820 assert_se(filename_is_safe("o.o"));
823 static void test_string_has_cc(void) {
824 assert_se(string_has_cc("abc\1", NULL));
825 assert_se(string_has_cc("abc\x7f", NULL));
826 assert_se(string_has_cc("abc\x7f", NULL));
827 assert_se(string_has_cc("abc\t\x7f", "\t"));
828 assert_se(string_has_cc("abc\t\x7f", "\t"));
829 assert_se(string_has_cc("\x7f", "\t"));
830 assert_se(string_has_cc("\x7f", "\t\a"));
832 assert_se(!string_has_cc("abc\t\t", "\t"));
833 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
834 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
837 static void test_ascii_strlower(void) {
838 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
839 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
842 static void test_files_same(void) {
843 _cleanup_close_ int fd = -1;
844 char name[] = "/tmp/test-files_same.XXXXXX";
845 char name_alias[] = "/tmp/test-files_same.alias";
847 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
849 assert_se(symlink(name, name_alias) >= 0);
851 assert_se(files_same(name, name));
852 assert_se(files_same(name, name_alias));
858 static void test_is_valid_documentation_url(void) {
859 assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
860 assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
861 assert_se(is_valid_documentation_url("file:foo"));
862 assert_se(is_valid_documentation_url("man:systemd.special(7)"));
863 assert_se(is_valid_documentation_url("info:bar"));
865 assert_se(!is_valid_documentation_url("foo:"));
866 assert_se(!is_valid_documentation_url("info:"));
867 assert_se(!is_valid_documentation_url(""));
870 static void test_file_in_same_dir(void) {
873 t = file_in_same_dir("/", "a");
874 assert_se(streq(t, "/a"));
877 t = file_in_same_dir("/", "/a");
878 assert_se(streq(t, "/a"));
881 t = file_in_same_dir("", "a");
882 assert_se(streq(t, "a"));
885 t = file_in_same_dir("a/", "a");
886 assert_se(streq(t, "a/a"));
889 t = file_in_same_dir("bar/foo", "bar");
890 assert_se(streq(t, "bar/bar"));
894 static void test_endswith(void) {
895 assert_se(endswith("foobar", "bar"));
896 assert_se(endswith("foobar", ""));
897 assert_se(endswith("foobar", "foobar"));
898 assert_se(endswith("", ""));
900 assert_se(!endswith("foobar", "foo"));
901 assert_se(!endswith("foobar", "foobarfoofoo"));
904 static void test_close_nointr(void) {
905 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
908 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
910 assert_se(close_nointr(fd) >= 0);
911 assert_se(close_nointr(fd) < 0);
917 static void test_unlink_noerrno(void) {
918 char name[] = "/tmp/test-close_nointr.XXXXXX";
921 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
923 assert_se(close_nointr(fd) >= 0);
928 assert_se(unlink_noerrno(name) >= 0);
929 assert_se(errno == -42);
930 assert_se(unlink_noerrno(name) < 0);
931 assert_se(errno == -42);
935 static void test_readlink_and_make_absolute(void) {
936 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
937 char name[] = "/tmp/test-readlink_and_make_absolute/original";
938 char name2[] = "test-readlink_and_make_absolute/original";
939 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
942 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
943 assert_se(touch(name) >= 0);
945 assert_se(symlink(name, name_alias) >= 0);
946 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
947 assert_se(streq(r, name));
949 assert_se(unlink(name_alias) >= 0);
951 assert_se(chdir(tempdir) >= 0);
952 assert_se(symlink(name2, name_alias) >= 0);
953 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
954 assert_se(streq(r, name));
956 assert_se(unlink(name_alias) >= 0);
958 assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
961 static void test_read_one_char(void) {
962 _cleanup_fclose_ FILE *file = NULL;
965 char name[] = "/tmp/test-read_one_char.XXXXXX";
968 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
970 file = fdopen(fd, "r+");
972 assert_se(fputs("c\n", file) >= 0);
975 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
978 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
981 assert_se(fputs("foobar\n", file) >= 0);
983 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
986 assert_se(fputs("\n", file) >= 0);
988 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
993 static void test_ignore_signals(void) {
994 assert_se(ignore_signals(SIGINT, -1) >= 0);
995 assert_se(kill(getpid(), SIGINT) >= 0);
996 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
997 assert_se(kill(getpid(), SIGUSR1) >= 0);
998 assert_se(kill(getpid(), SIGUSR2) >= 0);
999 assert_se(kill(getpid(), SIGTERM) >= 0);
1000 assert_se(kill(getpid(), SIGPIPE) >= 0);
1001 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1004 static void test_strshorten(void) {
1005 char s[] = "foobar";
1007 assert_se(strlen(strshorten(s, 6)) == 6);
1008 assert_se(strlen(strshorten(s, 12)) == 6);
1009 assert_se(strlen(strshorten(s, 2)) == 2);
1010 assert_se(strlen(strshorten(s, 0)) == 0);
1013 static void test_strappenda(void) {
1016 actual = strappenda("", "foo", "bar");
1017 assert_se(streq(actual, "foobar"));
1019 actual = strappenda("foo", "bar", "baz");
1020 assert_se(streq(actual, "foobarbaz"));
1022 actual = strappenda("foo", "", "bar", "baz");
1023 assert_se(streq(actual, "foobarbaz"));
1026 static void test_is_symlink(void) {
1027 char name[] = "/tmp/test-is_symlink.XXXXXX";
1028 char name_link[] = "/tmp/test-is_symlink.link";
1029 _cleanup_close_ int fd = -1;
1031 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1033 assert_se(symlink(name, name_link) >= 0);
1035 assert_se(is_symlink(name) == 0);
1036 assert_se(is_symlink(name_link) == 1);
1037 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1044 static void test_pid_is_unwaited(void) {
1048 assert_se(pid >= 0);
1050 _exit(EXIT_SUCCESS);
1054 waitpid(pid, &status, 0);
1055 assert_se(!pid_is_unwaited(pid));
1057 assert_se(pid_is_unwaited(getpid()));
1058 assert_se(!pid_is_unwaited(-1));
1061 static void test_pid_is_alive(void) {
1065 assert_se(pid >= 0);
1067 _exit(EXIT_SUCCESS);
1071 waitpid(pid, &status, 0);
1072 assert_se(!pid_is_alive(pid));
1074 assert_se(pid_is_alive(getpid()));
1075 assert_se(!pid_is_alive(-1));
1078 static void test_search_and_fopen(void) {
1079 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1080 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1085 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1089 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1093 r = search_and_fopen(name, "r", NULL, dirs, &f);
1097 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1101 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1103 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1109 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1114 static void test_search_and_fopen_nulstr(void) {
1115 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1116 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1121 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1125 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1129 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1133 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1135 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1141 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1145 static void test_glob_exists(void) {
1146 char name[] = "/tmp/test-glob_exists.XXXXXX";
1150 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1154 r = glob_exists("/tmp/test-glob_exists*");
1159 r = glob_exists("/tmp/test-glob_exists*");
1163 static void test_execute_directory(void) {
1164 char name[] = "/tmp/test-execute_directory/script1";
1165 char name2[] = "/tmp/test-execute_directory/script2";
1166 char name3[] = "/tmp/test-execute_directory/useless";
1167 char tempdir[] = "/tmp/test-execute_directory/";
1169 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1170 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1171 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1172 assert_se(chmod(name, 0755) == 0);
1173 assert_se(chmod(name2, 0755) == 0);
1174 assert_se(touch(name3) >= 0);
1176 execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
1177 assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1178 assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1180 rm_rf_dangerous(tempdir, false, true, false);
1183 static void test_unquote_first_word(void) {
1184 const char *p, *original;
1187 p = original = "foobar waldo";
1188 assert_se(unquote_first_word(&p, &t, false) > 0);
1189 assert_se(streq(t, "foobar"));
1191 assert_se(p == original + 7);
1193 assert_se(unquote_first_word(&p, &t, false) > 0);
1194 assert_se(streq(t, "waldo"));
1196 assert_se(p == original + 12);
1198 assert_se(unquote_first_word(&p, &t, false) == 0);
1200 assert_se(p == original + 12);
1202 p = original = "\"foobar\" \'waldo\'";
1203 assert_se(unquote_first_word(&p, &t, false) > 0);
1204 assert_se(streq(t, "foobar"));
1206 assert_se(p == original + 9);
1208 assert_se(unquote_first_word(&p, &t, false) > 0);
1209 assert_se(streq(t, "waldo"));
1211 assert_se(p == original + 16);
1213 assert_se(unquote_first_word(&p, &t, false) == 0);
1215 assert_se(p == original + 16);
1217 p = original = "\"";
1218 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1219 assert_se(p == original + 1);
1221 p = original = "\'";
1222 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1223 assert_se(p == original + 1);
1225 p = original = "\'fooo";
1226 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1227 assert_se(p == original + 5);
1229 p = original = "\'fooo";
1230 assert_se(unquote_first_word(&p, &t, true) > 0);
1231 assert_se(streq(t, "fooo"));
1233 assert_se(p == original + 5);
1235 p = original = "yay\'foo\'bar";
1236 assert_se(unquote_first_word(&p, &t, false) > 0);
1237 assert_se(streq(t, "yayfoobar"));
1239 assert_se(p == original + 11);
1241 p = original = " foobar ";
1242 assert_se(unquote_first_word(&p, &t, false) > 0);
1243 assert_se(streq(t, "foobar"));
1245 assert_se(p == original + 12);
1248 static void test_unquote_many_words(void) {
1249 const char *p, *original;
1252 p = original = "foobar waldi piep";
1253 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1254 assert_se(p == original + 17);
1255 assert_se(streq_ptr(a, "foobar"));
1256 assert_se(streq_ptr(b, "waldi"));
1257 assert_se(streq_ptr(c, "piep"));
1262 p = original = "'foobar' wa\"ld\"i ";
1263 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1264 assert_se(p == original + 19);
1265 assert_se(streq_ptr(a, "foobar"));
1266 assert_se(streq_ptr(b, "waldi"));
1267 assert_se(streq_ptr(c, NULL));
1272 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1273 assert_se(p == original);
1274 assert_se(streq_ptr(a, NULL));
1275 assert_se(streq_ptr(b, NULL));
1276 assert_se(streq_ptr(c, NULL));
1279 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1280 assert_se(p == original+2);
1281 assert_se(streq_ptr(a, NULL));
1282 assert_se(streq_ptr(b, NULL));
1283 assert_se(streq_ptr(c, NULL));
1285 p = original = "foobar";
1286 assert_se(unquote_many_words(&p, NULL) == 0);
1287 assert_se(p == original);
1289 p = original = "foobar waldi";
1290 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1291 assert_se(p == original+7);
1292 assert_se(streq_ptr(a, "foobar"));
1295 p = original = " foobar ";
1296 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1297 assert_se(p == original+15);
1298 assert_se(streq_ptr(a, "foobar"));
1302 static int parse_item(const char *key, const char *value) {
1305 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1309 static void test_parse_proc_cmdline(void) {
1310 assert_se(parse_proc_cmdline(parse_item) >= 0);
1313 int main(int argc, char *argv[]) {
1314 log_parse_environment();
1318 test_align_power2();
1320 test_container_of();
1324 test_parse_boolean();
1331 test_delete_chars();
1341 test_foreach_word();
1342 test_foreach_word_quoted();
1343 test_default_term_for_tty();
1344 test_memdup_multiply();
1345 test_hostname_is_valid();
1347 test_get_process_comm();
1348 test_protect_errno();
1350 test_config_parse_iec_off();
1354 test_fstab_node_to_udev_node();
1355 test_get_files_in_directory();
1357 test_writing_tmpfile();
1360 test_foreach_string();
1361 test_filename_is_safe();
1362 test_string_has_cc();
1363 test_ascii_strlower();
1365 test_is_valid_documentation_url();
1366 test_file_in_same_dir();
1368 test_close_nointr();
1369 test_unlink_noerrno();
1370 test_readlink_and_make_absolute();
1371 test_read_one_char();
1372 test_ignore_signals();
1376 test_pid_is_unwaited();
1377 test_pid_is_alive();
1378 test_search_and_fopen();
1379 test_search_and_fopen_nulstr();
1381 test_execute_directory();
1382 test_unquote_first_word();
1383 test_unquote_many_words();
1384 test_parse_proc_cmdline();