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));
99 static void test_first_word(void) {
100 assert_se(first_word("Hello", ""));
101 assert_se(first_word("Hello", "Hello"));
102 assert_se(first_word("Hello world", "Hello"));
103 assert_se(first_word("Hello\tworld", "Hello"));
104 assert_se(first_word("Hello\nworld", "Hello"));
105 assert_se(first_word("Hello\rworld", "Hello"));
106 assert_se(first_word("Hello ", "Hello"));
108 assert_se(!first_word("Hello", "Hellooo"));
109 assert_se(!first_word("Hello", "xxxxx"));
110 assert_se(!first_word("Hellooo", "Hello"));
113 static void test_close_many(void) {
115 char name0[] = "/tmp/test-close-many.XXXXXX";
116 char name1[] = "/tmp/test-close-many.XXXXXX";
117 char name2[] = "/tmp/test-close-many.XXXXXX";
119 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
120 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
121 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
125 assert_se(fcntl(fds[0], F_GETFD) == -1);
126 assert_se(fcntl(fds[1], F_GETFD) == -1);
127 assert_se(fcntl(fds[2], F_GETFD) >= 0);
136 static void test_parse_boolean(void) {
137 assert_se(parse_boolean("1") == 1);
138 assert_se(parse_boolean("y") == 1);
139 assert_se(parse_boolean("Y") == 1);
140 assert_se(parse_boolean("yes") == 1);
141 assert_se(parse_boolean("YES") == 1);
142 assert_se(parse_boolean("true") == 1);
143 assert_se(parse_boolean("TRUE") == 1);
144 assert_se(parse_boolean("on") == 1);
145 assert_se(parse_boolean("ON") == 1);
147 assert_se(parse_boolean("0") == 0);
148 assert_se(parse_boolean("n") == 0);
149 assert_se(parse_boolean("N") == 0);
150 assert_se(parse_boolean("no") == 0);
151 assert_se(parse_boolean("NO") == 0);
152 assert_se(parse_boolean("false") == 0);
153 assert_se(parse_boolean("FALSE") == 0);
154 assert_se(parse_boolean("off") == 0);
155 assert_se(parse_boolean("OFF") == 0);
157 assert_se(parse_boolean("garbage") < 0);
158 assert_se(parse_boolean("") < 0);
159 assert_se(parse_boolean("full") < 0);
162 static void test_parse_pid(void) {
166 r = parse_pid("100", &pid);
168 assert_se(pid == 100);
170 r = parse_pid("0x7FFFFFFF", &pid);
172 assert_se(pid == 2147483647);
174 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
175 r = parse_pid("0", &pid);
176 assert_se(r == -ERANGE);
177 assert_se(pid == 65);
179 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
180 r = parse_pid("-100", &pid);
181 assert_se(r == -ERANGE);
182 assert_se(pid == 65);
184 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
185 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
186 assert(r == -ERANGE);
187 assert_se(pid == 65);
190 static void test_parse_uid(void) {
194 r = parse_uid("100", &uid);
196 assert_se(uid == 100);
199 static void test_safe_atolli(void) {
203 r = safe_atolli("12345", &l);
205 assert_se(l == 12345);
207 r = safe_atolli("junk", &l);
208 assert_se(r == -EINVAL);
211 static void test_safe_atod(void) {
216 r = safe_atod("junk", &d);
217 assert_se(r == -EINVAL);
219 r = safe_atod("0.2244", &d);
221 assert_se(fabs(d - 0.2244) < 0.000001);
223 r = safe_atod("0,5", &d);
224 assert_se(r == -EINVAL);
228 assert_se(*e == ',');
230 /* Check if this really is locale independent */
231 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
233 r = safe_atod("0.2244", &d);
235 assert_se(fabs(d - 0.2244) < 0.000001);
237 r = safe_atod("0,5", &d);
238 assert_se(r == -EINVAL);
241 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
244 /* And check again, reset */
245 assert_se(setlocale(LC_NUMERIC, "C"));
247 r = safe_atod("0.2244", &d);
249 assert_se(fabs(d - 0.2244) < 0.000001);
251 r = safe_atod("0,5", &d);
252 assert_se(r == -EINVAL);
256 assert_se(*e == ',');
259 static void test_strappend(void) {
260 _cleanup_free_ char *t1, *t2, *t3, *t4;
262 t1 = strappend(NULL, NULL);
263 assert_se(streq(t1, ""));
265 t2 = strappend(NULL, "suf");
266 assert_se(streq(t2, "suf"));
268 t3 = strappend("pre", NULL);
269 assert_se(streq(t3, "pre"));
271 t4 = strappend("pre", "suf");
272 assert_se(streq(t4, "presuf"));
275 static void test_strstrip(void) {
277 char input[] = " hello, waldo. ";
280 assert_se(streq(r, "hello, waldo."));
283 static void test_delete_chars(void) {
285 char input[] = " hello, waldo. abc";
287 r = delete_chars(input, WHITESPACE);
288 assert_se(streq(r, "hello,waldo.abc"));
291 static void test_in_charset(void) {
292 assert_se(in_charset("dddaaabbbcccc", "abcd"));
293 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
296 static void test_hexchar(void) {
297 assert_se(hexchar(0xa) == 'a');
298 assert_se(hexchar(0x0) == '0');
301 static void test_unhexchar(void) {
302 assert_se(unhexchar('a') == 0xA);
303 assert_se(unhexchar('A') == 0xA);
304 assert_se(unhexchar('0') == 0x0);
307 static void test_octchar(void) {
308 assert_se(octchar(00) == '0');
309 assert_se(octchar(07) == '7');
312 static void test_unoctchar(void) {
313 assert_se(unoctchar('0') == 00);
314 assert_se(unoctchar('7') == 07);
317 static void test_decchar(void) {
318 assert_se(decchar(0) == '0');
319 assert_se(decchar(9) == '9');
322 static void test_undecchar(void) {
323 assert_se(undecchar('0') == 0);
324 assert_se(undecchar('9') == 9);
327 static void test_cescape(void) {
328 _cleanup_free_ char *escaped;
330 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
331 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
334 static void test_cunescape(void) {
335 _cleanup_free_ char *unescaped;
337 assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
338 assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
341 static void test_foreach_word(void) {
342 const char *word, *state;
345 const char test[] = "test abc d\te f ";
346 const char * const expected[] = {
356 FOREACH_WORD(word, l, test, state)
357 assert_se(strneq(expected[i++], word, l));
360 static void test_foreach_word_quoted(void) {
361 const char *word, *state;
364 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
365 const char * const expected[] = {
381 printf("<%s>\n", test);
382 FOREACH_WORD_QUOTED(word, l, test, state) {
383 _cleanup_free_ char *t = NULL;
385 assert_se(t = strndup(word, l));
386 assert_se(strneq(expected[i++], word, l));
389 assert(isempty(state));
392 static void test_default_term_for_tty(void) {
393 puts(default_term_for_tty("/dev/tty23"));
394 puts(default_term_for_tty("/dev/ttyS23"));
395 puts(default_term_for_tty("/dev/tty0"));
396 puts(default_term_for_tty("/dev/pty0"));
397 puts(default_term_for_tty("/dev/pts/0"));
398 puts(default_term_for_tty("/dev/console"));
399 puts(default_term_for_tty("tty23"));
400 puts(default_term_for_tty("ttyS23"));
401 puts(default_term_for_tty("tty0"));
402 puts(default_term_for_tty("pty0"));
403 puts(default_term_for_tty("pts/0"));
404 puts(default_term_for_tty("console"));
407 static void test_memdup_multiply(void) {
408 int org[] = {1, 2, 3};
411 dup = (int*)memdup_multiply(org, sizeof(int), 3);
414 assert_se(dup[0] == 1);
415 assert_se(dup[1] == 2);
416 assert_se(dup[2] == 3);
420 static void test_hostname_is_valid(void) {
421 assert(hostname_is_valid("foobar"));
422 assert(hostname_is_valid("foobar.com"));
423 assert(!hostname_is_valid("fööbar"));
424 assert(!hostname_is_valid(""));
425 assert(!hostname_is_valid("."));
426 assert(!hostname_is_valid(".."));
427 assert(!hostname_is_valid("foobar."));
428 assert(!hostname_is_valid(".foobar"));
429 assert(!hostname_is_valid("foo..bar"));
430 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
433 static void test_u64log2(void) {
434 assert(u64log2(0) == 0);
435 assert(u64log2(8) == 3);
436 assert(u64log2(9) == 3);
437 assert(u64log2(15) == 3);
438 assert(u64log2(16) == 4);
439 assert(u64log2(1024*1024) == 20);
440 assert(u64log2(1024*1024+5) == 20);
443 static void test_get_process_comm(void) {
445 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
446 unsigned long long b;
453 if (stat("/proc/1/comm", &st) == 0) {
454 assert_se(get_process_comm(1, &a) >= 0);
455 log_info("pid1 comm: '%s'", a);
457 log_warning("/proc/1/comm does not exist.");
460 assert_se(get_starttime_of_pid(1, &b) >= 0);
461 log_info("pid1 starttime: '%llu'", b);
463 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
464 log_info("pid1 cmdline: '%s'", c);
466 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
467 log_info("pid1 cmdline truncated: '%s'", d);
469 assert_se(get_parent_of_pid(1, &e) >= 0);
470 log_info("pid1 ppid: "PID_FMT, e);
473 assert_se(is_kernel_thread(1) == 0);
475 r = get_process_exe(1, &f);
476 assert_se(r >= 0 || r == -EACCES);
477 log_info("pid1 exe: '%s'", strna(f));
479 assert_se(get_process_uid(1, &u) == 0);
480 log_info("pid1 uid: "UID_FMT, u);
483 assert_se(get_process_gid(1, &g) == 0);
484 log_info("pid1 gid: "GID_FMT, g);
487 assert(get_ctty_devnr(1, &h) == -ENOENT);
489 getenv_for_pid(1, "PATH", &i);
490 log_info("pid1 $PATH: '%s'", strna(i));
493 static void test_protect_errno(void) {
502 static void test_parse_size(void) {
505 assert_se(parse_size("111", 1024, &bytes) == 0);
506 assert_se(bytes == 111);
508 assert_se(parse_size("111.4", 1024, &bytes) == 0);
509 assert_se(bytes == 111);
511 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
512 assert_se(bytes == 112);
514 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
515 assert_se(bytes == 112);
517 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
518 assert_se(bytes == 3*1024 + 512);
520 assert_se(parse_size("3. K", 1024, &bytes) == 0);
521 assert_se(bytes == 3*1024);
523 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
524 assert_se(bytes == 3*1024);
526 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
528 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
529 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
531 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
533 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
534 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
536 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
537 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
539 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
541 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
542 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
544 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
545 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
547 assert_se(parse_size("12P", 1024, &bytes) == 0);
548 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
550 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
552 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
553 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
555 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
557 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
559 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
561 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
562 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
563 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
565 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
567 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
570 static void test_config_parse_iec_off(void) {
572 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
573 assert_se(offset == 4 * 1024 * 1024);
575 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
578 static void test_strextend(void) {
579 _cleanup_free_ char *str = strdup("0123");
580 strextend(&str, "456", "78", "9", NULL);
581 assert_se(streq(str, "0123456789"));
584 static void test_strrep(void) {
585 _cleanup_free_ char *one, *three, *zero;
586 one = strrep("waldo", 1);
587 three = strrep("waldo", 3);
588 zero = strrep("waldo", 0);
590 assert_se(streq(one, "waldo"));
591 assert_se(streq(three, "waldowaldowaldo"));
592 assert_se(streq(zero, ""));
595 static void test_split_pair(void) {
596 _cleanup_free_ char *a = NULL, *b = NULL;
598 assert_se(split_pair("", "", &a, &b) == -EINVAL);
599 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
600 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
601 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
602 assert_se(streq(a, "foo"));
603 assert_se(streq(b, "bar"));
606 assert_se(split_pair("==", "==", &a, &b) >= 0);
607 assert_se(streq(a, ""));
608 assert_se(streq(b, ""));
612 assert_se(split_pair("===", "==", &a, &b) >= 0);
613 assert_se(streq(a, ""));
614 assert_se(streq(b, "="));
617 static void test_fstab_node_to_udev_node(void) {
620 n = fstab_node_to_udev_node("LABEL=applé/jack");
622 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
625 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
627 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
630 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
632 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
635 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
637 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
640 n = fstab_node_to_udev_node("PONIES=awesome");
642 assert_se(streq(n, "PONIES=awesome"));
645 n = fstab_node_to_udev_node("/dev/xda1");
647 assert_se(streq(n, "/dev/xda1"));
651 static void test_get_files_in_directory(void) {
652 _cleanup_strv_free_ char **l = NULL, **t = NULL;
654 assert_se(get_files_in_directory("/tmp", &l) >= 0);
655 assert_se(get_files_in_directory(".", &t) >= 0);
656 assert_se(get_files_in_directory(".", NULL) >= 0);
659 static void test_in_set(void) {
660 assert_se(IN_SET(1, 1));
661 assert_se(IN_SET(1, 1, 2, 3, 4));
662 assert_se(IN_SET(2, 1, 2, 3, 4));
663 assert_se(IN_SET(3, 1, 2, 3, 4));
664 assert_se(IN_SET(4, 1, 2, 3, 4));
665 assert_se(!IN_SET(0, 1));
666 assert_se(!IN_SET(0, 1, 2, 3, 4));
669 static void test_writing_tmpfile(void) {
670 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
671 _cleanup_free_ char *contents = NULL;
676 IOVEC_SET_STRING(iov[0], "abc\n");
677 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
678 IOVEC_SET_STRING(iov[2], "");
680 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
681 printf("tmpfile: %s", name);
683 r = writev(fd, iov, 3);
686 r = read_full_file(name, &contents, &size);
688 printf("contents: %s", contents);
689 assert(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
694 static void test_hexdump(void) {
698 hexdump(stdout, NULL, 0);
699 hexdump(stdout, "", 0);
700 hexdump(stdout, "", 1);
701 hexdump(stdout, "x", 1);
702 hexdump(stdout, "x", 2);
703 hexdump(stdout, "foobar", 7);
704 hexdump(stdout, "f\nobar", 7);
705 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
707 for (i = 0; i < ELEMENTSOF(data); i++)
710 hexdump(stdout, data, sizeof(data));
713 static void test_log2i(void) {
714 assert_se(log2i(1) == 0);
715 assert_se(log2i(2) == 1);
716 assert_se(log2i(3) == 1);
717 assert_se(log2i(4) == 2);
718 assert_se(log2i(32) == 5);
719 assert_se(log2i(33) == 5);
720 assert_se(log2i(63) == 5);
721 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
724 static void test_foreach_string(void) {
725 const char * const t[] = {
734 FOREACH_STRING(x, "foo", "bar", "waldo")
735 assert_se(streq_ptr(t[i++], x));
739 FOREACH_STRING(x, "zzz")
740 assert_se(streq(x, "zzz"));
743 static void test_filename_is_safe(void) {
744 char foo[FILENAME_MAX+2];
747 assert_se(!filename_is_safe(""));
748 assert_se(!filename_is_safe("/bar/foo"));
749 assert_se(!filename_is_safe("/"));
750 assert_se(!filename_is_safe("."));
751 assert_se(!filename_is_safe(".."));
753 for (i=0; i<FILENAME_MAX+1; i++)
755 foo[FILENAME_MAX+1] = '\0';
757 assert_se(!filename_is_safe(foo));
759 assert_se(filename_is_safe("foo_bar-333"));
760 assert_se(filename_is_safe("o.o"));
763 static void test_string_has_cc(void) {
764 assert_se(string_has_cc("abc\1", NULL));
765 assert_se(string_has_cc("abc\x7f", NULL));
766 assert_se(string_has_cc("abc\x7f", NULL));
767 assert_se(string_has_cc("abc\t\x7f", "\t"));
768 assert_se(string_has_cc("abc\t\x7f", "\t"));
769 assert_se(string_has_cc("\x7f", "\t"));
770 assert_se(string_has_cc("\x7f", "\t\a"));
772 assert_se(!string_has_cc("abc\t\t", "\t"));
773 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
774 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
777 static void test_ascii_strlower(void) {
778 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
779 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
782 static void test_files_same(void) {
783 _cleanup_close_ int fd = -1;
784 char name[] = "/tmp/test-files_same.XXXXXX";
785 char name_alias[] = "/tmp/test-files_same.alias";
787 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
789 assert_se(symlink(name, name_alias) >= 0);
791 assert_se(files_same(name, name));
792 assert_se(files_same(name, name_alias));
798 static void test_is_valid_documentation_url(void) {
799 assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
800 assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
801 assert_se(is_valid_documentation_url("file:foo"));
802 assert_se(is_valid_documentation_url("man:systemd.special(7)"));
803 assert_se(is_valid_documentation_url("info:bar"));
805 assert_se(!is_valid_documentation_url("foo:"));
806 assert_se(!is_valid_documentation_url("info:"));
807 assert_se(!is_valid_documentation_url(""));
810 static void test_file_in_same_dir(void) {
811 assert_se(streq(file_in_same_dir("/", "a"), "/a"));
812 assert_se(streq(file_in_same_dir("/", "/a"), "/a"));
813 assert_se(streq(file_in_same_dir("", "a"), "a"));
814 assert_se(streq(file_in_same_dir("a/", "a"), "a/a"));
815 assert_se(streq(file_in_same_dir("bar/foo", "bar"), "bar/bar"));
818 static void test_endswith(void) {
819 assert_se(endswith("foobar", "bar"));
820 assert_se(endswith("foobar", ""));
821 assert_se(endswith("foobar", "foobar"));
822 assert_se(endswith("", ""));
824 assert_se(!endswith("foobar", "foo"));
825 assert_se(!endswith("foobar", "foobarfoofoo"));
828 static void test_close_nointr(void) {
829 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
832 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
834 assert_se(close_nointr(fd) >= 0);
835 assert_se(close_nointr(fd) < 0);
841 static void test_unlink_noerrno(void) {
842 char name[] = "/tmp/test-close_nointr.XXXXXX";
845 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
847 assert_se(close_nointr(fd) >= 0);
852 assert_se(unlink_noerrno(name) >= 0);
853 assert_se(errno == -42);
854 assert_se(unlink_noerrno(name) < 0);
855 assert_se(errno == -42);
859 static void test_readlink_and_make_absolute(void) {
860 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
861 char name[] = "/tmp/test-readlink_and_make_absolute/original";
862 char name2[] = "test-readlink_and_make_absolute/original";
863 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
866 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
867 assert_se(touch(name) >= 0);
869 assert_se(symlink(name, name_alias) >= 0);
870 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
871 assert_se(streq(r, name));
873 assert_se(unlink(name_alias) >= 0);
875 assert_se(chdir(tempdir) >= 0);
876 assert_se(symlink(name2, name_alias) >= 0);
877 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
878 assert_se(streq(r, name));
880 assert_se(unlink(name_alias) >= 0);
882 assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
885 static void test_read_one_char(void) {
888 char name[] = "/tmp/test-read_one_char.XXXXXX";
889 _cleanup_close_ int fd = -1;
892 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
894 file = fdopen(fd, "r+");
896 assert_se(fputs("c\n", file) >= 0);
899 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
902 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
905 assert_se(fputs("foobar\n", file) >= 0);
907 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
910 assert_se(fputs("\n", file) >= 0);
912 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
917 static void test_ignore_signals(void) {
918 assert_se(ignore_signals(SIGINT, -1) >= 0);
919 assert_se(kill(getpid(), SIGINT) >= 0);
920 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
921 assert_se(kill(getpid(), SIGUSR1) >= 0);
922 assert_se(kill(getpid(), SIGUSR2) >= 0);
923 assert_se(kill(getpid(), SIGTERM) >= 0);
924 assert_se(kill(getpid(), SIGPIPE) >= 0);
925 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
928 static void test_strshorten(void) {
931 assert_se(strlen(strshorten(s, 6)) == 6);
932 assert_se(strlen(strshorten(s, 12)) == 6);
933 assert_se(strlen(strshorten(s, 2)) == 2);
934 assert_se(strlen(strshorten(s, 0)) == 0);
937 static void test_strappenda(void) {
940 actual = strappenda("", "foo", "bar");
941 assert_se(streq(actual, "foobar"));
943 actual = strappenda("foo", "bar", "baz");
944 assert_se(streq(actual, "foobarbaz"));
946 actual = strappenda("foo", "", "bar", "baz");
947 assert_se(streq(actual, "foobarbaz"));
950 static void test_is_symlink(void) {
951 char name[] = "/tmp/test-is_symlink.XXXXXX";
952 char name_link[] = "/tmp/test-is_symlink.link";
953 _cleanup_close_ int fd = -1;
955 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
957 assert_se(symlink(name, name_link) >= 0);
959 assert_se(is_symlink(name) == 0);
960 assert_se(is_symlink(name_link) == 1);
961 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
968 static void test_pid_is_unwaited(void) {
978 waitpid(pid, &status, 0);
979 assert_se(!pid_is_unwaited(pid));
981 assert_se(pid_is_unwaited(getpid()));
982 assert_se(!pid_is_unwaited(-1));
985 static void test_pid_is_alive(void) {
995 waitpid(pid, &status, 0);
996 assert_se(!pid_is_alive(pid));
998 assert_se(pid_is_alive(getpid()));
999 assert_se(!pid_is_alive(-1));
1002 static void test_search_and_fopen(void) {
1003 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1004 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1009 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1013 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1017 r = search_and_fopen(name, "r", NULL, dirs, &f);
1021 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1025 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1027 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1033 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1038 static void test_search_and_fopen_nulstr(void) {
1039 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1040 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1045 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1049 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1053 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1057 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1059 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1065 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1069 static void test_glob_exists(void) {
1070 char name[] = "/tmp/test-glob_exists.XXXXXX";
1074 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1078 r = glob_exists("/tmp/test-glob_exists*");
1083 r = glob_exists("/tmp/test-glob_exists*");
1087 static void test_execute_directory(void) {
1088 char name[] = "/tmp/test-execute_directory/script1";
1089 char name2[] = "/tmp/test-execute_directory/script2";
1090 char name3[] = "/tmp/test-execute_directory/useless";
1091 char tempdir[] = "/tmp/test-execute_directory/";
1093 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1094 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1095 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1096 assert_se(chmod(name, 0755) == 0);
1097 assert_se(chmod(name2, 0755) == 0);
1098 assert_se(touch(name3) >= 0);
1100 execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
1101 assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1102 assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1104 rm_rf_dangerous(tempdir, false, true, false);
1107 static void test_unquote_first_word(void) {
1108 const char *p, *original;
1111 p = original = "foobar waldo";
1112 assert_se(unquote_first_word(&p, &t) > 0);
1113 assert_se(streq(t, "foobar"));
1115 assert_se(p == original + 7);
1117 assert_se(unquote_first_word(&p, &t) > 0);
1118 assert_se(streq(t, "waldo"));
1120 assert_se(p == original + 12);
1122 assert_se(unquote_first_word(&p, &t) == 0);
1124 assert_se(p == original + 12);
1126 p = original = "\"foobar\" \'waldo\'";
1127 assert_se(unquote_first_word(&p, &t) > 0);
1128 assert_se(streq(t, "foobar"));
1130 assert_se(p == original + 9);
1132 assert_se(unquote_first_word(&p, &t) > 0);
1133 assert_se(streq(t, "waldo"));
1135 assert_se(p == original + 16);
1137 assert_se(unquote_first_word(&p, &t) == 0);
1139 assert_se(p == original + 16);
1141 p = original = "\"";
1142 assert_se(unquote_first_word(&p, &t) == -EINVAL);
1143 assert_se(p == original + 1);
1145 p = original = "\'";
1146 assert_se(unquote_first_word(&p, &t) == -EINVAL);
1147 assert_se(p == original + 1);
1149 p = original = "yay\'foo\'bar";
1150 assert_se(unquote_first_word(&p, &t) > 0);
1151 assert_se(streq(t, "yayfoobar"));
1153 assert_se(p == original + 11);
1155 p = original = " foobar ";
1156 assert_se(unquote_first_word(&p, &t) > 0);
1157 assert_se(streq(t, "foobar"));
1159 assert_se(p == original + 12);
1162 static void test_unquote_many_words(void) {
1163 const char *p, *original;
1166 p = original = "foobar waldi piep";
1167 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1168 assert_se(p == original + 17);
1169 assert_se(streq_ptr(a, "foobar"));
1170 assert_se(streq_ptr(b, "waldi"));
1171 assert_se(streq_ptr(c, "piep"));
1176 p = original = "'foobar' wa\"ld\"i ";
1177 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1178 assert_se(p == original + 19);
1179 assert_se(streq_ptr(a, "foobar"));
1180 assert_se(streq_ptr(b, "waldi"));
1181 assert_se(streq_ptr(c, NULL));
1186 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1187 assert_se(p == original);
1188 assert_se(streq_ptr(a, NULL));
1189 assert_se(streq_ptr(b, NULL));
1190 assert_se(streq_ptr(c, NULL));
1193 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1194 assert_se(p == original+2);
1195 assert_se(streq_ptr(a, NULL));
1196 assert_se(streq_ptr(b, NULL));
1197 assert_se(streq_ptr(c, NULL));
1199 p = original = "foobar";
1200 assert_se(unquote_many_words(&p, NULL) == 0);
1201 assert_se(p == original);
1203 p = original = "foobar waldi";
1204 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1205 assert_se(p == original+7);
1206 assert_se(streq_ptr(a, "foobar"));
1208 p = original = " foobar ";
1209 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1210 assert_se(p == original+15);
1211 assert_se(streq_ptr(a, "foobar"));
1214 int main(int argc, char *argv[]) {
1215 log_parse_environment();
1219 test_align_power2();
1223 test_parse_boolean();
1230 test_delete_chars();
1240 test_foreach_word();
1241 test_foreach_word_quoted();
1242 test_default_term_for_tty();
1243 test_memdup_multiply();
1244 test_hostname_is_valid();
1246 test_get_process_comm();
1247 test_protect_errno();
1249 test_config_parse_iec_off();
1253 test_fstab_node_to_udev_node();
1254 test_get_files_in_directory();
1256 test_writing_tmpfile();
1259 test_foreach_string();
1260 test_filename_is_safe();
1261 test_string_has_cc();
1262 test_ascii_strlower();
1264 test_is_valid_documentation_url();
1265 test_file_in_same_dir();
1267 test_close_nointr();
1268 test_unlink_noerrno();
1269 test_readlink_and_make_absolute();
1270 test_read_one_char();
1271 test_ignore_signals();
1275 test_pid_is_unwaited();
1276 test_pid_is_alive();
1277 test_search_and_fopen();
1278 test_search_and_fopen_nulstr();
1280 test_execute_directory();
1281 test_unquote_first_word();
1282 test_unquote_many_words();