]>
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/>.
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"
51 #include "stat-util.h"
52 #include "string-util.h"
54 #include "user-util.h"
58 #include "xattr-util.h"
60 static void test_streq_ptr(void) {
61 assert_se(streq_ptr(NULL
, NULL
));
62 assert_se(!streq_ptr("abc", "cdef"));
65 static void test_align_power2(void) {
68 assert_se(ALIGN_POWER2(0) == 0);
69 assert_se(ALIGN_POWER2(1) == 1);
70 assert_se(ALIGN_POWER2(2) == 2);
71 assert_se(ALIGN_POWER2(3) == 4);
72 assert_se(ALIGN_POWER2(12) == 16);
74 assert_se(ALIGN_POWER2(ULONG_MAX
) == 0);
75 assert_se(ALIGN_POWER2(ULONG_MAX
- 1) == 0);
76 assert_se(ALIGN_POWER2(ULONG_MAX
- 1024) == 0);
77 assert_se(ALIGN_POWER2(ULONG_MAX
/ 2) == ULONG_MAX
/ 2 + 1);
78 assert_se(ALIGN_POWER2(ULONG_MAX
+ 1) == 0);
80 for (i
= 1; i
< 131071; ++i
) {
81 for (p2
= 1; p2
< i
; p2
<<= 1)
84 assert_se(ALIGN_POWER2(i
) == p2
);
87 for (i
= ULONG_MAX
- 1024; i
< ULONG_MAX
; ++i
) {
88 for (p2
= 1; p2
&& p2
< i
; p2
<<= 1)
91 assert_se(ALIGN_POWER2(i
) == p2
);
95 static void test_max(void) {
98 int b
[CONST_MAX(10, 100)];
100 .a
= CONST_MAX(10, 100),
104 assert_cc(sizeof(val1
.b
) == sizeof(int) * 100);
106 /* CONST_MAX returns (void) instead of a value if the passed arguments
107 * are not of the same type or not constant expressions. */
108 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
109 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
111 assert_se(val1
.a
== 100);
112 assert_se(MAX(++d
, 0) == 1);
115 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
116 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
117 assert_cc(MAXSIZE(char, long) == sizeof(long));
119 assert_se(MAX(-5, 5) == 5);
120 assert_se(MAX(5, 5) == 5);
121 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
122 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
123 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
124 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
125 assert_se(LESS_BY(8, 4) == 4);
126 assert_se(LESS_BY(8, 8) == 0);
127 assert_se(LESS_BY(4, 8) == 0);
128 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
129 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
130 assert_se(CLAMP(-5, 0, 1) == 0);
131 assert_se(CLAMP(5, 0, 1) == 1);
132 assert_se(CLAMP(5, -10, 1) == 1);
133 assert_se(CLAMP(5, -10, 10) == 5);
134 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
137 static void test_container_of(void) {
143 } _packed_ myval
= { };
145 assert_cc(sizeof(myval
) == 17);
146 assert_se(container_of(&myval
.v1
, struct mytype
, v1
) == &myval
);
147 assert_se(container_of(&myval
.v2
, struct mytype
, v2
) == &myval
);
148 assert_se(container_of(&container_of(&myval
.v2
,
155 static void test_alloca(void) {
156 static const uint8_t zero
[997] = { };
159 t
= alloca_align(17, 512);
160 assert_se(!((uintptr_t)t
& 0xff));
163 t
= alloca0_align(997, 1024);
164 assert_se(!((uintptr_t)t
& 0x1ff));
165 assert_se(!memcmp(t
, zero
, 997));
168 static void test_div_round_up(void) {
172 assert_se(DIV_ROUND_UP(0, 8) == 0);
173 assert_se(DIV_ROUND_UP(1, 8) == 1);
174 assert_se(DIV_ROUND_UP(8, 8) == 1);
175 assert_se(DIV_ROUND_UP(12, 8) == 2);
176 assert_se(DIV_ROUND_UP(16, 8) == 2);
178 /* test multiple evaluation */
180 assert_se(DIV_ROUND_UP(div
++, 8) == 0 && div
== 1);
181 assert_se(DIV_ROUND_UP(++div
, 8) == 1 && div
== 2);
182 assert_se(DIV_ROUND_UP(8, div
++) == 4 && div
== 3);
183 assert_se(DIV_ROUND_UP(8, ++div
) == 2 && div
== 4);
185 /* overflow test with exact division */
186 assert_se(sizeof(0U) == 4);
187 assert_se(0xfffffffaU
% 10U == 0U);
188 assert_se(0xfffffffaU
/ 10U == 429496729U);
189 assert_se(DIV_ROUND_UP(0xfffffffaU
, 10U) == 429496729U);
190 assert_se((0xfffffffaU
+ 10U - 1U) / 10U == 0U);
191 assert_se(0xfffffffaU
/ 10U + !!(0xfffffffaU
% 10U) == 429496729U);
193 /* overflow test with rounded division */
194 assert_se(0xfffffffdU
% 10U == 3U);
195 assert_se(0xfffffffdU
/ 10U == 429496729U);
196 assert_se(DIV_ROUND_UP(0xfffffffdU
, 10U) == 429496730U);
197 assert_se((0xfffffffdU
+ 10U - 1U) / 10U == 0U);
198 assert_se(0xfffffffdU
/ 10U + !!(0xfffffffdU
% 10U) == 429496730U);
201 static void test_first_word(void) {
202 assert_se(first_word("Hello", ""));
203 assert_se(first_word("Hello", "Hello"));
204 assert_se(first_word("Hello world", "Hello"));
205 assert_se(first_word("Hello\tworld", "Hello"));
206 assert_se(first_word("Hello\nworld", "Hello"));
207 assert_se(first_word("Hello\rworld", "Hello"));
208 assert_se(first_word("Hello ", "Hello"));
210 assert_se(!first_word("Hello", "Hellooo"));
211 assert_se(!first_word("Hello", "xxxxx"));
212 assert_se(!first_word("Hellooo", "Hello"));
215 static void test_close_many(void) {
217 char name0
[] = "/tmp/test-close-many.XXXXXX";
218 char name1
[] = "/tmp/test-close-many.XXXXXX";
219 char name2
[] = "/tmp/test-close-many.XXXXXX";
221 fds
[0] = mkostemp_safe(name0
, O_RDWR
|O_CLOEXEC
);
222 fds
[1] = mkostemp_safe(name1
, O_RDWR
|O_CLOEXEC
);
223 fds
[2] = mkostemp_safe(name2
, O_RDWR
|O_CLOEXEC
);
227 assert_se(fcntl(fds
[0], F_GETFD
) == -1);
228 assert_se(fcntl(fds
[1], F_GETFD
) == -1);
229 assert_se(fcntl(fds
[2], F_GETFD
) >= 0);
238 static void test_parse_uid(void) {
242 r
= parse_uid("100", &uid
);
244 assert_se(uid
== 100);
246 r
= parse_uid("65535", &uid
);
247 assert_se(r
== -ENXIO
);
249 r
= parse_uid("asdsdas", &uid
);
250 assert_se(r
== -EINVAL
);
253 static void test_strappend(void) {
254 _cleanup_free_
char *t1
, *t2
, *t3
, *t4
;
256 t1
= strappend(NULL
, NULL
);
257 assert_se(streq(t1
, ""));
259 t2
= strappend(NULL
, "suf");
260 assert_se(streq(t2
, "suf"));
262 t3
= strappend("pre", NULL
);
263 assert_se(streq(t3
, "pre"));
265 t4
= strappend("pre", "suf");
266 assert_se(streq(t4
, "presuf"));
269 static void test_strstrip(void) {
271 char input
[] = " hello, waldo. ";
274 assert_se(streq(r
, "hello, waldo."));
277 static void test_delete_chars(void) {
279 char input
[] = " hello, waldo. abc";
281 r
= delete_chars(input
, WHITESPACE
);
282 assert_se(streq(r
, "hello,waldo.abc"));
285 static void test_in_charset(void) {
286 assert_se(in_charset("dddaaabbbcccc", "abcd"));
287 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
290 static void test_hexchar(void) {
291 assert_se(hexchar(0xa) == 'a');
292 assert_se(hexchar(0x0) == '0');
295 static void test_unhexchar(void) {
296 assert_se(unhexchar('a') == 0xA);
297 assert_se(unhexchar('A') == 0xA);
298 assert_se(unhexchar('0') == 0x0);
301 static void test_base32hexchar(void) {
302 assert_se(base32hexchar(0) == '0');
303 assert_se(base32hexchar(9) == '9');
304 assert_se(base32hexchar(10) == 'A');
305 assert_se(base32hexchar(31) == 'V');
308 static void test_unbase32hexchar(void) {
309 assert_se(unbase32hexchar('0') == 0);
310 assert_se(unbase32hexchar('9') == 9);
311 assert_se(unbase32hexchar('A') == 10);
312 assert_se(unbase32hexchar('V') == 31);
313 assert_se(unbase32hexchar('=') == -EINVAL
);
316 static void test_base64char(void) {
317 assert_se(base64char(0) == 'A');
318 assert_se(base64char(26) == 'a');
319 assert_se(base64char(63) == '/');
322 static void test_unbase64char(void) {
323 assert_se(unbase64char('A') == 0);
324 assert_se(unbase64char('Z') == 25);
325 assert_se(unbase64char('a') == 26);
326 assert_se(unbase64char('z') == 51);
327 assert_se(unbase64char('0') == 52);
328 assert_se(unbase64char('9') == 61);
329 assert_se(unbase64char('+') == 62);
330 assert_se(unbase64char('/') == 63);
331 assert_se(unbase64char('=') == -EINVAL
);
334 static void test_octchar(void) {
335 assert_se(octchar(00) == '0');
336 assert_se(octchar(07) == '7');
339 static void test_unoctchar(void) {
340 assert_se(unoctchar('0') == 00);
341 assert_se(unoctchar('7') == 07);
344 static void test_decchar(void) {
345 assert_se(decchar(0) == '0');
346 assert_se(decchar(9) == '9');
349 static void test_undecchar(void) {
350 assert_se(undecchar('0') == 0);
351 assert_se(undecchar('9') == 9);
354 static void test_unhexmem(void) {
355 const char *hex
= "efa214921";
356 const char *hex_invalid
= "efa214921o";
357 _cleanup_free_
char *hex2
= NULL
;
358 _cleanup_free_
void *mem
= NULL
;
361 assert_se(unhexmem(hex
, strlen(hex
), &mem
, &len
) == 0);
362 assert_se(unhexmem(hex
, strlen(hex
) + 1, &mem
, &len
) == -EINVAL
);
363 assert_se(unhexmem(hex_invalid
, strlen(hex_invalid
), &mem
, &len
) == -EINVAL
);
365 assert_se((hex2
= hexmem(mem
, len
)));
369 assert_se(memcmp(hex
, hex2
, strlen(hex
)) == 0);
373 assert_se(unhexmem(hex
, strlen(hex
) - 1, &mem
, &len
) == 0);
374 assert_se((hex2
= hexmem(mem
, len
)));
375 assert_se(memcmp(hex
, hex2
, strlen(hex
) - 1) == 0);
378 /* https://tools.ietf.org/html/rfc4648#section-10 */
379 static void test_base32hexmem(void) {
382 b32
= base32hexmem("", strlen(""), true);
384 assert_se(streq(b32
, ""));
387 b32
= base32hexmem("f", strlen("f"), true);
389 assert_se(streq(b32
, "CO======"));
392 b32
= base32hexmem("fo", strlen("fo"), true);
394 assert_se(streq(b32
, "CPNG===="));
397 b32
= base32hexmem("foo", strlen("foo"), true);
399 assert_se(streq(b32
, "CPNMU==="));
402 b32
= base32hexmem("foob", strlen("foob"), true);
404 assert_se(streq(b32
, "CPNMUOG="));
407 b32
= base32hexmem("fooba", strlen("fooba"), true);
409 assert_se(streq(b32
, "CPNMUOJ1"));
412 b32
= base32hexmem("foobar", strlen("foobar"), true);
414 assert_se(streq(b32
, "CPNMUOJ1E8======"));
417 b32
= base32hexmem("", strlen(""), false);
419 assert_se(streq(b32
, ""));
422 b32
= base32hexmem("f", strlen("f"), false);
424 assert_se(streq(b32
, "CO"));
427 b32
= base32hexmem("fo", strlen("fo"), false);
429 assert_se(streq(b32
, "CPNG"));
432 b32
= base32hexmem("foo", strlen("foo"), false);
434 assert_se(streq(b32
, "CPNMU"));
437 b32
= base32hexmem("foob", strlen("foob"), false);
439 assert_se(streq(b32
, "CPNMUOG"));
442 b32
= base32hexmem("fooba", strlen("fooba"), false);
444 assert_se(streq(b32
, "CPNMUOJ1"));
447 b32
= base32hexmem("foobar", strlen("foobar"), false);
449 assert_se(streq(b32
, "CPNMUOJ1E8"));
453 static void test_unbase32hexmem(void) {
457 assert_se(unbase32hexmem("", strlen(""), true, &mem
, &len
) == 0);
458 assert_se(streq(strndupa(mem
, len
), ""));
461 assert_se(unbase32hexmem("CO======", strlen("CO======"), true, &mem
, &len
) == 0);
462 assert_se(streq(strndupa(mem
, len
), "f"));
465 assert_se(unbase32hexmem("CPNG====", strlen("CPNG===="), true, &mem
, &len
) == 0);
466 assert_se(streq(strndupa(mem
, len
), "fo"));
469 assert_se(unbase32hexmem("CPNMU===", strlen("CPNMU==="), true, &mem
, &len
) == 0);
470 assert_se(streq(strndupa(mem
, len
), "foo"));
473 assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), true, &mem
, &len
) == 0);
474 assert_se(streq(strndupa(mem
, len
), "foob"));
477 assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == 0);
478 assert_se(streq(strndupa(mem
, len
), "fooba"));
481 assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), true, &mem
, &len
) == 0);
482 assert_se(streq(strndupa(mem
, len
), "foobar"));
485 assert_se(unbase32hexmem("A", strlen("A"), true, &mem
, &len
) == -EINVAL
);
486 assert_se(unbase32hexmem("A=======", strlen("A======="), true, &mem
, &len
) == -EINVAL
);
487 assert_se(unbase32hexmem("AAA=====", strlen("AAA====="), true, &mem
, &len
) == -EINVAL
);
488 assert_se(unbase32hexmem("AAAAAA==", strlen("AAAAAA=="), true, &mem
, &len
) == -EINVAL
);
489 assert_se(unbase32hexmem("AB======", strlen("AB======"), true, &mem
, &len
) == -EINVAL
);
490 assert_se(unbase32hexmem("AAAB====", strlen("AAAB===="), true, &mem
, &len
) == -EINVAL
);
491 assert_se(unbase32hexmem("AAAAB===", strlen("AAAAB==="), true, &mem
, &len
) == -EINVAL
);
492 assert_se(unbase32hexmem("AAAAAAB=", strlen("AAAAAAB="), true, &mem
, &len
) == -EINVAL
);
494 assert_se(unbase32hexmem("XPNMUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
495 assert_se(unbase32hexmem("CXNMUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
496 assert_se(unbase32hexmem("CPXMUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
497 assert_se(unbase32hexmem("CPNXUOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
498 assert_se(unbase32hexmem("CPNMXOJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
499 assert_se(unbase32hexmem("CPNMUXJ1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
500 assert_se(unbase32hexmem("CPNMUOX1", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
501 assert_se(unbase32hexmem("CPNMUOJX", strlen("CPNMUOJ1"), true, &mem
, &len
) == -EINVAL
);
503 assert_se(unbase32hexmem("", strlen(""), false, &mem
, &len
) == 0);
504 assert_se(streq(strndupa(mem
, len
), ""));
507 assert_se(unbase32hexmem("CO", strlen("CO"), false, &mem
, &len
) == 0);
508 assert_se(streq(strndupa(mem
, len
), "f"));
511 assert_se(unbase32hexmem("CPNG", strlen("CPNG"), false, &mem
, &len
) == 0);
512 assert_se(streq(strndupa(mem
, len
), "fo"));
515 assert_se(unbase32hexmem("CPNMU", strlen("CPNMU"), false, &mem
, &len
) == 0);
516 assert_se(streq(strndupa(mem
, len
), "foo"));
519 assert_se(unbase32hexmem("CPNMUOG", strlen("CPNMUOG"), false, &mem
, &len
) == 0);
520 assert_se(streq(strndupa(mem
, len
), "foob"));
523 assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), false, &mem
, &len
) == 0);
524 assert_se(streq(strndupa(mem
, len
), "fooba"));
527 assert_se(unbase32hexmem("CPNMUOJ1E8", strlen("CPNMUOJ1E8"), false, &mem
, &len
) == 0);
528 assert_se(streq(strndupa(mem
, len
), "foobar"));
531 assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), false, &mem
, &len
) == -EINVAL
);
532 assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), false, &mem
, &len
) == -EINVAL
);
533 assert_se(unbase32hexmem("A", strlen("A"), false, &mem
, &len
) == -EINVAL
);
534 assert_se(unbase32hexmem("A", strlen("A"), false, &mem
, &len
) == -EINVAL
);
535 assert_se(unbase32hexmem("AAA", strlen("AAA"), false, &mem
, &len
) == -EINVAL
);
536 assert_se(unbase32hexmem("AAAAAA", strlen("AAAAAA"), false, &mem
, &len
) == -EINVAL
);
537 assert_se(unbase32hexmem("AB", strlen("AB"), false, &mem
, &len
) == -EINVAL
);
538 assert_se(unbase32hexmem("AAAB", strlen("AAAB"), false, &mem
, &len
) == -EINVAL
);
539 assert_se(unbase32hexmem("AAAAB", strlen("AAAAB"), false, &mem
, &len
) == -EINVAL
);
540 assert_se(unbase32hexmem("AAAAAAB", strlen("AAAAAAB"), false, &mem
, &len
) == -EINVAL
);
543 /* https://tools.ietf.org/html/rfc4648#section-10 */
544 static void test_base64mem(void) {
547 b64
= base64mem("", strlen(""));
549 assert_se(streq(b64
, ""));
552 b64
= base64mem("f", strlen("f"));
554 assert_se(streq(b64
, "Zg=="));
557 b64
= base64mem("fo", strlen("fo"));
559 assert_se(streq(b64
, "Zm8="));
562 b64
= base64mem("foo", strlen("foo"));
564 assert_se(streq(b64
, "Zm9v"));
567 b64
= base64mem("foob", strlen("foob"));
569 assert_se(streq(b64
, "Zm9vYg=="));
572 b64
= base64mem("fooba", strlen("fooba"));
574 assert_se(streq(b64
, "Zm9vYmE="));
577 b64
= base64mem("foobar", strlen("foobar"));
579 assert_se(streq(b64
, "Zm9vYmFy"));
583 static void test_unbase64mem(void) {
587 assert_se(unbase64mem("", strlen(""), &mem
, &len
) == 0);
588 assert_se(streq(strndupa(mem
, len
), ""));
591 assert_se(unbase64mem("Zg==", strlen("Zg=="), &mem
, &len
) == 0);
592 assert_se(streq(strndupa(mem
, len
), "f"));
595 assert_se(unbase64mem("Zm8=", strlen("Zm8="), &mem
, &len
) == 0);
596 assert_se(streq(strndupa(mem
, len
), "fo"));
599 assert_se(unbase64mem("Zm9v", strlen("Zm9v"), &mem
, &len
) == 0);
600 assert_se(streq(strndupa(mem
, len
), "foo"));
603 assert_se(unbase64mem("Zm9vYg==", strlen("Zm9vYg=="), &mem
, &len
) == 0);
604 assert_se(streq(strndupa(mem
, len
), "foob"));
607 assert_se(unbase64mem("Zm9vYmE=", strlen("Zm9vYmE="), &mem
, &len
) == 0);
608 assert_se(streq(strndupa(mem
, len
), "fooba"));
611 assert_se(unbase64mem("Zm9vYmFy", strlen("Zm9vYmFy"), &mem
, &len
) == 0);
612 assert_se(streq(strndupa(mem
, len
), "foobar"));
615 assert_se(unbase64mem("A", strlen("A"), &mem
, &len
) == -EINVAL
);
616 assert_se(unbase64mem("A====", strlen("A===="), &mem
, &len
) == -EINVAL
);
617 assert_se(unbase64mem("AAB==", strlen("AAB=="), &mem
, &len
) == -EINVAL
);
618 assert_se(unbase64mem("AAAB=", strlen("AAAB="), &mem
, &len
) == -EINVAL
);
621 static void test_cescape(void) {
622 _cleanup_free_
char *escaped
;
624 assert_se(escaped
= cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
625 assert_se(streq(escaped
, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
628 static void test_cunescape(void) {
629 _cleanup_free_
char *unescaped
;
631 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped
) < 0);
632 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX
, &unescaped
) >= 0);
633 assert_se(streq_ptr(unescaped
, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
634 unescaped
= mfree(unescaped
);
636 /* incomplete sequences */
637 assert_se(cunescape("\\x0", 0, &unescaped
) < 0);
638 assert_se(cunescape("\\x0", UNESCAPE_RELAX
, &unescaped
) >= 0);
639 assert_se(streq_ptr(unescaped
, "\\x0"));
640 unescaped
= mfree(unescaped
);
642 assert_se(cunescape("\\x", 0, &unescaped
) < 0);
643 assert_se(cunescape("\\x", UNESCAPE_RELAX
, &unescaped
) >= 0);
644 assert_se(streq_ptr(unescaped
, "\\x"));
645 unescaped
= mfree(unescaped
);
647 assert_se(cunescape("\\", 0, &unescaped
) < 0);
648 assert_se(cunescape("\\", UNESCAPE_RELAX
, &unescaped
) >= 0);
649 assert_se(streq_ptr(unescaped
, "\\"));
650 unescaped
= mfree(unescaped
);
652 assert_se(cunescape("\\11", 0, &unescaped
) < 0);
653 assert_se(cunescape("\\11", UNESCAPE_RELAX
, &unescaped
) >= 0);
654 assert_se(streq_ptr(unescaped
, "\\11"));
655 unescaped
= mfree(unescaped
);
657 assert_se(cunescape("\\1", 0, &unescaped
) < 0);
658 assert_se(cunescape("\\1", UNESCAPE_RELAX
, &unescaped
) >= 0);
659 assert_se(streq_ptr(unescaped
, "\\1"));
660 unescaped
= mfree(unescaped
);
662 assert_se(cunescape("\\u0000", 0, &unescaped
) < 0);
663 assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX
, &unescaped
) >= 0);
664 assert_se(streq_ptr(unescaped
, "ßßΠA"));
665 unescaped
= mfree(unescaped
);
667 assert_se(cunescape("\\073", 0, &unescaped
) >= 0);
668 assert_se(streq_ptr(unescaped
, ";"));
671 static void test_foreach_word(void) {
672 const char *word
, *state
;
675 const char test
[] = "test abc d\te f ";
676 const char * const expected
[] = {
686 FOREACH_WORD(word
, l
, test
, state
)
687 assert_se(strneq(expected
[i
++], word
, l
));
690 static void check(const char *test
, char** expected
, bool trailing
) {
691 const char *word
, *state
;
695 printf("<<<%s>>>\n", test
);
696 FOREACH_WORD_QUOTED(word
, l
, test
, state
) {
697 _cleanup_free_
char *t
= NULL
;
699 assert_se(t
= strndup(word
, l
));
700 assert_se(strneq(expected
[i
++], word
, l
));
703 printf("<<<%s>>>\n", state
);
704 assert_se(expected
[i
] == NULL
);
705 assert_se(isempty(state
) == !trailing
);
708 static void test_foreach_word_quoted(void) {
709 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
733 static void test_memdup_multiply(void) {
734 int org
[] = {1, 2, 3};
737 dup
= (int*)memdup_multiply(org
, sizeof(int), 3);
740 assert_se(dup
[0] == 1);
741 assert_se(dup
[1] == 2);
742 assert_se(dup
[2] == 3);
746 static void test_u64log2(void) {
747 assert_se(u64log2(0) == 0);
748 assert_se(u64log2(8) == 3);
749 assert_se(u64log2(9) == 3);
750 assert_se(u64log2(15) == 3);
751 assert_se(u64log2(16) == 4);
752 assert_se(u64log2(1024*1024) == 20);
753 assert_se(u64log2(1024*1024+5) == 20);
756 static void test_protect_errno(void) {
762 assert_se(errno
== 12);
765 static void test_parse_cpu_set(void) {
770 /* Simple range (from CPUAffinity example) */
771 ncpus
= parse_cpu_set_and_warn("1 2", &c
, NULL
, "fake", 1, "CPUAffinity");
772 assert_se(ncpus
>= 1024);
773 assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus
), c
));
774 assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus
), c
));
775 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 2);
778 /* A more interesting range */
779 ncpus
= parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c
, NULL
, "fake", 1, "CPUAffinity");
780 assert_se(ncpus
>= 1024);
781 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
782 for (cpu
= 0; cpu
< 4; cpu
++)
783 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
784 for (cpu
= 8; cpu
< 12; cpu
++)
785 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
789 ncpus
= parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c
, NULL
, "fake", 1, "CPUAffinity");
790 assert_se(ncpus
>= 1024);
791 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 4);
792 for (cpu
= 8; cpu
< 12; cpu
++)
793 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
796 /* Use commas as separators */
797 ncpus
= parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c
, NULL
, "fake", 1, "CPUAffinity");
798 assert_se(ncpus
>= 1024);
799 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
800 for (cpu
= 0; cpu
< 4; cpu
++)
801 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
802 for (cpu
= 8; cpu
< 12; cpu
++)
803 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
806 /* Commas with spaces (and trailing comma, space) */
807 ncpus
= parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c
, NULL
, "fake", 1, "CPUAffinity");
808 assert_se(ncpus
>= 1024);
809 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
810 for (cpu
= 0; cpu
< 8; cpu
++)
811 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
815 ncpus
= parse_cpu_set_and_warn("0-3,8-11", &c
, NULL
, "fake", 1, "CPUAffinity");
816 assert_se(ncpus
>= 1024);
817 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
818 for (cpu
= 0; cpu
< 4; cpu
++)
819 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
820 for (cpu
= 8; cpu
< 12; cpu
++)
821 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
824 /* Ranges with trailing comma, space */
825 ncpus
= parse_cpu_set_and_warn("0-3 8-11, ", &c
, NULL
, "fake", 1, "CPUAffinity");
826 assert_se(ncpus
>= 1024);
827 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 8);
828 for (cpu
= 0; cpu
< 4; cpu
++)
829 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
830 for (cpu
= 8; cpu
< 12; cpu
++)
831 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
834 /* Negative range (returns empty cpu_set) */
835 ncpus
= parse_cpu_set_and_warn("3-0", &c
, NULL
, "fake", 1, "CPUAffinity");
836 assert_se(ncpus
>= 1024);
837 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 0);
840 /* Overlapping ranges */
841 ncpus
= parse_cpu_set_and_warn("0-7 4-11", &c
, NULL
, "fake", 1, "CPUAffinity");
842 assert_se(ncpus
>= 1024);
843 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 12);
844 for (cpu
= 0; cpu
< 12; cpu
++)
845 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
848 /* Mix ranges and individual CPUs */
849 ncpus
= parse_cpu_set_and_warn("0,1 4-11", &c
, NULL
, "fake", 1, "CPUAffinity");
850 assert_se(ncpus
>= 1024);
851 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus
), c
) == 10);
852 assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus
), c
));
853 assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus
), c
));
854 for (cpu
= 4; cpu
< 12; cpu
++)
855 assert_se(CPU_ISSET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
));
859 ncpus
= parse_cpu_set_and_warn("0 1 2 3 garbage", &c
, NULL
, "fake", 1, "CPUAffinity");
860 assert_se(ncpus
< 0);
863 /* Range with garbage */
864 ncpus
= parse_cpu_set_and_warn("0-3 8-garbage", &c
, NULL
, "fake", 1, "CPUAffinity");
865 assert_se(ncpus
< 0);
870 ncpus
= parse_cpu_set_and_warn("", &c
, NULL
, "fake", 1, "CPUAffinity");
871 assert_se(ncpus
== 0); /* empty string returns 0 */
874 /* Runnaway quoted string */
875 ncpus
= parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c
, NULL
, "fake", 1, "CPUAffinity");
876 assert_se(ncpus
< 0);
880 static void test_config_parse_iec_uint64(void) {
882 assert_se(config_parse_iec_uint64(NULL
, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset
, NULL
) == 0);
883 assert_se(offset
== 4 * 1024 * 1024);
885 assert_se(config_parse_iec_uint64(NULL
, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset
, NULL
) == 0);
888 static void test_strextend(void) {
889 _cleanup_free_
char *str
= strdup("0123");
890 strextend(&str
, "456", "78", "9", NULL
);
891 assert_se(streq(str
, "0123456789"));
894 static void test_strrep(void) {
895 _cleanup_free_
char *one
, *three
, *zero
;
896 one
= strrep("waldo", 1);
897 three
= strrep("waldo", 3);
898 zero
= strrep("waldo", 0);
900 assert_se(streq(one
, "waldo"));
901 assert_se(streq(three
, "waldowaldowaldo"));
902 assert_se(streq(zero
, ""));
905 static void test_split_pair(void) {
906 _cleanup_free_
char *a
= NULL
, *b
= NULL
;
908 assert_se(split_pair("", "", &a
, &b
) == -EINVAL
);
909 assert_se(split_pair("foo=bar", "", &a
, &b
) == -EINVAL
);
910 assert_se(split_pair("", "=", &a
, &b
) == -EINVAL
);
911 assert_se(split_pair("foo=bar", "=", &a
, &b
) >= 0);
912 assert_se(streq(a
, "foo"));
913 assert_se(streq(b
, "bar"));
916 assert_se(split_pair("==", "==", &a
, &b
) >= 0);
917 assert_se(streq(a
, ""));
918 assert_se(streq(b
, ""));
922 assert_se(split_pair("===", "==", &a
, &b
) >= 0);
923 assert_se(streq(a
, ""));
924 assert_se(streq(b
, "="));
927 static void test_fstab_node_to_udev_node(void) {
930 n
= fstab_node_to_udev_node("LABEL=applé/jack");
932 assert_se(streq(n
, "/dev/disk/by-label/applé\\x2fjack"));
935 n
= fstab_node_to_udev_node("PARTLABEL=pinkié pie");
937 assert_se(streq(n
, "/dev/disk/by-partlabel/pinkié\\x20pie"));
940 n
= fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
942 assert_se(streq(n
, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
945 n
= fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
947 assert_se(streq(n
, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
950 n
= fstab_node_to_udev_node("PONIES=awesome");
952 assert_se(streq(n
, "PONIES=awesome"));
955 n
= fstab_node_to_udev_node("/dev/xda1");
957 assert_se(streq(n
, "/dev/xda1"));
961 static void test_get_files_in_directory(void) {
962 _cleanup_strv_free_
char **l
= NULL
, **t
= NULL
;
964 assert_se(get_files_in_directory("/tmp", &l
) >= 0);
965 assert_se(get_files_in_directory(".", &t
) >= 0);
966 assert_se(get_files_in_directory(".", NULL
) >= 0);
969 static void test_in_set(void) {
970 assert_se(IN_SET(1, 1));
971 assert_se(IN_SET(1, 1, 2, 3, 4));
972 assert_se(IN_SET(2, 1, 2, 3, 4));
973 assert_se(IN_SET(3, 1, 2, 3, 4));
974 assert_se(IN_SET(4, 1, 2, 3, 4));
975 assert_se(!IN_SET(0, 1));
976 assert_se(!IN_SET(0, 1, 2, 3, 4));
979 static void test_writing_tmpfile(void) {
980 char name
[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
981 _cleanup_free_
char *contents
= NULL
;
986 IOVEC_SET_STRING(iov
[0], "abc\n");
987 IOVEC_SET_STRING(iov
[1], ALPHANUMERICAL
"\n");
988 IOVEC_SET_STRING(iov
[2], "");
990 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
991 printf("tmpfile: %s", name
);
993 r
= writev(fd
, iov
, 3);
996 r
= read_full_file(name
, &contents
, &size
);
998 printf("contents: %s", contents
);
999 assert_se(streq(contents
, "abc\n" ALPHANUMERICAL
"\n"));
1004 static void test_hexdump(void) {
1008 hexdump(stdout
, NULL
, 0);
1009 hexdump(stdout
, "", 0);
1010 hexdump(stdout
, "", 1);
1011 hexdump(stdout
, "x", 1);
1012 hexdump(stdout
, "x", 2);
1013 hexdump(stdout
, "foobar", 7);
1014 hexdump(stdout
, "f\nobar", 7);
1015 hexdump(stdout
, "xxxxxxxxxxxxxxxxxxxxyz", 23);
1017 for (i
= 0; i
< ELEMENTSOF(data
); i
++)
1020 hexdump(stdout
, data
, sizeof(data
));
1023 static void test_log2i(void) {
1024 assert_se(log2i(1) == 0);
1025 assert_se(log2i(2) == 1);
1026 assert_se(log2i(3) == 1);
1027 assert_se(log2i(4) == 2);
1028 assert_se(log2i(32) == 5);
1029 assert_se(log2i(33) == 5);
1030 assert_se(log2i(63) == 5);
1031 assert_se(log2i(INT_MAX
) == sizeof(int)*8-2);
1034 static void test_foreach_string(void) {
1035 const char * const t
[] = {
1044 FOREACH_STRING(x
, "foo", "bar", "waldo")
1045 assert_se(streq_ptr(t
[i
++], x
));
1049 FOREACH_STRING(x
, "zzz")
1050 assert_se(streq(x
, "zzz"));
1053 static void test_filename_is_valid(void) {
1054 char foo
[FILENAME_MAX
+2];
1057 assert_se(!filename_is_valid(""));
1058 assert_se(!filename_is_valid("/bar/foo"));
1059 assert_se(!filename_is_valid("/"));
1060 assert_se(!filename_is_valid("."));
1061 assert_se(!filename_is_valid(".."));
1063 for (i
=0; i
<FILENAME_MAX
+1; i
++)
1065 foo
[FILENAME_MAX
+1] = '\0';
1067 assert_se(!filename_is_valid(foo
));
1069 assert_se(filename_is_valid("foo_bar-333"));
1070 assert_se(filename_is_valid("o.o"));
1073 static void test_string_has_cc(void) {
1074 assert_se(string_has_cc("abc\1", NULL
));
1075 assert_se(string_has_cc("abc\x7f", NULL
));
1076 assert_se(string_has_cc("abc\x7f", NULL
));
1077 assert_se(string_has_cc("abc\t\x7f", "\t"));
1078 assert_se(string_has_cc("abc\t\x7f", "\t"));
1079 assert_se(string_has_cc("\x7f", "\t"));
1080 assert_se(string_has_cc("\x7f", "\t\a"));
1082 assert_se(!string_has_cc("abc\t\t", "\t"));
1083 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
1084 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
1087 static void test_ascii_strlower(void) {
1088 char a
[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
1089 assert_se(streq(ascii_strlower(a
), "aabbcc jk ii od lkjjj kkd lk"));
1092 static void test_files_same(void) {
1093 _cleanup_close_
int fd
= -1;
1094 char name
[] = "/tmp/test-files_same.XXXXXX";
1095 char name_alias
[] = "/tmp/test-files_same.alias";
1097 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1099 assert_se(symlink(name
, name_alias
) >= 0);
1101 assert_se(files_same(name
, name
));
1102 assert_se(files_same(name
, name_alias
));
1108 static void test_is_valid_documentation_url(void) {
1109 assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
1110 assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
1111 assert_se(documentation_url_is_valid("file:/foo/foo"));
1112 assert_se(documentation_url_is_valid("man:systemd.special(7)"));
1113 assert_se(documentation_url_is_valid("info:bar"));
1115 assert_se(!documentation_url_is_valid("foo:"));
1116 assert_se(!documentation_url_is_valid("info:"));
1117 assert_se(!documentation_url_is_valid(""));
1120 static void test_file_in_same_dir(void) {
1123 t
= file_in_same_dir("/", "a");
1124 assert_se(streq(t
, "/a"));
1127 t
= file_in_same_dir("/", "/a");
1128 assert_se(streq(t
, "/a"));
1131 t
= file_in_same_dir("", "a");
1132 assert_se(streq(t
, "a"));
1135 t
= file_in_same_dir("a/", "a");
1136 assert_se(streq(t
, "a/a"));
1139 t
= file_in_same_dir("bar/foo", "bar");
1140 assert_se(streq(t
, "bar/bar"));
1144 static void test_endswith(void) {
1145 assert_se(endswith("foobar", "bar"));
1146 assert_se(endswith("foobar", ""));
1147 assert_se(endswith("foobar", "foobar"));
1148 assert_se(endswith("", ""));
1150 assert_se(!endswith("foobar", "foo"));
1151 assert_se(!endswith("foobar", "foobarfoofoo"));
1154 static void test_endswith_no_case(void) {
1155 assert_se(endswith_no_case("fooBAR", "bar"));
1156 assert_se(endswith_no_case("foobar", ""));
1157 assert_se(endswith_no_case("foobar", "FOOBAR"));
1158 assert_se(endswith_no_case("", ""));
1160 assert_se(!endswith_no_case("foobar", "FOO"));
1161 assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
1164 static void test_close_nointr(void) {
1165 char name
[] = "/tmp/test-test-close_nointr.XXXXXX";
1168 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1170 assert_se(close_nointr(fd
) >= 0);
1171 assert_se(close_nointr(fd
) < 0);
1177 static void test_unlink_noerrno(void) {
1178 char name
[] = "/tmp/test-close_nointr.XXXXXX";
1181 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1183 assert_se(close_nointr(fd
) >= 0);
1188 assert_se(unlink_noerrno(name
) >= 0);
1189 assert_se(errno
== -42);
1190 assert_se(unlink_noerrno(name
) < 0);
1191 assert_se(errno
== -42);
1195 static void test_readlink_and_make_absolute(void) {
1196 char tempdir
[] = "/tmp/test-readlink_and_make_absolute";
1197 char name
[] = "/tmp/test-readlink_and_make_absolute/original";
1198 char name2
[] = "test-readlink_and_make_absolute/original";
1199 char name_alias
[] = "/tmp/test-readlink_and_make_absolute-alias";
1202 assert_se(mkdir_safe(tempdir
, 0755, getuid(), getgid()) >= 0);
1203 assert_se(touch(name
) >= 0);
1205 assert_se(symlink(name
, name_alias
) >= 0);
1206 assert_se(readlink_and_make_absolute(name_alias
, &r
) >= 0);
1207 assert_se(streq(r
, name
));
1209 assert_se(unlink(name_alias
) >= 0);
1211 assert_se(chdir(tempdir
) >= 0);
1212 assert_se(symlink(name2
, name_alias
) >= 0);
1213 assert_se(readlink_and_make_absolute(name_alias
, &r
) >= 0);
1214 assert_se(streq(r
, name
));
1216 assert_se(unlink(name_alias
) >= 0);
1218 assert_se(rm_rf(tempdir
, REMOVE_ROOT
|REMOVE_PHYSICAL
) >= 0);
1221 static void test_ignore_signals(void) {
1222 assert_se(ignore_signals(SIGINT
, -1) >= 0);
1223 assert_se(kill(getpid(), SIGINT
) >= 0);
1224 assert_se(ignore_signals(SIGUSR1
, SIGUSR2
, SIGTERM
, SIGPIPE
, -1) >= 0);
1225 assert_se(kill(getpid(), SIGUSR1
) >= 0);
1226 assert_se(kill(getpid(), SIGUSR2
) >= 0);
1227 assert_se(kill(getpid(), SIGTERM
) >= 0);
1228 assert_se(kill(getpid(), SIGPIPE
) >= 0);
1229 assert_se(default_signals(SIGINT
, SIGUSR1
, SIGUSR2
, SIGTERM
, SIGPIPE
, -1) >= 0);
1232 static void test_strshorten(void) {
1233 char s
[] = "foobar";
1235 assert_se(strlen(strshorten(s
, 6)) == 6);
1236 assert_se(strlen(strshorten(s
, 12)) == 6);
1237 assert_se(strlen(strshorten(s
, 2)) == 2);
1238 assert_se(strlen(strshorten(s
, 0)) == 0);
1241 static void test_strjoina(void) {
1244 actual
= strjoina("", "foo", "bar");
1245 assert_se(streq(actual
, "foobar"));
1247 actual
= strjoina("foo", "bar", "baz");
1248 assert_se(streq(actual
, "foobarbaz"));
1250 actual
= strjoina("foo", "", "bar", "baz");
1251 assert_se(streq(actual
, "foobarbaz"));
1253 actual
= strjoina("foo");
1254 assert_se(streq(actual
, "foo"));
1256 actual
= strjoina(NULL
);
1257 assert_se(streq(actual
, ""));
1259 actual
= strjoina(NULL
, "foo");
1260 assert_se(streq(actual
, ""));
1262 actual
= strjoina("foo", NULL
, "bar");
1263 assert_se(streq(actual
, "foo"));
1266 static void test_is_symlink(void) {
1267 char name
[] = "/tmp/test-is_symlink.XXXXXX";
1268 char name_link
[] = "/tmp/test-is_symlink.link";
1269 _cleanup_close_
int fd
= -1;
1271 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1273 assert_se(symlink(name
, name_link
) >= 0);
1275 assert_se(is_symlink(name
) == 0);
1276 assert_se(is_symlink(name_link
) == 1);
1277 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1284 static void test_search_and_fopen(void) {
1285 const char *dirs
[] = {"/tmp/foo/bar", "/tmp", NULL
};
1286 char name
[] = "/tmp/test-search_and_fopen.XXXXXX";
1291 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1295 r
= search_and_fopen(basename(name
), "r", NULL
, dirs
, &f
);
1299 r
= search_and_fopen(name
, "r", NULL
, dirs
, &f
);
1303 r
= search_and_fopen(basename(name
), "r", "/", dirs
, &f
);
1307 r
= search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL
, dirs
, &f
);
1309 r
= search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL
, dirs
, &f
);
1315 r
= search_and_fopen(basename(name
), "r", NULL
, dirs
, &f
);
1320 static void test_search_and_fopen_nulstr(void) {
1321 const char dirs
[] = "/tmp/foo/bar\0/tmp\0";
1322 char name
[] = "/tmp/test-search_and_fopen.XXXXXX";
1327 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1331 r
= search_and_fopen_nulstr(basename(name
), "r", NULL
, dirs
, &f
);
1335 r
= search_and_fopen_nulstr(name
, "r", NULL
, dirs
, &f
);
1339 r
= search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL
, dirs
, &f
);
1341 r
= search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL
, dirs
, &f
);
1347 r
= search_and_fopen_nulstr(basename(name
), "r", NULL
, dirs
, &f
);
1351 static void test_glob_exists(void) {
1352 char name
[] = "/tmp/test-glob_exists.XXXXXX";
1356 fd
= mkostemp_safe(name
, O_RDWR
|O_CLOEXEC
);
1360 r
= glob_exists("/tmp/test-glob_exists*");
1365 r
= glob_exists("/tmp/test-glob_exists*");
1369 static void test_execute_directory(void) {
1370 char template_lo
[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1371 char template_hi
[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
1372 const char * dirs
[] = {template_hi
, template_lo
, NULL
};
1373 const char *name
, *name2
, *name3
, *overridden
, *override
, *masked
, *mask
;
1375 assert_se(mkdtemp(template_lo
));
1376 assert_se(mkdtemp(template_hi
));
1378 name
= strjoina(template_lo
, "/script");
1379 name2
= strjoina(template_hi
, "/script2");
1380 name3
= strjoina(template_lo
, "/useless");
1381 overridden
= strjoina(template_lo
, "/overridden");
1382 override
= strjoina(template_hi
, "/overridden");
1383 masked
= strjoina(template_lo
, "/masked");
1384 mask
= strjoina(template_hi
, "/masked");
1386 assert_se(write_string_file(name
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE
) == 0);
1387 assert_se(write_string_file(name2
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE
) == 0);
1388 assert_se(write_string_file(overridden
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE
) == 0);
1389 assert_se(write_string_file(override
, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE
) == 0);
1390 assert_se(write_string_file(masked
, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE
) == 0);
1391 assert_se(symlink("/dev/null", mask
) == 0);
1392 assert_se(chmod(name
, 0755) == 0);
1393 assert_se(chmod(name2
, 0755) == 0);
1394 assert_se(chmod(overridden
, 0755) == 0);
1395 assert_se(chmod(override
, 0755) == 0);
1396 assert_se(chmod(masked
, 0755) == 0);
1397 assert_se(touch(name3
) >= 0);
1399 execute_directories(dirs
, DEFAULT_TIMEOUT_USEC
, NULL
);
1401 assert_se(chdir(template_lo
) == 0);
1402 assert_se(access("it_works", F_OK
) >= 0);
1403 assert_se(access("failed", F_OK
) < 0);
1405 assert_se(chdir(template_hi
) == 0);
1406 assert_se(access("it_works2", F_OK
) >= 0);
1407 assert_se(access("failed", F_OK
) < 0);
1409 (void) rm_rf(template_lo
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
1410 (void) rm_rf(template_hi
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
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 static void test_shell_escape_one(const char *s
, const char *bad
, const char *expected
) {
1529 _cleanup_free_
char *r
;
1531 assert_se(r
= shell_escape(s
, bad
));
1532 assert_se(streq_ptr(r
, expected
));
1535 static void test_shell_escape(void) {
1536 test_shell_escape_one("", "", "");
1537 test_shell_escape_one("\\", "", "\\\\");
1538 test_shell_escape_one("foobar", "", "foobar");
1539 test_shell_escape_one("foobar", "o", "f\\o\\obar");
1540 test_shell_escape_one("foo:bar,baz", ",:", "foo\\:bar\\,baz");
1543 static void test_shell_maybe_quote_one(const char *s
, const char *expected
) {
1544 _cleanup_free_
char *r
;
1546 assert_se(r
= shell_maybe_quote(s
));
1547 assert_se(streq(r
, expected
));
1550 static void test_shell_maybe_quote(void) {
1552 test_shell_maybe_quote_one("", "");
1553 test_shell_maybe_quote_one("\\", "\"\\\\\"");
1554 test_shell_maybe_quote_one("\"", "\"\\\"\"");
1555 test_shell_maybe_quote_one("foobar", "foobar");
1556 test_shell_maybe_quote_one("foo bar", "\"foo bar\"");
1557 test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\"");
1558 test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
1561 static void test_tempfn(void) {
1562 char *ret
= NULL
, *p
;
1564 assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL
, &ret
) >= 0);
1565 assert_se(streq_ptr(ret
, "/foo/bar/.#waldoXXXXXX"));
1568 assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret
) >= 0);
1569 assert_se(streq_ptr(ret
, "/foo/bar/.#[miau]waldoXXXXXX"));
1572 assert_se(tempfn_random("/foo/bar/waldo", NULL
, &ret
) >= 0);
1573 assert_se(p
= startswith(ret
, "/foo/bar/.#waldo"));
1574 assert_se(strlen(p
) == 16);
1575 assert_se(in_charset(p
, "0123456789abcdef"));
1578 assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret
) >= 0);
1579 assert_se(p
= startswith(ret
, "/foo/bar/.#[wuff]waldo"));
1580 assert_se(strlen(p
) == 16);
1581 assert_se(in_charset(p
, "0123456789abcdef"));
1584 assert_se(tempfn_random_child("/foo/bar/waldo", NULL
, &ret
) >= 0);
1585 assert_se(p
= startswith(ret
, "/foo/bar/waldo/.#"));
1586 assert_se(strlen(p
) == 16);
1587 assert_se(in_charset(p
, "0123456789abcdef"));
1590 assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret
) >= 0);
1591 assert_se(p
= startswith(ret
, "/foo/bar/waldo/.#[kikiriki]"));
1592 assert_se(strlen(p
) == 16);
1593 assert_se(in_charset(p
, "0123456789abcdef"));
1597 static void test_strcmp_ptr(void) {
1598 assert_se(strcmp_ptr(NULL
, NULL
) == 0);
1599 assert_se(strcmp_ptr("", NULL
) > 0);
1600 assert_se(strcmp_ptr("foo", NULL
) > 0);
1601 assert_se(strcmp_ptr(NULL
, "") < 0);
1602 assert_se(strcmp_ptr(NULL
, "bar") < 0);
1603 assert_se(strcmp_ptr("foo", "bar") > 0);
1604 assert_se(strcmp_ptr("bar", "baz") < 0);
1605 assert_se(strcmp_ptr("foo", "foo") == 0);
1606 assert_se(strcmp_ptr("", "") == 0);
1609 static void test_fgetxattrat_fake(void) {
1610 char t
[] = "/var/tmp/xattrtestXXXXXX";
1611 _cleanup_close_
int fd
= -1;
1616 assert_se(mkdtemp(t
));
1617 x
= strjoina(t
, "/test");
1618 assert_se(touch(x
) >= 0);
1620 r
= setxattr(x
, "user.foo", "bar", 3, 0);
1621 if (r
< 0 && errno
== EOPNOTSUPP
) /* no xattrs supported on /var/tmp... */
1625 fd
= open(t
, O_RDONLY
|O_DIRECTORY
|O_CLOEXEC
|O_NOCTTY
);
1628 assert_se(fgetxattrat_fake(fd
, "test", "user.foo", v
, 3, 0) >= 0);
1629 assert_se(memcmp(v
, "bar", 3) == 0);
1632 fd
= open("/", O_RDONLY
|O_DIRECTORY
|O_CLOEXEC
|O_NOCTTY
);
1634 assert_se(fgetxattrat_fake(fd
, "usr", "user.idontexist", v
, 3, 0) == -ENODATA
);
1637 assert_se(unlink(x
) >= 0);
1638 assert_se(rmdir(t
) >= 0);
1641 int main(int argc
, char *argv
[]) {
1642 log_parse_environment();
1646 test_align_power2();
1648 test_container_of();
1650 test_div_round_up();
1656 test_delete_chars();
1660 test_base32hexchar();
1661 test_unbase32hexchar();
1663 test_unbase64char();
1669 test_base32hexmem();
1670 test_unbase32hexmem();
1675 test_foreach_word();
1676 test_foreach_word_quoted();
1677 test_memdup_multiply();
1679 test_protect_errno();
1680 test_parse_cpu_set();
1681 test_config_parse_iec_uint64();
1685 test_fstab_node_to_udev_node();
1686 test_get_files_in_directory();
1688 test_writing_tmpfile();
1691 test_foreach_string();
1692 test_filename_is_valid();
1693 test_string_has_cc();
1694 test_ascii_strlower();
1696 test_is_valid_documentation_url();
1697 test_file_in_same_dir();
1699 test_endswith_no_case();
1700 test_close_nointr();
1701 test_unlink_noerrno();
1702 test_readlink_and_make_absolute();
1703 test_ignore_signals();
1707 test_search_and_fopen();
1708 test_search_and_fopen_nulstr();
1710 test_execute_directory();
1711 test_parse_proc_cmdline();
1715 test_sparse_write();
1716 test_shell_escape();
1717 test_shell_maybe_quote();
1720 test_fgetxattrat_fake();