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 assert_se(base64mem("", strlen(""), &b64) == 0);
549 assert_se(streq(b64, ""));
552 assert_se(base64mem("f", strlen("f"), &b64) == 4);
553 assert_se(streq(b64, "Zg=="));
556 assert_se(base64mem("fo", strlen("fo"), &b64) == 4);
557 assert_se(streq(b64, "Zm8="));
560 assert_se(base64mem("foo", strlen("foo"), &b64) == 4);
561 assert_se(streq(b64, "Zm9v"));
564 assert_se(base64mem("foob", strlen("foob"), &b64) == 8);
565 assert_se(streq(b64, "Zm9vYg=="));
568 assert_se(base64mem("fooba", strlen("fooba"), &b64) == 8);
569 assert_se(streq(b64, "Zm9vYmE="));
572 assert_se(base64mem("foobar", strlen("foobar"), &b64) == 8);
573 assert_se(streq(b64, "Zm9vYmFy"));
577 static void test_unbase64mem(void) {
581 assert_se(unbase64mem("", strlen(""), &mem, &len) == 0);
582 assert_se(streq(strndupa(mem, len), ""));
585 assert_se(unbase64mem("Zg==", strlen("Zg=="), &mem, &len) == 0);
586 assert_se(streq(strndupa(mem, len), "f"));
589 assert_se(unbase64mem("Zm8=", strlen("Zm8="), &mem, &len) == 0);
590 assert_se(streq(strndupa(mem, len), "fo"));
593 assert_se(unbase64mem("Zm9v", strlen("Zm9v"), &mem, &len) == 0);
594 assert_se(streq(strndupa(mem, len), "foo"));
597 assert_se(unbase64mem("Zm9vYg==", strlen("Zm9vYg=="), &mem, &len) == 0);
598 assert_se(streq(strndupa(mem, len), "foob"));
601 assert_se(unbase64mem("Zm9vYmE=", strlen("Zm9vYmE="), &mem, &len) == 0);
602 assert_se(streq(strndupa(mem, len), "fooba"));
605 assert_se(unbase64mem("Zm9vYmFy", strlen("Zm9vYmFy"), &mem, &len) == 0);
606 assert_se(streq(strndupa(mem, len), "foobar"));
609 assert_se(unbase64mem("A", strlen("A"), &mem, &len) == -EINVAL);
610 assert_se(unbase64mem("A====", strlen("A===="), &mem, &len) == -EINVAL);
611 assert_se(unbase64mem("AAB==", strlen("AAB=="), &mem, &len) == -EINVAL);
612 assert_se(unbase64mem("AAAB=", strlen("AAAB="), &mem, &len) == -EINVAL);
615 static void test_cescape(void) {
616 _cleanup_free_ char *escaped;
618 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
619 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
622 static void test_cunescape(void) {
623 _cleanup_free_ char *unescaped;
625 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped) < 0);
626 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX, &unescaped) >= 0);
627 assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
628 unescaped = mfree(unescaped);
630 /* incomplete sequences */
631 assert_se(cunescape("\\x0", 0, &unescaped) < 0);
632 assert_se(cunescape("\\x0", UNESCAPE_RELAX, &unescaped) >= 0);
633 assert_se(streq_ptr(unescaped, "\\x0"));
634 unescaped = mfree(unescaped);
636 assert_se(cunescape("\\x", 0, &unescaped) < 0);
637 assert_se(cunescape("\\x", UNESCAPE_RELAX, &unescaped) >= 0);
638 assert_se(streq_ptr(unescaped, "\\x"));
639 unescaped = mfree(unescaped);
641 assert_se(cunescape("\\", 0, &unescaped) < 0);
642 assert_se(cunescape("\\", UNESCAPE_RELAX, &unescaped) >= 0);
643 assert_se(streq_ptr(unescaped, "\\"));
644 unescaped = mfree(unescaped);
646 assert_se(cunescape("\\11", 0, &unescaped) < 0);
647 assert_se(cunescape("\\11", UNESCAPE_RELAX, &unescaped) >= 0);
648 assert_se(streq_ptr(unescaped, "\\11"));
649 unescaped = mfree(unescaped);
651 assert_se(cunescape("\\1", 0, &unescaped) < 0);
652 assert_se(cunescape("\\1", UNESCAPE_RELAX, &unescaped) >= 0);
653 assert_se(streq_ptr(unescaped, "\\1"));
654 unescaped = mfree(unescaped);
656 assert_se(cunescape("\\u0000", 0, &unescaped) < 0);
657 assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX, &unescaped) >= 0);
658 assert_se(streq_ptr(unescaped, "ßßΠA"));
659 unescaped = mfree(unescaped);
661 assert_se(cunescape("\\073", 0, &unescaped) >= 0);
662 assert_se(streq_ptr(unescaped, ";"));
665 static void test_foreach_word(void) {
666 const char *word, *state;
669 const char test[] = "test abc d\te f ";
670 const char * const expected[] = {
680 FOREACH_WORD(word, l, test, state)
681 assert_se(strneq(expected[i++], word, l));
684 static void check(const char *test, char** expected, bool trailing) {
685 const char *word, *state;
689 printf("<<<%s>>>\n", test);
690 FOREACH_WORD_QUOTED(word, l, test, state) {
691 _cleanup_free_ char *t = NULL;
693 assert_se(t = strndup(word, l));
694 assert_se(strneq(expected[i++], word, l));
697 printf("<<<%s>>>\n", state);
698 assert_se(expected[i] == NULL);
699 assert_se(isempty(state) == !trailing);
702 static void test_foreach_word_quoted(void) {
703 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
727 static void test_memdup_multiply(void) {
728 int org[] = {1, 2, 3};
731 dup = (int*)memdup_multiply(org, sizeof(int), 3);
734 assert_se(dup[0] == 1);
735 assert_se(dup[1] == 2);
736 assert_se(dup[2] == 3);
740 static void test_u64log2(void) {
741 assert_se(u64log2(0) == 0);
742 assert_se(u64log2(8) == 3);
743 assert_se(u64log2(9) == 3);
744 assert_se(u64log2(15) == 3);
745 assert_se(u64log2(16) == 4);
746 assert_se(u64log2(1024*1024) == 20);
747 assert_se(u64log2(1024*1024+5) == 20);
750 static void test_protect_errno(void) {
756 assert_se(errno == 12);
759 static void test_parse_cpu_set(void) {
764 /* Simple range (from CPUAffinity example) */
765 ncpus = parse_cpu_set_and_warn("1 2", &c, NULL, "fake", 1, "CPUAffinity");
766 assert_se(ncpus >= 1024);
767 assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
768 assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
769 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
772 /* A more interesting range */
773 ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity");
774 assert_se(ncpus >= 1024);
775 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
776 for (cpu = 0; cpu < 4; cpu++)
777 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
778 for (cpu = 8; cpu < 12; cpu++)
779 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
783 ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity");
784 assert_se(ncpus >= 1024);
785 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
786 for (cpu = 8; cpu < 12; cpu++)
787 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
790 /* Use commas as separators */
791 ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity");
792 assert_se(ncpus >= 1024);
793 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
794 for (cpu = 0; cpu < 4; cpu++)
795 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
796 for (cpu = 8; cpu < 12; cpu++)
797 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
800 /* Commas with spaces (and trailing comma, space) */
801 ncpus = parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c, NULL, "fake", 1, "CPUAffinity");
802 assert_se(ncpus >= 1024);
803 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
804 for (cpu = 0; cpu < 8; cpu++)
805 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
809 ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
810 assert_se(ncpus >= 1024);
811 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
812 for (cpu = 0; cpu < 4; cpu++)
813 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
814 for (cpu = 8; cpu < 12; cpu++)
815 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
818 /* Ranges with trailing comma, space */
819 ncpus = parse_cpu_set_and_warn("0-3 8-11, ", &c, NULL, "fake", 1, "CPUAffinity");
820 assert_se(ncpus >= 1024);
821 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
822 for (cpu = 0; cpu < 4; cpu++)
823 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
824 for (cpu = 8; cpu < 12; cpu++)
825 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
828 /* Negative range (returns empty cpu_set) */
829 ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity");
830 assert_se(ncpus >= 1024);
831 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0);
834 /* Overlapping ranges */
835 ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity");
836 assert_se(ncpus >= 1024);
837 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
838 for (cpu = 0; cpu < 12; cpu++)
839 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
842 /* Mix ranges and individual CPUs */
843 ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity");
844 assert_se(ncpus >= 1024);
845 assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 10);
846 assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus), c));
847 assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
848 for (cpu = 4; cpu < 12; cpu++)
849 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
853 ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
854 assert_se(ncpus < 0);
857 /* Range with garbage */
858 ncpus = parse_cpu_set_and_warn("0-3 8-garbage", &c, NULL, "fake", 1, "CPUAffinity");
859 assert_se(ncpus < 0);
864 ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
865 assert_se(ncpus == 0); /* empty string returns 0 */
868 /* Runnaway quoted string */
869 ncpus = parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c, NULL, "fake", 1, "CPUAffinity");
870 assert_se(ncpus < 0);
874 static void test_config_parse_iec_uint64(void) {
876 assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
877 assert_se(offset == 4 * 1024 * 1024);
879 assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
882 static void test_strextend(void) {
883 _cleanup_free_ char *str = strdup("0123");
884 strextend(&str, "456", "78", "9", NULL);
885 assert_se(streq(str, "0123456789"));
888 static void test_strrep(void) {
889 _cleanup_free_ char *one, *three, *zero;
890 one = strrep("waldo", 1);
891 three = strrep("waldo", 3);
892 zero = strrep("waldo", 0);
894 assert_se(streq(one, "waldo"));
895 assert_se(streq(three, "waldowaldowaldo"));
896 assert_se(streq(zero, ""));
899 static void test_split_pair(void) {
900 _cleanup_free_ char *a = NULL, *b = NULL;
902 assert_se(split_pair("", "", &a, &b) == -EINVAL);
903 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
904 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
905 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
906 assert_se(streq(a, "foo"));
907 assert_se(streq(b, "bar"));
910 assert_se(split_pair("==", "==", &a, &b) >= 0);
911 assert_se(streq(a, ""));
912 assert_se(streq(b, ""));
916 assert_se(split_pair("===", "==", &a, &b) >= 0);
917 assert_se(streq(a, ""));
918 assert_se(streq(b, "="));
921 static void test_fstab_node_to_udev_node(void) {
924 n = fstab_node_to_udev_node("LABEL=applé/jack");
926 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
929 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
931 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
934 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
936 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
939 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
941 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
944 n = fstab_node_to_udev_node("PONIES=awesome");
946 assert_se(streq(n, "PONIES=awesome"));
949 n = fstab_node_to_udev_node("/dev/xda1");
951 assert_se(streq(n, "/dev/xda1"));
955 static void test_get_files_in_directory(void) {
956 _cleanup_strv_free_ char **l = NULL, **t = NULL;
958 assert_se(get_files_in_directory("/tmp", &l) >= 0);
959 assert_se(get_files_in_directory(".", &t) >= 0);
960 assert_se(get_files_in_directory(".", NULL) >= 0);
963 static void test_in_set(void) {
964 assert_se(IN_SET(1, 1));
965 assert_se(IN_SET(1, 1, 2, 3, 4));
966 assert_se(IN_SET(2, 1, 2, 3, 4));
967 assert_se(IN_SET(3, 1, 2, 3, 4));
968 assert_se(IN_SET(4, 1, 2, 3, 4));
969 assert_se(!IN_SET(0, 1));
970 assert_se(!IN_SET(0, 1, 2, 3, 4));
973 static void test_writing_tmpfile(void) {
974 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
975 _cleanup_free_ char *contents = NULL;
980 IOVEC_SET_STRING(iov[0], "abc\n");
981 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
982 IOVEC_SET_STRING(iov[2], "");
984 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
985 printf("tmpfile: %s", name);
987 r = writev(fd, iov, 3);
990 r = read_full_file(name, &contents, &size);
992 printf("contents: %s", contents);
993 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
998 static void test_hexdump(void) {
1002 hexdump(stdout, NULL, 0);
1003 hexdump(stdout, "", 0);
1004 hexdump(stdout, "", 1);
1005 hexdump(stdout, "x", 1);
1006 hexdump(stdout, "x", 2);
1007 hexdump(stdout, "foobar", 7);
1008 hexdump(stdout, "f\nobar", 7);
1009 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
1011 for (i = 0; i < ELEMENTSOF(data); i++)
1014 hexdump(stdout, data, sizeof(data));
1017 static void test_log2i(void) {
1018 assert_se(log2i(1) == 0);
1019 assert_se(log2i(2) == 1);
1020 assert_se(log2i(3) == 1);
1021 assert_se(log2i(4) == 2);
1022 assert_se(log2i(32) == 5);
1023 assert_se(log2i(33) == 5);
1024 assert_se(log2i(63) == 5);
1025 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
1028 static void test_foreach_string(void) {
1029 const char * const t[] = {
1038 FOREACH_STRING(x, "foo", "bar", "waldo")
1039 assert_se(streq_ptr(t[i++], x));
1043 FOREACH_STRING(x, "zzz")
1044 assert_se(streq(x, "zzz"));
1047 static void test_filename_is_valid(void) {
1048 char foo[FILENAME_MAX+2];
1051 assert_se(!filename_is_valid(""));
1052 assert_se(!filename_is_valid("/bar/foo"));
1053 assert_se(!filename_is_valid("/"));
1054 assert_se(!filename_is_valid("."));
1055 assert_se(!filename_is_valid(".."));
1057 for (i=0; i<FILENAME_MAX+1; i++)
1059 foo[FILENAME_MAX+1] = '\0';
1061 assert_se(!filename_is_valid(foo));
1063 assert_se(filename_is_valid("foo_bar-333"));
1064 assert_se(filename_is_valid("o.o"));
1067 static void test_string_has_cc(void) {
1068 assert_se(string_has_cc("abc\1", NULL));
1069 assert_se(string_has_cc("abc\x7f", NULL));
1070 assert_se(string_has_cc("abc\x7f", NULL));
1071 assert_se(string_has_cc("abc\t\x7f", "\t"));
1072 assert_se(string_has_cc("abc\t\x7f", "\t"));
1073 assert_se(string_has_cc("\x7f", "\t"));
1074 assert_se(string_has_cc("\x7f", "\t\a"));
1076 assert_se(!string_has_cc("abc\t\t", "\t"));
1077 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
1078 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
1081 static void test_ascii_strlower(void) {
1082 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
1083 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
1086 static void test_files_same(void) {
1087 _cleanup_close_ int fd = -1;
1088 char name[] = "/tmp/test-files_same.XXXXXX";
1089 char name_alias[] = "/tmp/test-files_same.alias";
1091 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1093 assert_se(symlink(name, name_alias) >= 0);
1095 assert_se(files_same(name, name));
1096 assert_se(files_same(name, name_alias));
1102 static void test_is_valid_documentation_url(void) {
1103 assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
1104 assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
1105 assert_se(documentation_url_is_valid("file:/foo/foo"));
1106 assert_se(documentation_url_is_valid("man:systemd.special(7)"));
1107 assert_se(documentation_url_is_valid("info:bar"));
1109 assert_se(!documentation_url_is_valid("foo:"));
1110 assert_se(!documentation_url_is_valid("info:"));
1111 assert_se(!documentation_url_is_valid(""));
1114 static void test_file_in_same_dir(void) {
1117 t = file_in_same_dir("/", "a");
1118 assert_se(streq(t, "/a"));
1121 t = file_in_same_dir("/", "/a");
1122 assert_se(streq(t, "/a"));
1125 t = file_in_same_dir("", "a");
1126 assert_se(streq(t, "a"));
1129 t = file_in_same_dir("a/", "a");
1130 assert_se(streq(t, "a/a"));
1133 t = file_in_same_dir("bar/foo", "bar");
1134 assert_se(streq(t, "bar/bar"));
1138 static void test_endswith(void) {
1139 assert_se(endswith("foobar", "bar"));
1140 assert_se(endswith("foobar", ""));
1141 assert_se(endswith("foobar", "foobar"));
1142 assert_se(endswith("", ""));
1144 assert_se(!endswith("foobar", "foo"));
1145 assert_se(!endswith("foobar", "foobarfoofoo"));
1148 static void test_endswith_no_case(void) {
1149 assert_se(endswith_no_case("fooBAR", "bar"));
1150 assert_se(endswith_no_case("foobar", ""));
1151 assert_se(endswith_no_case("foobar", "FOOBAR"));
1152 assert_se(endswith_no_case("", ""));
1154 assert_se(!endswith_no_case("foobar", "FOO"));
1155 assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
1158 static void test_close_nointr(void) {
1159 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
1162 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1164 assert_se(close_nointr(fd) >= 0);
1165 assert_se(close_nointr(fd) < 0);
1171 static void test_unlink_noerrno(void) {
1172 char name[] = "/tmp/test-close_nointr.XXXXXX";
1175 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1177 assert_se(close_nointr(fd) >= 0);
1182 assert_se(unlink_noerrno(name) >= 0);
1183 assert_se(errno == -42);
1184 assert_se(unlink_noerrno(name) < 0);
1185 assert_se(errno == -42);
1189 static void test_readlink_and_make_absolute(void) {
1190 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
1191 char name[] = "/tmp/test-readlink_and_make_absolute/original";
1192 char name2[] = "test-readlink_and_make_absolute/original";
1193 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
1196 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1197 assert_se(touch(name) >= 0);
1199 assert_se(symlink(name, name_alias) >= 0);
1200 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1201 assert_se(streq(r, name));
1203 assert_se(unlink(name_alias) >= 0);
1205 assert_se(chdir(tempdir) >= 0);
1206 assert_se(symlink(name2, 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(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
1215 static void test_ignore_signals(void) {
1216 assert_se(ignore_signals(SIGINT, -1) >= 0);
1217 assert_se(kill(getpid(), SIGINT) >= 0);
1218 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1219 assert_se(kill(getpid(), SIGUSR1) >= 0);
1220 assert_se(kill(getpid(), SIGUSR2) >= 0);
1221 assert_se(kill(getpid(), SIGTERM) >= 0);
1222 assert_se(kill(getpid(), SIGPIPE) >= 0);
1223 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1226 static void test_strshorten(void) {
1227 char s[] = "foobar";
1229 assert_se(strlen(strshorten(s, 6)) == 6);
1230 assert_se(strlen(strshorten(s, 12)) == 6);
1231 assert_se(strlen(strshorten(s, 2)) == 2);
1232 assert_se(strlen(strshorten(s, 0)) == 0);
1235 static void test_strjoina(void) {
1238 actual = strjoina("", "foo", "bar");
1239 assert_se(streq(actual, "foobar"));
1241 actual = strjoina("foo", "bar", "baz");
1242 assert_se(streq(actual, "foobarbaz"));
1244 actual = strjoina("foo", "", "bar", "baz");
1245 assert_se(streq(actual, "foobarbaz"));
1247 actual = strjoina("foo");
1248 assert_se(streq(actual, "foo"));
1250 actual = strjoina(NULL);
1251 assert_se(streq(actual, ""));
1253 actual = strjoina(NULL, "foo");
1254 assert_se(streq(actual, ""));
1256 actual = strjoina("foo", NULL, "bar");
1257 assert_se(streq(actual, "foo"));
1260 static void test_is_symlink(void) {
1261 char name[] = "/tmp/test-is_symlink.XXXXXX";
1262 char name_link[] = "/tmp/test-is_symlink.link";
1263 _cleanup_close_ int fd = -1;
1265 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1267 assert_se(symlink(name, name_link) >= 0);
1269 assert_se(is_symlink(name) == 0);
1270 assert_se(is_symlink(name_link) == 1);
1271 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1278 static void test_search_and_fopen(void) {
1279 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1280 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1285 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1289 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1293 r = search_and_fopen(name, "r", NULL, dirs, &f);
1297 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1301 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1303 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1309 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1314 static void test_search_and_fopen_nulstr(void) {
1315 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1316 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1321 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1325 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1329 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1333 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1335 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1341 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1345 static void test_glob_exists(void) {
1346 char name[] = "/tmp/test-glob_exists.XXXXXX";
1350 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1354 r = glob_exists("/tmp/test-glob_exists*");
1359 r = glob_exists("/tmp/test-glob_exists*");
1363 static void test_execute_directory(void) {
1364 char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1365 char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
1366 const char * dirs[] = {template_hi, template_lo, NULL};
1367 const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
1369 assert_se(mkdtemp(template_lo));
1370 assert_se(mkdtemp(template_hi));
1372 name = strjoina(template_lo, "/script");
1373 name2 = strjoina(template_hi, "/script2");
1374 name3 = strjoina(template_lo, "/useless");
1375 overridden = strjoina(template_lo, "/overridden");
1376 override = strjoina(template_hi, "/overridden");
1377 masked = strjoina(template_lo, "/masked");
1378 mask = strjoina(template_hi, "/masked");
1380 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE) == 0);
1381 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE) == 0);
1382 assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
1383 assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE) == 0);
1384 assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
1385 assert_se(symlink("/dev/null", mask) == 0);
1386 assert_se(chmod(name, 0755) == 0);
1387 assert_se(chmod(name2, 0755) == 0);
1388 assert_se(chmod(overridden, 0755) == 0);
1389 assert_se(chmod(override, 0755) == 0);
1390 assert_se(chmod(masked, 0755) == 0);
1391 assert_se(touch(name3) >= 0);
1393 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
1395 assert_se(chdir(template_lo) == 0);
1396 assert_se(access("it_works", F_OK) >= 0);
1397 assert_se(access("failed", F_OK) < 0);
1399 assert_se(chdir(template_hi) == 0);
1400 assert_se(access("it_works2", F_OK) >= 0);
1401 assert_se(access("failed", F_OK) < 0);
1403 (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
1404 (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
1407 static int parse_item(const char *key, const char *value) {
1410 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1414 static void test_parse_proc_cmdline(void) {
1415 assert_se(parse_proc_cmdline(parse_item) >= 0);
1418 static void test_raw_clone(void) {
1419 pid_t parent, pid, pid2;
1422 log_info("before clone: getpid()→"PID_FMT, parent);
1423 assert_se(raw_getpid() == parent);
1425 pid = raw_clone(0, NULL);
1426 assert_se(pid >= 0);
1428 pid2 = raw_getpid();
1429 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1430 pid, getpid(), pid2);
1432 assert_se(pid2 != parent);
1433 _exit(EXIT_SUCCESS);
1437 assert_se(pid2 == parent);
1438 waitpid(pid, &status, __WCLONE);
1439 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1443 static void test_same_fd(void) {
1444 _cleanup_close_pair_ int p[2] = { -1, -1 };
1445 _cleanup_close_ int a = -1, b = -1, c = -1;
1447 assert_se(pipe2(p, O_CLOEXEC) >= 0);
1448 assert_se((a = dup(p[0])) >= 0);
1449 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1450 assert_se((c = dup(a)) >= 0);
1452 assert_se(same_fd(p[0], p[0]) > 0);
1453 assert_se(same_fd(p[1], p[1]) > 0);
1454 assert_se(same_fd(a, a) > 0);
1455 assert_se(same_fd(b, b) > 0);
1457 assert_se(same_fd(a, p[0]) > 0);
1458 assert_se(same_fd(p[0], a) > 0);
1459 assert_se(same_fd(c, p[0]) > 0);
1460 assert_se(same_fd(p[0], c) > 0);
1461 assert_se(same_fd(a, c) > 0);
1462 assert_se(same_fd(c, a) > 0);
1464 assert_se(same_fd(p[0], p[1]) == 0);
1465 assert_se(same_fd(p[1], p[0]) == 0);
1466 assert_se(same_fd(p[0], b) == 0);
1467 assert_se(same_fd(b, p[0]) == 0);
1468 assert_se(same_fd(p[1], a) == 0);
1469 assert_se(same_fd(a, p[1]) == 0);
1470 assert_se(same_fd(p[1], b) == 0);
1471 assert_se(same_fd(b, p[1]) == 0);
1473 assert_se(same_fd(a, b) == 0);
1474 assert_se(same_fd(b, a) == 0);
1477 static void test_uid_ptr(void) {
1479 assert_se(UID_TO_PTR(0) != NULL);
1480 assert_se(UID_TO_PTR(1000) != NULL);
1482 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1483 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1486 static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
1489 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1490 assert_se(ftruncate(fd, 0) >= 0);
1491 assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
1493 assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
1494 assert_se(ftruncate(fd, n) >= 0);
1496 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1497 assert_se(read(fd, check, n) == (ssize_t) n);
1499 assert_se(memcmp(buffer, check, n) == 0);
1502 static void test_sparse_write(void) {
1503 const char test_a[] = "test";
1504 const char test_b[] = "\0\0\0\0test\0\0\0\0";
1505 const char test_c[] = "\0\0test\0\0\0\0";
1506 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";
1507 const char test_e[] = "test\0\0\0\0test";
1508 _cleanup_close_ int fd = -1;
1509 char fn[] = "/tmp/sparseXXXXXX";
1511 fd = mkostemp(fn, O_CLOEXEC);
1515 test_sparse_write_one(fd, test_a, sizeof(test_a));
1516 test_sparse_write_one(fd, test_b, sizeof(test_b));
1517 test_sparse_write_one(fd, test_c, sizeof(test_c));
1518 test_sparse_write_one(fd, test_d, sizeof(test_d));
1519 test_sparse_write_one(fd, test_e, sizeof(test_e));
1522 static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
1523 _cleanup_free_ char *r;
1525 assert_se(r = shell_escape(s, bad));
1526 assert_se(streq_ptr(r, expected));
1529 static void test_shell_escape(void) {
1530 test_shell_escape_one("", "", "");
1531 test_shell_escape_one("\\", "", "\\\\");
1532 test_shell_escape_one("foobar", "", "foobar");
1533 test_shell_escape_one("foobar", "o", "f\\o\\obar");
1534 test_shell_escape_one("foo:bar,baz", ",:", "foo\\:bar\\,baz");
1537 static void test_shell_maybe_quote_one(const char *s, const char *expected) {
1538 _cleanup_free_ char *r;
1540 assert_se(r = shell_maybe_quote(s));
1541 assert_se(streq(r, expected));
1544 static void test_shell_maybe_quote(void) {
1546 test_shell_maybe_quote_one("", "");
1547 test_shell_maybe_quote_one("\\", "\"\\\\\"");
1548 test_shell_maybe_quote_one("\"", "\"\\\"\"");
1549 test_shell_maybe_quote_one("foobar", "foobar");
1550 test_shell_maybe_quote_one("foo bar", "\"foo bar\"");
1551 test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\"");
1552 test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
1555 static void test_tempfn(void) {
1556 char *ret = NULL, *p;
1558 assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
1559 assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
1562 assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret) >= 0);
1563 assert_se(streq_ptr(ret, "/foo/bar/.#[miau]waldoXXXXXX"));
1566 assert_se(tempfn_random("/foo/bar/waldo", NULL, &ret) >= 0);
1567 assert_se(p = startswith(ret, "/foo/bar/.#waldo"));
1568 assert_se(strlen(p) == 16);
1569 assert_se(in_charset(p, "0123456789abcdef"));
1572 assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret) >= 0);
1573 assert_se(p = startswith(ret, "/foo/bar/.#[wuff]waldo"));
1574 assert_se(strlen(p) == 16);
1575 assert_se(in_charset(p, "0123456789abcdef"));
1578 assert_se(tempfn_random_child("/foo/bar/waldo", NULL, &ret) >= 0);
1579 assert_se(p = startswith(ret, "/foo/bar/waldo/.#"));
1580 assert_se(strlen(p) == 16);
1581 assert_se(in_charset(p, "0123456789abcdef"));
1584 assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret) >= 0);
1585 assert_se(p = startswith(ret, "/foo/bar/waldo/.#[kikiriki]"));
1586 assert_se(strlen(p) == 16);
1587 assert_se(in_charset(p, "0123456789abcdef"));
1591 static void test_strcmp_ptr(void) {
1592 assert_se(strcmp_ptr(NULL, NULL) == 0);
1593 assert_se(strcmp_ptr("", NULL) > 0);
1594 assert_se(strcmp_ptr("foo", NULL) > 0);
1595 assert_se(strcmp_ptr(NULL, "") < 0);
1596 assert_se(strcmp_ptr(NULL, "bar") < 0);
1597 assert_se(strcmp_ptr("foo", "bar") > 0);
1598 assert_se(strcmp_ptr("bar", "baz") < 0);
1599 assert_se(strcmp_ptr("foo", "foo") == 0);
1600 assert_se(strcmp_ptr("", "") == 0);
1603 static void test_fgetxattrat_fake(void) {
1604 char t[] = "/var/tmp/xattrtestXXXXXX";
1605 _cleanup_close_ int fd = -1;
1610 assert_se(mkdtemp(t));
1611 x = strjoina(t, "/test");
1612 assert_se(touch(x) >= 0);
1614 r = setxattr(x, "user.foo", "bar", 3, 0);
1615 if (r < 0 && errno == EOPNOTSUPP) /* no xattrs supported on /var/tmp... */
1619 fd = open(t, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
1622 assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0) >= 0);
1623 assert_se(memcmp(v, "bar", 3) == 0);
1626 fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
1628 assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0) == -ENODATA);
1631 assert_se(unlink(x) >= 0);
1632 assert_se(rmdir(t) >= 0);
1635 static void test_runlevel_to_target(void) {
1636 assert_se(streq_ptr(runlevel_to_target(NULL), NULL));
1637 assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL));
1638 assert_se(streq_ptr(runlevel_to_target("3"), SPECIAL_MULTI_USER_TARGET));
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();
1721 test_runlevel_to_target();