1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
37 #include "conf-parser.h"
40 static void test_streq_ptr(void) {
41 assert_se(streq_ptr(NULL, NULL));
42 assert_se(!streq_ptr("abc", "cdef"));
45 static void test_align_power2(void) {
48 assert_se(ALIGN_POWER2(0) == 0);
49 assert_se(ALIGN_POWER2(1) == 1);
50 assert_se(ALIGN_POWER2(2) == 2);
51 assert_se(ALIGN_POWER2(3) == 4);
52 assert_se(ALIGN_POWER2(12) == 16);
54 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
55 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
56 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
57 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
58 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
60 for (i = 1; i < 131071; ++i) {
61 for (p2 = 1; p2 < i; p2 <<= 1)
64 assert_se(ALIGN_POWER2(i) == p2);
67 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
68 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
71 assert_se(ALIGN_POWER2(i) == p2);
75 static void test_max(void) {
78 int b[CONST_MAX(10, 100)];
80 .a = CONST_MAX(10, 100),
84 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
86 /* CONST_MAX returns (void) instead of a value if the passed arguments
87 * are not of the same type or not constant expressions. */
88 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
89 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
91 assert_se(val1.a == 100);
92 assert_se(MAX(++d, 0) == 1);
95 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
96 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
97 assert_cc(MAXSIZE(char, long) == sizeof(long));
99 assert_se(MAX(-5, 5) == 5);
100 assert_se(MAX(5, 5) == 5);
101 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
102 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
103 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
104 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
105 assert_se(LESS_BY(8, 4) == 4);
106 assert_se(LESS_BY(8, 8) == 0);
107 assert_se(LESS_BY(4, 8) == 0);
108 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
109 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
110 assert_se(CLAMP(-5, 0, 1) == 0);
111 assert_se(CLAMP(5, 0, 1) == 1);
112 assert_se(CLAMP(5, -10, 1) == 1);
113 assert_se(CLAMP(5, -10, 10) == 5);
114 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
117 static void test_container_of(void) {
123 } _packed_ myval = { };
125 assert_cc(sizeof(myval) == 17);
126 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
127 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
128 assert_se(container_of(&container_of(&myval.v2,
135 static void test_alloca(void) {
136 static const uint8_t zero[997] = { };
139 t = alloca_align(17, 512);
140 assert_se(!((uintptr_t)t & 0xff));
143 t = alloca0_align(997, 1024);
144 assert_se(!((uintptr_t)t & 0x1ff));
145 assert_se(!memcmp(t, zero, 997));
148 static void test_div_round_up(void) {
152 assert_se(DIV_ROUND_UP(0, 8) == 0);
153 assert_se(DIV_ROUND_UP(1, 8) == 1);
154 assert_se(DIV_ROUND_UP(8, 8) == 1);
155 assert_se(DIV_ROUND_UP(12, 8) == 2);
156 assert_se(DIV_ROUND_UP(16, 8) == 2);
158 /* test multiple evaluation */
160 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
161 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
162 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
163 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
165 /* overflow test with exact division */
166 assert_se(sizeof(0U) == 4);
167 assert_se(0xfffffffaU % 10U == 0U);
168 assert_se(0xfffffffaU / 10U == 429496729U);
169 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
170 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
171 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
173 /* overflow test with rounded division */
174 assert_se(0xfffffffdU % 10U == 3U);
175 assert_se(0xfffffffdU / 10U == 429496729U);
176 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
177 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
178 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
181 static void test_first_word(void) {
182 assert_se(first_word("Hello", ""));
183 assert_se(first_word("Hello", "Hello"));
184 assert_se(first_word("Hello world", "Hello"));
185 assert_se(first_word("Hello\tworld", "Hello"));
186 assert_se(first_word("Hello\nworld", "Hello"));
187 assert_se(first_word("Hello\rworld", "Hello"));
188 assert_se(first_word("Hello ", "Hello"));
190 assert_se(!first_word("Hello", "Hellooo"));
191 assert_se(!first_word("Hello", "xxxxx"));
192 assert_se(!first_word("Hellooo", "Hello"));
195 static void test_close_many(void) {
197 char name0[] = "/tmp/test-close-many.XXXXXX";
198 char name1[] = "/tmp/test-close-many.XXXXXX";
199 char name2[] = "/tmp/test-close-many.XXXXXX";
201 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
202 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
203 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
207 assert_se(fcntl(fds[0], F_GETFD) == -1);
208 assert_se(fcntl(fds[1], F_GETFD) == -1);
209 assert_se(fcntl(fds[2], F_GETFD) >= 0);
218 static void test_parse_boolean(void) {
219 assert_se(parse_boolean("1") == 1);
220 assert_se(parse_boolean("y") == 1);
221 assert_se(parse_boolean("Y") == 1);
222 assert_se(parse_boolean("yes") == 1);
223 assert_se(parse_boolean("YES") == 1);
224 assert_se(parse_boolean("true") == 1);
225 assert_se(parse_boolean("TRUE") == 1);
226 assert_se(parse_boolean("on") == 1);
227 assert_se(parse_boolean("ON") == 1);
229 assert_se(parse_boolean("0") == 0);
230 assert_se(parse_boolean("n") == 0);
231 assert_se(parse_boolean("N") == 0);
232 assert_se(parse_boolean("no") == 0);
233 assert_se(parse_boolean("NO") == 0);
234 assert_se(parse_boolean("false") == 0);
235 assert_se(parse_boolean("FALSE") == 0);
236 assert_se(parse_boolean("off") == 0);
237 assert_se(parse_boolean("OFF") == 0);
239 assert_se(parse_boolean("garbage") < 0);
240 assert_se(parse_boolean("") < 0);
241 assert_se(parse_boolean("full") < 0);
244 static void test_parse_pid(void) {
248 r = parse_pid("100", &pid);
250 assert_se(pid == 100);
252 r = parse_pid("0x7FFFFFFF", &pid);
254 assert_se(pid == 2147483647);
256 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
257 r = parse_pid("0", &pid);
258 assert_se(r == -ERANGE);
259 assert_se(pid == 65);
261 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
262 r = parse_pid("-100", &pid);
263 assert_se(r == -ERANGE);
264 assert_se(pid == 65);
266 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
267 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
268 assert_se(r == -ERANGE);
269 assert_se(pid == 65);
272 static void test_parse_uid(void) {
276 r = parse_uid("100", &uid);
278 assert_se(uid == 100);
281 static void test_safe_atolli(void) {
285 r = safe_atolli("12345", &l);
287 assert_se(l == 12345);
289 r = safe_atolli("junk", &l);
290 assert_se(r == -EINVAL);
293 static void test_safe_atod(void) {
298 r = safe_atod("junk", &d);
299 assert_se(r == -EINVAL);
301 r = safe_atod("0.2244", &d);
303 assert_se(fabs(d - 0.2244) < 0.000001);
305 r = safe_atod("0,5", &d);
306 assert_se(r == -EINVAL);
310 assert_se(*e == ',');
312 /* Check if this really is locale independent */
313 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
315 r = safe_atod("0.2244", &d);
317 assert_se(fabs(d - 0.2244) < 0.000001);
319 r = safe_atod("0,5", &d);
320 assert_se(r == -EINVAL);
323 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
326 /* And check again, reset */
327 assert_se(setlocale(LC_NUMERIC, "C"));
329 r = safe_atod("0.2244", &d);
331 assert_se(fabs(d - 0.2244) < 0.000001);
333 r = safe_atod("0,5", &d);
334 assert_se(r == -EINVAL);
338 assert_se(*e == ',');
341 static void test_strappend(void) {
342 _cleanup_free_ char *t1, *t2, *t3, *t4;
344 t1 = strappend(NULL, NULL);
345 assert_se(streq(t1, ""));
347 t2 = strappend(NULL, "suf");
348 assert_se(streq(t2, "suf"));
350 t3 = strappend("pre", NULL);
351 assert_se(streq(t3, "pre"));
353 t4 = strappend("pre", "suf");
354 assert_se(streq(t4, "presuf"));
357 static void test_strstrip(void) {
359 char input[] = " hello, waldo. ";
362 assert_se(streq(r, "hello, waldo."));
365 static void test_delete_chars(void) {
367 char input[] = " hello, waldo. abc";
369 r = delete_chars(input, WHITESPACE);
370 assert_se(streq(r, "hello,waldo.abc"));
373 static void test_in_charset(void) {
374 assert_se(in_charset("dddaaabbbcccc", "abcd"));
375 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
378 static void test_hexchar(void) {
379 assert_se(hexchar(0xa) == 'a');
380 assert_se(hexchar(0x0) == '0');
383 static void test_unhexchar(void) {
384 assert_se(unhexchar('a') == 0xA);
385 assert_se(unhexchar('A') == 0xA);
386 assert_se(unhexchar('0') == 0x0);
389 static void test_octchar(void) {
390 assert_se(octchar(00) == '0');
391 assert_se(octchar(07) == '7');
394 static void test_unoctchar(void) {
395 assert_se(unoctchar('0') == 00);
396 assert_se(unoctchar('7') == 07);
399 static void test_decchar(void) {
400 assert_se(decchar(0) == '0');
401 assert_se(decchar(9) == '9');
404 static void test_undecchar(void) {
405 assert_se(undecchar('0') == 0);
406 assert_se(undecchar('9') == 9);
409 static void test_cescape(void) {
410 _cleanup_free_ char *escaped;
412 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
413 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
416 static void test_cunescape(void) {
417 _cleanup_free_ char *unescaped;
419 assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
420 assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
423 static void test_foreach_word(void) {
424 const char *word, *state;
427 const char test[] = "test abc d\te f ";
428 const char * const expected[] = {
438 FOREACH_WORD(word, l, test, state)
439 assert_se(strneq(expected[i++], word, l));
442 static void check(const char *test, char** expected, bool trailing) {
443 const char *word, *state;
447 printf("<<<%s>>>\n", test);
448 FOREACH_WORD_QUOTED(word, l, test, state) {
449 _cleanup_free_ char *t = NULL;
451 assert_se(t = strndup(word, l));
452 assert_se(strneq(expected[i++], word, l));
455 printf("<<<%s>>>\n", state);
456 assert_se(expected[i] == NULL);
457 assert_se(isempty(state) == !trailing);
460 static void test_foreach_word_quoted(void) {
461 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
485 static void test_default_term_for_tty(void) {
486 puts(default_term_for_tty("/dev/tty23"));
487 puts(default_term_for_tty("/dev/ttyS23"));
488 puts(default_term_for_tty("/dev/tty0"));
489 puts(default_term_for_tty("/dev/pty0"));
490 puts(default_term_for_tty("/dev/pts/0"));
491 puts(default_term_for_tty("/dev/console"));
492 puts(default_term_for_tty("tty23"));
493 puts(default_term_for_tty("ttyS23"));
494 puts(default_term_for_tty("tty0"));
495 puts(default_term_for_tty("pty0"));
496 puts(default_term_for_tty("pts/0"));
497 puts(default_term_for_tty("console"));
500 static void test_memdup_multiply(void) {
501 int org[] = {1, 2, 3};
504 dup = (int*)memdup_multiply(org, sizeof(int), 3);
507 assert_se(dup[0] == 1);
508 assert_se(dup[1] == 2);
509 assert_se(dup[2] == 3);
513 static void test_hostname_is_valid(void) {
514 assert_se(hostname_is_valid("foobar"));
515 assert_se(hostname_is_valid("foobar.com"));
516 assert_se(!hostname_is_valid("fööbar"));
517 assert_se(!hostname_is_valid(""));
518 assert_se(!hostname_is_valid("."));
519 assert_se(!hostname_is_valid(".."));
520 assert_se(!hostname_is_valid("foobar."));
521 assert_se(!hostname_is_valid(".foobar"));
522 assert_se(!hostname_is_valid("foo..bar"));
523 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
526 static void test_u64log2(void) {
527 assert_se(u64log2(0) == 0);
528 assert_se(u64log2(8) == 3);
529 assert_se(u64log2(9) == 3);
530 assert_se(u64log2(15) == 3);
531 assert_se(u64log2(16) == 4);
532 assert_se(u64log2(1024*1024) == 20);
533 assert_se(u64log2(1024*1024+5) == 20);
536 static void test_get_process_comm(void) {
538 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
539 _cleanup_free_ char *env = NULL;
547 if (stat("/proc/1/comm", &st) == 0) {
548 assert_se(get_process_comm(1, &a) >= 0);
549 log_info("pid1 comm: '%s'", a);
551 log_warning("/proc/1/comm does not exist.");
554 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
555 log_info("pid1 cmdline: '%s'", c);
557 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
558 log_info("pid1 cmdline truncated: '%s'", d);
560 assert_se(get_parent_of_pid(1, &e) >= 0);
561 log_info("pid1 ppid: "PID_FMT, e);
564 assert_se(is_kernel_thread(1) == 0);
566 r = get_process_exe(1, &f);
567 assert_se(r >= 0 || r == -EACCES);
568 log_info("pid1 exe: '%s'", strna(f));
570 assert_se(get_process_uid(1, &u) == 0);
571 log_info("pid1 uid: "UID_FMT, u);
574 assert_se(get_process_gid(1, &g) == 0);
575 log_info("pid1 gid: "GID_FMT, g);
580 r = get_process_cwd(me, &cwd);
581 assert_se(r >= 0 || r == -EACCES);
582 log_info("pid1 cwd: '%s'", cwd);
584 r = get_process_root(me, &root);
585 assert_se(r >= 0 || r == -EACCES);
586 log_info("pid1 root: '%s'", root);
588 r = get_process_environ(me, &env);
589 assert_se(r >= 0 || r == -EACCES);
590 log_info("self strlen(environ): '%zd'", strlen(env));
592 if (!detect_container(NULL))
593 assert_se(get_ctty_devnr(1, &h) == -ENOENT);
595 getenv_for_pid(1, "PATH", &i);
596 log_info("pid1 $PATH: '%s'", strna(i));
599 static void test_protect_errno(void) {
605 assert_se(errno == 12);
608 static void test_parse_size(void) {
611 assert_se(parse_size("111", 1024, &bytes) == 0);
612 assert_se(bytes == 111);
614 assert_se(parse_size("111.4", 1024, &bytes) == 0);
615 assert_se(bytes == 111);
617 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
618 assert_se(bytes == 112);
620 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
621 assert_se(bytes == 112);
623 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
624 assert_se(bytes == 3*1024 + 512);
626 assert_se(parse_size("3. K", 1024, &bytes) == 0);
627 assert_se(bytes == 3*1024);
629 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
630 assert_se(bytes == 3*1024);
632 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
634 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
635 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
637 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
639 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
640 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
642 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
643 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
645 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
647 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
648 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
650 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
651 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
653 assert_se(parse_size("12P", 1024, &bytes) == 0);
654 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
656 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
658 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
659 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
661 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
663 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
665 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
667 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
668 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
669 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
671 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
673 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
676 static void test_config_parse_iec_off(void) {
678 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
679 assert_se(offset == 4 * 1024 * 1024);
681 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
684 static void test_strextend(void) {
685 _cleanup_free_ char *str = strdup("0123");
686 strextend(&str, "456", "78", "9", NULL);
687 assert_se(streq(str, "0123456789"));
690 static void test_strrep(void) {
691 _cleanup_free_ char *one, *three, *zero;
692 one = strrep("waldo", 1);
693 three = strrep("waldo", 3);
694 zero = strrep("waldo", 0);
696 assert_se(streq(one, "waldo"));
697 assert_se(streq(three, "waldowaldowaldo"));
698 assert_se(streq(zero, ""));
701 static void test_split_pair(void) {
702 _cleanup_free_ char *a = NULL, *b = NULL;
704 assert_se(split_pair("", "", &a, &b) == -EINVAL);
705 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
706 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
707 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
708 assert_se(streq(a, "foo"));
709 assert_se(streq(b, "bar"));
712 assert_se(split_pair("==", "==", &a, &b) >= 0);
713 assert_se(streq(a, ""));
714 assert_se(streq(b, ""));
718 assert_se(split_pair("===", "==", &a, &b) >= 0);
719 assert_se(streq(a, ""));
720 assert_se(streq(b, "="));
723 static void test_fstab_node_to_udev_node(void) {
726 n = fstab_node_to_udev_node("LABEL=applé/jack");
728 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
731 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
733 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
736 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
738 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
741 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
743 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
746 n = fstab_node_to_udev_node("PONIES=awesome");
748 assert_se(streq(n, "PONIES=awesome"));
751 n = fstab_node_to_udev_node("/dev/xda1");
753 assert_se(streq(n, "/dev/xda1"));
757 static void test_get_files_in_directory(void) {
758 _cleanup_strv_free_ char **l = NULL, **t = NULL;
760 assert_se(get_files_in_directory("/tmp", &l) >= 0);
761 assert_se(get_files_in_directory(".", &t) >= 0);
762 assert_se(get_files_in_directory(".", NULL) >= 0);
765 static void test_in_set(void) {
766 assert_se(IN_SET(1, 1));
767 assert_se(IN_SET(1, 1, 2, 3, 4));
768 assert_se(IN_SET(2, 1, 2, 3, 4));
769 assert_se(IN_SET(3, 1, 2, 3, 4));
770 assert_se(IN_SET(4, 1, 2, 3, 4));
771 assert_se(!IN_SET(0, 1));
772 assert_se(!IN_SET(0, 1, 2, 3, 4));
775 static void test_writing_tmpfile(void) {
776 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
777 _cleanup_free_ char *contents = NULL;
782 IOVEC_SET_STRING(iov[0], "abc\n");
783 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
784 IOVEC_SET_STRING(iov[2], "");
786 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
787 printf("tmpfile: %s", name);
789 r = writev(fd, iov, 3);
792 r = read_full_file(name, &contents, &size);
794 printf("contents: %s", contents);
795 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
800 static void test_hexdump(void) {
804 hexdump(stdout, NULL, 0);
805 hexdump(stdout, "", 0);
806 hexdump(stdout, "", 1);
807 hexdump(stdout, "x", 1);
808 hexdump(stdout, "x", 2);
809 hexdump(stdout, "foobar", 7);
810 hexdump(stdout, "f\nobar", 7);
811 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
813 for (i = 0; i < ELEMENTSOF(data); i++)
816 hexdump(stdout, data, sizeof(data));
819 static void test_log2i(void) {
820 assert_se(log2i(1) == 0);
821 assert_se(log2i(2) == 1);
822 assert_se(log2i(3) == 1);
823 assert_se(log2i(4) == 2);
824 assert_se(log2i(32) == 5);
825 assert_se(log2i(33) == 5);
826 assert_se(log2i(63) == 5);
827 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
830 static void test_foreach_string(void) {
831 const char * const t[] = {
840 FOREACH_STRING(x, "foo", "bar", "waldo")
841 assert_se(streq_ptr(t[i++], x));
845 FOREACH_STRING(x, "zzz")
846 assert_se(streq(x, "zzz"));
849 static void test_filename_is_valid(void) {
850 char foo[FILENAME_MAX+2];
853 assert_se(!filename_is_valid(""));
854 assert_se(!filename_is_valid("/bar/foo"));
855 assert_se(!filename_is_valid("/"));
856 assert_se(!filename_is_valid("."));
857 assert_se(!filename_is_valid(".."));
859 for (i=0; i<FILENAME_MAX+1; i++)
861 foo[FILENAME_MAX+1] = '\0';
863 assert_se(!filename_is_valid(foo));
865 assert_se(filename_is_valid("foo_bar-333"));
866 assert_se(filename_is_valid("o.o"));
869 static void test_string_has_cc(void) {
870 assert_se(string_has_cc("abc\1", NULL));
871 assert_se(string_has_cc("abc\x7f", NULL));
872 assert_se(string_has_cc("abc\x7f", NULL));
873 assert_se(string_has_cc("abc\t\x7f", "\t"));
874 assert_se(string_has_cc("abc\t\x7f", "\t"));
875 assert_se(string_has_cc("\x7f", "\t"));
876 assert_se(string_has_cc("\x7f", "\t\a"));
878 assert_se(!string_has_cc("abc\t\t", "\t"));
879 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
880 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
883 static void test_ascii_strlower(void) {
884 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
885 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
888 static void test_files_same(void) {
889 _cleanup_close_ int fd = -1;
890 char name[] = "/tmp/test-files_same.XXXXXX";
891 char name_alias[] = "/tmp/test-files_same.alias";
893 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
895 assert_se(symlink(name, name_alias) >= 0);
897 assert_se(files_same(name, name));
898 assert_se(files_same(name, name_alias));
904 static void test_is_valid_documentation_url(void) {
905 assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
906 assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
907 assert_se(is_valid_documentation_url("file:foo"));
908 assert_se(is_valid_documentation_url("man:systemd.special(7)"));
909 assert_se(is_valid_documentation_url("info:bar"));
911 assert_se(!is_valid_documentation_url("foo:"));
912 assert_se(!is_valid_documentation_url("info:"));
913 assert_se(!is_valid_documentation_url(""));
916 static void test_file_in_same_dir(void) {
919 t = file_in_same_dir("/", "a");
920 assert_se(streq(t, "/a"));
923 t = file_in_same_dir("/", "/a");
924 assert_se(streq(t, "/a"));
927 t = file_in_same_dir("", "a");
928 assert_se(streq(t, "a"));
931 t = file_in_same_dir("a/", "a");
932 assert_se(streq(t, "a/a"));
935 t = file_in_same_dir("bar/foo", "bar");
936 assert_se(streq(t, "bar/bar"));
940 static void test_endswith(void) {
941 assert_se(endswith("foobar", "bar"));
942 assert_se(endswith("foobar", ""));
943 assert_se(endswith("foobar", "foobar"));
944 assert_se(endswith("", ""));
946 assert_se(!endswith("foobar", "foo"));
947 assert_se(!endswith("foobar", "foobarfoofoo"));
950 static void test_close_nointr(void) {
951 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
954 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
956 assert_se(close_nointr(fd) >= 0);
957 assert_se(close_nointr(fd) < 0);
963 static void test_unlink_noerrno(void) {
964 char name[] = "/tmp/test-close_nointr.XXXXXX";
967 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
969 assert_se(close_nointr(fd) >= 0);
974 assert_se(unlink_noerrno(name) >= 0);
975 assert_se(errno == -42);
976 assert_se(unlink_noerrno(name) < 0);
977 assert_se(errno == -42);
981 static void test_readlink_and_make_absolute(void) {
982 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
983 char name[] = "/tmp/test-readlink_and_make_absolute/original";
984 char name2[] = "test-readlink_and_make_absolute/original";
985 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
988 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
989 assert_se(touch(name) >= 0);
991 assert_se(symlink(name, name_alias) >= 0);
992 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
993 assert_se(streq(r, name));
995 assert_se(unlink(name_alias) >= 0);
997 assert_se(chdir(tempdir) >= 0);
998 assert_se(symlink(name2, name_alias) >= 0);
999 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1000 assert_se(streq(r, name));
1002 assert_se(unlink(name_alias) >= 0);
1004 assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
1007 static void test_read_one_char(void) {
1008 _cleanup_fclose_ FILE *file = NULL;
1011 char name[] = "/tmp/test-read_one_char.XXXXXX";
1014 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1016 file = fdopen(fd, "r+");
1018 assert_se(fputs("c\n", file) >= 0);
1021 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
1022 assert_se(!need_nl);
1023 assert_se(r == 'c');
1024 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1027 assert_se(fputs("foobar\n", file) >= 0);
1029 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1032 assert_se(fputs("\n", file) >= 0);
1034 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1039 static void test_ignore_signals(void) {
1040 assert_se(ignore_signals(SIGINT, -1) >= 0);
1041 assert_se(kill(getpid(), SIGINT) >= 0);
1042 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1043 assert_se(kill(getpid(), SIGUSR1) >= 0);
1044 assert_se(kill(getpid(), SIGUSR2) >= 0);
1045 assert_se(kill(getpid(), SIGTERM) >= 0);
1046 assert_se(kill(getpid(), SIGPIPE) >= 0);
1047 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1050 static void test_strshorten(void) {
1051 char s[] = "foobar";
1053 assert_se(strlen(strshorten(s, 6)) == 6);
1054 assert_se(strlen(strshorten(s, 12)) == 6);
1055 assert_se(strlen(strshorten(s, 2)) == 2);
1056 assert_se(strlen(strshorten(s, 0)) == 0);
1059 static void test_strappenda(void) {
1062 actual = strappenda("", "foo", "bar");
1063 assert_se(streq(actual, "foobar"));
1065 actual = strappenda("foo", "bar", "baz");
1066 assert_se(streq(actual, "foobarbaz"));
1068 actual = strappenda("foo", "", "bar", "baz");
1069 assert_se(streq(actual, "foobarbaz"));
1072 static void test_is_symlink(void) {
1073 char name[] = "/tmp/test-is_symlink.XXXXXX";
1074 char name_link[] = "/tmp/test-is_symlink.link";
1075 _cleanup_close_ int fd = -1;
1077 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1079 assert_se(symlink(name, name_link) >= 0);
1081 assert_se(is_symlink(name) == 0);
1082 assert_se(is_symlink(name_link) == 1);
1083 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1090 static void test_pid_is_unwaited(void) {
1094 assert_se(pid >= 0);
1096 _exit(EXIT_SUCCESS);
1100 waitpid(pid, &status, 0);
1101 assert_se(!pid_is_unwaited(pid));
1103 assert_se(pid_is_unwaited(getpid()));
1104 assert_se(!pid_is_unwaited(-1));
1107 static void test_pid_is_alive(void) {
1111 assert_se(pid >= 0);
1113 _exit(EXIT_SUCCESS);
1117 waitpid(pid, &status, 0);
1118 assert_se(!pid_is_alive(pid));
1120 assert_se(pid_is_alive(getpid()));
1121 assert_se(!pid_is_alive(-1));
1124 static void test_search_and_fopen(void) {
1125 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1126 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1131 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1135 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1139 r = search_and_fopen(name, "r", NULL, dirs, &f);
1143 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1147 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1149 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1155 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1160 static void test_search_and_fopen_nulstr(void) {
1161 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1162 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1167 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1171 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1175 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1179 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1181 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1187 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1191 static void test_glob_exists(void) {
1192 char name[] = "/tmp/test-glob_exists.XXXXXX";
1196 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1200 r = glob_exists("/tmp/test-glob_exists*");
1205 r = glob_exists("/tmp/test-glob_exists*");
1209 static void test_execute_directory(void) {
1210 char name[] = "/tmp/test-execute_directory/script1";
1211 char name2[] = "/tmp/test-execute_directory/script2";
1212 char name3[] = "/tmp/test-execute_directory/useless";
1213 char tempdir[] = "/tmp/test-execute_directory/";
1215 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1216 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1217 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1218 assert_se(chmod(name, 0755) == 0);
1219 assert_se(chmod(name2, 0755) == 0);
1220 assert_se(touch(name3) >= 0);
1222 execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
1223 assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1224 assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1226 rm_rf_dangerous(tempdir, false, true, false);
1229 static void test_unquote_first_word(void) {
1230 const char *p, *original;
1233 p = original = "foobar waldo";
1234 assert_se(unquote_first_word(&p, &t, false) > 0);
1235 assert_se(streq(t, "foobar"));
1237 assert_se(p == original + 7);
1239 assert_se(unquote_first_word(&p, &t, false) > 0);
1240 assert_se(streq(t, "waldo"));
1242 assert_se(p == original + 12);
1244 assert_se(unquote_first_word(&p, &t, false) == 0);
1246 assert_se(p == original + 12);
1248 p = original = "\"foobar\" \'waldo\'";
1249 assert_se(unquote_first_word(&p, &t, false) > 0);
1250 assert_se(streq(t, "foobar"));
1252 assert_se(p == original + 9);
1254 assert_se(unquote_first_word(&p, &t, false) > 0);
1255 assert_se(streq(t, "waldo"));
1257 assert_se(p == original + 16);
1259 assert_se(unquote_first_word(&p, &t, false) == 0);
1261 assert_se(p == original + 16);
1263 p = original = "\"";
1264 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1265 assert_se(p == original + 1);
1267 p = original = "\'";
1268 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1269 assert_se(p == original + 1);
1271 p = original = "\'fooo";
1272 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1273 assert_se(p == original + 5);
1275 p = original = "\'fooo";
1276 assert_se(unquote_first_word(&p, &t, true) > 0);
1277 assert_se(streq(t, "fooo"));
1279 assert_se(p == original + 5);
1281 p = original = "yay\'foo\'bar";
1282 assert_se(unquote_first_word(&p, &t, false) > 0);
1283 assert_se(streq(t, "yayfoobar"));
1285 assert_se(p == original + 11);
1287 p = original = " foobar ";
1288 assert_se(unquote_first_word(&p, &t, false) > 0);
1289 assert_se(streq(t, "foobar"));
1291 assert_se(p == original + 12);
1294 static void test_unquote_many_words(void) {
1295 const char *p, *original;
1298 p = original = "foobar waldi piep";
1299 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1300 assert_se(p == original + 17);
1301 assert_se(streq_ptr(a, "foobar"));
1302 assert_se(streq_ptr(b, "waldi"));
1303 assert_se(streq_ptr(c, "piep"));
1308 p = original = "'foobar' wa\"ld\"i ";
1309 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1310 assert_se(p == original + 19);
1311 assert_se(streq_ptr(a, "foobar"));
1312 assert_se(streq_ptr(b, "waldi"));
1313 assert_se(streq_ptr(c, NULL));
1318 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1319 assert_se(p == original);
1320 assert_se(streq_ptr(a, NULL));
1321 assert_se(streq_ptr(b, NULL));
1322 assert_se(streq_ptr(c, NULL));
1325 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1326 assert_se(p == original+2);
1327 assert_se(streq_ptr(a, NULL));
1328 assert_se(streq_ptr(b, NULL));
1329 assert_se(streq_ptr(c, NULL));
1331 p = original = "foobar";
1332 assert_se(unquote_many_words(&p, NULL) == 0);
1333 assert_se(p == original);
1335 p = original = "foobar waldi";
1336 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1337 assert_se(p == original+7);
1338 assert_se(streq_ptr(a, "foobar"));
1341 p = original = " foobar ";
1342 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1343 assert_se(p == original+15);
1344 assert_se(streq_ptr(a, "foobar"));
1348 static int parse_item(const char *key, const char *value) {
1351 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1355 static void test_parse_proc_cmdline(void) {
1356 assert_se(parse_proc_cmdline(parse_item) >= 0);
1359 static void test_raw_clone(void) {
1360 pid_t parent, pid, pid2;
1363 log_info("before clone: getpid()→"PID_FMT, parent);
1364 assert_se(raw_getpid() == parent);
1366 pid = raw_clone(0, NULL);
1367 assert_se(pid >= 0);
1369 pid2 = raw_getpid();
1370 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1371 pid, getpid(), pid2);
1373 assert_se(pid2 != parent);
1374 _exit(EXIT_SUCCESS);
1378 assert_se(pid2 == parent);
1379 waitpid(pid, &status, __WCLONE);
1380 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1384 static void test_same_fd(void) {
1385 _cleanup_close_pair_ int p[2] = { -1, -1 };
1386 _cleanup_close_ int a = -1, b = -1, c = -1;
1388 assert_se(pipe2(p, O_CLOEXEC) >= 0);
1389 assert_se((a = dup(p[0])) >= 0);
1390 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1391 assert_se((c = dup(a)) >= 0);
1393 assert_se(same_fd(p[0], p[0]) > 0);
1394 assert_se(same_fd(p[1], p[1]) > 0);
1395 assert_se(same_fd(a, a) > 0);
1396 assert_se(same_fd(b, b) > 0);
1398 assert_se(same_fd(a, p[0]) > 0);
1399 assert_se(same_fd(p[0], a) > 0);
1400 assert_se(same_fd(c, p[0]) > 0);
1401 assert_se(same_fd(p[0], c) > 0);
1402 assert_se(same_fd(a, c) > 0);
1403 assert_se(same_fd(c, a) > 0);
1405 assert_se(same_fd(p[0], p[1]) == 0);
1406 assert_se(same_fd(p[1], p[0]) == 0);
1407 assert_se(same_fd(p[0], b) == 0);
1408 assert_se(same_fd(b, p[0]) == 0);
1409 assert_se(same_fd(p[1], a) == 0);
1410 assert_se(same_fd(a, p[1]) == 0);
1411 assert_se(same_fd(p[1], b) == 0);
1412 assert_se(same_fd(b, p[1]) == 0);
1414 assert_se(same_fd(a, b) == 0);
1415 assert_se(same_fd(b, a) == 0);
1418 int main(int argc, char *argv[]) {
1419 log_parse_environment();
1423 test_align_power2();
1425 test_container_of();
1427 test_div_round_up();
1430 test_parse_boolean();
1437 test_delete_chars();
1447 test_foreach_word();
1448 test_foreach_word_quoted();
1449 test_default_term_for_tty();
1450 test_memdup_multiply();
1451 test_hostname_is_valid();
1453 test_get_process_comm();
1454 test_protect_errno();
1456 test_config_parse_iec_off();
1460 test_fstab_node_to_udev_node();
1461 test_get_files_in_directory();
1463 test_writing_tmpfile();
1466 test_foreach_string();
1467 test_filename_is_valid();
1468 test_string_has_cc();
1469 test_ascii_strlower();
1471 test_is_valid_documentation_url();
1472 test_file_in_same_dir();
1474 test_close_nointr();
1475 test_unlink_noerrno();
1476 test_readlink_and_make_absolute();
1477 test_read_one_char();
1478 test_ignore_signals();
1482 test_pid_is_unwaited();
1483 test_pid_is_alive();
1484 test_search_and_fopen();
1485 test_search_and_fopen_nulstr();
1487 test_execute_directory();
1488 test_unquote_first_word();
1489 test_unquote_many_words();
1490 test_parse_proc_cmdline();