]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-util.c
basic: util - fix errorhandling in unhexmem()
[thirdparty/systemd.git] / src / test / test-util.c
CommitLineData
539ad707
TA
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
8
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.
13
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.
18
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/>.
21***/
22
23#include <string.h>
dbd73f9e
TA
24#include <unistd.h>
25#include <fcntl.h>
d6dd604b 26#include <locale.h>
2a371001 27#include <errno.h>
927be00c 28#include <signal.h>
8e211000 29#include <math.h>
8852362b 30#include <sys/wait.h>
539ad707
TA
31
32#include "util.h"
927be00c 33#include "mkdir.h"
c6878637 34#include "rm-rf.h"
893fa014 35#include "strv.h"
65b3903f
ZJS
36#include "def.h"
37#include "fileio.h"
9480794b 38#include "conf-parser.h"
0eb3cc88 39#include "virt.h"
0b452006 40#include "process-util.h"
958b66ea 41#include "hostname-util.h"
24882e06 42#include "signal-util.h"
539ad707
TA
43
44static void test_streq_ptr(void) {
8354c34e
TA
45 assert_se(streq_ptr(NULL, NULL));
46 assert_se(!streq_ptr("abc", "cdef"));
539ad707
TA
47}
48
625e870b
DH
49static void test_align_power2(void) {
50 unsigned long i, p2;
51
52 assert_se(ALIGN_POWER2(0) == 0);
53 assert_se(ALIGN_POWER2(1) == 1);
54 assert_se(ALIGN_POWER2(2) == 2);
55 assert_se(ALIGN_POWER2(3) == 4);
56 assert_se(ALIGN_POWER2(12) == 16);
57
58 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
59 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
60 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
61 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
62 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
63
64 for (i = 1; i < 131071; ++i) {
65 for (p2 = 1; p2 < i; p2 <<= 1)
66 /* empty */ ;
67
68 assert_se(ALIGN_POWER2(i) == p2);
69 }
70
71 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
72 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
73 /* empty */ ;
74
75 assert_se(ALIGN_POWER2(i) == p2);
76 }
77}
78
7242d742
DH
79static void test_max(void) {
80 static const struct {
81 int a;
82 int b[CONST_MAX(10, 100)];
83 } val1 = {
84 .a = CONST_MAX(10, 100),
85 };
86 int d = 0;
87
88 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
89
90 /* CONST_MAX returns (void) instead of a value if the passed arguments
91 * are not of the same type or not constant expressions. */
92 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
7242d742
DH
93 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
94
95 assert_se(val1.a == 100);
96 assert_se(MAX(++d, 0) == 1);
97 assert_se(d == 1);
40a1eebd
DH
98
99 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
100 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
101 assert_cc(MAXSIZE(char, long) == sizeof(long));
667a0377
DH
102
103 assert_se(MAX(-5, 5) == 5);
104 assert_se(MAX(5, 5) == 5);
105 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
106 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
107 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
108 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
109 assert_se(LESS_BY(8, 4) == 4);
110 assert_se(LESS_BY(8, 8) == 0);
111 assert_se(LESS_BY(4, 8) == 0);
112 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
113 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
114 assert_se(CLAMP(-5, 0, 1) == 0);
115 assert_se(CLAMP(5, 0, 1) == 1);
116 assert_se(CLAMP(5, -10, 1) == 1);
117 assert_se(CLAMP(5, -10, 10) == 5);
118 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
7242d742
DH
119}
120
fb835651
DH
121static void test_container_of(void) {
122 struct mytype {
123 uint8_t pad1[3];
124 uint64_t v1;
125 uint8_t pad2[2];
126 uint32_t v2;
127 } _packed_ myval = { };
128
129 assert_cc(sizeof(myval) == 17);
130 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
131 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
132 assert_se(container_of(&container_of(&myval.v2,
133 struct mytype,
134 v2)->v1,
135 struct mytype,
136 v1) == &myval);
137}
138
95d78c7e
DH
139static void test_alloca(void) {
140 static const uint8_t zero[997] = { };
141 char *t;
142
143 t = alloca_align(17, 512);
144 assert_se(!((uintptr_t)t & 0xff));
145 memzero(t, 17);
146
147 t = alloca0_align(997, 1024);
148 assert_se(!((uintptr_t)t & 0x1ff));
149 assert_se(!memcmp(t, zero, 997));
150}
151
180a60bc
DH
152static void test_div_round_up(void) {
153 int div;
154
155 /* basic tests */
156 assert_se(DIV_ROUND_UP(0, 8) == 0);
157 assert_se(DIV_ROUND_UP(1, 8) == 1);
158 assert_se(DIV_ROUND_UP(8, 8) == 1);
159 assert_se(DIV_ROUND_UP(12, 8) == 2);
160 assert_se(DIV_ROUND_UP(16, 8) == 2);
161
162 /* test multiple evaluation */
163 div = 0;
164 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
165 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
166 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
167 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
168
169 /* overflow test with exact division */
170 assert_se(sizeof(0U) == 4);
171 assert_se(0xfffffffaU % 10U == 0U);
172 assert_se(0xfffffffaU / 10U == 429496729U);
173 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
174 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
175 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
176
177 /* overflow test with rounded division */
178 assert_se(0xfffffffdU % 10U == 3U);
179 assert_se(0xfffffffdU / 10U == 429496729U);
180 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
181 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
182 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
183}
184
539ad707 185static void test_first_word(void) {
8354c34e
TA
186 assert_se(first_word("Hello", ""));
187 assert_se(first_word("Hello", "Hello"));
188 assert_se(first_word("Hello world", "Hello"));
189 assert_se(first_word("Hello\tworld", "Hello"));
190 assert_se(first_word("Hello\nworld", "Hello"));
191 assert_se(first_word("Hello\rworld", "Hello"));
192 assert_se(first_word("Hello ", "Hello"));
193
194 assert_se(!first_word("Hello", "Hellooo"));
195 assert_se(!first_word("Hello", "xxxxx"));
196 assert_se(!first_word("Hellooo", "Hello"));
197}
198
dbd73f9e
TA
199static void test_close_many(void) {
200 int fds[3];
201 char name0[] = "/tmp/test-close-many.XXXXXX";
202 char name1[] = "/tmp/test-close-many.XXXXXX";
203 char name2[] = "/tmp/test-close-many.XXXXXX";
204
2d5bdf5b
LP
205 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
206 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
207 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
dbd73f9e
TA
208
209 close_many(fds, 2);
210
211 assert_se(fcntl(fds[0], F_GETFD) == -1);
212 assert_se(fcntl(fds[1], F_GETFD) == -1);
213 assert_se(fcntl(fds[2], F_GETFD) >= 0);
214
03e334a1 215 safe_close(fds[2]);
dbd73f9e
TA
216
217 unlink(name0);
218 unlink(name1);
219 unlink(name2);
220}
221
8354c34e
TA
222static void test_parse_boolean(void) {
223 assert_se(parse_boolean("1") == 1);
224 assert_se(parse_boolean("y") == 1);
225 assert_se(parse_boolean("Y") == 1);
226 assert_se(parse_boolean("yes") == 1);
227 assert_se(parse_boolean("YES") == 1);
228 assert_se(parse_boolean("true") == 1);
229 assert_se(parse_boolean("TRUE") == 1);
230 assert_se(parse_boolean("on") == 1);
231 assert_se(parse_boolean("ON") == 1);
232
233 assert_se(parse_boolean("0") == 0);
234 assert_se(parse_boolean("n") == 0);
235 assert_se(parse_boolean("N") == 0);
236 assert_se(parse_boolean("no") == 0);
237 assert_se(parse_boolean("NO") == 0);
238 assert_se(parse_boolean("false") == 0);
239 assert_se(parse_boolean("FALSE") == 0);
240 assert_se(parse_boolean("off") == 0);
241 assert_se(parse_boolean("OFF") == 0);
242
243 assert_se(parse_boolean("garbage") < 0);
244 assert_se(parse_boolean("") < 0);
0f625d0b 245 assert_se(parse_boolean("full") < 0);
539ad707
TA
246}
247
8d99e5f5
TA
248static void test_parse_pid(void) {
249 int r;
250 pid_t pid;
251
252 r = parse_pid("100", &pid);
253 assert_se(r == 0);
254 assert_se(pid == 100);
255
256 r = parse_pid("0x7FFFFFFF", &pid);
257 assert_se(r == 0);
258 assert_se(pid == 2147483647);
259
260 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
261 r = parse_pid("0", &pid);
262 assert_se(r == -ERANGE);
263 assert_se(pid == 65);
264
265 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
266 r = parse_pid("-100", &pid);
267 assert_se(r == -ERANGE);
268 assert_se(pid == 65);
269
270 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
271 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
bdf7026e 272 assert_se(r == -ERANGE);
8d99e5f5
TA
273 assert_se(pid == 65);
274}
275
276static void test_parse_uid(void) {
277 int r;
278 uid_t uid;
279
280 r = parse_uid("100", &uid);
281 assert_se(r == 0);
282 assert_se(uid == 100);
283}
284
285static void test_safe_atolli(void) {
286 int r;
287 long long l;
288
289 r = safe_atolli("12345", &l);
290 assert_se(r == 0);
291 assert_se(l == 12345);
292
293 r = safe_atolli("junk", &l);
294 assert_se(r == -EINVAL);
295}
296
297static void test_safe_atod(void) {
298 int r;
299 double d;
d6dd604b
LP
300 char *e;
301
302 r = safe_atod("junk", &d);
303 assert_se(r == -EINVAL);
8d99e5f5
TA
304
305 r = safe_atod("0.2244", &d);
306 assert_se(r == 0);
8e211000 307 assert_se(fabs(d - 0.2244) < 0.000001);
8d99e5f5 308
d6dd604b 309 r = safe_atod("0,5", &d);
8d99e5f5 310 assert_se(r == -EINVAL);
d6dd604b
LP
311
312 errno = 0;
313 strtod("0,5", &e);
314 assert_se(*e == ',');
315
316 /* Check if this really is locale independent */
926446f4 317 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
d6dd604b 318
926446f4
DH
319 r = safe_atod("0.2244", &d);
320 assert_se(r == 0);
321 assert_se(fabs(d - 0.2244) < 0.000001);
d6dd604b 322
926446f4
DH
323 r = safe_atod("0,5", &d);
324 assert_se(r == -EINVAL);
d6dd604b 325
926446f4
DH
326 errno = 0;
327 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
328 }
d6dd604b
LP
329
330 /* And check again, reset */
926446f4 331 assert_se(setlocale(LC_NUMERIC, "C"));
d6dd604b
LP
332
333 r = safe_atod("0.2244", &d);
334 assert_se(r == 0);
8e211000 335 assert_se(fabs(d - 0.2244) < 0.000001);
d6dd604b
LP
336
337 r = safe_atod("0,5", &d);
338 assert_se(r == -EINVAL);
339
340 errno = 0;
341 strtod("0,5", &e);
342 assert_se(*e == ',');
8d99e5f5
TA
343}
344
dbd73f9e 345static void test_strappend(void) {
998b087f 346 _cleanup_free_ char *t1, *t2, *t3, *t4;
dbd73f9e 347
998b087f
TA
348 t1 = strappend(NULL, NULL);
349 assert_se(streq(t1, ""));
dbd73f9e 350
998b087f
TA
351 t2 = strappend(NULL, "suf");
352 assert_se(streq(t2, "suf"));
dbd73f9e 353
998b087f
TA
354 t3 = strappend("pre", NULL);
355 assert_se(streq(t3, "pre"));
dbd73f9e 356
998b087f
TA
357 t4 = strappend("pre", "suf");
358 assert_se(streq(t4, "presuf"));
dbd73f9e
TA
359}
360
1ef04f0b 361static void test_strstrip(void) {
998b087f
TA
362 char *r;
363 char input[] = " hello, waldo. ";
1ef04f0b 364
998b087f
TA
365 r = strstrip(input);
366 assert_se(streq(r, "hello, waldo."));
1ef04f0b
TA
367}
368
369static void test_delete_chars(void) {
998b087f
TA
370 char *r;
371 char input[] = " hello, waldo. abc";
1ef04f0b 372
998b087f
TA
373 r = delete_chars(input, WHITESPACE);
374 assert_se(streq(r, "hello,waldo.abc"));
1ef04f0b
TA
375}
376
377static void test_in_charset(void) {
998b087f
TA
378 assert_se(in_charset("dddaaabbbcccc", "abcd"));
379 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
1ef04f0b
TA
380}
381
44f4c86c
DB
382static void test_hexchar(void) {
383 assert_se(hexchar(0xa) == 'a');
384 assert_se(hexchar(0x0) == '0');
385}
386
387static void test_unhexchar(void) {
388 assert_se(unhexchar('a') == 0xA);
389 assert_se(unhexchar('A') == 0xA);
390 assert_se(unhexchar('0') == 0x0);
391}
392
393static void test_octchar(void) {
394 assert_se(octchar(00) == '0');
395 assert_se(octchar(07) == '7');
396}
397
398static void test_unoctchar(void) {
399 assert_se(unoctchar('0') == 00);
400 assert_se(unoctchar('7') == 07);
401}
402
403static void test_decchar(void) {
404 assert_se(decchar(0) == '0');
405 assert_se(decchar(9) == '9');
406}
407
408static void test_undecchar(void) {
409 assert_se(undecchar('0') == 0);
410 assert_se(undecchar('9') == 9);
411}
412
30494563
TG
413static void test_unhexmem(void) {
414 const char *hex = "efa214921";
415 const char *hex_invalid = "efa214921o";
416 _cleanup_free_ char *hex2 = NULL;
417 _cleanup_free_ void *mem = NULL;
418 size_t len;
419
420 assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0);
421 assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL);
422 assert_se(unhexmem(hex_invalid, strlen(hex_invalid), &mem, &len) == -EINVAL);
423
424 assert_se((hex2 = hexmem(mem, len)));
425
426 free(mem);
427
428 assert_se(memcmp(hex, hex2, strlen(hex)) == 0);
429
430 free(hex2);
431
432 assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == 0);
433 assert_se((hex2 = hexmem(mem, len)));
434 assert_se(memcmp(hex, hex2, strlen(hex) - 1) == 0);
435}
436
b4ecc959
TA
437static void test_cescape(void) {
438 _cleanup_free_ char *escaped;
e0a33e7b
LP
439
440 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
927be00c 441 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
b4ecc959
TA
442}
443
444static void test_cunescape(void) {
445 _cleanup_free_ char *unescaped;
e0a33e7b 446
527b7a42
LP
447 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped) < 0);
448 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX, &unescaped) >= 0);
f3ee6297 449 assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
527b7a42
LP
450 free(unescaped);
451 unescaped = NULL;
7f769619
ZJS
452
453 /* incomplete sequences */
527b7a42
LP
454 assert_se(cunescape("\\x0", 0, &unescaped) < 0);
455 assert_se(cunescape("\\x0", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 456 assert_se(streq_ptr(unescaped, "\\x0"));
527b7a42
LP
457 free(unescaped);
458 unescaped = NULL;
7f769619 459
527b7a42
LP
460 assert_se(cunescape("\\x", 0, &unescaped) < 0);
461 assert_se(cunescape("\\x", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 462 assert_se(streq_ptr(unescaped, "\\x"));
527b7a42
LP
463 free(unescaped);
464 unescaped = NULL;
7f769619 465
527b7a42
LP
466 assert_se(cunescape("\\", 0, &unescaped) < 0);
467 assert_se(cunescape("\\", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 468 assert_se(streq_ptr(unescaped, "\\"));
527b7a42
LP
469 free(unescaped);
470 unescaped = NULL;
7f769619 471
527b7a42
LP
472 assert_se(cunescape("\\11", 0, &unescaped) < 0);
473 assert_se(cunescape("\\11", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 474 assert_se(streq_ptr(unescaped, "\\11"));
527b7a42
LP
475 free(unescaped);
476 unescaped = NULL;
7f769619 477
527b7a42
LP
478 assert_se(cunescape("\\1", 0, &unescaped) < 0);
479 assert_se(cunescape("\\1", UNESCAPE_RELAX, &unescaped) >= 0);
7f769619 480 assert_se(streq_ptr(unescaped, "\\1"));
f3ee6297
LP
481 free(unescaped);
482 unescaped = NULL;
483
484 assert_se(cunescape("\\u0000", 0, &unescaped) < 0);
485 assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX, &unescaped) >= 0);
486 assert_se(streq_ptr(unescaped, "ßßΠA"));
602ee553
TA
487 free(unescaped);
488 unescaped = NULL;
3b51f8dd
DM
489
490 assert_se(cunescape("\\073", 0, &unescaped) >= 0);
491 assert_se(streq_ptr(unescaped, ";"));
b4ecc959
TA
492}
493
1ef04f0b 494static void test_foreach_word(void) {
a2a5291b 495 const char *word, *state;
1ef04f0b
TA
496 size_t l;
497 int i = 0;
498 const char test[] = "test abc d\te f ";
499 const char * const expected[] = {
500 "test",
501 "abc",
502 "d",
503 "e",
504 "f",
505 "",
506 NULL
507 };
508
a2a5291b
ZJS
509 FOREACH_WORD(word, l, test, state)
510 assert_se(strneq(expected[i++], word, l));
1ef04f0b
TA
511}
512
ba774317 513static void check(const char *test, char** expected, bool trailing) {
a2a5291b 514 const char *word, *state;
539ad707 515 size_t l;
1ef04f0b 516 int i = 0;
1ef04f0b 517
ba774317 518 printf("<<<%s>>>\n", test);
a2a5291b 519 FOREACH_WORD_QUOTED(word, l, test, state) {
1ef04f0b 520 _cleanup_free_ char *t = NULL;
539ad707 521
a2a5291b
ZJS
522 assert_se(t = strndup(word, l));
523 assert_se(strneq(expected[i++], word, l));
539ad707 524 printf("<%s>\n", t);
539ad707 525 }
ba774317 526 printf("<<<%s>>>\n", state);
e50221bf 527 assert_se(expected[i] == NULL);
ba774317
ZJS
528 assert_se(isempty(state) == !trailing);
529}
530
531static void test_foreach_word_quoted(void) {
532 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
533 STRV_MAKE("test",
534 "a",
535 "b",
536 "c",
537 "d",
538 "e",
539 "",
540 "",
541 "hhh",
542 "",
543 "",
544 "a b c"),
545 false);
546
547 check("test \"xxx",
548 STRV_MAKE("test"),
549 true);
550
551 check("test\\",
552 STRV_MAKE_EMPTY,
553 true);
539ad707
TA
554}
555
0d585d82
TA
556static void test_memdup_multiply(void) {
557 int org[] = {1, 2, 3};
558 int *dup;
559
560 dup = (int*)memdup_multiply(org, sizeof(int), 3);
561
562 assert_se(dup);
563 assert_se(dup[0] == 1);
564 assert_se(dup[1] == 2);
565 assert_se(dup[2] == 3);
566 free(dup);
567}
568
aa3c5cf8 569static void test_hostname_is_valid(void) {
bdf7026e
TA
570 assert_se(hostname_is_valid("foobar"));
571 assert_se(hostname_is_valid("foobar.com"));
572 assert_se(!hostname_is_valid("fööbar"));
573 assert_se(!hostname_is_valid(""));
574 assert_se(!hostname_is_valid("."));
575 assert_se(!hostname_is_valid(".."));
576 assert_se(!hostname_is_valid("foobar."));
577 assert_se(!hostname_is_valid(".foobar"));
578 assert_se(!hostname_is_valid("foo..bar"));
579 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
aa3c5cf8
LP
580}
581
139e5336
MP
582static void test_read_hostname_config(void) {
583 char path[] = "/tmp/hostname.XXXXXX";
584 char *hostname;
585 int fd;
586
587 fd = mkostemp_safe(path, O_RDWR|O_CLOEXEC);
588 assert(fd > 0);
589 close(fd);
590
591 /* simple hostname */
4c1fc3e4 592 write_string_file(path, "foo", WRITE_STRING_FILE_CREATE);
139e5336
MP
593 assert_se(read_hostname_config(path, &hostname) == 0);
594 assert_se(streq(hostname, "foo"));
595 free(hostname);
e136009d 596 hostname = NULL;
139e5336
MP
597
598 /* with comment */
4c1fc3e4 599 write_string_file(path, "# comment\nfoo", WRITE_STRING_FILE_CREATE);
139e5336 600 assert_se(read_hostname_config(path, &hostname) == 0);
e136009d 601 assert_se(hostname);
139e5336
MP
602 assert_se(streq(hostname, "foo"));
603 free(hostname);
e136009d 604 hostname = NULL;
139e5336
MP
605
606 /* with comment and extra whitespace */
4c1fc3e4 607 write_string_file(path, "# comment\n\n foo ", WRITE_STRING_FILE_CREATE);
139e5336 608 assert_se(read_hostname_config(path, &hostname) == 0);
e136009d 609 assert_se(hostname);
139e5336
MP
610 assert_se(streq(hostname, "foo"));
611 free(hostname);
e136009d 612 hostname = NULL;
139e5336
MP
613
614 /* cleans up name */
4c1fc3e4 615 write_string_file(path, "!foo/bar.com", WRITE_STRING_FILE_CREATE);
139e5336 616 assert_se(read_hostname_config(path, &hostname) == 0);
e136009d 617 assert_se(hostname);
139e5336
MP
618 assert_se(streq(hostname, "foobar.com"));
619 free(hostname);
e136009d 620 hostname = NULL;
139e5336
MP
621
622 /* no value set */
623 hostname = (char*) 0x1234;
4c1fc3e4 624 write_string_file(path, "# nothing here\n", WRITE_STRING_FILE_CREATE);
139e5336
MP
625 assert_se(read_hostname_config(path, &hostname) == -ENOENT);
626 assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */
627
628 /* nonexisting file */
629 assert_se(read_hostname_config("/non/existing", &hostname) == -ENOENT);
630 assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */
631
632 unlink(path);
633}
634
144e51ec 635static void test_u64log2(void) {
bdf7026e
TA
636 assert_se(u64log2(0) == 0);
637 assert_se(u64log2(8) == 3);
638 assert_se(u64log2(9) == 3);
639 assert_se(u64log2(15) == 3);
640 assert_se(u64log2(16) == 4);
641 assert_se(u64log2(1024*1024) == 20);
642 assert_se(u64log2(1024*1024+5) == 20);
144e51ec
CR
643}
644
2a371001
ZJS
645static void test_protect_errno(void) {
646 errno = 12;
647 {
648 PROTECT_ERRNO;
649 errno = 11;
650 }
bdf7026e 651 assert_se(errno == 12);
2a371001
ZJS
652}
653
5556b5fe 654static void test_parse_size(void) {
b32ff512
ZJS
655 off_t bytes;
656
5556b5fe 657 assert_se(parse_size("111", 1024, &bytes) == 0);
b32ff512
ZJS
658 assert_se(bytes == 111);
659
9480794b
ZJS
660 assert_se(parse_size("111.4", 1024, &bytes) == 0);
661 assert_se(bytes == 111);
662
5556b5fe 663 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
b32ff512
ZJS
664 assert_se(bytes == 112);
665
9480794b
ZJS
666 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
667 assert_se(bytes == 112);
668
669 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
670 assert_se(bytes == 3*1024 + 512);
671
672 assert_se(parse_size("3. K", 1024, &bytes) == 0);
673 assert_se(bytes == 3*1024);
674
675 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
b32ff512
ZJS
676 assert_se(bytes == 3*1024);
677
840292be 678 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
b32ff512 679
9480794b
ZJS
680 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
681 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
682
840292be
ZJS
683 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
684
685 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
9480794b 686 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
b32ff512 687
840292be
ZJS
688 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
689 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
690
691 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
692
693 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
694 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
695
696 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
b32ff512
ZJS
697 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
698
5556b5fe 699 assert_se(parse_size("12P", 1024, &bytes) == 0);
b32ff512
ZJS
700 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
701
840292be
ZJS
702 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
703
5556b5fe 704 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
b32ff512
ZJS
705 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
706
5556b5fe 707 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
b32ff512 708
9480794b
ZJS
709 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
710
711 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
712
5556b5fe
LP
713 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
714 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
715 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
b32ff512 716
5556b5fe 717 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
b32ff512 718
5556b5fe 719 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
b32ff512
ZJS
720}
721
9480794b
ZJS
722static void test_config_parse_iec_off(void) {
723 off_t offset = 0;
724 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
725 assert_se(offset == 4 * 1024 * 1024);
726
727 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
728}
729
b4ecc959
TA
730static void test_strextend(void) {
731 _cleanup_free_ char *str = strdup("0123");
732 strextend(&str, "456", "78", "9", NULL);
733 assert_se(streq(str, "0123456789"));
734}
735
736static void test_strrep(void) {
737 _cleanup_free_ char *one, *three, *zero;
738 one = strrep("waldo", 1);
739 three = strrep("waldo", 3);
740 zero = strrep("waldo", 0);
741
742 assert_se(streq(one, "waldo"));
743 assert_se(streq(three, "waldowaldowaldo"));
744 assert_se(streq(zero, ""));
745}
746
d4ac85c6
LP
747static void test_split_pair(void) {
748 _cleanup_free_ char *a = NULL, *b = NULL;
749
750 assert_se(split_pair("", "", &a, &b) == -EINVAL);
751 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
752 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
753 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
754 assert_se(streq(a, "foo"));
755 assert_se(streq(b, "bar"));
756 free(a);
757 free(b);
758 assert_se(split_pair("==", "==", &a, &b) >= 0);
759 assert_se(streq(a, ""));
760 assert_se(streq(b, ""));
761 free(a);
762 free(b);
763
764 assert_se(split_pair("===", "==", &a, &b) >= 0);
765 assert_se(streq(a, ""));
766 assert_se(streq(b, "="));
767}
768
22f5f628
DR
769static void test_fstab_node_to_udev_node(void) {
770 char *n;
771
772 n = fstab_node_to_udev_node("LABEL=applé/jack");
773 puts(n);
774 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
775 free(n);
776
777 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
778 puts(n);
779 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
780 free(n);
781
782 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
783 puts(n);
784 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
785 free(n);
786
787 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
788 puts(n);
789 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
790 free(n);
791
22f5f628
DR
792 n = fstab_node_to_udev_node("PONIES=awesome");
793 puts(n);
794 assert_se(streq(n, "PONIES=awesome"));
795 free(n);
796
797 n = fstab_node_to_udev_node("/dev/xda1");
798 puts(n);
799 assert_se(streq(n, "/dev/xda1"));
800 free(n);
801}
802
893fa014
ZJS
803static void test_get_files_in_directory(void) {
804 _cleanup_strv_free_ char **l = NULL, **t = NULL;
805
806 assert_se(get_files_in_directory("/tmp", &l) >= 0);
510b857f 807 assert_se(get_files_in_directory(".", &t) >= 0);
893fa014
ZJS
808 assert_se(get_files_in_directory(".", NULL) >= 0);
809}
810
cabb7806
LP
811static void test_in_set(void) {
812 assert_se(IN_SET(1, 1));
813 assert_se(IN_SET(1, 1, 2, 3, 4));
814 assert_se(IN_SET(2, 1, 2, 3, 4));
815 assert_se(IN_SET(3, 1, 2, 3, 4));
816 assert_se(IN_SET(4, 1, 2, 3, 4));
817 assert_se(!IN_SET(0, 1));
818 assert_se(!IN_SET(0, 1, 2, 3, 4));
819}
820
87b02843
ZJS
821static void test_writing_tmpfile(void) {
822 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
39883f62 823 _cleanup_free_ char *contents = NULL;
65b3903f
ZJS
824 size_t size;
825 int fd, r;
65b3903f 826 struct iovec iov[3];
39883f62 827
65b3903f
ZJS
828 IOVEC_SET_STRING(iov[0], "abc\n");
829 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
830 IOVEC_SET_STRING(iov[2], "");
831
2d5bdf5b 832 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
87b02843 833 printf("tmpfile: %s", name);
65b3903f 834
87b02843 835 r = writev(fd, iov, 3);
bdf7026e 836 assert_se(r >= 0);
65b3903f
ZJS
837
838 r = read_full_file(name, &contents, &size);
bdf7026e 839 assert_se(r == 0);
65b3903f 840 printf("contents: %s", contents);
bdf7026e 841 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
40edd236
RC
842
843 unlink(name);
65b3903f
ZJS
844}
845
29bfbcd6
LP
846static void test_hexdump(void) {
847 uint8_t data[146];
848 unsigned i;
849
850 hexdump(stdout, NULL, 0);
851 hexdump(stdout, "", 0);
852 hexdump(stdout, "", 1);
853 hexdump(stdout, "x", 1);
854 hexdump(stdout, "x", 2);
855 hexdump(stdout, "foobar", 7);
856 hexdump(stdout, "f\nobar", 7);
857 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
858
859 for (i = 0; i < ELEMENTSOF(data); i++)
860 data[i] = i*2;
861
862 hexdump(stdout, data, sizeof(data));
863}
864
8fe90522
ZJS
865static void test_log2i(void) {
866 assert_se(log2i(1) == 0);
867 assert_se(log2i(2) == 1);
868 assert_se(log2i(3) == 1);
869 assert_se(log2i(4) == 2);
870 assert_se(log2i(32) == 5);
871 assert_se(log2i(33) == 5);
872 assert_se(log2i(63) == 5);
873 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
874}
875
c4a7b2c5
LP
876static void test_foreach_string(void) {
877 const char * const t[] = {
878 "foo",
879 "bar",
880 "waldo",
881 NULL
882 };
883 const char *x;
884 unsigned i = 0;
885
886 FOREACH_STRING(x, "foo", "bar", "waldo")
887 assert_se(streq_ptr(t[i++], x));
888
889 assert_se(i == 3);
890
891 FOREACH_STRING(x, "zzz")
892 assert_se(streq(x, "zzz"));
893}
894
ae6c3cc0 895static void test_filename_is_valid(void) {
927be00c
RC
896 char foo[FILENAME_MAX+2];
897 int i;
898
ae6c3cc0
LP
899 assert_se(!filename_is_valid(""));
900 assert_se(!filename_is_valid("/bar/foo"));
901 assert_se(!filename_is_valid("/"));
902 assert_se(!filename_is_valid("."));
903 assert_se(!filename_is_valid(".."));
927be00c
RC
904
905 for (i=0; i<FILENAME_MAX+1; i++)
906 foo[i] = 'a';
907 foo[FILENAME_MAX+1] = '\0';
908
ae6c3cc0 909 assert_se(!filename_is_valid(foo));
927be00c 910
ae6c3cc0
LP
911 assert_se(filename_is_valid("foo_bar-333"));
912 assert_se(filename_is_valid("o.o"));
927be00c
RC
913}
914
1cb1767a
ZJS
915static void test_string_has_cc(void) {
916 assert_se(string_has_cc("abc\1", NULL));
917 assert_se(string_has_cc("abc\x7f", NULL));
918 assert_se(string_has_cc("abc\x7f", NULL));
919 assert_se(string_has_cc("abc\t\x7f", "\t"));
920 assert_se(string_has_cc("abc\t\x7f", "\t"));
921 assert_se(string_has_cc("\x7f", "\t"));
922 assert_se(string_has_cc("\x7f", "\t\a"));
923
924 assert_se(!string_has_cc("abc\t\t", "\t"));
925 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
926 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
927}
928
927be00c
RC
929static void test_ascii_strlower(void) {
930 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
931 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
932}
933
934static void test_files_same(void) {
935 _cleanup_close_ int fd = -1;
936 char name[] = "/tmp/test-files_same.XXXXXX";
937 char name_alias[] = "/tmp/test-files_same.alias";
938
939 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
940 assert_se(fd >= 0);
941 assert_se(symlink(name, name_alias) >= 0);
942
943 assert_se(files_same(name, name));
944 assert_se(files_same(name, name_alias));
945
946 unlink(name);
947 unlink(name_alias);
948}
949
950static void test_is_valid_documentation_url(void) {
a2e03378
LP
951 assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
952 assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
953 assert_se(documentation_url_is_valid("file:/foo/foo"));
954 assert_se(documentation_url_is_valid("man:systemd.special(7)"));
955 assert_se(documentation_url_is_valid("info:bar"));
956
957 assert_se(!documentation_url_is_valid("foo:"));
958 assert_se(!documentation_url_is_valid("info:"));
959 assert_se(!documentation_url_is_valid(""));
927be00c
RC
960}
961
962static void test_file_in_same_dir(void) {
eee84633
DH
963 char *t;
964
965 t = file_in_same_dir("/", "a");
966 assert_se(streq(t, "/a"));
967 free(t);
968
969 t = file_in_same_dir("/", "/a");
970 assert_se(streq(t, "/a"));
971 free(t);
972
973 t = file_in_same_dir("", "a");
974 assert_se(streq(t, "a"));
975 free(t);
976
977 t = file_in_same_dir("a/", "a");
978 assert_se(streq(t, "a/a"));
979 free(t);
980
981 t = file_in_same_dir("bar/foo", "bar");
982 assert_se(streq(t, "bar/bar"));
983 free(t);
927be00c
RC
984}
985
986static void test_endswith(void) {
987 assert_se(endswith("foobar", "bar"));
988 assert_se(endswith("foobar", ""));
989 assert_se(endswith("foobar", "foobar"));
990 assert_se(endswith("", ""));
991
992 assert_se(!endswith("foobar", "foo"));
993 assert_se(!endswith("foobar", "foobarfoofoo"));
994}
995
996static void test_close_nointr(void) {
997 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
998 int fd;
999
1000 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1001 assert_se(fd >= 0);
1002 assert_se(close_nointr(fd) >= 0);
1003 assert_se(close_nointr(fd) < 0);
1004
1005 unlink(name);
1006}
1007
1008
1009static void test_unlink_noerrno(void) {
1010 char name[] = "/tmp/test-close_nointr.XXXXXX";
1011 int fd;
1012
1013 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1014 assert_se(fd >= 0);
1015 assert_se(close_nointr(fd) >= 0);
1016
1017 {
1018 PROTECT_ERRNO;
1019 errno = -42;
1020 assert_se(unlink_noerrno(name) >= 0);
1021 assert_se(errno == -42);
1022 assert_se(unlink_noerrno(name) < 0);
1023 assert_se(errno == -42);
1024 }
1025}
1026
1027static void test_readlink_and_make_absolute(void) {
1028 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
1029 char name[] = "/tmp/test-readlink_and_make_absolute/original";
1030 char name2[] = "test-readlink_and_make_absolute/original";
1031 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
1032 char *r = NULL;
1033
684fc892 1034 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
927be00c
RC
1035 assert_se(touch(name) >= 0);
1036
1037 assert_se(symlink(name, name_alias) >= 0);
1038 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1039 assert_se(streq(r, name));
1040 free(r);
1041 assert_se(unlink(name_alias) >= 0);
1042
1043 assert_se(chdir(tempdir) >= 0);
1044 assert_se(symlink(name2, name_alias) >= 0);
1045 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1046 assert_se(streq(r, name));
1047 free(r);
1048 assert_se(unlink(name_alias) >= 0);
1049
c6878637 1050 assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
927be00c
RC
1051}
1052
927be00c
RC
1053static void test_ignore_signals(void) {
1054 assert_se(ignore_signals(SIGINT, -1) >= 0);
1055 assert_se(kill(getpid(), SIGINT) >= 0);
1056 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1057 assert_se(kill(getpid(), SIGUSR1) >= 0);
1058 assert_se(kill(getpid(), SIGUSR2) >= 0);
1059 assert_se(kill(getpid(), SIGTERM) >= 0);
1060 assert_se(kill(getpid(), SIGPIPE) >= 0);
1061 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1062}
1063
1064static void test_strshorten(void) {
1065 char s[] = "foobar";
1066
1067 assert_se(strlen(strshorten(s, 6)) == 6);
1068 assert_se(strlen(strshorten(s, 12)) == 6);
1069 assert_se(strlen(strshorten(s, 2)) == 2);
1070 assert_se(strlen(strshorten(s, 0)) == 0);
1071}
1072
63c372cb 1073static void test_strjoina(void) {
8085f163
DR
1074 char *actual;
1075
63c372cb 1076 actual = strjoina("", "foo", "bar");
8085f163
DR
1077 assert_se(streq(actual, "foobar"));
1078
63c372cb 1079 actual = strjoina("foo", "bar", "baz");
8085f163
DR
1080 assert_se(streq(actual, "foobarbaz"));
1081
63c372cb 1082 actual = strjoina("foo", "", "bar", "baz");
8085f163 1083 assert_se(streq(actual, "foobarbaz"));
63c372cb
LP
1084
1085 actual = strjoina("foo");
1086 assert_se(streq(actual, "foo"));
1087
1088 actual = strjoina(NULL);
1089 assert_se(streq(actual, ""));
1090
1091 actual = strjoina(NULL, "foo");
1092 assert_se(streq(actual, ""));
1093
1094 actual = strjoina("foo", NULL, "bar");
1095 assert_se(streq(actual, "foo"));
8085f163
DR
1096}
1097
8852362b
RC
1098static void test_is_symlink(void) {
1099 char name[] = "/tmp/test-is_symlink.XXXXXX";
1100 char name_link[] = "/tmp/test-is_symlink.link";
1101 _cleanup_close_ int fd = -1;
1102
1103 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1104 assert_se(fd >= 0);
1105 assert_se(symlink(name, name_link) >= 0);
1106
1107 assert_se(is_symlink(name) == 0);
1108 assert_se(is_symlink(name_link) == 1);
1109 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1110
1111
1112 unlink(name);
1113 unlink(name_link);
1114}
1115
8852362b
RC
1116static void test_search_and_fopen(void) {
1117 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1118 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1119 int fd = -1;
1120 int r;
1121 FILE *f;
1122
1123 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1124 assert_se(fd >= 0);
1125 close(fd);
1126
1127 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1128 assert_se(r >= 0);
1129 fclose(f);
1130
1131 r = search_and_fopen(name, "r", NULL, dirs, &f);
1132 assert_se(r >= 0);
1133 fclose(f);
1134
1135 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1136 assert_se(r >= 0);
1137 fclose(f);
1138
1139 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1140 assert_se(r < 0);
1141 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1142 assert_se(r < 0);
1143
1144 r = unlink(name);
1145 assert_se(r == 0);
1146
1147 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1148 assert_se(r < 0);
1149}
1150
1151
1152static void test_search_and_fopen_nulstr(void) {
1153 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1154 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1155 int fd = -1;
1156 int r;
1157 FILE *f;
1158
1159 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1160 assert_se(fd >= 0);
1161 close(fd);
1162
1163 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1164 assert_se(r >= 0);
1165 fclose(f);
1166
1167 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1168 assert_se(r >= 0);
1169 fclose(f);
1170
1171 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1172 assert_se(r < 0);
1173 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1174 assert_se(r < 0);
1175
1176 r = unlink(name);
1177 assert_se(r == 0);
1178
1179 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1180 assert_se(r < 0);
1181}
1182
1183static void test_glob_exists(void) {
1184 char name[] = "/tmp/test-glob_exists.XXXXXX";
1185 int fd = -1;
1186 int r;
1187
1188 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1189 assert_se(fd >= 0);
1190 close(fd);
1191
1192 r = glob_exists("/tmp/test-glob_exists*");
1193 assert_se(r == 1);
1194
1195 r = unlink(name);
1196 assert_se(r == 0);
1197 r = glob_exists("/tmp/test-glob_exists*");
1198 assert_se(r == 0);
1199}
1200
1201static void test_execute_directory(void) {
aac7766c
ZJS
1202 char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1203 char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
76f282c6 1204 const char * dirs[] = {template_hi, template_lo, NULL};
aac7766c
ZJS
1205 const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
1206
1207 assert_se(mkdtemp(template_lo));
1208 assert_se(mkdtemp(template_hi));
1209
63c372cb
LP
1210 name = strjoina(template_lo, "/script");
1211 name2 = strjoina(template_hi, "/script2");
1212 name3 = strjoina(template_lo, "/useless");
1213 overridden = strjoina(template_lo, "/overridden");
1214 override = strjoina(template_hi, "/overridden");
1215 masked = strjoina(template_lo, "/masked");
1216 mask = strjoina(template_hi, "/masked");
e801700e 1217
4c1fc3e4
DM
1218 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE) == 0);
1219 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE) == 0);
1220 assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
1221 assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE) == 0);
1222 assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
aac7766c 1223 assert_se(symlink("/dev/null", mask) == 0);
8852362b
RC
1224 assert_se(chmod(name, 0755) == 0);
1225 assert_se(chmod(name2, 0755) == 0);
aac7766c
ZJS
1226 assert_se(chmod(overridden, 0755) == 0);
1227 assert_se(chmod(override, 0755) == 0);
1228 assert_se(chmod(masked, 0755) == 0);
8852362b
RC
1229 assert_se(touch(name3) >= 0);
1230
e801700e 1231 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
aac7766c 1232
0c0cdb06 1233 assert_se(chdir(template_lo) == 0);
e801700e 1234 assert_se(access("it_works", F_OK) >= 0);
aac7766c
ZJS
1235 assert_se(access("failed", F_OK) < 0);
1236
0c0cdb06 1237 assert_se(chdir(template_hi) == 0);
e801700e 1238 assert_se(access("it_works2", F_OK) >= 0);
aac7766c 1239 assert_se(access("failed", F_OK) < 0);
8852362b 1240
c6878637
LP
1241 (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
1242 (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
8852362b
RC
1243}
1244
7629889c
LP
1245static void test_unquote_first_word(void) {
1246 const char *p, *original;
1247 char *t;
1248
1249 p = original = "foobar waldo";
4034a06d 1250 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1251 assert_se(streq(t, "foobar"));
1252 free(t);
1253 assert_se(p == original + 7);
1254
4034a06d 1255 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1256 assert_se(streq(t, "waldo"));
1257 free(t);
1258 assert_se(p == original + 12);
1259
4034a06d 1260 assert_se(unquote_first_word(&p, &t, 0) == 0);
7629889c
LP
1261 assert_se(!t);
1262 assert_se(p == original + 12);
1263
1264 p = original = "\"foobar\" \'waldo\'";
4034a06d 1265 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1266 assert_se(streq(t, "foobar"));
1267 free(t);
1268 assert_se(p == original + 9);
1269
4034a06d 1270 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1271 assert_se(streq(t, "waldo"));
1272 free(t);
1273 assert_se(p == original + 16);
1274
4034a06d 1275 assert_se(unquote_first_word(&p, &t, 0) == 0);
7629889c
LP
1276 assert_se(!t);
1277 assert_se(p == original + 16);
1278
1279 p = original = "\"";
4034a06d 1280 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
7629889c
LP
1281 assert_se(p == original + 1);
1282
1283 p = original = "\'";
4034a06d 1284 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
7629889c
LP
1285 assert_se(p == original + 1);
1286
f32d2db1 1287 p = original = "\'fooo";
4034a06d 1288 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
f32d2db1
LP
1289 assert_se(p == original + 5);
1290
1291 p = original = "\'fooo";
4034a06d 1292 assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
f32d2db1 1293 assert_se(streq(t, "fooo"));
e1ba963f 1294 free(t);
f32d2db1
LP
1295 assert_se(p == original + 5);
1296
7629889c 1297 p = original = "yay\'foo\'bar";
4034a06d 1298 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1299 assert_se(streq(t, "yayfoobar"));
1300 free(t);
1301 assert_se(p == original + 11);
1302
1303 p = original = " foobar ";
4034a06d 1304 assert_se(unquote_first_word(&p, &t, 0) > 0);
7629889c
LP
1305 assert_se(streq(t, "foobar"));
1306 free(t);
1307 assert_se(p == original + 12);
4034a06d
LP
1308
1309 p = original = " foo\\ba\\x6ar ";
1310 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1311 assert_se(streq(t, "foo\ba\x6ar"));
1312 free(t);
1313 assert_se(p == original + 13);
1314
1315 p = original = " foo\\ba\\x6ar ";
1316 assert_se(unquote_first_word(&p, &t, 0) > 0);
1317 assert_se(streq(t, "foobax6ar"));
1318 free(t);
1319 assert_se(p == original + 13);
8ebac1f9
LP
1320
1321 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
1322 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1323 assert_se(streq(t, "föo"));
1324 free(t);
1325 assert_se(p == original + 13);
1326
1327 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1328 assert_se(streq(t, "pi\360\237\222\251le"));
1329 free(t);
1330 assert_se(p == original + 32);
d6293c07
FB
1331
1332 p = original = "fooo\\";
1333 assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
1334 assert_se(streq(t, "fooo"));
1335 free(t);
1336 assert_se(p == original + 5);
1337
1338 p = original = "fooo\\";
1339 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX) > 0);
1340 assert_se(streq(t, "fooo\\"));
1341 free(t);
1342 assert_se(p == original + 5);
1343
1344 p = original = "fooo\\";
1345 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX|UNQUOTE_RELAX) > 0);
1346 assert_se(streq(t, "fooo\\"));
1347 free(t);
1348 assert_se(p == original + 5);
1349
1350 p = original = "fooo\\";
1351 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX) > 0);
1352 assert_se(streq(t, "fooo\\"));
1353 free(t);
1354 assert_se(p == original + 5);
1355
1356 p = original = "\"foo\\";
1357 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
1358 assert_se(p == original + 5);
1359
1360 p = original = "\"foo\\";
1361 assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
1362 assert_se(streq(t, "foo"));
1363 free(t);
1364 assert_se(p == original + 5);
1365
1366 p = original = "\"foo\\";
1367 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX) == -EINVAL);
1368 assert_se(p == original + 5);
1369
1370 p = original = "\"foo\\";
1371 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX|UNQUOTE_RELAX) > 0);
1372 assert_se(streq(t, "foo\\"));
1373 free(t);
1374 assert_se(p == original + 5);
1375
1376 p = original = "\"foo\\";
1377 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX|UNQUOTE_RELAX) > 0);
1378 assert_se(streq(t, "foo\\"));
1379 free(t);
1380 assert_se(p == original + 5);
1381
1382 p = original = "fooo\\ bar quux";
1383 assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
1384 assert_se(streq(t, "fooo bar"));
1385 free(t);
1386 assert_se(p == original + 10);
1387
1388 p = original = "fooo\\ bar quux";
1389 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX) > 0);
1390 assert_se(streq(t, "fooo bar"));
1391 free(t);
1392 assert_se(p == original + 10);
1393
1394 p = original = "fooo\\ bar quux";
1395 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX|UNQUOTE_RELAX) > 0);
1396 assert_se(streq(t, "fooo bar"));
1397 free(t);
1398 assert_se(p == original + 10);
1399
1400 p = original = "fooo\\ bar quux";
1401 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) == -EINVAL);
1402 assert_se(p == original + 5);
1403
1404 p = original = "fooo\\ bar quux";
1405 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX) > 0);
1406 assert_se(streq(t, "fooo\\ bar"));
1407 free(t);
1408 assert_se(p == original + 10);
1409
1410 p = original = "\\w+@\\K[\\d.]+";
1411 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) == -EINVAL);
1412 assert_se(p == original + 1);
1413
1414 p = original = "\\w+@\\K[\\d.]+";
1415 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX) > 0);
1416 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
1417 free(t);
1418 assert_se(p == original + 12);
1419
1420 p = original = "\\w+\\b";
1421 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX) > 0);
1422 assert_se(streq(t, "\\w+\b"));
1423 free(t);
1424 assert_se(p == original + 5);
7629889c
LP
1425}
1426
b59292b2
FB
1427static void test_unquote_first_word_and_warn(void) {
1428 const char *p, *original;
1429 char *t;
1430
1431 p = original = "foobar waldo";
1432 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
1433 assert_se(streq(t, "foobar"));
1434 free(t);
1435 assert_se(p == original + 7);
1436
1437 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
1438 assert_se(streq(t, "waldo"));
1439 free(t);
1440 assert_se(p == original + 12);
1441
1442 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == 0);
1443 assert_se(!t);
1444 assert_se(p == original + 12);
1445
1446 p = original = "\"foobar\" \'waldo\'";
1447 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
1448 assert_se(streq(t, "foobar"));
1449 free(t);
1450 assert_se(p == original + 9);
1451
1452 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
1453 assert_se(streq(t, "waldo"));
1454 free(t);
1455 assert_se(p == original + 16);
1456
1457 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == 0);
1458 assert_se(!t);
1459 assert_se(p == original + 16);
1460
1461 p = original = "\"";
1462 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == -EINVAL);
1463 assert_se(p == original + 1);
1464
1465 p = original = "\'";
1466 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == -EINVAL);
1467 assert_se(p == original + 1);
1468
1469 p = original = "\'fooo";
1470 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == -EINVAL);
1471 assert_se(p == original + 5);
1472
1473 p = original = "\'fooo";
1474 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
1475 assert_se(streq(t, "fooo"));
1476 free(t);
1477 assert_se(p == original + 5);
1478
1479 p = original = " foo\\ba\\x6ar ";
1480 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
1481 assert_se(streq(t, "foo\ba\x6ar"));
1482 free(t);
1483 assert_se(p == original + 13);
1484
1485 p = original = " foo\\ba\\x6ar ";
1486 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
1487 assert_se(streq(t, "foobax6ar"));
1488 free(t);
1489 assert_se(p == original + 13);
1490
1491 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
1492 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
1493 assert_se(streq(t, "föo"));
1494 free(t);
1495 assert_se(p == original + 13);
1496
1497 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
1498 assert_se(streq(t, "pi\360\237\222\251le"));
1499 free(t);
1500 assert_se(p == original + 32);
1501
1502 p = original = "fooo\\";
1503 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
1504 assert_se(streq(t, "fooo"));
1505 free(t);
1506 assert_se(p == original + 5);
1507
1508 p = original = "fooo\\";
1509 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
1510 assert_se(streq(t, "fooo\\"));
1511 free(t);
1512 assert_se(p == original + 5);
1513
1514 p = original = "fooo\\";
1515 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
1516 assert_se(streq(t, "fooo\\"));
1517 free(t);
1518 assert_se(p == original + 5);
1519
1520 p = original = "\"foo\\";
1521 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == -EINVAL);
1522 assert_se(p == original + 5);
1523
1524 p = original = "\"foo\\";
1525 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
1526 assert_se(streq(t, "foo"));
1527 free(t);
1528 assert_se(p == original + 5);
1529
1530 p = original = "\"foo\\";
1531 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
1532 assert_se(p == original + 5);
1533
1534 p = original = "\"foo\\";
1535 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
1536 assert_se(streq(t, "foo"));
1537 free(t);
1538 assert_se(p == original + 5);
1539
1540 p = original = "fooo\\ bar quux";
1541 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
1542 assert_se(streq(t, "fooo bar"));
1543 free(t);
1544 assert_se(p == original + 10);
1545
1546 p = original = "fooo\\ bar quux";
1547 assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
1548 assert_se(streq(t, "fooo bar"));
1549 free(t);
1550 assert_se(p == original + 10);
1551
1552 p = original = "fooo\\ bar quux";
1553 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
1554 assert_se(streq(t, "fooo\\ bar"));
1555 free(t);
1556 assert_se(p == original + 10);
1557
1558 p = original = "\\w+@\\K[\\d.]+";
1559 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
1560 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
1561 free(t);
1562 assert_se(p == original + 12);
1563
1564 p = original = "\\w+\\b";
1565 assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
1566 assert_se(streq(t, "\\w+\b"));
1567 free(t);
1568 assert_se(p == original + 5);
1569}
1570
7629889c
LP
1571static void test_unquote_many_words(void) {
1572 const char *p, *original;
1573 char *a, *b, *c;
1574
1575 p = original = "foobar waldi piep";
4034a06d 1576 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 3);
7629889c
LP
1577 assert_se(p == original + 17);
1578 assert_se(streq_ptr(a, "foobar"));
1579 assert_se(streq_ptr(b, "waldi"));
1580 assert_se(streq_ptr(c, "piep"));
1581 free(a);
1582 free(b);
1583 free(c);
1584
1585 p = original = "'foobar' wa\"ld\"i ";
4034a06d 1586 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 2);
7629889c
LP
1587 assert_se(p == original + 19);
1588 assert_se(streq_ptr(a, "foobar"));
1589 assert_se(streq_ptr(b, "waldi"));
1590 assert_se(streq_ptr(c, NULL));
1591 free(a);
1592 free(b);
1593
1594 p = original = "";
4034a06d 1595 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
7629889c
LP
1596 assert_se(p == original);
1597 assert_se(streq_ptr(a, NULL));
1598 assert_se(streq_ptr(b, NULL));
1599 assert_se(streq_ptr(c, NULL));
1600
1601 p = original = " ";
4034a06d 1602 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
7629889c
LP
1603 assert_se(p == original+2);
1604 assert_se(streq_ptr(a, NULL));
1605 assert_se(streq_ptr(b, NULL));
1606 assert_se(streq_ptr(c, NULL));
1607
1608 p = original = "foobar";
4034a06d 1609 assert_se(unquote_many_words(&p, 0, NULL) == 0);
7629889c
LP
1610 assert_se(p == original);
1611
1612 p = original = "foobar waldi";
4034a06d 1613 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
7629889c
LP
1614 assert_se(p == original+7);
1615 assert_se(streq_ptr(a, "foobar"));
eee84633 1616 free(a);
7629889c
LP
1617
1618 p = original = " foobar ";
4034a06d 1619 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
7629889c
LP
1620 assert_se(p == original+15);
1621 assert_se(streq_ptr(a, "foobar"));
eee84633 1622 free(a);
7629889c
LP
1623}
1624
f32d2db1
LP
1625static int parse_item(const char *key, const char *value) {
1626 assert_se(key);
1627
1628 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1629 return 0;
1630}
1631
1632static void test_parse_proc_cmdline(void) {
1633 assert_se(parse_proc_cmdline(parse_item) >= 0);
1634}
1635
ee05e779
ZJS
1636static void test_raw_clone(void) {
1637 pid_t parent, pid, pid2;
1638
1639 parent = getpid();
1640 log_info("before clone: getpid()→"PID_FMT, parent);
1641 assert_se(raw_getpid() == parent);
1642
1643 pid = raw_clone(0, NULL);
e50221bf 1644 assert_se(pid >= 0);
ee05e779
ZJS
1645
1646 pid2 = raw_getpid();
1647 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1648 pid, getpid(), pid2);
0289a5bc 1649 if (pid == 0) {
e50221bf 1650 assert_se(pid2 != parent);
0289a5bc
FB
1651 _exit(EXIT_SUCCESS);
1652 } else {
1653 int status;
1654
e50221bf 1655 assert_se(pid2 == parent);
0289a5bc
FB
1656 waitpid(pid, &status, __WCLONE);
1657 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1658 }
ee05e779
ZJS
1659}
1660
f7ad54a3
LP
1661static void test_same_fd(void) {
1662 _cleanup_close_pair_ int p[2] = { -1, -1 };
1663 _cleanup_close_ int a = -1, b = -1, c = -1;
1664
1665 assert_se(pipe2(p, O_CLOEXEC) >= 0);
1666 assert_se((a = dup(p[0])) >= 0);
1667 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1668 assert_se((c = dup(a)) >= 0);
1669
1670 assert_se(same_fd(p[0], p[0]) > 0);
1671 assert_se(same_fd(p[1], p[1]) > 0);
1672 assert_se(same_fd(a, a) > 0);
1673 assert_se(same_fd(b, b) > 0);
1674
1675 assert_se(same_fd(a, p[0]) > 0);
1676 assert_se(same_fd(p[0], a) > 0);
1677 assert_se(same_fd(c, p[0]) > 0);
1678 assert_se(same_fd(p[0], c) > 0);
1679 assert_se(same_fd(a, c) > 0);
1680 assert_se(same_fd(c, a) > 0);
1681
1682 assert_se(same_fd(p[0], p[1]) == 0);
1683 assert_se(same_fd(p[1], p[0]) == 0);
1684 assert_se(same_fd(p[0], b) == 0);
1685 assert_se(same_fd(b, p[0]) == 0);
1686 assert_se(same_fd(p[1], a) == 0);
1687 assert_se(same_fd(a, p[1]) == 0);
1688 assert_se(same_fd(p[1], b) == 0);
1689 assert_se(same_fd(b, p[1]) == 0);
1690
1691 assert_se(same_fd(a, b) == 0);
1692 assert_se(same_fd(b, a) == 0);
1693}
1694
8cb4ab00
LP
1695static void test_uid_ptr(void) {
1696
1697 assert_se(UID_TO_PTR(0) != NULL);
1698 assert_se(UID_TO_PTR(1000) != NULL);
1699
1700 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1701 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1702}
1703
ff6a7460
LP
1704static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
1705 char check[n];
1706
1707 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1708 assert_se(ftruncate(fd, 0) >= 0);
1709 assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
1710
1711 assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
1712 assert_se(ftruncate(fd, n) >= 0);
1713
1714 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1715 assert_se(read(fd, check, n) == (ssize_t) n);
1716
1717 assert_se(memcmp(buffer, check, n) == 0);
1718}
1719
1720static void test_sparse_write(void) {
1721 const char test_a[] = "test";
1722 const char test_b[] = "\0\0\0\0test\0\0\0\0";
1723 const char test_c[] = "\0\0test\0\0\0\0";
1724 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";
1725 const char test_e[] = "test\0\0\0\0test";
1726 _cleanup_close_ int fd = -1;
1727 char fn[] = "/tmp/sparseXXXXXX";
1728
1729 fd = mkostemp(fn, O_CLOEXEC);
1730 assert_se(fd >= 0);
1731 unlink(fn);
1732
1733 test_sparse_write_one(fd, test_a, sizeof(test_a));
1734 test_sparse_write_one(fd, test_b, sizeof(test_b));
1735 test_sparse_write_one(fd, test_c, sizeof(test_c));
1736 test_sparse_write_one(fd, test_d, sizeof(test_d));
1737 test_sparse_write_one(fd, test_e, sizeof(test_e));
1738}
1739
019c7fba
LP
1740static void test_shell_maybe_quote_one(const char *s, const char *expected) {
1741 _cleanup_free_ char *r;
1742
1743 assert_se(r = shell_maybe_quote(s));
1744 assert_se(streq(r, expected));
1745}
1746
1747static void test_shell_maybe_quote(void) {
1748
1749 test_shell_maybe_quote_one("", "");
1750 test_shell_maybe_quote_one("\\", "\"\\\\\"");
1751 test_shell_maybe_quote_one("\"", "\"\\\"\"");
1752 test_shell_maybe_quote_one("foobar", "foobar");
1753 test_shell_maybe_quote_one("foo bar", "\"foo bar\"");
1754 test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\"");
1755 test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
1756}
1757
2ff7b0a5
LP
1758static void test_parse_mode(void) {
1759 mode_t m;
1760
1761 assert_se(parse_mode("-1", &m) < 0);
1762 assert_se(parse_mode("", &m) < 0);
1763 assert_se(parse_mode("888", &m) < 0);
1764 assert_se(parse_mode("77777", &m) < 0);
1765
1766 assert_se(parse_mode("544", &m) >= 0 && m == 0544);
1767 assert_se(parse_mode("777", &m) >= 0 && m == 0777);
1768 assert_se(parse_mode("7777", &m) >= 0 && m == 07777);
1769 assert_se(parse_mode("0", &m) >= 0 && m == 0);
1770}
1771
14bcf25c
LP
1772static void test_tempfn(void) {
1773 char *ret = NULL, *p;
1774
1775 assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
1776 assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
1777 free(ret);
1778
1779 assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret) >= 0);
1780 assert_se(streq_ptr(ret, "/foo/bar/.#[miau]waldoXXXXXX"));
1781 free(ret);
1782
1783 assert_se(tempfn_random("/foo/bar/waldo", NULL, &ret) >= 0);
1784 assert_se(p = startswith(ret, "/foo/bar/.#waldo"));
1785 assert_se(strlen(p) == 16);
1786 assert_se(in_charset(p, "0123456789abcdef"));
1787 free(ret);
1788
1789 assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret) >= 0);
1790 assert_se(p = startswith(ret, "/foo/bar/.#[wuff]waldo"));
1791 assert_se(strlen(p) == 16);
1792 assert_se(in_charset(p, "0123456789abcdef"));
1793 free(ret);
1794
1795 assert_se(tempfn_random_child("/foo/bar/waldo", NULL, &ret) >= 0);
1796 assert_se(p = startswith(ret, "/foo/bar/waldo/.#"));
1797 assert_se(strlen(p) == 16);
1798 assert_se(in_charset(p, "0123456789abcdef"));
1799 free(ret);
1800
1801 assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret) >= 0);
1802 assert_se(p = startswith(ret, "/foo/bar/waldo/.#[kikiriki]"));
1803 assert_se(strlen(p) == 16);
1804 assert_se(in_charset(p, "0123456789abcdef"));
1805 free(ret);
1806}
1807
539ad707 1808int main(int argc, char *argv[]) {
9480794b
ZJS
1809 log_parse_environment();
1810 log_open();
1811
539ad707 1812 test_streq_ptr();
625e870b 1813 test_align_power2();
7242d742 1814 test_max();
fb835651 1815 test_container_of();
95d78c7e 1816 test_alloca();
180a60bc 1817 test_div_round_up();
539ad707 1818 test_first_word();
dbd73f9e 1819 test_close_many();
8354c34e 1820 test_parse_boolean();
8d99e5f5
TA
1821 test_parse_pid();
1822 test_parse_uid();
1823 test_safe_atolli();
1824 test_safe_atod();
dbd73f9e 1825 test_strappend();
1ef04f0b
TA
1826 test_strstrip();
1827 test_delete_chars();
1828 test_in_charset();
44f4c86c
DB
1829 test_hexchar();
1830 test_unhexchar();
1831 test_octchar();
1832 test_unoctchar();
1833 test_decchar();
1834 test_undecchar();
30494563 1835 test_unhexmem();
b4ecc959
TA
1836 test_cescape();
1837 test_cunescape();
1ef04f0b 1838 test_foreach_word();
539ad707 1839 test_foreach_word_quoted();
0d585d82 1840 test_memdup_multiply();
aa3c5cf8 1841 test_hostname_is_valid();
139e5336 1842 test_read_hostname_config();
144e51ec 1843 test_u64log2();
2a371001 1844 test_protect_errno();
5556b5fe 1845 test_parse_size();
9480794b 1846 test_config_parse_iec_off();
b4ecc959
TA
1847 test_strextend();
1848 test_strrep();
d4ac85c6 1849 test_split_pair();
22f5f628 1850 test_fstab_node_to_udev_node();
893fa014 1851 test_get_files_in_directory();
cabb7806 1852 test_in_set();
87b02843 1853 test_writing_tmpfile();
29bfbcd6 1854 test_hexdump();
8fe90522 1855 test_log2i();
c4a7b2c5 1856 test_foreach_string();
ae6c3cc0 1857 test_filename_is_valid();
1cb1767a 1858 test_string_has_cc();
927be00c
RC
1859 test_ascii_strlower();
1860 test_files_same();
1861 test_is_valid_documentation_url();
1862 test_file_in_same_dir();
1863 test_endswith();
1864 test_close_nointr();
1865 test_unlink_noerrno();
1866 test_readlink_and_make_absolute();
927be00c
RC
1867 test_ignore_signals();
1868 test_strshorten();
63c372cb 1869 test_strjoina();
8852362b 1870 test_is_symlink();
8852362b
RC
1871 test_search_and_fopen();
1872 test_search_and_fopen_nulstr();
1873 test_glob_exists();
1874 test_execute_directory();
7629889c 1875 test_unquote_first_word();
b59292b2 1876 test_unquote_first_word_and_warn();
7629889c 1877 test_unquote_many_words();
f32d2db1 1878 test_parse_proc_cmdline();
ee05e779 1879 test_raw_clone();
f7ad54a3 1880 test_same_fd();
8cb4ab00 1881 test_uid_ptr();
ff6a7460 1882 test_sparse_write();
019c7fba 1883 test_shell_maybe_quote();
2ff7b0a5 1884 test_parse_mode();
14bcf25c 1885 test_tempfn();
539ad707
TA
1886
1887 return 0;
1888}