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/>.
27 #include <sys/types.h>
29 #include <sys/xattr.h>
32 #include "alloc-util.h"
33 #include "conf-parser.h"
34 #include "cpu-set-util.h"
40 #include "fstab-util.h"
41 #include "glob-util.h"
42 #include "hexdecoct.h"
45 #include "parse-util.h"
46 #include "path-util.h"
47 #include "proc-cmdline.h"
48 #include "process-util.h"
50 #include "signal-util.h"
52 #include "stat-util.h"
53 #include "string-util.h"
55 #include "user-util.h"
59 #include "xattr-util.h"
61 static void test_streq_ptr(void) {
62 assert_se(streq_ptr(NULL
, NULL
));
63 assert_se(!streq_ptr("abc", "cdef"));
66 static void test_align_power2(void) {
69 assert_se(ALIGN_POWER2(0) == 0);
70 assert_se(ALIGN_POWER2(1) == 1);
71 assert_se(ALIGN_POWER2(2) == 2);
72 assert_se(ALIGN_POWER2(3) == 4);
73 assert_se(ALIGN_POWER2(12) == 16);
75 assert_se(ALIGN_POWER2(ULONG_MAX
) == 0);
76 assert_se(ALIGN_POWER2(ULONG_MAX
- 1) == 0);
77 assert_se(ALIGN_POWER2(ULONG_MAX
- 1024) == 0);
78 assert_se(ALIGN_POWER2(ULONG_MAX
/ 2) == ULONG_MAX
/ 2 + 1);
79 assert_se(ALIGN_POWER2(ULONG_MAX
+ 1) == 0);
81 for (i
= 1; i
< 131071; ++i
) {
82 for (p2
= 1; p2
< i
; p2
<<= 1)
85 assert_se(ALIGN_POWER2(i
) == p2
);
88 for (i
= ULONG_MAX
- 1024; i
< ULONG_MAX
; ++i
) {
89 for (p2
= 1; p2
&& p2
< i
; p2
<<= 1)
92 assert_se(ALIGN_POWER2(i
) == p2
);
96 static void test_max(void) {
99 int b
[CONST_MAX(10, 100)];
101 .a
= CONST_MAX(10, 100),
105 assert_cc(sizeof(val1
.b
) == sizeof(int) * 100);
107 /* CONST_MAX returns (void) instead of a value if the passed arguments
108 * are not of the same type or not constant expressions. */
109 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
110 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
112 assert_se(val1
.a
== 100);
113 assert_se(MAX(++d
, 0) == 1);
116 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
117 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
118 assert_cc(MAXSIZE(char, long) == sizeof(long));
120 assert_se(MAX(-5, 5) == 5);
121 assert_se(MAX(5, 5) == 5);
122 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
123 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
124 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
125 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
126 assert_se(LESS_BY(8, 4) == 4);
127 assert_se(LESS_BY(8, 8) == 0);
128 assert_se(LESS_BY(4, 8) == 0);
129 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
130 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
131 assert_se(CLAMP(-5, 0, 1) == 0);
132 assert_se(CLAMP(5, 0, 1) == 1);
133 assert_se(CLAMP(5, -10, 1) == 1);
134 assert_se(CLAMP(5, -10, 10) == 5);
135 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
138 static void test_container_of(void) {
144 } _packed_ myval
= { };
146 assert_cc(sizeof(myval
) == 17);
147 assert_se(container_of(&myval
.v1
, struct mytype
, v1
) == &myval
);
148 assert_se(container_of(&myval
.v2
, struct mytype
, v2
) == &myval
);
149 assert_se(container_of(&container_of(&myval
.v2
,
156 static void test_alloca(void) {
157 static const uint8_t zero
[997] = { };
160 t
= alloca_align(17, 512);
161 assert_se(!((uintptr_t)t
& 0xff));
164 t
= alloca0_align(997, 1024);
165 assert_se(!((uintptr_t)t
& 0x1ff));
166 assert_se(!memcmp(t
, zero
, 997));
169 static void test_div_round_up(void) {
173 assert_se(DIV_ROUND_UP(0, 8) == 0);
174 assert_se(DIV_ROUND_UP(1, 8) == 1);
175 assert_se(DIV_ROUND_UP(8, 8) == 1);
176 assert_se(DIV_ROUND_UP(12, 8) == 2);
177 assert_se(DIV_ROUND_UP(16, 8) == 2);
179 /* test multiple evaluation */
181 assert_se(DIV_ROUND_UP(div
++, 8) == 0 && div
== 1);
182 assert_se(DIV_ROUND_UP(++div
, 8) == 1 && div
== 2);
183 assert_se(DIV_ROUND_UP(8, div
++) == 4 && div
== 3);
184 assert_se(DIV_ROUND_UP(8, ++div
) == 2 && div
== 4);
186 /* overflow test with exact division */
187 assert_se(sizeof(0U) == 4);
188 assert_se(0xfffffffaU
% 10U == 0U);
189 assert_se(0xfffffffaU
/ 10U == 429496729U);
190 assert_se(DIV_ROUND_UP(0xfffffffaU
, 10U) == 429496729U);
191 assert_se((0xfffffffaU
+ 10U - 1U) / 10U == 0U);
192 assert_se(0xfffffffaU
/ 10U + !!(0xfffffffaU
% 10U) == 429496729U);
194 /* overflow test with rounded division */
195 assert_se(0xfffffffdU
% 10U == 3U);
196 assert_se(0xfffffffdU
/ 10U == 429496729U);
197 assert_se(DIV_ROUND_UP(0xfffffffdU
, 10U) == 429496730U);
198 assert_se((0xfffffffdU
+ 10U - 1U) / 10U == 0U);
199 assert_se(0xfffffffdU
/ 10U + !!(0xfffffffdU
% 10U) == 429496730U);
202 static void test_first_word(void) {
203 assert_se(first_word("Hello", ""));
204 assert_se(first_word("Hello", "Hello"));
205 assert_se(first_word("Hello world", "Hello"));
206 assert_se(first_word("Hello\tworld", "Hello"));
207 assert_se(first_word("Hello\nworld", "Hello"));
208 assert_se(first_word("Hello\rworld", "Hello"));
209 assert_se(first_word("Hello ", "Hello"));
211 assert_se(!first_word("Hello", "Hellooo"));
212 assert_se(!first_word("Hello", "xxxxx"));
213 assert_se(!first_word("Hellooo", "Hello"));
216 static void test_close_many(void) {
218 char name0
[] = "/tmp/test-close-many.XXXXXX";
219 char name1
[] = "/tmp/test-close-many.XXXXXX";
220 char name2
[] = "/tmp/test-close-many.XXXXXX";
222 fds
[0] = mkostemp_safe(name0
, O_RDWR
|O_CLOEXEC
);
223 fds
[1] = mkostemp_safe(name1
, O_RDWR
|O_CLOEXEC
);
224 fds
[2] = mkostemp_safe(name2
, O_RDWR
|O_CLOEXEC
);
228 assert_se(fcntl(fds
[0], F_GETFD
) == -1);
229 assert_se(fcntl(fds
[1], F_GETFD
) == -1);
230 assert_se(fcntl(fds
[2], F_GETFD
) >= 0);
239 static void test_parse_uid(void) {
243 r
= parse_uid("100", &uid
);
245 assert_se(uid
== 100);
247 r
= parse_uid("65535", &uid
);
248 assert_se(r
== -ENXIO
);
250 r
= parse_uid("asdsdas", &uid
);
251 assert_se(r
== -EINVAL
);
254 static void test_strappend(void) {
255 _cleanup_free_
char *t1
, *t2
, *t3
, *t4
;
257 t1
= strappend(NULL
, NULL
);
258 assert_se(streq(t1
, ""));
260 t2
= strappend(NULL
, "suf");
261 assert_se(streq(t2
, "suf"));
263 t3
= strappend("pre", NULL
);
264 assert_se(streq(t3
, "pre"));
266 t4
= strappend("pre", "suf");
267 assert_se(streq(t4
, "presuf"));
270 static void test_strstrip(void) {
272 char input
[] = " hello, waldo. ";
275 assert_se(streq(r
, "hello, waldo."));
278 static void test_delete_chars(void) {
280 char input
[] = " hello, waldo. abc";
282 r
= delete_chars(input
, WHITESPACE
);
283 assert_se(streq(r
, "hello,waldo.abc"));
286 static void test_in_charset(void) {
287 assert_se(in_charset("dddaaabbbcccc", "abcd"));
288 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
291 static void test_hexchar(void) {
292 assert_se(hexchar(0xa) == 'a');
293 assert_se(hexchar(0x0) == '0');
296 static void test_unhexchar(void) {
297 assert_se(unhexchar('a') == 0xA);
298 assert_se(unhexchar('A') == 0xA);
299 assert_se(unhexchar('0') == 0x0);
302 static void test_base32hexchar(void) {
303 assert_se(base32hexchar(0) == '0');
304 assert_se(base32hexchar(9) == '9');
305 assert_se(base32hexchar(10) == 'A');
306 assert_se(base32hexchar(31) == 'V');
309 static void test_unbase32hexchar(void) {
310 assert_se(unbase32hexchar('0') == 0);
311 assert_se(unbase32hexchar('9') == 9);
312 assert_se(unbase32hexchar('A') == 10);
313 assert_se(unbase32hexchar('V') == 31);
314 assert_se(unbase32hexchar('=') == -EINVAL
);
317 static void test_base64char(void) {
318 assert_se(base64char(0) == 'A');
319 assert_se(base64char(26) == 'a');
320 assert_se(base64char(63) == '/');
323 static void test_unbase64char(void) {
324 assert_se(unbase64char('A') == 0);
325 assert_se(unbase64char('Z') == 25);
326 assert_se(unbase64char('a') == 26);
327 assert_se(unbase64char('z') == 51);
328 assert_se(unbase64char('0') == 52);
329 assert_se(unbase64char('9') == 61);
330 assert_se(unbase64char('+') == 62);
331 assert_se(unbase64char('/') == 63);
332 assert_se(unbase64char('=') == -EINVAL
);
335 static void test_octchar(void) {
336 assert_se(octchar(00) == '0');
337 assert_se(octchar(07) == '7');
340 static void test_unoctchar(void) {
341 assert_se(unoctchar('0') == 00);
342 assert_se(unoctchar('7') == 07);
345 static void test_decchar(void) {
346 assert_se(decchar(0) == '0');
347 assert_se(decchar(9) == '9');
350 static void test_undecchar(void) {
351 assert_se(undecchar('0') == 0);
352 assert_se(undecchar('9') == 9);
355 static void test_unhexmem(void) {
356 const char *hex
= "efa214921";
357 const char *hex_invalid
= "efa214921o";
358 _cleanup_free_
char *hex2
= NULL
;
359 _cleanup_free_
void *mem
= NULL
;
362 assert_se(unhexmem(hex
, strlen(hex
), &mem
, &len
) == 0);
363 assert_se(unhexmem(hex
, strlen(hex
) + 1, &mem
, &len
) == -EINVAL
);
364 assert_se(unhexmem(hex_invalid
, strlen(hex_invalid
), &mem
, &len
) == -EINVAL
);
366 assert_se((hex2
= hexmem(mem
, len
)));
370 assert_se(memcmp(hex
, hex2
, strlen(hex
)) == 0);
374 assert_se(unhexmem(hex
, strlen(hex
) - 1, &mem
, &len
) == 0);
375 assert_se((hex2
= hexmem(mem
, len
)));
376 assert_se(memcmp(hex
, hex2
, strlen(hex
) - 1) == 0);
379 /* https://tools.ietf.org/html/rfc4648#section-10 */
380 static void test_base32hexmem(void) {
383 b32
= base32hexmem("", strlen(""), true);
385 assert_se(streq(b32
, ""));
388 b32
= base32hexmem("f", strlen("f"), true);
390 assert_se(streq(b32
, "CO======"));
393 b32
= base32hexmem("fo", strlen("fo"), true);
395 assert_se(streq(b32
, "CPNG===="));
398 b32
= base32hexmem("foo", strlen("foo"), true);
400 assert_se(streq(b32
, "CPNMU==="));
403 b32
= base32hexmem("foob", strlen("foob"), true);
405 assert_se(streq(b32
, "CPNMUOG="));
408 b32
= base32hexmem("fooba", strlen("fooba"), true);
410 assert_se(streq(b32
, "CPNMUOJ1"));
413 b32
= base32hexmem("foobar", strlen("foobar"), true);
415 assert_se(streq(b32
, "CPNMUOJ1E8======"));
418 b32
= base32hexmem("", strlen(""), false);
420 assert_se(streq(b32
, ""));
423 b32
= base32hexmem("f", strlen("f"), false);
425 assert_se(streq(b32
, "CO"));
428 b32
= base32hexmem("fo", strlen("fo"), false);
430 assert_se(streq(b32
, "CPNG"));
433 b32
= base32hexmem("foo", strlen("foo"), false);
435 assert_se(streq(b32
, "CPNMU"));
438 b32
= base32hexmem("foob", strlen("foob"), false);
440 assert_se(streq(b32
, "CPNMUOG"));
443 b32
= base32hexmem("fooba", strlen("fooba"), false);
445 assert_se(streq(b32
, "CPNMUOJ1"));
448 b32
= base32hexmem("foobar", strlen("foobar"), false);
450 assert_se(streq(b32
, "CPNMUOJ1E8"));
454 static void test_unbase32hexmem(void) {
458 assert_se(unbase32hexmem("", strlen(""), true, &mem
, &len
) == 0);
459 assert_se(streq(strndupa(mem
, len
), ""));
462 assert_se(unbase32hexmem("CO======", strlen("CO======"), true, &mem
, &len
) == 0);
463 assert_se(streq(strndupa(mem
, len
), "f"));
466 assert_se(unbase32hexmem("CPNG====", strlen("CPNG===="), true, &mem
, &len
) == 0);
467 assert_se(streq(strndupa(mem
, len
), "fo"));
470 assert_se(unbase32hexmem("CPNMU===", strlen("CPNMU==="), true, &mem
, &len
) == 0);
471 assert_se(streq(strndupa(mem
, len
), "foo"));
474 assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), true, &mem
, &len
) == 0);
475 assert_se(streq(strndupa(mem
, len
), "foob"));
478 assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == 0);
479 assert_se(streq(strndupa(mem
, len
), "fooba"));
482 assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), true, &mem
, &len
) == 0);
483 assert_se(streq(strndupa(mem
, len
), "foobar"));
486 assert_se(unbase32hexmem("A", strlen("A"), true, &mem
, &len
) == -EINVAL
);
487 assert_se(unbase32hexmem("A=======", strlen("A======="), true, &mem
, &len
) == -EINVAL
);
488 assert_se(unbase32hexmem("AAA=====", strlen("AAA====="), true, &mem
, &len
) == -EINVAL
);
489 assert_se(unbase32hexmem("AAAAAA==", strlen("AAAAAA=="), true, &mem
, &len
) == -EINVAL
);
490 assert_se(unbase32hexmem("AB======", strlen("AB======"), true, &mem
, &len
) == -EINVAL
);
491 assert_se(unbase32hexmem("AAAB====", strlen("AAAB===="), true, &mem
, &len
) == -EINVAL
);
492 assert_se(unbase32hexmem("AAAAB===", strlen("AAAAB==="), true, &mem
, &len
) == -EINVAL
);
493 assert_se(unbase32hexmem("AAAAAAB=", strlen("AAAAAAB="), true, &mem
, &len
) == -EINVAL
);
495 assert_se(unbase32hexmem("XPNMUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
496 assert_se(unbase32hexmem("CXNMUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
497 assert_se(unbase32hexmem("CPXMUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
498 assert_se(unbase32hexmem("CPNXUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
499 assert_se(unbase32hexmem("CPNMXOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
500 assert_se(unbase32hexmem("CPNMUXJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
501 assert_se(unbase32hexmem("CPNMUOX1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
502 assert_se(unbase32hexmem("CPNMUOJX", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
504 assert_se(unbase32hexmem("", strlen(""), false, &mem
, &len
) == 0);
505 assert_se(streq(strndupa(mem
, len
), ""));
508 assert_se(unbase32hexmem("CO", strlen("CO"), false, &mem
, &len
) == 0);
509 assert_se(streq(strndupa(mem
, len
), "f"));
512 assert_se(unbase32hexmem("CPNG", strlen("CPNG"), false, &mem
, &len
) == 0);
513 assert_se(streq(strndupa(mem
, len
), "fo"));
516 assert_se(unbase32hexmem("CPNMU", strlen("CPNMU"), false, &mem
, &len
) == 0);
517 assert_se(streq(strndupa(mem
, len
), "foo"));
520 assert_se(unbase32hexmem("CPNMUOG", strlen("CPNMUOG"), false, &mem
, &len
) == 0);
521 assert_se(streq(strndupa(mem
, len
), "foob"));
524 assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), false, &mem
, &len
) == 0);
525 assert_se(streq(strndupa(mem
, len
), "fooba"));
528 assert_se(unbase32hexmem("CPNMUOJ1E8", strlen("CPNMUOJ1E8"), false, &mem
, &len
) == 0);
529 assert_se(streq(strndupa(mem
, len
), "foobar"));
532 assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), false, &mem
, &len
) == -EINVAL
);
533 assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), false, &mem
, &len
) == -EINVAL
);
534 assert_se(unbase32hexmem("A", strlen("A"), false, &mem
, &len
) == -EINVAL
);
535 assert_se(unbase32hexmem("A", strlen("A"), false, &mem
, &len
) == -EINVAL
);
536 assert_se(unbase32hexmem("AAA", strlen("AAA"), false, &mem
, &len
) == -EINVAL
);
537 assert_se(unbase32hexmem("AAAAAA", strlen("AAAAAA"), false, &mem
, &len
) == -EINVAL
);
538 assert_se(unbase32hexmem("AB", strlen("AB"), false, &mem
, &len
) == -EINVAL
);
539 assert_se(unbase32hexmem("AAAB", strlen("AAAB"), false, &mem
, &len
) == -EINVAL
);
540 assert_se(unbase32hexmem("AAAAB", strlen("AAAAB"), false, &mem
, &len
) == -EINVAL
);
541 assert_se(unbase32hexmem("AAAAAAB", strlen("AAAAAAB"), false, &mem
, &len
) == -EINVAL
);
544 /* https://tools.ietf.org/html/rfc4648#section-10 */
545 static void test_base64mem(void) {
548 b64
= base64mem("", strlen(""));
550 assert_se(streq(b64
, ""));
553 b64
= base64mem("f", strlen("f"));
555 assert_se(streq(b64
, "Zg=="));
558 b64
= base64mem("fo", strlen("fo"));
560 assert_se(streq(b64
, "Zm8="));
563 b64
= base64mem("foo", strlen("foo"));
565 assert_se(streq(b64
, "Zm9v"));
568 b64
= base64mem("foob", strlen("foob"));
570 assert_se(streq(b64
, "Zm9vYg=="));
573 b64
= base64mem("fooba", strlen("fooba"));
575 assert_se(streq(b64
, "Zm9vYmE="));
578 b64
= base64mem("foobar", strlen("foobar"));
580 assert_se(streq(b64
, "Zm9vYmFy"));
584 static void test_unbase64mem(void) {
588 assert_se(unbase64mem("", strlen(""), &mem
, &len
) == 0);
589 assert_se(streq(strndupa(mem
, len
), ""));
592 assert_se(unbase64mem("Zg==", strlen("Zg=="), &mem
, &len
) == 0);
593 assert_se(streq(strndupa(mem
, len
), "f"));
596 assert_se(unbase64mem("Zm8=", strlen("Zm8="), &mem
, &len
) == 0);
597 assert_se(streq(strndupa(mem
, len
), "fo"));
600 assert_se(unbase64mem("Zm9v", strlen("Zm9v"), &mem
, &len
) == 0);
601 assert_se(streq(strndupa(mem
, len
), "foo"));
604 assert_se(unbase64mem("Zm9vYg==", strlen("Zm9vYg=="), &mem
, &len
) == 0);
605 assert_se(streq(strndupa(mem
, len
), "foob"));
608 assert_se(unbase64mem("Zm9vYmE=", strlen("Zm9vYmE="), &mem
, &len
) == 0);
609 assert_se(streq(strndupa(mem
, len
), "fooba"));
612 assert_se(unbase64mem("Zm9vYmFy", strlen("Zm9vYmFy"), &mem
, &len
) == 0);
613 assert_se(streq(strndupa(mem
, len
), "foobar"));
616 assert_se(unbase64mem("A", strlen("A"), &mem
, &len
) == -EINVAL
);
617 assert_se(unbase64mem("A====", strlen("A===="), &mem
, &len
) == -EINVAL
);
618 assert_se(unbase64mem("AAB==", strlen("AAB=="), &mem
, &len
) == -EINVAL
);
619 assert_se(unbase64mem("AAAB=", strlen("AAAB="), &mem
, &len
) == -EINVAL
);
622 static void test_cescape(void) {
623 _cleanup_free_
char *escaped
;
625 assert_se(escaped
= cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
626 assert_se(streq(escaped
, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
629 static void test_cunescape(void) {
630 _cleanup_free_
char *unescaped
;
632 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped
) < 0);
633 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX
, &unescaped
) >= 0);
634 assert_se(streq_ptr(unescaped
, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
635 unescaped
= mfree(unescaped
);
637 /* incomplete sequences */
638 assert_se(cunescape("\\x0", 0, &unescaped
) < 0);
639 assert_se(cunescape("\\x0", UNESCAPE_RELAX
, &unescaped
) >= 0);
640 assert_se(streq_ptr(unescaped
, "\\x0"));
641 unescaped
= mfree(unescaped
);
643 assert_se(cunescape("\\x", 0, &unescaped
) < 0);
644 assert_se(cunescape("\\x", UNESCAPE_RELAX
, &unescaped
) >= 0);
645 assert_se(streq_ptr(unescaped
, "\\x"));
646 unescaped
= mfree(unescaped
);
648 assert_se(cunescape("\\", 0, &unescaped
) < 0);
649 assert_se(cunescape("\\", UNESCAPE_RELAX
, &unescaped
) >= 0);
650 assert_se(streq_ptr(unescaped
, "\\"));
651 unescaped
= mfree(unescaped
);
653 assert_se(cunescape("\\11", 0, &unescaped
) < 0);
654 assert_se(cunescape("\\11", UNESCAPE_RELAX
, &unescaped
) >= 0);
655 assert_se(streq_ptr(unescaped
, "\\11"));
656 unescaped
= mfree(unescaped
);
658 assert_se(cunescape("\\1", 0, &unescaped
) < 0);
659 assert_se(cunescape("\\1", UNESCAPE_RELAX
, &unescaped
) >= 0);
660 assert_se(streq_ptr(unescaped
, "\\1"));
661 unescaped
= mfree(unescaped
);
663 assert_se(cunescape("\\u0000", 0, &unescaped
) < 0);
664 assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX
, &unescaped
) >= 0);
665 assert_se(streq_ptr(unescaped
, "ßßΠA"));
666 unescaped
= mfree(unescaped
);
668 assert_se(cunescape("\\073", 0, &unescaped
) >= 0);
669 assert_se(streq_ptr(unescaped
, ";"));
672 static void test_foreach_word(void) {
673 const char *word
, *state
;
676 const char test
[] = "test abc d\te f ";
677 const char * const expected
[] = {
687 FOREACH_WORD(word
, l
, test
, state
)
688 assert_se(strneq(expected
[i
++], word
, l
));
691 static void check(const char *test
, char** expected
, bool trailing
) {
692 const char *word
, *state
;
696 printf("<<<%s>>>\n", test
);
697 FOREACH_WORD_QUOTED(word
, l
, test
, state
) {
698 _cleanup_free_
char *t
= NULL
;
700 assert_se(t
= strndup(word
, l
));
701 assert_se(strneq(expected
[i
++], word
, l
));
704 printf("<<<%s>>>\n", state
);
705 assert_se(expected
[i
] == NULL
);
706 assert_se(isempty(state
) == !trailing
);
709 static void test_foreach_word_quoted(void) {
710 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
734 static void test_memdup_multiply(void) {
735 int org
[] = {1, 2, 3};
738 dup
= (int*)memdup_multiply(org
, sizeof(int), 3);
741 assert_se(dup
[0] == 1);
742 assert_se(dup
[1] == 2);
743 assert_se(dup
[2] == 3);
747 static void test_u64log2(void) {
748 assert_se(u64log2(0) == 0);
749 assert_se(u64log2(8) == 3);
750 assert_se(u64log2(9) == 3);
751 assert_se(u64log2(15) == 3);
752 assert_se(u64log2(16) == 4);
753 assert_se(u64log2(1024*1024) == 20);
754 assert_se(u64log2(1024*1024+5) == 20);
757 static void test_protect_errno(void) {
763 assert_se(errno
== 12);
766 static void test_parse_cpu_set(void) {
771 /* Simple range (from CPUAffinity example) */
772 ncpus
= parse_cpu_set_and_warn("1 2", &c
, NULL
, "fake", 1, "CPUAffinity");
773 assert_se(ncpus
>= 1024);
774 assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus
), c
));
775 assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus
), c
));
776 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 2);
779 /* A more interesting range */
780 ncpus
= parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c
, NULL
, "fake", 1, "CPUAffinity");
781 assert_se(ncpus
>= 1024);
782 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
783 for (cpu
= 0; cpu
< 4; cpu
++)
784 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
785 for (cpu
= 8; cpu
< 12; cpu
++)
786 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
790 ncpus
= parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c
, NULL
, "fake", 1, "CPUAffinity");
791 assert_se(ncpus
>= 1024);
792 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 4);
793 for (cpu
= 8; cpu
< 12; cpu
++)
794 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
797 /* Use commas as separators */
798 ncpus
= parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c
, NULL
, "fake", 1, "CPUAffinity");
799 assert_se(ncpus
>= 1024);
800 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
801 for (cpu
= 0; cpu
< 4; cpu
++)
802 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
803 for (cpu
= 8; cpu
< 12; cpu
++)
804 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
807 /* Commas with spaces (and trailing comma, space) */
808 ncpus
= parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c
, NULL
, "fake", 1, "CPUAffinity");
809 assert_se(ncpus
>= 1024);
810 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
811 for (cpu
= 0; cpu
< 8; cpu
++)
812 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
816 ncpus
= parse_cpu_set_and_warn("0-3,8-11", &c
, NULL
, "fake", 1, "CPUAffinity");
817 assert_se(ncpus
>= 1024);
818 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
819 for (cpu
= 0; cpu
< 4; cpu
++)
820 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
821 for (cpu
= 8; cpu
< 12; cpu
++)
822 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
825 /* Ranges with trailing comma, space */
826 ncpus
= parse_cpu_set_and_warn("0-3 8-11, ", &c
, NULL
, "fake", 1, "CPUAffinity");
827 assert_se(ncpus
>= 1024);
828 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
829 for (cpu
= 0; cpu
< 4; cpu
++)
830 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
831 for (cpu
= 8; cpu
< 12; cpu
++)
832 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
835 /* Negative range (returns empty cpu_set) */
836 ncpus
= parse_cpu_set_and_warn("3-0", &c
, NULL
, "fake", 1, "CPUAffinity");
837 assert_se(ncpus
>= 1024);
838 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 0);
841 /* Overlapping ranges */
842 ncpus
= parse_cpu_set_and_warn("0-7 4-11", &c
, NULL
, "fake", 1, "CPUAffinity");
843 assert_se(ncpus
>= 1024);
844 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 12);
845 for (cpu
= 0; cpu
< 12; cpu
++)
846 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
849 /* Mix ranges and individual CPUs */
850 ncpus
= parse_cpu_set_and_warn("0,1 4-11", &c
, NULL
, "fake", 1, "CPUAffinity");
851 assert_se(ncpus
>= 1024);
852 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 10);
853 assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus
), c
));
854 assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus
), c
));
855 for (cpu
= 4; cpu
< 12; cpu
++)
856 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
860 ncpus
= parse_cpu_set_and_warn("0 1 2 3 garbage", &c
, NULL
, "fake", 1, "CPUAffinity");
861 assert_se(ncpus
< 0);
864 /* Range with garbage */
865 ncpus
= parse_cpu_set_and_warn("0-3 8-garbage", &c
, NULL
, "fake", 1, "CPUAffinity");
866 assert_se(ncpus
< 0);
871 ncpus
= parse_cpu_set_and_warn("", &c
, NULL
, "fake", 1, "CPUAffinity");
872 assert_se(ncpus
== 0); /* empty string returns 0 */
875 /* Runnaway quoted string */
876 ncpus
= parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c
, NULL
, "fake", 1, "CPUAffinity");
877 assert_se(ncpus
< 0);
881 static void test_config_parse_iec_uint64(void) {
883 assert_se(config_parse_iec_uint64(NULL
, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset
, NULL
) == 0);
884 assert_se(offset
== 4 * 1024 * 1024);
886 assert_se(config_parse_iec_uint64(NULL
, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset
, NULL
) == 0);
889 static void test_strextend(void) {
890 _cleanup_free_
char *str
= strdup("0123");
891 strextend(&str
, "456", "78", "9", NULL
);
892 assert_se(streq(str
, "0123456789"));
895 static void test_strrep(void) {
896 _cleanup_free_
char *one
, *three
, *zero
;
897 one
= strrep("waldo", 1);
898 three
= strrep("waldo", 3);
899 zero
= strrep("waldo", 0);
901 assert_se(streq(one
, "waldo"));
902 assert_se(streq(three
, "waldowaldowaldo"));
903 assert_se(streq(zero
, ""));
906 static void test_split_pair(void) {
907 _cleanup_free_
char *a
= NULL
, *b
= NULL
;
909 assert_se(split_pair("", "", &a
, &b
) == -EINVAL
);
910 assert_se(split_pair("foo=bar", "", &a
, &b
) == -EINVAL
);
911 assert_se(split_pair("", "=", &a
, &b
) == -EINVAL
);
912 assert_se(split_pair("foo=bar", "=", &a
, &b
) >= 0);
913 assert_se(streq(a
, "foo"));
914 assert_se(streq(b
, "bar"));
917 assert_se(split_pair("==", "==", &a
, &b
) >= 0);
918 assert_se(streq(a
, ""));
919 assert_se(streq(b
, ""));
923 assert_se(split_pair("===", "==", &a
, &b
) >= 0);
924 assert_se(streq(a
, ""));
925 assert_se(streq(b
, "="));
928 static void test_fstab_node_to_udev_node(void) {
931 n
= fstab_node_to_udev_node("LABEL=applé/jack");
933 assert_se(streq(n
, "/dev/disk/by-label/applé\\x2fjack"));
936 n
= fstab_node_to_udev_node("PARTLABEL=pinkié pie");
938 assert_se(streq(n
, "/dev/disk/by-partlabel/pinkié\\x20pie"));
941 n
= fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
943 assert_se(streq(n
, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
946 n
= fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
948 assert_se(streq(n
, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
951 n
= fstab_node_to_udev_node("PONIES=awesome");
953 assert_se(streq(n
, "PONIES=awesome"));
956 n
= fstab_node_to_udev_node("/dev/xda1");
958 assert_se(streq(n
, "/dev/xda1"));
962 static void test_get_files_in_directory(void) {
963 _cleanup_strv_free_
char **l
= NULL
, **t
= NULL
;
965 assert_se(get_files_in_directory("/tmp", &l
) >= 0);
966 assert_se(get_files_in_directory(".", &t
) >= 0);
967 assert_se(get_files_in_directory(".", NULL
) >= 0);
970 static void test_in_set(void) {
971 assert_se(IN_SET(1, 1));
972 assert_se(IN_SET(1, 1, 2, 3, 4));
973 assert_se(IN_SET(2, 1, 2, 3, 4));
974 assert_se(IN_SET(3, 1, 2, 3, 4));
975 assert_se(IN_SET(4, 1, 2, 3, 4));
976 assert_se(!IN_SET(0, 1));
977 assert_se(!IN_SET(0, 1, 2, 3, 4));
980 static void test_writing_tmpfile(void) {
981 char name
[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
982 _cleanup_free_
char *contents
= NULL
;
987 IOVEC_SET_STRING(iov
[0], "abc\n");
988 IOVEC_SET_STRING(iov
[1], ALPHANUMERICAL
"\n");
989 IOVEC_SET_STRING(iov
[2], "");
991 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
992 printf("tmpfile: %s", name
);
994 r
= writev(fd
, iov
, 3);
997 r
= read_full_file(name
, &contents
, &size
);
999 printf("contents: %s", contents
);
1000 assert_se(streq(contents
, "abc\n" ALPHANUMERICAL
"\n"));
1005 static void test_hexdump(void) {
1009 hexdump(stdout
, NULL
, 0);
1010 hexdump(stdout
, "", 0);
1011 hexdump(stdout
, "", 1);
1012 hexdump(stdout
, "x", 1);
1013 hexdump(stdout
, "x", 2);
1014 hexdump(stdout
, "foobar", 7);
1015 hexdump(stdout
, "f\nobar", 7);
1016 hexdump(stdout
, "xxxxxxxxxxxxxxxxxxxxyz", 23);
1018 for (i
= 0; i
< ELEMENTSOF(data
); i
++)
1021 hexdump(stdout
, data
, sizeof(data
));
1024 static void test_log2i(void) {
1025 assert_se(log2i(1) == 0);
1026 assert_se(log2i(2) == 1);
1027 assert_se(log2i(3) == 1);
1028 assert_se(log2i(4) == 2);
1029 assert_se(log2i(32) == 5);
1030 assert_se(log2i(33) == 5);
1031 assert_se(log2i(63) == 5);
1032 assert_se(log2i(INT_MAX
) == sizeof(int)*8-2);
1035 static void test_foreach_string(void) {
1036 const char * const t
[] = {
1045 FOREACH_STRING(x
, "foo", "bar", "waldo")
1046 assert_se(streq_ptr(t
[i
++], x
));
1050 FOREACH_STRING(x
, "zzz")
1051 assert_se(streq(x
, "zzz"));
1054 static void test_filename_is_valid(void) {
1055 char foo
[FILENAME_MAX
+2];
1058 assert_se(!filename_is_valid(""));
1059 assert_se(!filename_is_valid("/bar/foo"));
1060 assert_se(!filename_is_valid("/"));
1061 assert_se(!filename_is_valid("."));
1062 assert_se(!filename_is_valid(".."));
1064 for (i
=0; i
<FILENAME_MAX
+1; i
++)
1066 foo
[FILENAME_MAX
+1] = '\0';
1068 assert_se(!filename_is_valid(foo
));
1070 assert_se(filename_is_valid("foo_bar-333"));
1071 assert_se(filename_is_valid("o.o"));
1074 static void test_string_has_cc(void) {
1075 assert_se(string_has_cc("abc\1", NULL
));
1076 assert_se(string_has_cc("abc\x7f", NULL
));
1077 assert_se(string_has_cc("abc\x7f", NULL
));
1078 assert_se(string_has_cc("abc\t\x7f", "\t"));
1079 assert_se(string_has_cc("abc\t\x7f", "\t"));
1080 assert_se(string_has_cc("\x7f", "\t"));
1081 assert_se(string_has_cc("\x7f", "\t\a"));
1083 assert_se(!string_has_cc("abc\t\t", "\t"));
1084 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
1085 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
1088 static void test_ascii_strlower(void) {
1089 char a
[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
1090 assert_se(streq(ascii_strlower(a
), "aabbcc jk ii od lkjjj kkd lk"));
1093 static void test_files_same(void) {
1094 _cleanup_close_
int fd
= -1;
1095 char name
[] = "/tmp/test-files_same.XXXXXX";
1096 char name_alias
[] = "/tmp/test-files_same.alias";
1098 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1100 assert_se(symlink(name
, name_alias
) >= 0);
1102 assert_se(files_same(name
, name
));
1103 assert_se(files_same(name
, name_alias
));
1109 static void test_is_valid_documentation_url(void) {
1110 assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
1111 assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
1112 assert_se(documentation_url_is_valid("file:/foo/foo"));
1113 assert_se(documentation_url_is_valid("man:systemd.special(7)"));
1114 assert_se(documentation_url_is_valid("info:bar"));
1116 assert_se(!documentation_url_is_valid("foo:"));
1117 assert_se(!documentation_url_is_valid("info:"));
1118 assert_se(!documentation_url_is_valid(""));
1121 static void test_file_in_same_dir(void) {
1124 t
= file_in_same_dir("/", "a");
1125 assert_se(streq(t
, "/a"));
1128 t
= file_in_same_dir("/", "/a");
1129 assert_se(streq(t
, "/a"));
1132 t
= file_in_same_dir("", "a");
1133 assert_se(streq(t
, "a"));
1136 t
= file_in_same_dir("a/", "a");
1137 assert_se(streq(t
, "a/a"));
1140 t
= file_in_same_dir("bar/foo", "bar");
1141 assert_se(streq(t
, "bar/bar"));
1145 static void test_endswith(void) {
1146 assert_se(endswith("foobar", "bar"));
1147 assert_se(endswith("foobar", ""));
1148 assert_se(endswith("foobar", "foobar"));
1149 assert_se(endswith("", ""));
1151 assert_se(!endswith("foobar", "foo"));
1152 assert_se(!endswith("foobar", "foobarfoofoo"));
1155 static void test_endswith_no_case(void) {
1156 assert_se(endswith_no_case("fooBAR", "bar"));
1157 assert_se(endswith_no_case("foobar", ""));
1158 assert_se(endswith_no_case("foobar", "FOOBAR"));
1159 assert_se(endswith_no_case("", ""));
1161 assert_se(!endswith_no_case("foobar", "FOO"));
1162 assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
1165 static void test_close_nointr(void) {
1166 char name
[] = "/tmp/test-test-close_nointr.XXXXXX";
1169 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1171 assert_se(close_nointr(fd
) >= 0);
1172 assert_se(close_nointr(fd
) < 0);
1178 static void test_unlink_noerrno(void) {
1179 char name
[] = "/tmp/test-close_nointr.XXXXXX";
1182 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1184 assert_se(close_nointr(fd
) >= 0);
1189 assert_se(unlink_noerrno(name
) >= 0);
1190 assert_se(errno
== -42);
1191 assert_se(unlink_noerrno(name
) < 0);
1192 assert_se(errno
== -42);
1196 static void test_readlink_and_make_absolute(void) {
1197 char tempdir
[] = "/tmp/test-readlink_and_make_absolute";
1198 char name
[] = "/tmp/test-readlink_and_make_absolute/original";
1199 char name2
[] = "test-readlink_and_make_absolute/original";
1200 char name_alias
[] = "/tmp/test-readlink_and_make_absolute-alias";
1203 assert_se(mkdir_safe(tempdir
, 0755, getuid(), getgid()) >= 0);
1204 assert_se(touch(name
) >= 0);
1206 assert_se(symlink(name
, name_alias
) >= 0);
1207 assert_se(readlink_and_make_absolute(name_alias
, &r
) >= 0);
1208 assert_se(streq(r
, name
));
1210 assert_se(unlink(name_alias
) >= 0);
1212 assert_se(chdir(tempdir
) >= 0);
1213 assert_se(symlink(name2
, name_alias
) >= 0);
1214 assert_se(readlink_and_make_absolute(name_alias
, &r
) >= 0);
1215 assert_se(streq(r
, name
));
1217 assert_se(unlink(name_alias
) >= 0);
1219 assert_se(rm_rf(tempdir
, REMOVE_ROOT
|REMOVE_PHYSICAL
) >= 0);
1222 static void test_ignore_signals(void) {
1223 assert_se(ignore_signals(SIGINT
, -1) >= 0);
1224 assert_se(kill(getpid(), SIGINT
) >= 0);
1225 assert_se(ignore_signals(SIGUSR1
, SIGUSR2
, SIGTERM
, SIGPIPE
, -1) >= 0);
1226 assert_se(kill(getpid(), SIGUSR1
) >= 0);
1227 assert_se(kill(getpid(), SIGUSR2
) >= 0);
1228 assert_se(kill(getpid(), SIGTERM
) >= 0);
1229 assert_se(kill(getpid(), SIGPIPE
) >= 0);
1230 assert_se(default_signals(SIGINT
, SIGUSR1
, SIGUSR2
, SIGTERM
, SIGPIPE
, -1) >= 0);
1233 static void test_strshorten(void) {
1234 char s
[] = "foobar";
1236 assert_se(strlen(strshorten(s
, 6)) == 6);
1237 assert_se(strlen(strshorten(s
, 12)) == 6);
1238 assert_se(strlen(strshorten(s
, 2)) == 2);
1239 assert_se(strlen(strshorten(s
, 0)) == 0);
1242 static void test_strjoina(void) {
1245 actual
= strjoina("", "foo", "bar");
1246 assert_se(streq(actual
, "foobar"));
1248 actual
= strjoina("foo", "bar", "baz");
1249 assert_se(streq(actual
, "foobarbaz"));
1251 actual
= strjoina("foo", "", "bar", "baz");
1252 assert_se(streq(actual
, "foobarbaz"));
1254 actual
= strjoina("foo");
1255 assert_se(streq(actual
, "foo"));
1257 actual
= strjoina(NULL
);
1258 assert_se(streq(actual
, ""));
1260 actual
= strjoina(NULL
, "foo");
1261 assert_se(streq(actual
, ""));
1263 actual
= strjoina("foo", NULL
, "bar");
1264 assert_se(streq(actual
, "foo"));
1267 static void test_is_symlink(void) {
1268 char name
[] = "/tmp/test-is_symlink.XXXXXX";
1269 char name_link
[] = "/tmp/test-is_symlink.link";
1270 _cleanup_close_
int fd
= -1;
1272 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1274 assert_se(symlink(name
, name_link
) >= 0);
1276 assert_se(is_symlink(name
) == 0);
1277 assert_se(is_symlink(name_link
) == 1);
1278 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1285 static void test_search_and_fopen(void) {
1286 const char *dirs
[] = {"/tmp/foo/bar", "/tmp", NULL
};
1287 char name
[] = "/tmp/test-search_and_fopen.XXXXXX";
1292 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1296 r
= search_and_fopen(basename(name
), "r", NULL
, dirs
, &f
);
1300 r
= search_and_fopen(name
, "r", NULL
, dirs
, &f
);
1304 r
= search_and_fopen(basename(name
), "r", "/", dirs
, &f
);
1308 r
= search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL
, dirs
, &f
);
1310 r
= search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL
, dirs
, &f
);
1316 r
= search_and_fopen(basename(name
), "r", NULL
, dirs
, &f
);
1321 static void test_search_and_fopen_nulstr(void) {
1322 const char dirs
[] = "/tmp/foo/bar\0/tmp\0";
1323 char name
[] = "/tmp/test-search_and_fopen.XXXXXX";
1328 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1332 r
= search_and_fopen_nulstr(basename(name
), "r", NULL
, dirs
, &f
);
1336 r
= search_and_fopen_nulstr(name
, "r", NULL
, dirs
, &f
);
1340 r
= search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL
, dirs
, &f
);
1342 r
= search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL
, dirs
, &f
);
1348 r
= search_and_fopen_nulstr(basename(name
), "r", NULL
, dirs
, &f
);
1352 static void test_glob_exists(void) {
1353 char name
[] = "/tmp/test-glob_exists.XXXXXX";
1357 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1361 r
= glob_exists("/tmp/test-glob_exists*");
1366 r
= glob_exists("/tmp/test-glob_exists*");
1370 static void test_execute_directory(void) {
1371 char template_lo
[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1372 char template_hi
[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
1373 const char * dirs
[] = {template_hi
, template_lo
, NULL
};
1374 const char *name
, *name2
, *name3
, *overridden
, *override
, *masked
, *mask
;
1376 assert_se(mkdtemp(template_lo
));
1377 assert_se(mkdtemp(template_hi
));
1379 name
= strjoina(template_lo
, "/script");
1380 name2
= strjoina(template_hi
, "/script2");
1381 name3
= strjoina(template_lo
, "/useless");
1382 overridden
= strjoina(template_lo
, "/overridden");
1383 override
= strjoina(template_hi
, "/overridden");
1384 masked
= strjoina(template_lo
, "/masked");
1385 mask
= strjoina(template_hi
, "/masked");
1387 assert_se(write_string_file(name
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE
) == 0);
1388 assert_se(write_string_file(name2
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE
) == 0);
1389 assert_se(write_string_file(overridden
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE
) == 0);
1390 assert_se(write_string_file(override
, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE
) == 0);
1391 assert_se(write_string_file(masked
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE
) == 0);
1392 assert_se(symlink("/dev/null", mask
) == 0);
1393 assert_se(chmod(name
, 0755) == 0);
1394 assert_se(chmod(name2
, 0755) == 0);
1395 assert_se(chmod(overridden
, 0755) == 0);
1396 assert_se(chmod(override
, 0755) == 0);
1397 assert_se(chmod(masked
, 0755) == 0);
1398 assert_se(touch(name3
) >= 0);
1400 execute_directories(dirs
, DEFAULT_TIMEOUT_USEC
, NULL
);
1402 assert_se(chdir(template_lo
) == 0);
1403 assert_se(access("it_works", F_OK
) >= 0);
1404 assert_se(access("failed", F_OK
) < 0);
1406 assert_se(chdir(template_hi
) == 0);
1407 assert_se(access("it_works2", F_OK
) >= 0);
1408 assert_se(access("failed", F_OK
) < 0);
1410 (void) rm_rf(template_lo
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
1411 (void) rm_rf(template_hi
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
1414 static int parse_item(const char *key
, const char *value
) {
1417 log_info("kernel cmdline option <%s> = <%s>", key
, strna(value
));
1421 static void test_parse_proc_cmdline(void) {
1422 assert_se(parse_proc_cmdline(parse_item
) >= 0);
1425 static void test_raw_clone(void) {
1426 pid_t parent
, pid
, pid2
;
1429 log_info("before clone: getpid()→"PID_FMT
, parent
);
1430 assert_se(raw_getpid() == parent
);
1432 pid
= raw_clone(0, NULL
);
1433 assert_se(pid
>= 0);
1435 pid2
= raw_getpid();
1436 log_info("raw_clone: "PID_FMT
" getpid()→"PID_FMT
" raw_getpid()→"PID_FMT
,
1437 pid
, getpid(), pid2
);
1439 assert_se(pid2
!= parent
);
1440 _exit(EXIT_SUCCESS
);
1444 assert_se(pid2
== parent
);
1445 waitpid(pid
, &status
, __WCLONE
);
1446 assert_se(WIFEXITED(status
) && WEXITSTATUS(status
) == EXIT_SUCCESS
);
1450 static void test_same_fd(void) {
1451 _cleanup_close_pair_
int p
[2] = { -1, -1 };
1452 _cleanup_close_
int a
= -1, b
= -1, c
= -1;
1454 assert_se(pipe2(p
, O_CLOEXEC
) >= 0);
1455 assert_se((a
= dup(p
[0])) >= 0);
1456 assert_se((b
= open("/dev/null", O_RDONLY
|O_CLOEXEC
)) >= 0);
1457 assert_se((c
= dup(a
)) >= 0);
1459 assert_se(same_fd(p
[0], p
[0]) > 0);
1460 assert_se(same_fd(p
[1], p
[1]) > 0);
1461 assert_se(same_fd(a
, a
) > 0);
1462 assert_se(same_fd(b
, b
) > 0);
1464 assert_se(same_fd(a
, p
[0]) > 0);
1465 assert_se(same_fd(p
[0], a
) > 0);
1466 assert_se(same_fd(c
, p
[0]) > 0);
1467 assert_se(same_fd(p
[0], c
) > 0);
1468 assert_se(same_fd(a
, c
) > 0);
1469 assert_se(same_fd(c
, a
) > 0);
1471 assert_se(same_fd(p
[0], p
[1]) == 0);
1472 assert_se(same_fd(p
[1], p
[0]) == 0);
1473 assert_se(same_fd(p
[0], b
) == 0);
1474 assert_se(same_fd(b
, p
[0]) == 0);
1475 assert_se(same_fd(p
[1], a
) == 0);
1476 assert_se(same_fd(a
, p
[1]) == 0);
1477 assert_se(same_fd(p
[1], b
) == 0);
1478 assert_se(same_fd(b
, p
[1]) == 0);
1480 assert_se(same_fd(a
, b
) == 0);
1481 assert_se(same_fd(b
, a
) == 0);
1484 static void test_uid_ptr(void) {
1486 assert_se(UID_TO_PTR(0) != NULL
);
1487 assert_se(UID_TO_PTR(1000) != NULL
);
1489 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1490 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1493 static void test_sparse_write_one(int fd
, const char *buffer
, size_t n
) {
1496 assert_se(lseek(fd
, 0, SEEK_SET
) == 0);
1497 assert_se(ftruncate(fd
, 0) >= 0);
1498 assert_se(sparse_write(fd
, buffer
, n
, 4) == (ssize_t
) n
);
1500 assert_se(lseek(fd
, 0, SEEK_CUR
) == (off_t
) n
);
1501 assert_se(ftruncate(fd
, n
) >= 0);
1503 assert_se(lseek(fd
, 0, SEEK_SET
) == 0);
1504 assert_se(read(fd
, check
, n
) == (ssize_t
) n
);
1506 assert_se(memcmp(buffer
, check
, n
) == 0);
1509 static void test_sparse_write(void) {
1510 const char test_a
[] = "test";
1511 const char test_b
[] = "\0\0\0\0test\0\0\0\0";
1512 const char test_c
[] = "\0\0test\0\0\0\0";
1513 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";
1514 const char test_e
[] = "test\0\0\0\0test";
1515 _cleanup_close_
int fd
= -1;
1516 char fn
[] = "/tmp/sparseXXXXXX";
1518 fd
= mkostemp(fn
, O_CLOEXEC
);
1522 test_sparse_write_one(fd
, test_a
, sizeof(test_a
));
1523 test_sparse_write_one(fd
, test_b
, sizeof(test_b
));
1524 test_sparse_write_one(fd
, test_c
, sizeof(test_c
));
1525 test_sparse_write_one(fd
, test_d
, sizeof(test_d
));
1526 test_sparse_write_one(fd
, test_e
, sizeof(test_e
));
1529 static void test_shell_escape_one(const char *s
, const char *bad
, const char *expected
) {
1530 _cleanup_free_
char *r
;
1532 assert_se(r
= shell_escape(s
, bad
));
1533 assert_se(streq_ptr(r
, expected
));
1536 static void test_shell_escape(void) {
1537 test_shell_escape_one("", "", "");
1538 test_shell_escape_one("\\", "", "\\\\");
1539 test_shell_escape_one("foobar", "", "foobar");
1540 test_shell_escape_one("foobar", "o", "f\\o\\obar");
1541 test_shell_escape_one("foo:bar,baz", ",:", "foo\\:bar\\,baz");
1544 static void test_shell_maybe_quote_one(const char *s
, const char *expected
) {
1545 _cleanup_free_
char *r
;
1547 assert_se(r
= shell_maybe_quote(s
));
1548 assert_se(streq(r
, expected
));
1551 static void test_shell_maybe_quote(void) {
1553 test_shell_maybe_quote_one("", "");
1554 test_shell_maybe_quote_one("\\", "\"\\\\\"");
1555 test_shell_maybe_quote_one("\"", "\"\\\"\"");
1556 test_shell_maybe_quote_one("foobar", "foobar");
1557 test_shell_maybe_quote_one("foo bar", "\"foo bar\"");
1558 test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\"");
1559 test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
1562 static void test_tempfn(void) {
1563 char *ret
= NULL
, *p
;
1565 assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL
, &ret
) >= 0);
1566 assert_se(streq_ptr(ret
, "/foo/bar/.#waldoXXXXXX"));
1569 assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret
) >= 0);
1570 assert_se(streq_ptr(ret
, "/foo/bar/.#[miau]waldoXXXXXX"));
1573 assert_se(tempfn_random("/foo/bar/waldo", NULL
, &ret
) >= 0);
1574 assert_se(p
= startswith(ret
, "/foo/bar/.#waldo"));
1575 assert_se(strlen(p
) == 16);
1576 assert_se(in_charset(p
, "0123456789abcdef"));
1579 assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret
) >= 0);
1580 assert_se(p
= startswith(ret
, "/foo/bar/.#[wuff]waldo"));
1581 assert_se(strlen(p
) == 16);
1582 assert_se(in_charset(p
, "0123456789abcdef"));
1585 assert_se(tempfn_random_child("/foo/bar/waldo", NULL
, &ret
) >= 0);
1586 assert_se(p
= startswith(ret
, "/foo/bar/waldo/.#"));
1587 assert_se(strlen(p
) == 16);
1588 assert_se(in_charset(p
, "0123456789abcdef"));
1591 assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret
) >= 0);
1592 assert_se(p
= startswith(ret
, "/foo/bar/waldo/.#[kikiriki]"));
1593 assert_se(strlen(p
) == 16);
1594 assert_se(in_charset(p
, "0123456789abcdef"));
1598 static void test_strcmp_ptr(void) {
1599 assert_se(strcmp_ptr(NULL
, NULL
) == 0);
1600 assert_se(strcmp_ptr("", NULL
) > 0);
1601 assert_se(strcmp_ptr("foo", NULL
) > 0);
1602 assert_se(strcmp_ptr(NULL
, "") < 0);
1603 assert_se(strcmp_ptr(NULL
, "bar") < 0);
1604 assert_se(strcmp_ptr("foo", "bar") > 0);
1605 assert_se(strcmp_ptr("bar", "baz") < 0);
1606 assert_se(strcmp_ptr("foo", "foo") == 0);
1607 assert_se(strcmp_ptr("", "") == 0);
1610 static void test_fgetxattrat_fake(void) {
1611 char t
[] = "/var/tmp/xattrtestXXXXXX";
1612 _cleanup_close_
int fd
= -1;
1617 assert_se(mkdtemp(t
));
1618 x
= strjoina(t
, "/test");
1619 assert_se(touch(x
) >= 0);
1621 r
= setxattr(x
, "user.foo", "bar", 3, 0);
1622 if (r
< 0 && errno
== EOPNOTSUPP
) /* no xattrs supported on /var/tmp... */
1626 fd
= open(t
, O_RDONLY
|O_DIRECTORY
|O_CLOEXEC
|O_NOCTTY
);
1629 assert_se(fgetxattrat_fake(fd
, "test", "user.foo", v
, 3, 0) >= 0);
1630 assert_se(memcmp(v
, "bar", 3) == 0);
1633 fd
= open("/", O_RDONLY
|O_DIRECTORY
|O_CLOEXEC
|O_NOCTTY
);
1635 assert_se(fgetxattrat_fake(fd
, "usr", "user.idontexist", v
, 3, 0) == -ENODATA
);
1638 assert_se(unlink(x
) >= 0);
1639 assert_se(rmdir(t
) >= 0);
1642 static void test_runlevel_to_target(void) {
1643 assert_se(streq_ptr(runlevel_to_target(NULL
), NULL
));
1644 assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL
));
1645 assert_se(streq_ptr(runlevel_to_target("3"), SPECIAL_MULTI_USER_TARGET
));
1648 int main(int argc
, char *argv
[]) {
1649 log_parse_environment();
1653 test_align_power2();
1655 test_container_of();
1657 test_div_round_up();
1663 test_delete_chars();
1667 test_base32hexchar();
1668 test_unbase32hexchar();
1670 test_unbase64char();
1676 test_base32hexmem();
1677 test_unbase32hexmem();
1682 test_foreach_word();
1683 test_foreach_word_quoted();
1684 test_memdup_multiply();
1686 test_protect_errno();
1687 test_parse_cpu_set();
1688 test_config_parse_iec_uint64();
1692 test_fstab_node_to_udev_node();
1693 test_get_files_in_directory();
1695 test_writing_tmpfile();
1698 test_foreach_string();
1699 test_filename_is_valid();
1700 test_string_has_cc();
1701 test_ascii_strlower();
1703 test_is_valid_documentation_url();
1704 test_file_in_same_dir();
1706 test_endswith_no_case();
1707 test_close_nointr();
1708 test_unlink_noerrno();
1709 test_readlink_and_make_absolute();
1710 test_ignore_signals();
1714 test_search_and_fopen();
1715 test_search_and_fopen_nulstr();
1717 test_execute_directory();
1718 test_parse_proc_cmdline();
1722 test_sparse_write();
1723 test_shell_escape();
1724 test_shell_maybe_quote();
1727 test_fgetxattrat_fake();
1728 test_runlevel_to_target();