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_first_word(void) {
135 assert_se(first_word("Hello", ""));
136 assert_se(first_word("Hello", "Hello"));
137 assert_se(first_word("Hello world", "Hello"));
138 assert_se(first_word("Hello\tworld", "Hello"));
139 assert_se(first_word("Hello\nworld", "Hello"));
140 assert_se(first_word("Hello\rworld", "Hello"));
141 assert_se(first_word("Hello ", "Hello"));
143 assert_se(!first_word("Hello", "Hellooo"));
144 assert_se(!first_word("Hello", "xxxxx"));
145 assert_se(!first_word("Hellooo", "Hello"));
148 static void test_close_many(void) {
150 char name0[] = "/tmp/test-close-many.XXXXXX";
151 char name1[] = "/tmp/test-close-many.XXXXXX";
152 char name2[] = "/tmp/test-close-many.XXXXXX";
154 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
155 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
156 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
160 assert_se(fcntl(fds[0], F_GETFD) == -1);
161 assert_se(fcntl(fds[1], F_GETFD) == -1);
162 assert_se(fcntl(fds[2], F_GETFD) >= 0);
171 static void test_parse_boolean(void) {
172 assert_se(parse_boolean("1") == 1);
173 assert_se(parse_boolean("y") == 1);
174 assert_se(parse_boolean("Y") == 1);
175 assert_se(parse_boolean("yes") == 1);
176 assert_se(parse_boolean("YES") == 1);
177 assert_se(parse_boolean("true") == 1);
178 assert_se(parse_boolean("TRUE") == 1);
179 assert_se(parse_boolean("on") == 1);
180 assert_se(parse_boolean("ON") == 1);
182 assert_se(parse_boolean("0") == 0);
183 assert_se(parse_boolean("n") == 0);
184 assert_se(parse_boolean("N") == 0);
185 assert_se(parse_boolean("no") == 0);
186 assert_se(parse_boolean("NO") == 0);
187 assert_se(parse_boolean("false") == 0);
188 assert_se(parse_boolean("FALSE") == 0);
189 assert_se(parse_boolean("off") == 0);
190 assert_se(parse_boolean("OFF") == 0);
192 assert_se(parse_boolean("garbage") < 0);
193 assert_se(parse_boolean("") < 0);
194 assert_se(parse_boolean("full") < 0);
197 static void test_parse_pid(void) {
201 r = parse_pid("100", &pid);
203 assert_se(pid == 100);
205 r = parse_pid("0x7FFFFFFF", &pid);
207 assert_se(pid == 2147483647);
209 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
210 r = parse_pid("0", &pid);
211 assert_se(r == -ERANGE);
212 assert_se(pid == 65);
214 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
215 r = parse_pid("-100", &pid);
216 assert_se(r == -ERANGE);
217 assert_se(pid == 65);
219 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
220 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
221 assert(r == -ERANGE);
222 assert_se(pid == 65);
225 static void test_parse_uid(void) {
229 r = parse_uid("100", &uid);
231 assert_se(uid == 100);
234 static void test_safe_atolli(void) {
238 r = safe_atolli("12345", &l);
240 assert_se(l == 12345);
242 r = safe_atolli("junk", &l);
243 assert_se(r == -EINVAL);
246 static void test_safe_atod(void) {
251 r = safe_atod("junk", &d);
252 assert_se(r == -EINVAL);
254 r = safe_atod("0.2244", &d);
256 assert_se(fabs(d - 0.2244) < 0.000001);
258 r = safe_atod("0,5", &d);
259 assert_se(r == -EINVAL);
263 assert_se(*e == ',');
265 /* Check if this really is locale independent */
266 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
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);
276 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
279 /* And check again, reset */
280 assert_se(setlocale(LC_NUMERIC, "C"));
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);
291 assert_se(*e == ',');
294 static void test_strappend(void) {
295 _cleanup_free_ char *t1, *t2, *t3, *t4;
297 t1 = strappend(NULL, NULL);
298 assert_se(streq(t1, ""));
300 t2 = strappend(NULL, "suf");
301 assert_se(streq(t2, "suf"));
303 t3 = strappend("pre", NULL);
304 assert_se(streq(t3, "pre"));
306 t4 = strappend("pre", "suf");
307 assert_se(streq(t4, "presuf"));
310 static void test_strstrip(void) {
312 char input[] = " hello, waldo. ";
315 assert_se(streq(r, "hello, waldo."));
318 static void test_delete_chars(void) {
320 char input[] = " hello, waldo. abc";
322 r = delete_chars(input, WHITESPACE);
323 assert_se(streq(r, "hello,waldo.abc"));
326 static void test_in_charset(void) {
327 assert_se(in_charset("dddaaabbbcccc", "abcd"));
328 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
331 static void test_hexchar(void) {
332 assert_se(hexchar(0xa) == 'a');
333 assert_se(hexchar(0x0) == '0');
336 static void test_unhexchar(void) {
337 assert_se(unhexchar('a') == 0xA);
338 assert_se(unhexchar('A') == 0xA);
339 assert_se(unhexchar('0') == 0x0);
342 static void test_octchar(void) {
343 assert_se(octchar(00) == '0');
344 assert_se(octchar(07) == '7');
347 static void test_unoctchar(void) {
348 assert_se(unoctchar('0') == 00);
349 assert_se(unoctchar('7') == 07);
352 static void test_decchar(void) {
353 assert_se(decchar(0) == '0');
354 assert_se(decchar(9) == '9');
357 static void test_undecchar(void) {
358 assert_se(undecchar('0') == 0);
359 assert_se(undecchar('9') == 9);
362 static void test_cescape(void) {
363 _cleanup_free_ char *escaped;
365 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
366 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
369 static void test_cunescape(void) {
370 _cleanup_free_ char *unescaped;
372 assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
373 assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
376 static void test_foreach_word(void) {
377 const char *word, *state;
380 const char test[] = "test abc d\te f ";
381 const char * const expected[] = {
391 FOREACH_WORD(word, l, test, state)
392 assert_se(strneq(expected[i++], word, l));
395 static void test_foreach_word_quoted(void) {
396 const char *word, *state;
399 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
400 const char * const expected[] = {
416 printf("<%s>\n", test);
417 FOREACH_WORD_QUOTED(word, l, test, state) {
418 _cleanup_free_ char *t = NULL;
420 assert_se(t = strndup(word, l));
421 assert_se(strneq(expected[i++], word, l));
424 assert(isempty(state));
427 static void test_default_term_for_tty(void) {
428 puts(default_term_for_tty("/dev/tty23"));
429 puts(default_term_for_tty("/dev/ttyS23"));
430 puts(default_term_for_tty("/dev/tty0"));
431 puts(default_term_for_tty("/dev/pty0"));
432 puts(default_term_for_tty("/dev/pts/0"));
433 puts(default_term_for_tty("/dev/console"));
434 puts(default_term_for_tty("tty23"));
435 puts(default_term_for_tty("ttyS23"));
436 puts(default_term_for_tty("tty0"));
437 puts(default_term_for_tty("pty0"));
438 puts(default_term_for_tty("pts/0"));
439 puts(default_term_for_tty("console"));
442 static void test_memdup_multiply(void) {
443 int org[] = {1, 2, 3};
446 dup = (int*)memdup_multiply(org, sizeof(int), 3);
449 assert_se(dup[0] == 1);
450 assert_se(dup[1] == 2);
451 assert_se(dup[2] == 3);
455 static void test_hostname_is_valid(void) {
456 assert(hostname_is_valid("foobar"));
457 assert(hostname_is_valid("foobar.com"));
458 assert(!hostname_is_valid("fööbar"));
459 assert(!hostname_is_valid(""));
460 assert(!hostname_is_valid("."));
461 assert(!hostname_is_valid(".."));
462 assert(!hostname_is_valid("foobar."));
463 assert(!hostname_is_valid(".foobar"));
464 assert(!hostname_is_valid("foo..bar"));
465 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
468 static void test_u64log2(void) {
469 assert(u64log2(0) == 0);
470 assert(u64log2(8) == 3);
471 assert(u64log2(9) == 3);
472 assert(u64log2(15) == 3);
473 assert(u64log2(16) == 4);
474 assert(u64log2(1024*1024) == 20);
475 assert(u64log2(1024*1024+5) == 20);
478 static void test_get_process_comm(void) {
480 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
481 unsigned long long b;
488 if (stat("/proc/1/comm", &st) == 0) {
489 assert_se(get_process_comm(1, &a) >= 0);
490 log_info("pid1 comm: '%s'", a);
492 log_warning("/proc/1/comm does not exist.");
495 assert_se(get_starttime_of_pid(1, &b) >= 0);
496 log_info("pid1 starttime: '%llu'", b);
498 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
499 log_info("pid1 cmdline: '%s'", c);
501 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
502 log_info("pid1 cmdline truncated: '%s'", d);
504 assert_se(get_parent_of_pid(1, &e) >= 0);
505 log_info("pid1 ppid: "PID_FMT, e);
508 assert_se(is_kernel_thread(1) == 0);
510 r = get_process_exe(1, &f);
511 assert_se(r >= 0 || r == -EACCES);
512 log_info("pid1 exe: '%s'", strna(f));
514 assert_se(get_process_uid(1, &u) == 0);
515 log_info("pid1 uid: "UID_FMT, u);
518 assert_se(get_process_gid(1, &g) == 0);
519 log_info("pid1 gid: "GID_FMT, g);
522 assert(get_ctty_devnr(1, &h) == -ENOENT);
524 getenv_for_pid(1, "PATH", &i);
525 log_info("pid1 $PATH: '%s'", strna(i));
528 static void test_protect_errno(void) {
537 static void test_parse_size(void) {
540 assert_se(parse_size("111", 1024, &bytes) == 0);
541 assert_se(bytes == 111);
543 assert_se(parse_size("111.4", 1024, &bytes) == 0);
544 assert_se(bytes == 111);
546 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
547 assert_se(bytes == 112);
549 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
550 assert_se(bytes == 112);
552 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
553 assert_se(bytes == 3*1024 + 512);
555 assert_se(parse_size("3. K", 1024, &bytes) == 0);
556 assert_se(bytes == 3*1024);
558 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
559 assert_se(bytes == 3*1024);
561 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
563 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
564 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
566 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
568 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
569 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
571 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
572 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
574 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
576 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
577 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
579 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
580 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
582 assert_se(parse_size("12P", 1024, &bytes) == 0);
583 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
585 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
587 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
588 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
590 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
592 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
594 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
596 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
597 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
598 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
600 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
602 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
605 static void test_config_parse_iec_off(void) {
607 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
608 assert_se(offset == 4 * 1024 * 1024);
610 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
613 static void test_strextend(void) {
614 _cleanup_free_ char *str = strdup("0123");
615 strextend(&str, "456", "78", "9", NULL);
616 assert_se(streq(str, "0123456789"));
619 static void test_strrep(void) {
620 _cleanup_free_ char *one, *three, *zero;
621 one = strrep("waldo", 1);
622 three = strrep("waldo", 3);
623 zero = strrep("waldo", 0);
625 assert_se(streq(one, "waldo"));
626 assert_se(streq(three, "waldowaldowaldo"));
627 assert_se(streq(zero, ""));
630 static void test_split_pair(void) {
631 _cleanup_free_ char *a = NULL, *b = NULL;
633 assert_se(split_pair("", "", &a, &b) == -EINVAL);
634 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
635 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
636 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
637 assert_se(streq(a, "foo"));
638 assert_se(streq(b, "bar"));
641 assert_se(split_pair("==", "==", &a, &b) >= 0);
642 assert_se(streq(a, ""));
643 assert_se(streq(b, ""));
647 assert_se(split_pair("===", "==", &a, &b) >= 0);
648 assert_se(streq(a, ""));
649 assert_se(streq(b, "="));
652 static void test_fstab_node_to_udev_node(void) {
655 n = fstab_node_to_udev_node("LABEL=applé/jack");
657 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
660 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
662 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
665 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
667 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
670 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
672 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
675 n = fstab_node_to_udev_node("PONIES=awesome");
677 assert_se(streq(n, "PONIES=awesome"));
680 n = fstab_node_to_udev_node("/dev/xda1");
682 assert_se(streq(n, "/dev/xda1"));
686 static void test_get_files_in_directory(void) {
687 _cleanup_strv_free_ char **l = NULL, **t = NULL;
689 assert_se(get_files_in_directory("/tmp", &l) >= 0);
690 assert_se(get_files_in_directory(".", &t) >= 0);
691 assert_se(get_files_in_directory(".", NULL) >= 0);
694 static void test_in_set(void) {
695 assert_se(IN_SET(1, 1));
696 assert_se(IN_SET(1, 1, 2, 3, 4));
697 assert_se(IN_SET(2, 1, 2, 3, 4));
698 assert_se(IN_SET(3, 1, 2, 3, 4));
699 assert_se(IN_SET(4, 1, 2, 3, 4));
700 assert_se(!IN_SET(0, 1));
701 assert_se(!IN_SET(0, 1, 2, 3, 4));
704 static void test_writing_tmpfile(void) {
705 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
706 _cleanup_free_ char *contents = NULL;
711 IOVEC_SET_STRING(iov[0], "abc\n");
712 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
713 IOVEC_SET_STRING(iov[2], "");
715 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
716 printf("tmpfile: %s", name);
718 r = writev(fd, iov, 3);
721 r = read_full_file(name, &contents, &size);
723 printf("contents: %s", contents);
724 assert(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
729 static void test_hexdump(void) {
733 hexdump(stdout, NULL, 0);
734 hexdump(stdout, "", 0);
735 hexdump(stdout, "", 1);
736 hexdump(stdout, "x", 1);
737 hexdump(stdout, "x", 2);
738 hexdump(stdout, "foobar", 7);
739 hexdump(stdout, "f\nobar", 7);
740 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
742 for (i = 0; i < ELEMENTSOF(data); i++)
745 hexdump(stdout, data, sizeof(data));
748 static void test_log2i(void) {
749 assert_se(log2i(1) == 0);
750 assert_se(log2i(2) == 1);
751 assert_se(log2i(3) == 1);
752 assert_se(log2i(4) == 2);
753 assert_se(log2i(32) == 5);
754 assert_se(log2i(33) == 5);
755 assert_se(log2i(63) == 5);
756 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
759 static void test_foreach_string(void) {
760 const char * const t[] = {
769 FOREACH_STRING(x, "foo", "bar", "waldo")
770 assert_se(streq_ptr(t[i++], x));
774 FOREACH_STRING(x, "zzz")
775 assert_se(streq(x, "zzz"));
778 static void test_filename_is_safe(void) {
779 char foo[FILENAME_MAX+2];
782 assert_se(!filename_is_safe(""));
783 assert_se(!filename_is_safe("/bar/foo"));
784 assert_se(!filename_is_safe("/"));
785 assert_se(!filename_is_safe("."));
786 assert_se(!filename_is_safe(".."));
788 for (i=0; i<FILENAME_MAX+1; i++)
790 foo[FILENAME_MAX+1] = '\0';
792 assert_se(!filename_is_safe(foo));
794 assert_se(filename_is_safe("foo_bar-333"));
795 assert_se(filename_is_safe("o.o"));
798 static void test_string_has_cc(void) {
799 assert_se(string_has_cc("abc\1", NULL));
800 assert_se(string_has_cc("abc\x7f", NULL));
801 assert_se(string_has_cc("abc\x7f", NULL));
802 assert_se(string_has_cc("abc\t\x7f", "\t"));
803 assert_se(string_has_cc("abc\t\x7f", "\t"));
804 assert_se(string_has_cc("\x7f", "\t"));
805 assert_se(string_has_cc("\x7f", "\t\a"));
807 assert_se(!string_has_cc("abc\t\t", "\t"));
808 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
809 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
812 static void test_ascii_strlower(void) {
813 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
814 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
817 static void test_files_same(void) {
818 _cleanup_close_ int fd = -1;
819 char name[] = "/tmp/test-files_same.XXXXXX";
820 char name_alias[] = "/tmp/test-files_same.alias";
822 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
824 assert_se(symlink(name, name_alias) >= 0);
826 assert_se(files_same(name, name));
827 assert_se(files_same(name, name_alias));
833 static void test_is_valid_documentation_url(void) {
834 assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
835 assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
836 assert_se(is_valid_documentation_url("file:foo"));
837 assert_se(is_valid_documentation_url("man:systemd.special(7)"));
838 assert_se(is_valid_documentation_url("info:bar"));
840 assert_se(!is_valid_documentation_url("foo:"));
841 assert_se(!is_valid_documentation_url("info:"));
842 assert_se(!is_valid_documentation_url(""));
845 static void test_file_in_same_dir(void) {
846 assert_se(streq(file_in_same_dir("/", "a"), "/a"));
847 assert_se(streq(file_in_same_dir("/", "/a"), "/a"));
848 assert_se(streq(file_in_same_dir("", "a"), "a"));
849 assert_se(streq(file_in_same_dir("a/", "a"), "a/a"));
850 assert_se(streq(file_in_same_dir("bar/foo", "bar"), "bar/bar"));
853 static void test_endswith(void) {
854 assert_se(endswith("foobar", "bar"));
855 assert_se(endswith("foobar", ""));
856 assert_se(endswith("foobar", "foobar"));
857 assert_se(endswith("", ""));
859 assert_se(!endswith("foobar", "foo"));
860 assert_se(!endswith("foobar", "foobarfoofoo"));
863 static void test_close_nointr(void) {
864 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
867 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
869 assert_se(close_nointr(fd) >= 0);
870 assert_se(close_nointr(fd) < 0);
876 static void test_unlink_noerrno(void) {
877 char name[] = "/tmp/test-close_nointr.XXXXXX";
880 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
882 assert_se(close_nointr(fd) >= 0);
887 assert_se(unlink_noerrno(name) >= 0);
888 assert_se(errno == -42);
889 assert_se(unlink_noerrno(name) < 0);
890 assert_se(errno == -42);
894 static void test_readlink_and_make_absolute(void) {
895 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
896 char name[] = "/tmp/test-readlink_and_make_absolute/original";
897 char name2[] = "test-readlink_and_make_absolute/original";
898 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
901 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
902 assert_se(touch(name) >= 0);
904 assert_se(symlink(name, name_alias) >= 0);
905 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
906 assert_se(streq(r, name));
908 assert_se(unlink(name_alias) >= 0);
910 assert_se(chdir(tempdir) >= 0);
911 assert_se(symlink(name2, name_alias) >= 0);
912 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
913 assert_se(streq(r, name));
915 assert_se(unlink(name_alias) >= 0);
917 assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
920 static void test_read_one_char(void) {
923 char name[] = "/tmp/test-read_one_char.XXXXXX";
924 _cleanup_close_ int fd = -1;
927 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
929 file = fdopen(fd, "r+");
931 assert_se(fputs("c\n", file) >= 0);
934 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
937 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
940 assert_se(fputs("foobar\n", file) >= 0);
942 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
945 assert_se(fputs("\n", file) >= 0);
947 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
952 static void test_ignore_signals(void) {
953 assert_se(ignore_signals(SIGINT, -1) >= 0);
954 assert_se(kill(getpid(), SIGINT) >= 0);
955 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
956 assert_se(kill(getpid(), SIGUSR1) >= 0);
957 assert_se(kill(getpid(), SIGUSR2) >= 0);
958 assert_se(kill(getpid(), SIGTERM) >= 0);
959 assert_se(kill(getpid(), SIGPIPE) >= 0);
960 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
963 static void test_strshorten(void) {
966 assert_se(strlen(strshorten(s, 6)) == 6);
967 assert_se(strlen(strshorten(s, 12)) == 6);
968 assert_se(strlen(strshorten(s, 2)) == 2);
969 assert_se(strlen(strshorten(s, 0)) == 0);
972 static void test_strappenda(void) {
975 actual = strappenda("", "foo", "bar");
976 assert_se(streq(actual, "foobar"));
978 actual = strappenda("foo", "bar", "baz");
979 assert_se(streq(actual, "foobarbaz"));
981 actual = strappenda("foo", "", "bar", "baz");
982 assert_se(streq(actual, "foobarbaz"));
985 static void test_is_symlink(void) {
986 char name[] = "/tmp/test-is_symlink.XXXXXX";
987 char name_link[] = "/tmp/test-is_symlink.link";
988 _cleanup_close_ int fd = -1;
990 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
992 assert_se(symlink(name, name_link) >= 0);
994 assert_se(is_symlink(name) == 0);
995 assert_se(is_symlink(name_link) == 1);
996 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1003 static void test_pid_is_unwaited(void) {
1007 assert_se(pid >= 0);
1009 _exit(EXIT_SUCCESS);
1013 waitpid(pid, &status, 0);
1014 assert_se(!pid_is_unwaited(pid));
1016 assert_se(pid_is_unwaited(getpid()));
1017 assert_se(!pid_is_unwaited(-1));
1020 static void test_pid_is_alive(void) {
1024 assert_se(pid >= 0);
1026 _exit(EXIT_SUCCESS);
1030 waitpid(pid, &status, 0);
1031 assert_se(!pid_is_alive(pid));
1033 assert_se(pid_is_alive(getpid()));
1034 assert_se(!pid_is_alive(-1));
1037 static void test_search_and_fopen(void) {
1038 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1039 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1044 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1048 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1052 r = search_and_fopen(name, "r", NULL, dirs, &f);
1056 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1060 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1062 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1068 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1073 static void test_search_and_fopen_nulstr(void) {
1074 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1075 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1080 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1084 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1088 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1092 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1094 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1100 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1104 static void test_glob_exists(void) {
1105 char name[] = "/tmp/test-glob_exists.XXXXXX";
1109 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1113 r = glob_exists("/tmp/test-glob_exists*");
1118 r = glob_exists("/tmp/test-glob_exists*");
1122 static void test_execute_directory(void) {
1123 char name[] = "/tmp/test-execute_directory/script1";
1124 char name2[] = "/tmp/test-execute_directory/script2";
1125 char name3[] = "/tmp/test-execute_directory/useless";
1126 char tempdir[] = "/tmp/test-execute_directory/";
1128 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1129 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1130 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1131 assert_se(chmod(name, 0755) == 0);
1132 assert_se(chmod(name2, 0755) == 0);
1133 assert_se(touch(name3) >= 0);
1135 execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
1136 assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1137 assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1139 rm_rf_dangerous(tempdir, false, true, false);
1142 static void test_unquote_first_word(void) {
1143 const char *p, *original;
1146 p = original = "foobar waldo";
1147 assert_se(unquote_first_word(&p, &t) > 0);
1148 assert_se(streq(t, "foobar"));
1150 assert_se(p == original + 7);
1152 assert_se(unquote_first_word(&p, &t) > 0);
1153 assert_se(streq(t, "waldo"));
1155 assert_se(p == original + 12);
1157 assert_se(unquote_first_word(&p, &t) == 0);
1159 assert_se(p == original + 12);
1161 p = original = "\"foobar\" \'waldo\'";
1162 assert_se(unquote_first_word(&p, &t) > 0);
1163 assert_se(streq(t, "foobar"));
1165 assert_se(p == original + 9);
1167 assert_se(unquote_first_word(&p, &t) > 0);
1168 assert_se(streq(t, "waldo"));
1170 assert_se(p == original + 16);
1172 assert_se(unquote_first_word(&p, &t) == 0);
1174 assert_se(p == original + 16);
1176 p = original = "\"";
1177 assert_se(unquote_first_word(&p, &t) == -EINVAL);
1178 assert_se(p == original + 1);
1180 p = original = "\'";
1181 assert_se(unquote_first_word(&p, &t) == -EINVAL);
1182 assert_se(p == original + 1);
1184 p = original = "yay\'foo\'bar";
1185 assert_se(unquote_first_word(&p, &t) > 0);
1186 assert_se(streq(t, "yayfoobar"));
1188 assert_se(p == original + 11);
1190 p = original = " foobar ";
1191 assert_se(unquote_first_word(&p, &t) > 0);
1192 assert_se(streq(t, "foobar"));
1194 assert_se(p == original + 12);
1197 static void test_unquote_many_words(void) {
1198 const char *p, *original;
1201 p = original = "foobar waldi piep";
1202 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1203 assert_se(p == original + 17);
1204 assert_se(streq_ptr(a, "foobar"));
1205 assert_se(streq_ptr(b, "waldi"));
1206 assert_se(streq_ptr(c, "piep"));
1211 p = original = "'foobar' wa\"ld\"i ";
1212 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1213 assert_se(p == original + 19);
1214 assert_se(streq_ptr(a, "foobar"));
1215 assert_se(streq_ptr(b, "waldi"));
1216 assert_se(streq_ptr(c, NULL));
1221 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1222 assert_se(p == original);
1223 assert_se(streq_ptr(a, NULL));
1224 assert_se(streq_ptr(b, NULL));
1225 assert_se(streq_ptr(c, NULL));
1228 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1229 assert_se(p == original+2);
1230 assert_se(streq_ptr(a, NULL));
1231 assert_se(streq_ptr(b, NULL));
1232 assert_se(streq_ptr(c, NULL));
1234 p = original = "foobar";
1235 assert_se(unquote_many_words(&p, NULL) == 0);
1236 assert_se(p == original);
1238 p = original = "foobar waldi";
1239 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1240 assert_se(p == original+7);
1241 assert_se(streq_ptr(a, "foobar"));
1243 p = original = " foobar ";
1244 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1245 assert_se(p == original+15);
1246 assert_se(streq_ptr(a, "foobar"));
1249 int main(int argc, char *argv[]) {
1250 log_parse_environment();
1254 test_align_power2();
1256 test_container_of();
1259 test_parse_boolean();
1266 test_delete_chars();
1276 test_foreach_word();
1277 test_foreach_word_quoted();
1278 test_default_term_for_tty();
1279 test_memdup_multiply();
1280 test_hostname_is_valid();
1282 test_get_process_comm();
1283 test_protect_errno();
1285 test_config_parse_iec_off();
1289 test_fstab_node_to_udev_node();
1290 test_get_files_in_directory();
1292 test_writing_tmpfile();
1295 test_foreach_string();
1296 test_filename_is_safe();
1297 test_string_has_cc();
1298 test_ascii_strlower();
1300 test_is_valid_documentation_url();
1301 test_file_in_same_dir();
1303 test_close_nointr();
1304 test_unlink_noerrno();
1305 test_readlink_and_make_absolute();
1306 test_read_one_char();
1307 test_ignore_signals();
1311 test_pid_is_unwaited();
1312 test_pid_is_alive();
1313 test_search_and_fopen();
1314 test_search_and_fopen_nulstr();
1316 test_execute_directory();
1317 test_unquote_first_word();
1318 test_unquote_many_words();