1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
37 #include "conf-parser.h"
39 static void test_streq_ptr(void) {
40 assert_se(streq_ptr(NULL, NULL));
41 assert_se(!streq_ptr("abc", "cdef"));
44 static void test_align_power2(void) {
47 assert_se(ALIGN_POWER2(0) == 0);
48 assert_se(ALIGN_POWER2(1) == 1);
49 assert_se(ALIGN_POWER2(2) == 2);
50 assert_se(ALIGN_POWER2(3) == 4);
51 assert_se(ALIGN_POWER2(12) == 16);
53 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
54 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
55 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
56 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
57 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
59 for (i = 1; i < 131071; ++i) {
60 for (p2 = 1; p2 < i; p2 <<= 1)
63 assert_se(ALIGN_POWER2(i) == p2);
66 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
67 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
70 assert_se(ALIGN_POWER2(i) == p2);
74 static void test_max(void) {
77 int b[CONST_MAX(10, 100)];
79 .a = CONST_MAX(10, 100),
83 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
85 /* CONST_MAX returns (void) instead of a value if the passed arguments
86 * are not of the same type or not constant expressions. */
87 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
88 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
90 assert_se(val1.a == 100);
91 assert_se(MAX(++d, 0) == 1);
94 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
95 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
96 assert_cc(MAXSIZE(char, long) == sizeof(long));
98 assert_se(MAX(-5, 5) == 5);
99 assert_se(MAX(5, 5) == 5);
100 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
101 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
102 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
103 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
104 assert_se(LESS_BY(8, 4) == 4);
105 assert_se(LESS_BY(8, 8) == 0);
106 assert_se(LESS_BY(4, 8) == 0);
107 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
108 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
109 assert_se(CLAMP(-5, 0, 1) == 0);
110 assert_se(CLAMP(5, 0, 1) == 1);
111 assert_se(CLAMP(5, -10, 1) == 1);
112 assert_se(CLAMP(5, -10, 10) == 5);
113 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
116 static void test_container_of(void) {
122 } _packed_ myval = { };
124 assert_cc(sizeof(myval) == 17);
125 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
126 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
127 assert_se(container_of(&container_of(&myval.v2,
134 static void test_alloca(void) {
135 static const uint8_t zero[997] = { };
138 t = alloca_align(17, 512);
139 assert_se(!((uintptr_t)t & 0xff));
142 t = alloca0_align(997, 1024);
143 assert_se(!((uintptr_t)t & 0x1ff));
144 assert_se(!memcmp(t, zero, 997));
147 static void test_first_word(void) {
148 assert_se(first_word("Hello", ""));
149 assert_se(first_word("Hello", "Hello"));
150 assert_se(first_word("Hello world", "Hello"));
151 assert_se(first_word("Hello\tworld", "Hello"));
152 assert_se(first_word("Hello\nworld", "Hello"));
153 assert_se(first_word("Hello\rworld", "Hello"));
154 assert_se(first_word("Hello ", "Hello"));
156 assert_se(!first_word("Hello", "Hellooo"));
157 assert_se(!first_word("Hello", "xxxxx"));
158 assert_se(!first_word("Hellooo", "Hello"));
161 static void test_close_many(void) {
163 char name0[] = "/tmp/test-close-many.XXXXXX";
164 char name1[] = "/tmp/test-close-many.XXXXXX";
165 char name2[] = "/tmp/test-close-many.XXXXXX";
167 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
168 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
169 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
173 assert_se(fcntl(fds[0], F_GETFD) == -1);
174 assert_se(fcntl(fds[1], F_GETFD) == -1);
175 assert_se(fcntl(fds[2], F_GETFD) >= 0);
184 static void test_parse_boolean(void) {
185 assert_se(parse_boolean("1") == 1);
186 assert_se(parse_boolean("y") == 1);
187 assert_se(parse_boolean("Y") == 1);
188 assert_se(parse_boolean("yes") == 1);
189 assert_se(parse_boolean("YES") == 1);
190 assert_se(parse_boolean("true") == 1);
191 assert_se(parse_boolean("TRUE") == 1);
192 assert_se(parse_boolean("on") == 1);
193 assert_se(parse_boolean("ON") == 1);
195 assert_se(parse_boolean("0") == 0);
196 assert_se(parse_boolean("n") == 0);
197 assert_se(parse_boolean("N") == 0);
198 assert_se(parse_boolean("no") == 0);
199 assert_se(parse_boolean("NO") == 0);
200 assert_se(parse_boolean("false") == 0);
201 assert_se(parse_boolean("FALSE") == 0);
202 assert_se(parse_boolean("off") == 0);
203 assert_se(parse_boolean("OFF") == 0);
205 assert_se(parse_boolean("garbage") < 0);
206 assert_se(parse_boolean("") < 0);
207 assert_se(parse_boolean("full") < 0);
210 static void test_parse_pid(void) {
214 r = parse_pid("100", &pid);
216 assert_se(pid == 100);
218 r = parse_pid("0x7FFFFFFF", &pid);
220 assert_se(pid == 2147483647);
222 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
223 r = parse_pid("0", &pid);
224 assert_se(r == -ERANGE);
225 assert_se(pid == 65);
227 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
228 r = parse_pid("-100", &pid);
229 assert_se(r == -ERANGE);
230 assert_se(pid == 65);
232 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
233 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
234 assert_se(r == -ERANGE);
235 assert_se(pid == 65);
238 static void test_parse_uid(void) {
242 r = parse_uid("100", &uid);
244 assert_se(uid == 100);
247 static void test_safe_atolli(void) {
251 r = safe_atolli("12345", &l);
253 assert_se(l == 12345);
255 r = safe_atolli("junk", &l);
256 assert_se(r == -EINVAL);
259 static void test_safe_atod(void) {
264 r = safe_atod("junk", &d);
265 assert_se(r == -EINVAL);
267 r = safe_atod("0.2244", &d);
269 assert_se(fabs(d - 0.2244) < 0.000001);
271 r = safe_atod("0,5", &d);
272 assert_se(r == -EINVAL);
276 assert_se(*e == ',');
278 /* Check if this really is locale independent */
279 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
281 r = safe_atod("0.2244", &d);
283 assert_se(fabs(d - 0.2244) < 0.000001);
285 r = safe_atod("0,5", &d);
286 assert_se(r == -EINVAL);
289 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
292 /* And check again, reset */
293 assert_se(setlocale(LC_NUMERIC, "C"));
295 r = safe_atod("0.2244", &d);
297 assert_se(fabs(d - 0.2244) < 0.000001);
299 r = safe_atod("0,5", &d);
300 assert_se(r == -EINVAL);
304 assert_se(*e == ',');
307 static void test_strappend(void) {
308 _cleanup_free_ char *t1, *t2, *t3, *t4;
310 t1 = strappend(NULL, NULL);
311 assert_se(streq(t1, ""));
313 t2 = strappend(NULL, "suf");
314 assert_se(streq(t2, "suf"));
316 t3 = strappend("pre", NULL);
317 assert_se(streq(t3, "pre"));
319 t4 = strappend("pre", "suf");
320 assert_se(streq(t4, "presuf"));
323 static void test_strstrip(void) {
325 char input[] = " hello, waldo. ";
328 assert_se(streq(r, "hello, waldo."));
331 static void test_delete_chars(void) {
333 char input[] = " hello, waldo. abc";
335 r = delete_chars(input, WHITESPACE);
336 assert_se(streq(r, "hello,waldo.abc"));
339 static void test_in_charset(void) {
340 assert_se(in_charset("dddaaabbbcccc", "abcd"));
341 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
344 static void test_hexchar(void) {
345 assert_se(hexchar(0xa) == 'a');
346 assert_se(hexchar(0x0) == '0');
349 static void test_unhexchar(void) {
350 assert_se(unhexchar('a') == 0xA);
351 assert_se(unhexchar('A') == 0xA);
352 assert_se(unhexchar('0') == 0x0);
355 static void test_octchar(void) {
356 assert_se(octchar(00) == '0');
357 assert_se(octchar(07) == '7');
360 static void test_unoctchar(void) {
361 assert_se(unoctchar('0') == 00);
362 assert_se(unoctchar('7') == 07);
365 static void test_decchar(void) {
366 assert_se(decchar(0) == '0');
367 assert_se(decchar(9) == '9');
370 static void test_undecchar(void) {
371 assert_se(undecchar('0') == 0);
372 assert_se(undecchar('9') == 9);
375 static void test_cescape(void) {
376 _cleanup_free_ char *escaped;
378 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
379 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
382 static void test_cunescape(void) {
383 _cleanup_free_ char *unescaped;
385 assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
386 assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
389 static void test_foreach_word(void) {
390 const char *word, *state;
393 const char test[] = "test abc d\te f ";
394 const char * const expected[] = {
404 FOREACH_WORD(word, l, test, state)
405 assert_se(strneq(expected[i++], word, l));
408 static void test_foreach_word_quoted(void) {
409 const char *word, *state;
412 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
413 const char * const expected[] = {
429 printf("<%s>\n", test);
430 FOREACH_WORD_QUOTED(word, l, test, state) {
431 _cleanup_free_ char *t = NULL;
433 assert_se(t = strndup(word, l));
434 assert_se(strneq(expected[i++], word, l));
437 assert_se(isempty(state));
440 static void test_default_term_for_tty(void) {
441 puts(default_term_for_tty("/dev/tty23"));
442 puts(default_term_for_tty("/dev/ttyS23"));
443 puts(default_term_for_tty("/dev/tty0"));
444 puts(default_term_for_tty("/dev/pty0"));
445 puts(default_term_for_tty("/dev/pts/0"));
446 puts(default_term_for_tty("/dev/console"));
447 puts(default_term_for_tty("tty23"));
448 puts(default_term_for_tty("ttyS23"));
449 puts(default_term_for_tty("tty0"));
450 puts(default_term_for_tty("pty0"));
451 puts(default_term_for_tty("pts/0"));
452 puts(default_term_for_tty("console"));
455 static void test_memdup_multiply(void) {
456 int org[] = {1, 2, 3};
459 dup = (int*)memdup_multiply(org, sizeof(int), 3);
462 assert_se(dup[0] == 1);
463 assert_se(dup[1] == 2);
464 assert_se(dup[2] == 3);
468 static void test_hostname_is_valid(void) {
469 assert_se(hostname_is_valid("foobar"));
470 assert_se(hostname_is_valid("foobar.com"));
471 assert_se(!hostname_is_valid("fööbar"));
472 assert_se(!hostname_is_valid(""));
473 assert_se(!hostname_is_valid("."));
474 assert_se(!hostname_is_valid(".."));
475 assert_se(!hostname_is_valid("foobar."));
476 assert_se(!hostname_is_valid(".foobar"));
477 assert_se(!hostname_is_valid("foo..bar"));
478 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
481 static void test_u64log2(void) {
482 assert_se(u64log2(0) == 0);
483 assert_se(u64log2(8) == 3);
484 assert_se(u64log2(9) == 3);
485 assert_se(u64log2(15) == 3);
486 assert_se(u64log2(16) == 4);
487 assert_se(u64log2(1024*1024) == 20);
488 assert_se(u64log2(1024*1024+5) == 20);
491 static void test_get_process_comm(void) {
493 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
494 _cleanup_free_ char *env = NULL;
495 unsigned long long b;
503 if (stat("/proc/1/comm", &st) == 0) {
504 assert_se(get_process_comm(1, &a) >= 0);
505 log_info("pid1 comm: '%s'", a);
507 log_warning("/proc/1/comm does not exist.");
510 assert_se(get_starttime_of_pid(1, &b) >= 0);
511 log_info("pid1 starttime: '%llu'", b);
513 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
514 log_info("pid1 cmdline: '%s'", c);
516 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
517 log_info("pid1 cmdline truncated: '%s'", d);
519 assert_se(get_parent_of_pid(1, &e) >= 0);
520 log_info("pid1 ppid: "PID_FMT, e);
523 assert_se(is_kernel_thread(1) == 0);
525 r = get_process_exe(1, &f);
526 assert_se(r >= 0 || r == -EACCES);
527 log_info("pid1 exe: '%s'", strna(f));
529 assert_se(get_process_uid(1, &u) == 0);
530 log_info("pid1 uid: "UID_FMT, u);
533 assert_se(get_process_gid(1, &g) == 0);
534 log_info("pid1 gid: "GID_FMT, g);
539 r = get_process_cwd(me, &cwd);
540 assert_se(r >= 0 || r == -EACCES);
541 log_info("pid1 cwd: '%s'", cwd);
543 r = get_process_root(me, &root);
544 assert_se(r >= 0 || r == -EACCES);
545 log_info("pid1 root: '%s'", root);
547 r = get_process_environ(me, &env);
548 assert_se(r >= 0 || r == -EACCES);
549 log_info("self strlen(environ): '%zd'", strlen(env));
551 assert_se(get_ctty_devnr(1, &h) == -ENOENT);
553 getenv_for_pid(1, "PATH", &i);
554 log_info("pid1 $PATH: '%s'", strna(i));
557 static void test_protect_errno(void) {
563 assert_se(errno == 12);
566 static void test_parse_size(void) {
569 assert_se(parse_size("111", 1024, &bytes) == 0);
570 assert_se(bytes == 111);
572 assert_se(parse_size("111.4", 1024, &bytes) == 0);
573 assert_se(bytes == 111);
575 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
576 assert_se(bytes == 112);
578 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
579 assert_se(bytes == 112);
581 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
582 assert_se(bytes == 3*1024 + 512);
584 assert_se(parse_size("3. K", 1024, &bytes) == 0);
585 assert_se(bytes == 3*1024);
587 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
588 assert_se(bytes == 3*1024);
590 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
592 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
593 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
595 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
597 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
598 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
600 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
601 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
603 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
605 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
606 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
608 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
609 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
611 assert_se(parse_size("12P", 1024, &bytes) == 0);
612 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
614 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
616 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
617 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
619 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
621 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
623 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
625 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
626 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
627 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
629 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
631 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
634 static void test_config_parse_iec_off(void) {
636 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
637 assert_se(offset == 4 * 1024 * 1024);
639 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
642 static void test_strextend(void) {
643 _cleanup_free_ char *str = strdup("0123");
644 strextend(&str, "456", "78", "9", NULL);
645 assert_se(streq(str, "0123456789"));
648 static void test_strrep(void) {
649 _cleanup_free_ char *one, *three, *zero;
650 one = strrep("waldo", 1);
651 three = strrep("waldo", 3);
652 zero = strrep("waldo", 0);
654 assert_se(streq(one, "waldo"));
655 assert_se(streq(three, "waldowaldowaldo"));
656 assert_se(streq(zero, ""));
659 static void test_split_pair(void) {
660 _cleanup_free_ char *a = NULL, *b = NULL;
662 assert_se(split_pair("", "", &a, &b) == -EINVAL);
663 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
664 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
665 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
666 assert_se(streq(a, "foo"));
667 assert_se(streq(b, "bar"));
670 assert_se(split_pair("==", "==", &a, &b) >= 0);
671 assert_se(streq(a, ""));
672 assert_se(streq(b, ""));
676 assert_se(split_pair("===", "==", &a, &b) >= 0);
677 assert_se(streq(a, ""));
678 assert_se(streq(b, "="));
681 static void test_fstab_node_to_udev_node(void) {
684 n = fstab_node_to_udev_node("LABEL=applé/jack");
686 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
689 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
691 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
694 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
696 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
699 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
701 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
704 n = fstab_node_to_udev_node("PONIES=awesome");
706 assert_se(streq(n, "PONIES=awesome"));
709 n = fstab_node_to_udev_node("/dev/xda1");
711 assert_se(streq(n, "/dev/xda1"));
715 static void test_get_files_in_directory(void) {
716 _cleanup_strv_free_ char **l = NULL, **t = NULL;
718 assert_se(get_files_in_directory("/tmp", &l) >= 0);
719 assert_se(get_files_in_directory(".", &t) >= 0);
720 assert_se(get_files_in_directory(".", NULL) >= 0);
723 static void test_in_set(void) {
724 assert_se(IN_SET(1, 1));
725 assert_se(IN_SET(1, 1, 2, 3, 4));
726 assert_se(IN_SET(2, 1, 2, 3, 4));
727 assert_se(IN_SET(3, 1, 2, 3, 4));
728 assert_se(IN_SET(4, 1, 2, 3, 4));
729 assert_se(!IN_SET(0, 1));
730 assert_se(!IN_SET(0, 1, 2, 3, 4));
733 static void test_writing_tmpfile(void) {
734 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
735 _cleanup_free_ char *contents = NULL;
740 IOVEC_SET_STRING(iov[0], "abc\n");
741 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
742 IOVEC_SET_STRING(iov[2], "");
744 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
745 printf("tmpfile: %s", name);
747 r = writev(fd, iov, 3);
750 r = read_full_file(name, &contents, &size);
752 printf("contents: %s", contents);
753 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
758 static void test_hexdump(void) {
762 hexdump(stdout, NULL, 0);
763 hexdump(stdout, "", 0);
764 hexdump(stdout, "", 1);
765 hexdump(stdout, "x", 1);
766 hexdump(stdout, "x", 2);
767 hexdump(stdout, "foobar", 7);
768 hexdump(stdout, "f\nobar", 7);
769 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
771 for (i = 0; i < ELEMENTSOF(data); i++)
774 hexdump(stdout, data, sizeof(data));
777 static void test_log2i(void) {
778 assert_se(log2i(1) == 0);
779 assert_se(log2i(2) == 1);
780 assert_se(log2i(3) == 1);
781 assert_se(log2i(4) == 2);
782 assert_se(log2i(32) == 5);
783 assert_se(log2i(33) == 5);
784 assert_se(log2i(63) == 5);
785 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
788 static void test_foreach_string(void) {
789 const char * const t[] = {
798 FOREACH_STRING(x, "foo", "bar", "waldo")
799 assert_se(streq_ptr(t[i++], x));
803 FOREACH_STRING(x, "zzz")
804 assert_se(streq(x, "zzz"));
807 static void test_filename_is_safe(void) {
808 char foo[FILENAME_MAX+2];
811 assert_se(!filename_is_safe(""));
812 assert_se(!filename_is_safe("/bar/foo"));
813 assert_se(!filename_is_safe("/"));
814 assert_se(!filename_is_safe("."));
815 assert_se(!filename_is_safe(".."));
817 for (i=0; i<FILENAME_MAX+1; i++)
819 foo[FILENAME_MAX+1] = '\0';
821 assert_se(!filename_is_safe(foo));
823 assert_se(filename_is_safe("foo_bar-333"));
824 assert_se(filename_is_safe("o.o"));
827 static void test_string_has_cc(void) {
828 assert_se(string_has_cc("abc\1", NULL));
829 assert_se(string_has_cc("abc\x7f", NULL));
830 assert_se(string_has_cc("abc\x7f", NULL));
831 assert_se(string_has_cc("abc\t\x7f", "\t"));
832 assert_se(string_has_cc("abc\t\x7f", "\t"));
833 assert_se(string_has_cc("\x7f", "\t"));
834 assert_se(string_has_cc("\x7f", "\t\a"));
836 assert_se(!string_has_cc("abc\t\t", "\t"));
837 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
838 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
841 static void test_ascii_strlower(void) {
842 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
843 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
846 static void test_files_same(void) {
847 _cleanup_close_ int fd = -1;
848 char name[] = "/tmp/test-files_same.XXXXXX";
849 char name_alias[] = "/tmp/test-files_same.alias";
851 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
853 assert_se(symlink(name, name_alias) >= 0);
855 assert_se(files_same(name, name));
856 assert_se(files_same(name, name_alias));
862 static void test_is_valid_documentation_url(void) {
863 assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
864 assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
865 assert_se(is_valid_documentation_url("file:foo"));
866 assert_se(is_valid_documentation_url("man:systemd.special(7)"));
867 assert_se(is_valid_documentation_url("info:bar"));
869 assert_se(!is_valid_documentation_url("foo:"));
870 assert_se(!is_valid_documentation_url("info:"));
871 assert_se(!is_valid_documentation_url(""));
874 static void test_file_in_same_dir(void) {
877 t = file_in_same_dir("/", "a");
878 assert_se(streq(t, "/a"));
881 t = file_in_same_dir("/", "/a");
882 assert_se(streq(t, "/a"));
885 t = file_in_same_dir("", "a");
886 assert_se(streq(t, "a"));
889 t = file_in_same_dir("a/", "a");
890 assert_se(streq(t, "a/a"));
893 t = file_in_same_dir("bar/foo", "bar");
894 assert_se(streq(t, "bar/bar"));
898 static void test_endswith(void) {
899 assert_se(endswith("foobar", "bar"));
900 assert_se(endswith("foobar", ""));
901 assert_se(endswith("foobar", "foobar"));
902 assert_se(endswith("", ""));
904 assert_se(!endswith("foobar", "foo"));
905 assert_se(!endswith("foobar", "foobarfoofoo"));
908 static void test_close_nointr(void) {
909 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
912 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
914 assert_se(close_nointr(fd) >= 0);
915 assert_se(close_nointr(fd) < 0);
921 static void test_unlink_noerrno(void) {
922 char name[] = "/tmp/test-close_nointr.XXXXXX";
925 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
927 assert_se(close_nointr(fd) >= 0);
932 assert_se(unlink_noerrno(name) >= 0);
933 assert_se(errno == -42);
934 assert_se(unlink_noerrno(name) < 0);
935 assert_se(errno == -42);
939 static void test_readlink_and_make_absolute(void) {
940 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
941 char name[] = "/tmp/test-readlink_and_make_absolute/original";
942 char name2[] = "test-readlink_and_make_absolute/original";
943 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
946 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
947 assert_se(touch(name) >= 0);
949 assert_se(symlink(name, name_alias) >= 0);
950 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
951 assert_se(streq(r, name));
953 assert_se(unlink(name_alias) >= 0);
955 assert_se(chdir(tempdir) >= 0);
956 assert_se(symlink(name2, name_alias) >= 0);
957 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
958 assert_se(streq(r, name));
960 assert_se(unlink(name_alias) >= 0);
962 assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
965 static void test_read_one_char(void) {
966 _cleanup_fclose_ FILE *file = NULL;
969 char name[] = "/tmp/test-read_one_char.XXXXXX";
972 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
974 file = fdopen(fd, "r+");
976 assert_se(fputs("c\n", file) >= 0);
979 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
982 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
985 assert_se(fputs("foobar\n", file) >= 0);
987 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
990 assert_se(fputs("\n", file) >= 0);
992 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
997 static void test_ignore_signals(void) {
998 assert_se(ignore_signals(SIGINT, -1) >= 0);
999 assert_se(kill(getpid(), SIGINT) >= 0);
1000 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1001 assert_se(kill(getpid(), SIGUSR1) >= 0);
1002 assert_se(kill(getpid(), SIGUSR2) >= 0);
1003 assert_se(kill(getpid(), SIGTERM) >= 0);
1004 assert_se(kill(getpid(), SIGPIPE) >= 0);
1005 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1008 static void test_strshorten(void) {
1009 char s[] = "foobar";
1011 assert_se(strlen(strshorten(s, 6)) == 6);
1012 assert_se(strlen(strshorten(s, 12)) == 6);
1013 assert_se(strlen(strshorten(s, 2)) == 2);
1014 assert_se(strlen(strshorten(s, 0)) == 0);
1017 static void test_strappenda(void) {
1020 actual = strappenda("", "foo", "bar");
1021 assert_se(streq(actual, "foobar"));
1023 actual = strappenda("foo", "bar", "baz");
1024 assert_se(streq(actual, "foobarbaz"));
1026 actual = strappenda("foo", "", "bar", "baz");
1027 assert_se(streq(actual, "foobarbaz"));
1030 static void test_is_symlink(void) {
1031 char name[] = "/tmp/test-is_symlink.XXXXXX";
1032 char name_link[] = "/tmp/test-is_symlink.link";
1033 _cleanup_close_ int fd = -1;
1035 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1037 assert_se(symlink(name, name_link) >= 0);
1039 assert_se(is_symlink(name) == 0);
1040 assert_se(is_symlink(name_link) == 1);
1041 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1048 static void test_pid_is_unwaited(void) {
1052 assert_se(pid >= 0);
1054 _exit(EXIT_SUCCESS);
1058 waitpid(pid, &status, 0);
1059 assert_se(!pid_is_unwaited(pid));
1061 assert_se(pid_is_unwaited(getpid()));
1062 assert_se(!pid_is_unwaited(-1));
1065 static void test_pid_is_alive(void) {
1069 assert_se(pid >= 0);
1071 _exit(EXIT_SUCCESS);
1075 waitpid(pid, &status, 0);
1076 assert_se(!pid_is_alive(pid));
1078 assert_se(pid_is_alive(getpid()));
1079 assert_se(!pid_is_alive(-1));
1082 static void test_search_and_fopen(void) {
1083 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1084 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1089 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1093 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1097 r = search_and_fopen(name, "r", NULL, dirs, &f);
1101 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1105 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1107 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1113 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1118 static void test_search_and_fopen_nulstr(void) {
1119 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1120 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1125 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1129 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1133 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1137 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1139 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1145 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1149 static void test_glob_exists(void) {
1150 char name[] = "/tmp/test-glob_exists.XXXXXX";
1154 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1158 r = glob_exists("/tmp/test-glob_exists*");
1163 r = glob_exists("/tmp/test-glob_exists*");
1167 static void test_execute_directory(void) {
1168 char name[] = "/tmp/test-execute_directory/script1";
1169 char name2[] = "/tmp/test-execute_directory/script2";
1170 char name3[] = "/tmp/test-execute_directory/useless";
1171 char tempdir[] = "/tmp/test-execute_directory/";
1173 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1174 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1175 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1176 assert_se(chmod(name, 0755) == 0);
1177 assert_se(chmod(name2, 0755) == 0);
1178 assert_se(touch(name3) >= 0);
1180 execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
1181 assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1182 assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1184 rm_rf_dangerous(tempdir, false, true, false);
1187 static void test_unquote_first_word(void) {
1188 const char *p, *original;
1191 p = original = "foobar waldo";
1192 assert_se(unquote_first_word(&p, &t, false) > 0);
1193 assert_se(streq(t, "foobar"));
1195 assert_se(p == original + 7);
1197 assert_se(unquote_first_word(&p, &t, false) > 0);
1198 assert_se(streq(t, "waldo"));
1200 assert_se(p == original + 12);
1202 assert_se(unquote_first_word(&p, &t, false) == 0);
1204 assert_se(p == original + 12);
1206 p = original = "\"foobar\" \'waldo\'";
1207 assert_se(unquote_first_word(&p, &t, false) > 0);
1208 assert_se(streq(t, "foobar"));
1210 assert_se(p == original + 9);
1212 assert_se(unquote_first_word(&p, &t, false) > 0);
1213 assert_se(streq(t, "waldo"));
1215 assert_se(p == original + 16);
1217 assert_se(unquote_first_word(&p, &t, false) == 0);
1219 assert_se(p == original + 16);
1221 p = original = "\"";
1222 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1223 assert_se(p == original + 1);
1225 p = original = "\'";
1226 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1227 assert_se(p == original + 1);
1229 p = original = "\'fooo";
1230 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1231 assert_se(p == original + 5);
1233 p = original = "\'fooo";
1234 assert_se(unquote_first_word(&p, &t, true) > 0);
1235 assert_se(streq(t, "fooo"));
1237 assert_se(p == original + 5);
1239 p = original = "yay\'foo\'bar";
1240 assert_se(unquote_first_word(&p, &t, false) > 0);
1241 assert_se(streq(t, "yayfoobar"));
1243 assert_se(p == original + 11);
1245 p = original = " foobar ";
1246 assert_se(unquote_first_word(&p, &t, false) > 0);
1247 assert_se(streq(t, "foobar"));
1249 assert_se(p == original + 12);
1252 static void test_unquote_many_words(void) {
1253 const char *p, *original;
1256 p = original = "foobar waldi piep";
1257 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1258 assert_se(p == original + 17);
1259 assert_se(streq_ptr(a, "foobar"));
1260 assert_se(streq_ptr(b, "waldi"));
1261 assert_se(streq_ptr(c, "piep"));
1266 p = original = "'foobar' wa\"ld\"i ";
1267 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1268 assert_se(p == original + 19);
1269 assert_se(streq_ptr(a, "foobar"));
1270 assert_se(streq_ptr(b, "waldi"));
1271 assert_se(streq_ptr(c, NULL));
1276 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1277 assert_se(p == original);
1278 assert_se(streq_ptr(a, NULL));
1279 assert_se(streq_ptr(b, NULL));
1280 assert_se(streq_ptr(c, NULL));
1283 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1284 assert_se(p == original+2);
1285 assert_se(streq_ptr(a, NULL));
1286 assert_se(streq_ptr(b, NULL));
1287 assert_se(streq_ptr(c, NULL));
1289 p = original = "foobar";
1290 assert_se(unquote_many_words(&p, NULL) == 0);
1291 assert_se(p == original);
1293 p = original = "foobar waldi";
1294 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1295 assert_se(p == original+7);
1296 assert_se(streq_ptr(a, "foobar"));
1299 p = original = " foobar ";
1300 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1301 assert_se(p == original+15);
1302 assert_se(streq_ptr(a, "foobar"));
1306 static int parse_item(const char *key, const char *value) {
1309 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1313 static void test_parse_proc_cmdline(void) {
1314 assert_se(parse_proc_cmdline(parse_item) >= 0);
1317 int main(int argc, char *argv[]) {
1318 log_parse_environment();
1322 test_align_power2();
1324 test_container_of();
1328 test_parse_boolean();
1335 test_delete_chars();
1345 test_foreach_word();
1346 test_foreach_word_quoted();
1347 test_default_term_for_tty();
1348 test_memdup_multiply();
1349 test_hostname_is_valid();
1351 test_get_process_comm();
1352 test_protect_errno();
1354 test_config_parse_iec_off();
1358 test_fstab_node_to_udev_node();
1359 test_get_files_in_directory();
1361 test_writing_tmpfile();
1364 test_foreach_string();
1365 test_filename_is_safe();
1366 test_string_has_cc();
1367 test_ascii_strlower();
1369 test_is_valid_documentation_url();
1370 test_file_in_same_dir();
1372 test_close_nointr();
1373 test_unlink_noerrno();
1374 test_readlink_and_make_absolute();
1375 test_read_one_char();
1376 test_ignore_signals();
1380 test_pid_is_unwaited();
1381 test_pid_is_alive();
1382 test_search_and_fopen();
1383 test_search_and_fopen_nulstr();
1385 test_execute_directory();
1386 test_unquote_first_word();
1387 test_unquote_many_words();
1388 test_parse_proc_cmdline();