]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-util.c
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/>.
38 #include "conf-parser.h"
41 static void test_streq_ptr(void) {
42 assert_se(streq_ptr(NULL
, NULL
));
43 assert_se(!streq_ptr("abc", "cdef"));
46 static void test_align_power2(void) {
49 assert_se(ALIGN_POWER2(0) == 0);
50 assert_se(ALIGN_POWER2(1) == 1);
51 assert_se(ALIGN_POWER2(2) == 2);
52 assert_se(ALIGN_POWER2(3) == 4);
53 assert_se(ALIGN_POWER2(12) == 16);
55 assert_se(ALIGN_POWER2(ULONG_MAX
) == 0);
56 assert_se(ALIGN_POWER2(ULONG_MAX
- 1) == 0);
57 assert_se(ALIGN_POWER2(ULONG_MAX
- 1024) == 0);
58 assert_se(ALIGN_POWER2(ULONG_MAX
/ 2) == ULONG_MAX
/ 2 + 1);
59 assert_se(ALIGN_POWER2(ULONG_MAX
+ 1) == 0);
61 for (i
= 1; i
< 131071; ++i
) {
62 for (p2
= 1; p2
< i
; p2
<<= 1)
65 assert_se(ALIGN_POWER2(i
) == p2
);
68 for (i
= ULONG_MAX
- 1024; i
< ULONG_MAX
; ++i
) {
69 for (p2
= 1; p2
&& p2
< i
; p2
<<= 1)
72 assert_se(ALIGN_POWER2(i
) == p2
);
76 static void test_max(void) {
79 int b
[CONST_MAX(10, 100)];
81 .a
= CONST_MAX(10, 100),
85 assert_cc(sizeof(val1
.b
) == sizeof(int) * 100);
87 /* CONST_MAX returns (void) instead of a value if the passed arguments
88 * are not of the same type or not constant expressions. */
89 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
90 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
92 assert_se(val1
.a
== 100);
93 assert_se(MAX(++d
, 0) == 1);
96 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
97 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
98 assert_cc(MAXSIZE(char, long) == sizeof(long));
100 assert_se(MAX(-5, 5) == 5);
101 assert_se(MAX(5, 5) == 5);
102 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
103 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
104 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
105 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
106 assert_se(LESS_BY(8, 4) == 4);
107 assert_se(LESS_BY(8, 8) == 0);
108 assert_se(LESS_BY(4, 8) == 0);
109 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
110 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
111 assert_se(CLAMP(-5, 0, 1) == 0);
112 assert_se(CLAMP(5, 0, 1) == 1);
113 assert_se(CLAMP(5, -10, 1) == 1);
114 assert_se(CLAMP(5, -10, 10) == 5);
115 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
118 static void test_container_of(void) {
124 } _packed_ myval
= { };
126 assert_cc(sizeof(myval
) == 17);
127 assert_se(container_of(&myval
.v1
, struct mytype
, v1
) == &myval
);
128 assert_se(container_of(&myval
.v2
, struct mytype
, v2
) == &myval
);
129 assert_se(container_of(&container_of(&myval
.v2
,
136 static void test_alloca(void) {
137 static const uint8_t zero
[997] = { };
140 t
= alloca_align(17, 512);
141 assert_se(!((uintptr_t)t
& 0xff));
144 t
= alloca0_align(997, 1024);
145 assert_se(!((uintptr_t)t
& 0x1ff));
146 assert_se(!memcmp(t
, zero
, 997));
149 static void test_div_round_up(void) {
153 assert_se(DIV_ROUND_UP(0, 8) == 0);
154 assert_se(DIV_ROUND_UP(1, 8) == 1);
155 assert_se(DIV_ROUND_UP(8, 8) == 1);
156 assert_se(DIV_ROUND_UP(12, 8) == 2);
157 assert_se(DIV_ROUND_UP(16, 8) == 2);
159 /* test multiple evaluation */
161 assert_se(DIV_ROUND_UP(div
++, 8) == 0 && div
== 1);
162 assert_se(DIV_ROUND_UP(++div
, 8) == 1 && div
== 2);
163 assert_se(DIV_ROUND_UP(8, div
++) == 4 && div
== 3);
164 assert_se(DIV_ROUND_UP(8, ++div
) == 2 && div
== 4);
166 /* overflow test with exact division */
167 assert_se(sizeof(0U) == 4);
168 assert_se(0xfffffffaU
% 10U == 0U);
169 assert_se(0xfffffffaU
/ 10U == 429496729U);
170 assert_se(DIV_ROUND_UP(0xfffffffaU
, 10U) == 429496729U);
171 assert_se((0xfffffffaU
+ 10U - 1U) / 10U == 0U);
172 assert_se(0xfffffffaU
/ 10U + !!(0xfffffffaU
% 10U) == 429496729U);
174 /* overflow test with rounded division */
175 assert_se(0xfffffffdU
% 10U == 3U);
176 assert_se(0xfffffffdU
/ 10U == 429496729U);
177 assert_se(DIV_ROUND_UP(0xfffffffdU
, 10U) == 429496730U);
178 assert_se((0xfffffffdU
+ 10U - 1U) / 10U == 0U);
179 assert_se(0xfffffffdU
/ 10U + !!(0xfffffffdU
% 10U) == 429496730U);
182 static void test_first_word(void) {
183 assert_se(first_word("Hello", ""));
184 assert_se(first_word("Hello", "Hello"));
185 assert_se(first_word("Hello world", "Hello"));
186 assert_se(first_word("Hello\tworld", "Hello"));
187 assert_se(first_word("Hello\nworld", "Hello"));
188 assert_se(first_word("Hello\rworld", "Hello"));
189 assert_se(first_word("Hello ", "Hello"));
191 assert_se(!first_word("Hello", "Hellooo"));
192 assert_se(!first_word("Hello", "xxxxx"));
193 assert_se(!first_word("Hellooo", "Hello"));
196 static void test_close_many(void) {
198 char name0
[] = "/tmp/test-close-many.XXXXXX";
199 char name1
[] = "/tmp/test-close-many.XXXXXX";
200 char name2
[] = "/tmp/test-close-many.XXXXXX";
202 fds
[0] = mkostemp_safe(name0
, O_RDWR
|O_CLOEXEC
);
203 fds
[1] = mkostemp_safe(name1
, O_RDWR
|O_CLOEXEC
);
204 fds
[2] = mkostemp_safe(name2
, O_RDWR
|O_CLOEXEC
);
208 assert_se(fcntl(fds
[0], F_GETFD
) == -1);
209 assert_se(fcntl(fds
[1], F_GETFD
) == -1);
210 assert_se(fcntl(fds
[2], F_GETFD
) >= 0);
219 static void test_parse_boolean(void) {
220 assert_se(parse_boolean("1") == 1);
221 assert_se(parse_boolean("y") == 1);
222 assert_se(parse_boolean("Y") == 1);
223 assert_se(parse_boolean("yes") == 1);
224 assert_se(parse_boolean("YES") == 1);
225 assert_se(parse_boolean("true") == 1);
226 assert_se(parse_boolean("TRUE") == 1);
227 assert_se(parse_boolean("on") == 1);
228 assert_se(parse_boolean("ON") == 1);
230 assert_se(parse_boolean("0") == 0);
231 assert_se(parse_boolean("n") == 0);
232 assert_se(parse_boolean("N") == 0);
233 assert_se(parse_boolean("no") == 0);
234 assert_se(parse_boolean("NO") == 0);
235 assert_se(parse_boolean("false") == 0);
236 assert_se(parse_boolean("FALSE") == 0);
237 assert_se(parse_boolean("off") == 0);
238 assert_se(parse_boolean("OFF") == 0);
240 assert_se(parse_boolean("garbage") < 0);
241 assert_se(parse_boolean("") < 0);
242 assert_se(parse_boolean("full") < 0);
245 static void test_parse_pid(void) {
249 r
= parse_pid("100", &pid
);
251 assert_se(pid
== 100);
253 r
= parse_pid("0x7FFFFFFF", &pid
);
255 assert_se(pid
== 2147483647);
257 pid
= 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
258 r
= parse_pid("0", &pid
);
259 assert_se(r
== -ERANGE
);
260 assert_se(pid
== 65);
262 pid
= 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
263 r
= parse_pid("-100", &pid
);
264 assert_se(r
== -ERANGE
);
265 assert_se(pid
== 65);
267 pid
= 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
268 r
= parse_pid("0xFFFFFFFFFFFFFFFFF", &pid
);
269 assert_se(r
== -ERANGE
);
270 assert_se(pid
== 65);
273 static void test_parse_uid(void) {
277 r
= parse_uid("100", &uid
);
279 assert_se(uid
== 100);
282 static void test_safe_atolli(void) {
286 r
= safe_atolli("12345", &l
);
288 assert_se(l
== 12345);
290 r
= safe_atolli("junk", &l
);
291 assert_se(r
== -EINVAL
);
294 static void test_safe_atod(void) {
299 r
= safe_atod("junk", &d
);
300 assert_se(r
== -EINVAL
);
302 r
= safe_atod("0.2244", &d
);
304 assert_se(fabs(d
- 0.2244) < 0.000001);
306 r
= safe_atod("0,5", &d
);
307 assert_se(r
== -EINVAL
);
311 assert_se(*e
== ',');
313 /* Check if this really is locale independent */
314 if (setlocale(LC_NUMERIC
, "de_DE.utf8")) {
316 r
= safe_atod("0.2244", &d
);
318 assert_se(fabs(d
- 0.2244) < 0.000001);
320 r
= safe_atod("0,5", &d
);
321 assert_se(r
== -EINVAL
);
324 assert_se(fabs(strtod("0,5", &e
) - 0.5) < 0.00001);
327 /* And check again, reset */
328 assert_se(setlocale(LC_NUMERIC
, "C"));
330 r
= safe_atod("0.2244", &d
);
332 assert_se(fabs(d
- 0.2244) < 0.000001);
334 r
= safe_atod("0,5", &d
);
335 assert_se(r
== -EINVAL
);
339 assert_se(*e
== ',');
342 static void test_strappend(void) {
343 _cleanup_free_
char *t1
, *t2
, *t3
, *t4
;
345 t1
= strappend(NULL
, NULL
);
346 assert_se(streq(t1
, ""));
348 t2
= strappend(NULL
, "suf");
349 assert_se(streq(t2
, "suf"));
351 t3
= strappend("pre", NULL
);
352 assert_se(streq(t3
, "pre"));
354 t4
= strappend("pre", "suf");
355 assert_se(streq(t4
, "presuf"));
358 static void test_strstrip(void) {
360 char input
[] = " hello, waldo. ";
363 assert_se(streq(r
, "hello, waldo."));
366 static void test_delete_chars(void) {
368 char input
[] = " hello, waldo. abc";
370 r
= delete_chars(input
, WHITESPACE
);
371 assert_se(streq(r
, "hello,waldo.abc"));
374 static void test_in_charset(void) {
375 assert_se(in_charset("dddaaabbbcccc", "abcd"));
376 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
379 static void test_hexchar(void) {
380 assert_se(hexchar(0xa) == 'a');
381 assert_se(hexchar(0x0) == '0');
384 static void test_unhexchar(void) {
385 assert_se(unhexchar('a') == 0xA);
386 assert_se(unhexchar('A') == 0xA);
387 assert_se(unhexchar('0') == 0x0);
390 static void test_octchar(void) {
391 assert_se(octchar(00) == '0');
392 assert_se(octchar(07) == '7');
395 static void test_unoctchar(void) {
396 assert_se(unoctchar('0') == 00);
397 assert_se(unoctchar('7') == 07);
400 static void test_decchar(void) {
401 assert_se(decchar(0) == '0');
402 assert_se(decchar(9) == '9');
405 static void test_undecchar(void) {
406 assert_se(undecchar('0') == 0);
407 assert_se(undecchar('9') == 9);
410 static void test_cescape(void) {
411 _cleanup_free_
char *escaped
;
413 assert_se(escaped
= cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
414 assert_se(streq(escaped
, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
417 static void test_cunescape(void) {
418 _cleanup_free_
char *unescaped
;
420 unescaped
= cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00");
421 assert_se(streq_ptr(unescaped
, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
423 /* incomplete sequences */
424 unescaped
= cunescape("\\x0");
425 assert_se(streq_ptr(unescaped
, "\\x0"));
427 unescaped
= cunescape("\\x");
428 assert_se(streq_ptr(unescaped
, "\\x"));
430 unescaped
= cunescape("\\");
431 assert_se(streq_ptr(unescaped
, "\\"));
433 unescaped
= cunescape("\\11");
434 assert_se(streq_ptr(unescaped
, "\\11"));
436 unescaped
= cunescape("\\1");
437 assert_se(streq_ptr(unescaped
, "\\1"));
440 static void test_foreach_word(void) {
441 const char *word
, *state
;
444 const char test
[] = "test abc d\te f ";
445 const char * const expected
[] = {
455 FOREACH_WORD(word
, l
, test
, state
)
456 assert_se(strneq(expected
[i
++], word
, l
));
459 static void check(const char *test
, char** expected
, bool trailing
) {
460 const char *word
, *state
;
464 printf("<<<%s>>>\n", test
);
465 FOREACH_WORD_QUOTED(word
, l
, test
, state
) {
466 _cleanup_free_
char *t
= NULL
;
468 assert_se(t
= strndup(word
, l
));
469 assert_se(strneq(expected
[i
++], word
, l
));
472 printf("<<<%s>>>\n", state
);
473 assert_se(expected
[i
] == NULL
);
474 assert_se(isempty(state
) == !trailing
);
477 static void test_foreach_word_quoted(void) {
478 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
502 static void test_default_term_for_tty(void) {
503 puts(default_term_for_tty("/dev/tty23"));
504 puts(default_term_for_tty("/dev/ttyS23"));
505 puts(default_term_for_tty("/dev/tty0"));
506 puts(default_term_for_tty("/dev/pty0"));
507 puts(default_term_for_tty("/dev/pts/0"));
508 puts(default_term_for_tty("/dev/console"));
509 puts(default_term_for_tty("tty23"));
510 puts(default_term_for_tty("ttyS23"));
511 puts(default_term_for_tty("tty0"));
512 puts(default_term_for_tty("pty0"));
513 puts(default_term_for_tty("pts/0"));
514 puts(default_term_for_tty("console"));
517 static void test_memdup_multiply(void) {
518 int org
[] = {1, 2, 3};
521 dup
= (int*)memdup_multiply(org
, sizeof(int), 3);
524 assert_se(dup
[0] == 1);
525 assert_se(dup
[1] == 2);
526 assert_se(dup
[2] == 3);
530 static void test_hostname_is_valid(void) {
531 assert_se(hostname_is_valid("foobar"));
532 assert_se(hostname_is_valid("foobar.com"));
533 assert_se(!hostname_is_valid("fööbar"));
534 assert_se(!hostname_is_valid(""));
535 assert_se(!hostname_is_valid("."));
536 assert_se(!hostname_is_valid(".."));
537 assert_se(!hostname_is_valid("foobar."));
538 assert_se(!hostname_is_valid(".foobar"));
539 assert_se(!hostname_is_valid("foo..bar"));
540 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
543 static void test_u64log2(void) {
544 assert_se(u64log2(0) == 0);
545 assert_se(u64log2(8) == 3);
546 assert_se(u64log2(9) == 3);
547 assert_se(u64log2(15) == 3);
548 assert_se(u64log2(16) == 4);
549 assert_se(u64log2(1024*1024) == 20);
550 assert_se(u64log2(1024*1024+5) == 20);
553 static void test_get_process_comm(void) {
555 _cleanup_free_
char *a
= NULL
, *c
= NULL
, *d
= NULL
, *f
= NULL
, *i
= NULL
, *cwd
= NULL
, *root
= NULL
;
556 _cleanup_free_
char *env
= NULL
;
564 if (stat("/proc/1/comm", &st
) == 0) {
565 assert_se(get_process_comm(1, &a
) >= 0);
566 log_info("pid1 comm: '%s'", a
);
568 log_warning("/proc/1/comm does not exist.");
571 assert_se(get_process_cmdline(1, 0, true, &c
) >= 0);
572 log_info("pid1 cmdline: '%s'", c
);
574 assert_se(get_process_cmdline(1, 8, false, &d
) >= 0);
575 log_info("pid1 cmdline truncated: '%s'", d
);
577 assert_se(get_parent_of_pid(1, &e
) >= 0);
578 log_info("pid1 ppid: "PID_FMT
, e
);
581 assert_se(is_kernel_thread(1) == 0);
583 r
= get_process_exe(1, &f
);
584 assert_se(r
>= 0 || r
== -EACCES
);
585 log_info("pid1 exe: '%s'", strna(f
));
587 assert_se(get_process_uid(1, &u
) == 0);
588 log_info("pid1 uid: "UID_FMT
, u
);
591 assert_se(get_process_gid(1, &g
) == 0);
592 log_info("pid1 gid: "GID_FMT
, g
);
597 r
= get_process_cwd(me
, &cwd
);
598 assert_se(r
>= 0 || r
== -EACCES
);
599 log_info("pid1 cwd: '%s'", cwd
);
601 r
= get_process_root(me
, &root
);
602 assert_se(r
>= 0 || r
== -EACCES
);
603 log_info("pid1 root: '%s'", root
);
605 r
= get_process_environ(me
, &env
);
606 assert_se(r
>= 0 || r
== -EACCES
);
607 log_info("self strlen(environ): '%zu'", strlen(env
));
609 if (!detect_container(NULL
))
610 assert_se(get_ctty_devnr(1, &h
) == -ENOENT
);
612 getenv_for_pid(1, "PATH", &i
);
613 log_info("pid1 $PATH: '%s'", strna(i
));
616 static void test_protect_errno(void) {
622 assert_se(errno
== 12);
625 static void test_parse_size(void) {
628 assert_se(parse_size("111", 1024, &bytes
) == 0);
629 assert_se(bytes
== 111);
631 assert_se(parse_size("111.4", 1024, &bytes
) == 0);
632 assert_se(bytes
== 111);
634 assert_se(parse_size(" 112 B", 1024, &bytes
) == 0);
635 assert_se(bytes
== 112);
637 assert_se(parse_size(" 112.6 B", 1024, &bytes
) == 0);
638 assert_se(bytes
== 112);
640 assert_se(parse_size("3.5 K", 1024, &bytes
) == 0);
641 assert_se(bytes
== 3*1024 + 512);
643 assert_se(parse_size("3. K", 1024, &bytes
) == 0);
644 assert_se(bytes
== 3*1024);
646 assert_se(parse_size("3.0 K", 1024, &bytes
) == 0);
647 assert_se(bytes
== 3*1024);
649 assert_se(parse_size("3. 0 K", 1024, &bytes
) == -EINVAL
);
651 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes
) == 0);
652 assert_se(bytes
== 4*1024*1024 + 11 * 1024 + 512);
654 assert_se(parse_size("3B3.5G", 1024, &bytes
) == -EINVAL
);
656 assert_se(parse_size("3.5G3B", 1024, &bytes
) == 0);
657 assert_se(bytes
== 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
659 assert_se(parse_size("3.5G 4B", 1024, &bytes
) == 0);
660 assert_se(bytes
== 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
662 assert_se(parse_size("3B3G4T", 1024, &bytes
) == -EINVAL
);
664 assert_se(parse_size("4T3G3B", 1024, &bytes
) == 0);
665 assert_se(bytes
== (4ULL*1024 + 3)*1024*1024*1024 + 3);
667 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes
) == 0);
668 assert_se(bytes
== (4ULL*1024 + 3)*1024*1024*1024 + 3);
670 assert_se(parse_size("12P", 1024, &bytes
) == 0);
671 assert_se(bytes
== 12ULL * 1024*1024*1024*1024*1024);
673 assert_se(parse_size("12P12P", 1024, &bytes
) == -EINVAL
);
675 assert_se(parse_size("3E 2P", 1024, &bytes
) == 0);
676 assert_se(bytes
== (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
678 assert_se(parse_size("12X", 1024, &bytes
) == -EINVAL
);
680 assert_se(parse_size("12.5X", 1024, &bytes
) == -EINVAL
);
682 assert_se(parse_size("12.5e3", 1024, &bytes
) == -EINVAL
);
684 assert_se(parse_size("1024E", 1024, &bytes
) == -ERANGE
);
685 assert_se(parse_size("-1", 1024, &bytes
) == -ERANGE
);
686 assert_se(parse_size("-1024E", 1024, &bytes
) == -ERANGE
);
688 assert_se(parse_size("-1024P", 1024, &bytes
) == -ERANGE
);
690 assert_se(parse_size("-10B 20K", 1024, &bytes
) == -ERANGE
);
693 static void test_config_parse_iec_off(void) {
695 assert_se(config_parse_iec_off(NULL
, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset
, NULL
) == 0);
696 assert_se(offset
== 4 * 1024 * 1024);
698 assert_se(config_parse_iec_off(NULL
, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset
, NULL
) == 0);
701 static void test_strextend(void) {
702 _cleanup_free_
char *str
= strdup("0123");
703 strextend(&str
, "456", "78", "9", NULL
);
704 assert_se(streq(str
, "0123456789"));
707 static void test_strrep(void) {
708 _cleanup_free_
char *one
, *three
, *zero
;
709 one
= strrep("waldo", 1);
710 three
= strrep("waldo", 3);
711 zero
= strrep("waldo", 0);
713 assert_se(streq(one
, "waldo"));
714 assert_se(streq(three
, "waldowaldowaldo"));
715 assert_se(streq(zero
, ""));
718 static void test_split_pair(void) {
719 _cleanup_free_
char *a
= NULL
, *b
= NULL
;
721 assert_se(split_pair("", "", &a
, &b
) == -EINVAL
);
722 assert_se(split_pair("foo=bar", "", &a
, &b
) == -EINVAL
);
723 assert_se(split_pair("", "=", &a
, &b
) == -EINVAL
);
724 assert_se(split_pair("foo=bar", "=", &a
, &b
) >= 0);
725 assert_se(streq(a
, "foo"));
726 assert_se(streq(b
, "bar"));
729 assert_se(split_pair("==", "==", &a
, &b
) >= 0);
730 assert_se(streq(a
, ""));
731 assert_se(streq(b
, ""));
735 assert_se(split_pair("===", "==", &a
, &b
) >= 0);
736 assert_se(streq(a
, ""));
737 assert_se(streq(b
, "="));
740 static void test_fstab_node_to_udev_node(void) {
743 n
= fstab_node_to_udev_node("LABEL=applé/jack");
745 assert_se(streq(n
, "/dev/disk/by-label/applé\\x2fjack"));
748 n
= fstab_node_to_udev_node("PARTLABEL=pinkié pie");
750 assert_se(streq(n
, "/dev/disk/by-partlabel/pinkié\\x20pie"));
753 n
= fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
755 assert_se(streq(n
, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
758 n
= fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
760 assert_se(streq(n
, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
763 n
= fstab_node_to_udev_node("PONIES=awesome");
765 assert_se(streq(n
, "PONIES=awesome"));
768 n
= fstab_node_to_udev_node("/dev/xda1");
770 assert_se(streq(n
, "/dev/xda1"));
774 static void test_get_files_in_directory(void) {
775 _cleanup_strv_free_
char **l
= NULL
, **t
= NULL
;
777 assert_se(get_files_in_directory("/tmp", &l
) >= 0);
778 assert_se(get_files_in_directory(".", &t
) >= 0);
779 assert_se(get_files_in_directory(".", NULL
) >= 0);
782 static void test_in_set(void) {
783 assert_se(IN_SET(1, 1));
784 assert_se(IN_SET(1, 1, 2, 3, 4));
785 assert_se(IN_SET(2, 1, 2, 3, 4));
786 assert_se(IN_SET(3, 1, 2, 3, 4));
787 assert_se(IN_SET(4, 1, 2, 3, 4));
788 assert_se(!IN_SET(0, 1));
789 assert_se(!IN_SET(0, 1, 2, 3, 4));
792 static void test_writing_tmpfile(void) {
793 char name
[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
794 _cleanup_free_
char *contents
= NULL
;
799 IOVEC_SET_STRING(iov
[0], "abc\n");
800 IOVEC_SET_STRING(iov
[1], ALPHANUMERICAL
"\n");
801 IOVEC_SET_STRING(iov
[2], "");
803 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
804 printf("tmpfile: %s", name
);
806 r
= writev(fd
, iov
, 3);
809 r
= read_full_file(name
, &contents
, &size
);
811 printf("contents: %s", contents
);
812 assert_se(streq(contents
, "abc\n" ALPHANUMERICAL
"\n"));
817 static void test_hexdump(void) {
821 hexdump(stdout
, NULL
, 0);
822 hexdump(stdout
, "", 0);
823 hexdump(stdout
, "", 1);
824 hexdump(stdout
, "x", 1);
825 hexdump(stdout
, "x", 2);
826 hexdump(stdout
, "foobar", 7);
827 hexdump(stdout
, "f\nobar", 7);
828 hexdump(stdout
, "xxxxxxxxxxxxxxxxxxxxyz", 23);
830 for (i
= 0; i
< ELEMENTSOF(data
); i
++)
833 hexdump(stdout
, data
, sizeof(data
));
836 static void test_log2i(void) {
837 assert_se(log2i(1) == 0);
838 assert_se(log2i(2) == 1);
839 assert_se(log2i(3) == 1);
840 assert_se(log2i(4) == 2);
841 assert_se(log2i(32) == 5);
842 assert_se(log2i(33) == 5);
843 assert_se(log2i(63) == 5);
844 assert_se(log2i(INT_MAX
) == sizeof(int)*8-2);
847 static void test_foreach_string(void) {
848 const char * const t
[] = {
857 FOREACH_STRING(x
, "foo", "bar", "waldo")
858 assert_se(streq_ptr(t
[i
++], x
));
862 FOREACH_STRING(x
, "zzz")
863 assert_se(streq(x
, "zzz"));
866 static void test_filename_is_valid(void) {
867 char foo
[FILENAME_MAX
+2];
870 assert_se(!filename_is_valid(""));
871 assert_se(!filename_is_valid("/bar/foo"));
872 assert_se(!filename_is_valid("/"));
873 assert_se(!filename_is_valid("."));
874 assert_se(!filename_is_valid(".."));
876 for (i
=0; i
<FILENAME_MAX
+1; i
++)
878 foo
[FILENAME_MAX
+1] = '\0';
880 assert_se(!filename_is_valid(foo
));
882 assert_se(filename_is_valid("foo_bar-333"));
883 assert_se(filename_is_valid("o.o"));
886 static void test_string_has_cc(void) {
887 assert_se(string_has_cc("abc\1", NULL
));
888 assert_se(string_has_cc("abc\x7f", NULL
));
889 assert_se(string_has_cc("abc\x7f", NULL
));
890 assert_se(string_has_cc("abc\t\x7f", "\t"));
891 assert_se(string_has_cc("abc\t\x7f", "\t"));
892 assert_se(string_has_cc("\x7f", "\t"));
893 assert_se(string_has_cc("\x7f", "\t\a"));
895 assert_se(!string_has_cc("abc\t\t", "\t"));
896 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
897 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
900 static void test_ascii_strlower(void) {
901 char a
[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
902 assert_se(streq(ascii_strlower(a
), "aabbcc jk ii od lkjjj kkd lk"));
905 static void test_files_same(void) {
906 _cleanup_close_
int fd
= -1;
907 char name
[] = "/tmp/test-files_same.XXXXXX";
908 char name_alias
[] = "/tmp/test-files_same.alias";
910 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
912 assert_se(symlink(name
, name_alias
) >= 0);
914 assert_se(files_same(name
, name
));
915 assert_se(files_same(name
, name_alias
));
921 static void test_is_valid_documentation_url(void) {
922 assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
923 assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
924 assert_se(documentation_url_is_valid("file:/foo/foo"));
925 assert_se(documentation_url_is_valid("man:systemd.special(7)"));
926 assert_se(documentation_url_is_valid("info:bar"));
928 assert_se(!documentation_url_is_valid("foo:"));
929 assert_se(!documentation_url_is_valid("info:"));
930 assert_se(!documentation_url_is_valid(""));
933 static void test_file_in_same_dir(void) {
936 t
= file_in_same_dir("/", "a");
937 assert_se(streq(t
, "/a"));
940 t
= file_in_same_dir("/", "/a");
941 assert_se(streq(t
, "/a"));
944 t
= file_in_same_dir("", "a");
945 assert_se(streq(t
, "a"));
948 t
= file_in_same_dir("a/", "a");
949 assert_se(streq(t
, "a/a"));
952 t
= file_in_same_dir("bar/foo", "bar");
953 assert_se(streq(t
, "bar/bar"));
957 static void test_endswith(void) {
958 assert_se(endswith("foobar", "bar"));
959 assert_se(endswith("foobar", ""));
960 assert_se(endswith("foobar", "foobar"));
961 assert_se(endswith("", ""));
963 assert_se(!endswith("foobar", "foo"));
964 assert_se(!endswith("foobar", "foobarfoofoo"));
967 static void test_close_nointr(void) {
968 char name
[] = "/tmp/test-test-close_nointr.XXXXXX";
971 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
973 assert_se(close_nointr(fd
) >= 0);
974 assert_se(close_nointr(fd
) < 0);
980 static void test_unlink_noerrno(void) {
981 char name
[] = "/tmp/test-close_nointr.XXXXXX";
984 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
986 assert_se(close_nointr(fd
) >= 0);
991 assert_se(unlink_noerrno(name
) >= 0);
992 assert_se(errno
== -42);
993 assert_se(unlink_noerrno(name
) < 0);
994 assert_se(errno
== -42);
998 static void test_readlink_and_make_absolute(void) {
999 char tempdir
[] = "/tmp/test-readlink_and_make_absolute";
1000 char name
[] = "/tmp/test-readlink_and_make_absolute/original";
1001 char name2
[] = "test-readlink_and_make_absolute/original";
1002 char name_alias
[] = "/tmp/test-readlink_and_make_absolute-alias";
1005 assert_se(mkdir_safe(tempdir
, 0755, getuid(), getgid()) >= 0);
1006 assert_se(touch(name
) >= 0);
1008 assert_se(symlink(name
, name_alias
) >= 0);
1009 assert_se(readlink_and_make_absolute(name_alias
, &r
) >= 0);
1010 assert_se(streq(r
, name
));
1012 assert_se(unlink(name_alias
) >= 0);
1014 assert_se(chdir(tempdir
) >= 0);
1015 assert_se(symlink(name2
, name_alias
) >= 0);
1016 assert_se(readlink_and_make_absolute(name_alias
, &r
) >= 0);
1017 assert_se(streq(r
, name
));
1019 assert_se(unlink(name_alias
) >= 0);
1021 assert_se(rm_rf(tempdir
, REMOVE_ROOT
|REMOVE_PHYSICAL
) >= 0);
1024 static void test_read_one_char(void) {
1025 _cleanup_fclose_
FILE *file
= NULL
;
1028 char name
[] = "/tmp/test-read_one_char.XXXXXX";
1031 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1033 file
= fdopen(fd
, "r+");
1035 assert_se(fputs("c\n", file
) >= 0);
1038 assert_se(read_one_char(file
, &r
, 1000000, &need_nl
) >= 0);
1039 assert_se(!need_nl
);
1040 assert_se(r
== 'c');
1041 assert_se(read_one_char(file
, &r
, 1000000, &need_nl
) < 0);
1044 assert_se(fputs("foobar\n", file
) >= 0);
1046 assert_se(read_one_char(file
, &r
, 1000000, &need_nl
) < 0);
1049 assert_se(fputs("\n", file
) >= 0);
1051 assert_se(read_one_char(file
, &r
, 1000000, &need_nl
) < 0);
1056 static void test_ignore_signals(void) {
1057 assert_se(ignore_signals(SIGINT
, -1) >= 0);
1058 assert_se(kill(getpid(), SIGINT
) >= 0);
1059 assert_se(ignore_signals(SIGUSR1
, SIGUSR2
, SIGTERM
, SIGPIPE
, -1) >= 0);
1060 assert_se(kill(getpid(), SIGUSR1
) >= 0);
1061 assert_se(kill(getpid(), SIGUSR2
) >= 0);
1062 assert_se(kill(getpid(), SIGTERM
) >= 0);
1063 assert_se(kill(getpid(), SIGPIPE
) >= 0);
1064 assert_se(default_signals(SIGINT
, SIGUSR1
, SIGUSR2
, SIGTERM
, SIGPIPE
, -1) >= 0);
1067 static void test_strshorten(void) {
1068 char s
[] = "foobar";
1070 assert_se(strlen(strshorten(s
, 6)) == 6);
1071 assert_se(strlen(strshorten(s
, 12)) == 6);
1072 assert_se(strlen(strshorten(s
, 2)) == 2);
1073 assert_se(strlen(strshorten(s
, 0)) == 0);
1076 static void test_strjoina(void) {
1079 actual
= strjoina("", "foo", "bar");
1080 assert_se(streq(actual
, "foobar"));
1082 actual
= strjoina("foo", "bar", "baz");
1083 assert_se(streq(actual
, "foobarbaz"));
1085 actual
= strjoina("foo", "", "bar", "baz");
1086 assert_se(streq(actual
, "foobarbaz"));
1088 actual
= strjoina("foo");
1089 assert_se(streq(actual
, "foo"));
1091 actual
= strjoina(NULL
);
1092 assert_se(streq(actual
, ""));
1094 actual
= strjoina(NULL
, "foo");
1095 assert_se(streq(actual
, ""));
1097 actual
= strjoina("foo", NULL
, "bar");
1098 assert_se(streq(actual
, "foo"));
1101 static void test_is_symlink(void) {
1102 char name
[] = "/tmp/test-is_symlink.XXXXXX";
1103 char name_link
[] = "/tmp/test-is_symlink.link";
1104 _cleanup_close_
int fd
= -1;
1106 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1108 assert_se(symlink(name
, name_link
) >= 0);
1110 assert_se(is_symlink(name
) == 0);
1111 assert_se(is_symlink(name_link
) == 1);
1112 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1119 static void test_pid_is_unwaited(void) {
1123 assert_se(pid
>= 0);
1125 _exit(EXIT_SUCCESS
);
1129 waitpid(pid
, &status
, 0);
1130 assert_se(!pid_is_unwaited(pid
));
1132 assert_se(pid_is_unwaited(getpid()));
1133 assert_se(!pid_is_unwaited(-1));
1136 static void test_pid_is_alive(void) {
1140 assert_se(pid
>= 0);
1142 _exit(EXIT_SUCCESS
);
1146 waitpid(pid
, &status
, 0);
1147 assert_se(!pid_is_alive(pid
));
1149 assert_se(pid_is_alive(getpid()));
1150 assert_se(!pid_is_alive(-1));
1153 static void test_search_and_fopen(void) {
1154 const char *dirs
[] = {"/tmp/foo/bar", "/tmp", NULL
};
1155 char name
[] = "/tmp/test-search_and_fopen.XXXXXX";
1160 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1164 r
= search_and_fopen(basename(name
), "r", NULL
, dirs
, &f
);
1168 r
= search_and_fopen(name
, "r", NULL
, dirs
, &f
);
1172 r
= search_and_fopen(basename(name
), "r", "/", dirs
, &f
);
1176 r
= search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL
, dirs
, &f
);
1178 r
= search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL
, dirs
, &f
);
1184 r
= search_and_fopen(basename(name
), "r", NULL
, dirs
, &f
);
1189 static void test_search_and_fopen_nulstr(void) {
1190 const char dirs
[] = "/tmp/foo/bar\0/tmp\0";
1191 char name
[] = "/tmp/test-search_and_fopen.XXXXXX";
1196 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1200 r
= search_and_fopen_nulstr(basename(name
), "r", NULL
, dirs
, &f
);
1204 r
= search_and_fopen_nulstr(name
, "r", NULL
, dirs
, &f
);
1208 r
= search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL
, dirs
, &f
);
1210 r
= search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL
, dirs
, &f
);
1216 r
= search_and_fopen_nulstr(basename(name
), "r", NULL
, dirs
, &f
);
1220 static void test_glob_exists(void) {
1221 char name
[] = "/tmp/test-glob_exists.XXXXXX";
1225 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1229 r
= glob_exists("/tmp/test-glob_exists*");
1234 r
= glob_exists("/tmp/test-glob_exists*");
1238 static void test_execute_directory(void) {
1239 char template_lo
[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1240 char template_hi
[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
1241 const char * dirs
[] = {template_hi
, template_lo
, NULL
};
1242 const char *name
, *name2
, *name3
, *overridden
, *override
, *masked
, *mask
;
1244 assert_se(mkdtemp(template_lo
));
1245 assert_se(mkdtemp(template_hi
));
1247 name
= strjoina(template_lo
, "/script");
1248 name2
= strjoina(template_hi
, "/script2");
1249 name3
= strjoina(template_lo
, "/useless");
1250 overridden
= strjoina(template_lo
, "/overridden");
1251 override
= strjoina(template_hi
, "/overridden");
1252 masked
= strjoina(template_lo
, "/masked");
1253 mask
= strjoina(template_hi
, "/masked");
1255 assert_se(write_string_file(name
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works") == 0);
1256 assert_se(write_string_file(name2
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2") == 0);
1257 assert_se(write_string_file(overridden
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1258 assert_se(write_string_file(override
, "#!/bin/sh\necho 'Executing '$0") == 0);
1259 assert_se(write_string_file(masked
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1260 assert_se(symlink("/dev/null", mask
) == 0);
1261 assert_se(chmod(name
, 0755) == 0);
1262 assert_se(chmod(name2
, 0755) == 0);
1263 assert_se(chmod(overridden
, 0755) == 0);
1264 assert_se(chmod(override
, 0755) == 0);
1265 assert_se(chmod(masked
, 0755) == 0);
1266 assert_se(touch(name3
) >= 0);
1268 execute_directories(dirs
, DEFAULT_TIMEOUT_USEC
, NULL
);
1270 assert_se(chdir(template_lo
) == 0);
1271 assert_se(access("it_works", F_OK
) >= 0);
1272 assert_se(access("failed", F_OK
) < 0);
1274 assert_se(chdir(template_hi
) == 0);
1275 assert_se(access("it_works2", F_OK
) >= 0);
1276 assert_se(access("failed", F_OK
) < 0);
1278 (void) rm_rf(template_lo
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
1279 (void) rm_rf(template_hi
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
1282 static void test_unquote_first_word(void) {
1283 const char *p
, *original
;
1286 p
= original
= "foobar waldo";
1287 assert_se(unquote_first_word(&p
, &t
, 0) > 0);
1288 assert_se(streq(t
, "foobar"));
1290 assert_se(p
== original
+ 7);
1292 assert_se(unquote_first_word(&p
, &t
, 0) > 0);
1293 assert_se(streq(t
, "waldo"));
1295 assert_se(p
== original
+ 12);
1297 assert_se(unquote_first_word(&p
, &t
, 0) == 0);
1299 assert_se(p
== original
+ 12);
1301 p
= original
= "\"foobar\" \'waldo\'";
1302 assert_se(unquote_first_word(&p
, &t
, 0) > 0);
1303 assert_se(streq(t
, "foobar"));
1305 assert_se(p
== original
+ 9);
1307 assert_se(unquote_first_word(&p
, &t
, 0) > 0);
1308 assert_se(streq(t
, "waldo"));
1310 assert_se(p
== original
+ 16);
1312 assert_se(unquote_first_word(&p
, &t
, 0) == 0);
1314 assert_se(p
== original
+ 16);
1316 p
= original
= "\"";
1317 assert_se(unquote_first_word(&p
, &t
, 0) == -EINVAL
);
1318 assert_se(p
== original
+ 1);
1320 p
= original
= "\'";
1321 assert_se(unquote_first_word(&p
, &t
, 0) == -EINVAL
);
1322 assert_se(p
== original
+ 1);
1324 p
= original
= "\'fooo";
1325 assert_se(unquote_first_word(&p
, &t
, 0) == -EINVAL
);
1326 assert_se(p
== original
+ 5);
1328 p
= original
= "\'fooo";
1329 assert_se(unquote_first_word(&p
, &t
, UNQUOTE_RELAX
) > 0);
1330 assert_se(streq(t
, "fooo"));
1332 assert_se(p
== original
+ 5);
1334 p
= original
= "yay\'foo\'bar";
1335 assert_se(unquote_first_word(&p
, &t
, 0) > 0);
1336 assert_se(streq(t
, "yayfoobar"));
1338 assert_se(p
== original
+ 11);
1340 p
= original
= " foobar ";
1341 assert_se(unquote_first_word(&p
, &t
, 0) > 0);
1342 assert_se(streq(t
, "foobar"));
1344 assert_se(p
== original
+ 12);
1346 p
= original
= " foo\\ba\\x6ar ";
1347 assert_se(unquote_first_word(&p
, &t
, UNQUOTE_CUNESCAPE
) > 0);
1348 assert_se(streq(t
, "foo\ba\x6ar"));
1350 assert_se(p
== original
+ 13);
1352 p
= original
= " foo\\ba\\x6ar ";
1353 assert_se(unquote_first_word(&p
, &t
, 0) > 0);
1354 assert_se(streq(t
, "foobax6ar"));
1356 assert_se(p
== original
+ 13);
1359 static void test_unquote_many_words(void) {
1360 const char *p
, *original
;
1363 p
= original
= "foobar waldi piep";
1364 assert_se(unquote_many_words(&p
, 0, &a
, &b
, &c
, NULL
) == 3);
1365 assert_se(p
== original
+ 17);
1366 assert_se(streq_ptr(a
, "foobar"));
1367 assert_se(streq_ptr(b
, "waldi"));
1368 assert_se(streq_ptr(c
, "piep"));
1373 p
= original
= "'foobar' wa\"ld\"i ";
1374 assert_se(unquote_many_words(&p
, 0, &a
, &b
, &c
, NULL
) == 2);
1375 assert_se(p
== original
+ 19);
1376 assert_se(streq_ptr(a
, "foobar"));
1377 assert_se(streq_ptr(b
, "waldi"));
1378 assert_se(streq_ptr(c
, NULL
));
1383 assert_se(unquote_many_words(&p
, 0, &a
, &b
, &c
, NULL
) == 0);
1384 assert_se(p
== original
);
1385 assert_se(streq_ptr(a
, NULL
));
1386 assert_se(streq_ptr(b
, NULL
));
1387 assert_se(streq_ptr(c
, NULL
));
1390 assert_se(unquote_many_words(&p
, 0, &a
, &b
, &c
, NULL
) == 0);
1391 assert_se(p
== original
+2);
1392 assert_se(streq_ptr(a
, NULL
));
1393 assert_se(streq_ptr(b
, NULL
));
1394 assert_se(streq_ptr(c
, NULL
));
1396 p
= original
= "foobar";
1397 assert_se(unquote_many_words(&p
, 0, NULL
) == 0);
1398 assert_se(p
== original
);
1400 p
= original
= "foobar waldi";
1401 assert_se(unquote_many_words(&p
, 0, &a
, NULL
) == 1);
1402 assert_se(p
== original
+7);
1403 assert_se(streq_ptr(a
, "foobar"));
1406 p
= original
= " foobar ";
1407 assert_se(unquote_many_words(&p
, 0, &a
, NULL
) == 1);
1408 assert_se(p
== original
+15);
1409 assert_se(streq_ptr(a
, "foobar"));
1413 static int parse_item(const char *key
, const char *value
) {
1416 log_info("kernel cmdline option <%s> = <%s>", key
, strna(value
));
1420 static void test_parse_proc_cmdline(void) {
1421 assert_se(parse_proc_cmdline(parse_item
) >= 0);
1424 static void test_raw_clone(void) {
1425 pid_t parent
, pid
, pid2
;
1428 log_info("before clone: getpid()→"PID_FMT
, parent
);
1429 assert_se(raw_getpid() == parent
);
1431 pid
= raw_clone(0, NULL
);
1432 assert_se(pid
>= 0);
1434 pid2
= raw_getpid();
1435 log_info("raw_clone: "PID_FMT
" getpid()→"PID_FMT
" raw_getpid()→"PID_FMT
,
1436 pid
, getpid(), pid2
);
1438 assert_se(pid2
!= parent
);
1439 _exit(EXIT_SUCCESS
);
1443 assert_se(pid2
== parent
);
1444 waitpid(pid
, &status
, __WCLONE
);
1445 assert_se(WIFEXITED(status
) && WEXITSTATUS(status
) == EXIT_SUCCESS
);
1449 static void test_same_fd(void) {
1450 _cleanup_close_pair_
int p
[2] = { -1, -1 };
1451 _cleanup_close_
int a
= -1, b
= -1, c
= -1;
1453 assert_se(pipe2(p
, O_CLOEXEC
) >= 0);
1454 assert_se((a
= dup(p
[0])) >= 0);
1455 assert_se((b
= open("/dev/null", O_RDONLY
|O_CLOEXEC
)) >= 0);
1456 assert_se((c
= dup(a
)) >= 0);
1458 assert_se(same_fd(p
[0], p
[0]) > 0);
1459 assert_se(same_fd(p
[1], p
[1]) > 0);
1460 assert_se(same_fd(a
, a
) > 0);
1461 assert_se(same_fd(b
, b
) > 0);
1463 assert_se(same_fd(a
, p
[0]) > 0);
1464 assert_se(same_fd(p
[0], a
) > 0);
1465 assert_se(same_fd(c
, p
[0]) > 0);
1466 assert_se(same_fd(p
[0], c
) > 0);
1467 assert_se(same_fd(a
, c
) > 0);
1468 assert_se(same_fd(c
, a
) > 0);
1470 assert_se(same_fd(p
[0], p
[1]) == 0);
1471 assert_se(same_fd(p
[1], p
[0]) == 0);
1472 assert_se(same_fd(p
[0], b
) == 0);
1473 assert_se(same_fd(b
, p
[0]) == 0);
1474 assert_se(same_fd(p
[1], a
) == 0);
1475 assert_se(same_fd(a
, p
[1]) == 0);
1476 assert_se(same_fd(p
[1], b
) == 0);
1477 assert_se(same_fd(b
, p
[1]) == 0);
1479 assert_se(same_fd(a
, b
) == 0);
1480 assert_se(same_fd(b
, a
) == 0);
1483 static void test_uid_ptr(void) {
1485 assert_se(UID_TO_PTR(0) != NULL
);
1486 assert_se(UID_TO_PTR(1000) != NULL
);
1488 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1489 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1492 static void test_sparse_write_one(int fd
, const char *buffer
, size_t n
) {
1495 assert_se(lseek(fd
, 0, SEEK_SET
) == 0);
1496 assert_se(ftruncate(fd
, 0) >= 0);
1497 assert_se(sparse_write(fd
, buffer
, n
, 4) == (ssize_t
) n
);
1499 assert_se(lseek(fd
, 0, SEEK_CUR
) == (off_t
) n
);
1500 assert_se(ftruncate(fd
, n
) >= 0);
1502 assert_se(lseek(fd
, 0, SEEK_SET
) == 0);
1503 assert_se(read(fd
, check
, n
) == (ssize_t
) n
);
1505 assert_se(memcmp(buffer
, check
, n
) == 0);
1508 static void test_sparse_write(void) {
1509 const char test_a
[] = "test";
1510 const char test_b
[] = "\0\0\0\0test\0\0\0\0";
1511 const char test_c
[] = "\0\0test\0\0\0\0";
1512 const char test_d
[] = "\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0test\0\0\0test\0\0\0\0test\0\0\0\0\0\0\0\0";
1513 const char test_e
[] = "test\0\0\0\0test";
1514 _cleanup_close_
int fd
= -1;
1515 char fn
[] = "/tmp/sparseXXXXXX";
1517 fd
= mkostemp(fn
, O_CLOEXEC
);
1521 test_sparse_write_one(fd
, test_a
, sizeof(test_a
));
1522 test_sparse_write_one(fd
, test_b
, sizeof(test_b
));
1523 test_sparse_write_one(fd
, test_c
, sizeof(test_c
));
1524 test_sparse_write_one(fd
, test_d
, sizeof(test_d
));
1525 test_sparse_write_one(fd
, test_e
, sizeof(test_e
));
1528 int main(int argc
, char *argv
[]) {
1529 log_parse_environment();
1533 test_align_power2();
1535 test_container_of();
1537 test_div_round_up();
1540 test_parse_boolean();
1547 test_delete_chars();
1557 test_foreach_word();
1558 test_foreach_word_quoted();
1559 test_default_term_for_tty();
1560 test_memdup_multiply();
1561 test_hostname_is_valid();
1563 test_get_process_comm();
1564 test_protect_errno();
1566 test_config_parse_iec_off();
1570 test_fstab_node_to_udev_node();
1571 test_get_files_in_directory();
1573 test_writing_tmpfile();
1576 test_foreach_string();
1577 test_filename_is_valid();
1578 test_string_has_cc();
1579 test_ascii_strlower();
1581 test_is_valid_documentation_url();
1582 test_file_in_same_dir();
1584 test_close_nointr();
1585 test_unlink_noerrno();
1586 test_readlink_and_make_absolute();
1587 test_read_one_char();
1588 test_ignore_signals();
1592 test_pid_is_unwaited();
1593 test_pid_is_alive();
1594 test_search_and_fopen();
1595 test_search_and_fopen_nulstr();
1597 test_execute_directory();
1598 test_unquote_first_word();
1599 test_unquote_many_words();
1600 test_parse_proc_cmdline();
1604 test_sparse_write();