]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-util.c
update TODO
[thirdparty/systemd.git] / src / test / test-util.c
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>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <locale.h>
27 #include <errno.h>
28 #include <signal.h>
29 #include <math.h>
30 #include <sys/wait.h>
31
32 #include "util.h"
33 #include "mkdir.h"
34 #include "strv.h"
35 #include "def.h"
36 #include "fileio.h"
37 #include "conf-parser.h"
38 #include "virt.h"
39
40 static void test_streq_ptr(void) {
41 assert_se(streq_ptr(NULL, NULL));
42 assert_se(!streq_ptr("abc", "cdef"));
43 }
44
45 static void test_align_power2(void) {
46 unsigned long i, p2;
47
48 assert_se(ALIGN_POWER2(0) == 0);
49 assert_se(ALIGN_POWER2(1) == 1);
50 assert_se(ALIGN_POWER2(2) == 2);
51 assert_se(ALIGN_POWER2(3) == 4);
52 assert_se(ALIGN_POWER2(12) == 16);
53
54 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
55 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
56 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
57 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
58 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
59
60 for (i = 1; i < 131071; ++i) {
61 for (p2 = 1; p2 < i; p2 <<= 1)
62 /* empty */ ;
63
64 assert_se(ALIGN_POWER2(i) == p2);
65 }
66
67 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
68 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
69 /* empty */ ;
70
71 assert_se(ALIGN_POWER2(i) == p2);
72 }
73 }
74
75 static void test_max(void) {
76 static const struct {
77 int a;
78 int b[CONST_MAX(10, 100)];
79 } val1 = {
80 .a = CONST_MAX(10, 100),
81 };
82 int d = 0;
83
84 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
85
86 /* CONST_MAX returns (void) instead of a value if the passed arguments
87 * are not of the same type or not constant expressions. */
88 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
89 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
90
91 assert_se(val1.a == 100);
92 assert_se(MAX(++d, 0) == 1);
93 assert_se(d == 1);
94
95 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
96 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
97 assert_cc(MAXSIZE(char, long) == sizeof(long));
98
99 assert_se(MAX(-5, 5) == 5);
100 assert_se(MAX(5, 5) == 5);
101 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
102 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
103 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
104 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
105 assert_se(LESS_BY(8, 4) == 4);
106 assert_se(LESS_BY(8, 8) == 0);
107 assert_se(LESS_BY(4, 8) == 0);
108 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
109 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
110 assert_se(CLAMP(-5, 0, 1) == 0);
111 assert_se(CLAMP(5, 0, 1) == 1);
112 assert_se(CLAMP(5, -10, 1) == 1);
113 assert_se(CLAMP(5, -10, 10) == 5);
114 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
115 }
116
117 static void test_container_of(void) {
118 struct mytype {
119 uint8_t pad1[3];
120 uint64_t v1;
121 uint8_t pad2[2];
122 uint32_t v2;
123 } _packed_ myval = { };
124
125 assert_cc(sizeof(myval) == 17);
126 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
127 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
128 assert_se(container_of(&container_of(&myval.v2,
129 struct mytype,
130 v2)->v1,
131 struct mytype,
132 v1) == &myval);
133 }
134
135 static void test_alloca(void) {
136 static const uint8_t zero[997] = { };
137 char *t;
138
139 t = alloca_align(17, 512);
140 assert_se(!((uintptr_t)t & 0xff));
141 memzero(t, 17);
142
143 t = alloca0_align(997, 1024);
144 assert_se(!((uintptr_t)t & 0x1ff));
145 assert_se(!memcmp(t, zero, 997));
146 }
147
148 static void test_div_round_up(void) {
149 int div;
150
151 /* basic tests */
152 assert_se(DIV_ROUND_UP(0, 8) == 0);
153 assert_se(DIV_ROUND_UP(1, 8) == 1);
154 assert_se(DIV_ROUND_UP(8, 8) == 1);
155 assert_se(DIV_ROUND_UP(12, 8) == 2);
156 assert_se(DIV_ROUND_UP(16, 8) == 2);
157
158 /* test multiple evaluation */
159 div = 0;
160 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
161 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
162 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
163 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
164
165 /* overflow test with exact division */
166 assert_se(sizeof(0U) == 4);
167 assert_se(0xfffffffaU % 10U == 0U);
168 assert_se(0xfffffffaU / 10U == 429496729U);
169 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
170 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
171 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
172
173 /* overflow test with rounded division */
174 assert_se(0xfffffffdU % 10U == 3U);
175 assert_se(0xfffffffdU / 10U == 429496729U);
176 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
177 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
178 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
179 }
180
181 static void test_first_word(void) {
182 assert_se(first_word("Hello", ""));
183 assert_se(first_word("Hello", "Hello"));
184 assert_se(first_word("Hello world", "Hello"));
185 assert_se(first_word("Hello\tworld", "Hello"));
186 assert_se(first_word("Hello\nworld", "Hello"));
187 assert_se(first_word("Hello\rworld", "Hello"));
188 assert_se(first_word("Hello ", "Hello"));
189
190 assert_se(!first_word("Hello", "Hellooo"));
191 assert_se(!first_word("Hello", "xxxxx"));
192 assert_se(!first_word("Hellooo", "Hello"));
193 }
194
195 static void test_close_many(void) {
196 int fds[3];
197 char name0[] = "/tmp/test-close-many.XXXXXX";
198 char name1[] = "/tmp/test-close-many.XXXXXX";
199 char name2[] = "/tmp/test-close-many.XXXXXX";
200
201 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
202 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
203 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
204
205 close_many(fds, 2);
206
207 assert_se(fcntl(fds[0], F_GETFD) == -1);
208 assert_se(fcntl(fds[1], F_GETFD) == -1);
209 assert_se(fcntl(fds[2], F_GETFD) >= 0);
210
211 safe_close(fds[2]);
212
213 unlink(name0);
214 unlink(name1);
215 unlink(name2);
216 }
217
218 static void test_parse_boolean(void) {
219 assert_se(parse_boolean("1") == 1);
220 assert_se(parse_boolean("y") == 1);
221 assert_se(parse_boolean("Y") == 1);
222 assert_se(parse_boolean("yes") == 1);
223 assert_se(parse_boolean("YES") == 1);
224 assert_se(parse_boolean("true") == 1);
225 assert_se(parse_boolean("TRUE") == 1);
226 assert_se(parse_boolean("on") == 1);
227 assert_se(parse_boolean("ON") == 1);
228
229 assert_se(parse_boolean("0") == 0);
230 assert_se(parse_boolean("n") == 0);
231 assert_se(parse_boolean("N") == 0);
232 assert_se(parse_boolean("no") == 0);
233 assert_se(parse_boolean("NO") == 0);
234 assert_se(parse_boolean("false") == 0);
235 assert_se(parse_boolean("FALSE") == 0);
236 assert_se(parse_boolean("off") == 0);
237 assert_se(parse_boolean("OFF") == 0);
238
239 assert_se(parse_boolean("garbage") < 0);
240 assert_se(parse_boolean("") < 0);
241 assert_se(parse_boolean("full") < 0);
242 }
243
244 static void test_parse_pid(void) {
245 int r;
246 pid_t pid;
247
248 r = parse_pid("100", &pid);
249 assert_se(r == 0);
250 assert_se(pid == 100);
251
252 r = parse_pid("0x7FFFFFFF", &pid);
253 assert_se(r == 0);
254 assert_se(pid == 2147483647);
255
256 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
257 r = parse_pid("0", &pid);
258 assert_se(r == -ERANGE);
259 assert_se(pid == 65);
260
261 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
262 r = parse_pid("-100", &pid);
263 assert_se(r == -ERANGE);
264 assert_se(pid == 65);
265
266 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
267 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
268 assert_se(r == -ERANGE);
269 assert_se(pid == 65);
270 }
271
272 static void test_parse_uid(void) {
273 int r;
274 uid_t uid;
275
276 r = parse_uid("100", &uid);
277 assert_se(r == 0);
278 assert_se(uid == 100);
279 }
280
281 static void test_safe_atolli(void) {
282 int r;
283 long long l;
284
285 r = safe_atolli("12345", &l);
286 assert_se(r == 0);
287 assert_se(l == 12345);
288
289 r = safe_atolli("junk", &l);
290 assert_se(r == -EINVAL);
291 }
292
293 static void test_safe_atod(void) {
294 int r;
295 double d;
296 char *e;
297
298 r = safe_atod("junk", &d);
299 assert_se(r == -EINVAL);
300
301 r = safe_atod("0.2244", &d);
302 assert_se(r == 0);
303 assert_se(fabs(d - 0.2244) < 0.000001);
304
305 r = safe_atod("0,5", &d);
306 assert_se(r == -EINVAL);
307
308 errno = 0;
309 strtod("0,5", &e);
310 assert_se(*e == ',');
311
312 /* Check if this really is locale independent */
313 if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
314
315 r = safe_atod("0.2244", &d);
316 assert_se(r == 0);
317 assert_se(fabs(d - 0.2244) < 0.000001);
318
319 r = safe_atod("0,5", &d);
320 assert_se(r == -EINVAL);
321
322 errno = 0;
323 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
324 }
325
326 /* And check again, reset */
327 assert_se(setlocale(LC_NUMERIC, "C"));
328
329 r = safe_atod("0.2244", &d);
330 assert_se(r == 0);
331 assert_se(fabs(d - 0.2244) < 0.000001);
332
333 r = safe_atod("0,5", &d);
334 assert_se(r == -EINVAL);
335
336 errno = 0;
337 strtod("0,5", &e);
338 assert_se(*e == ',');
339 }
340
341 static void test_strappend(void) {
342 _cleanup_free_ char *t1, *t2, *t3, *t4;
343
344 t1 = strappend(NULL, NULL);
345 assert_se(streq(t1, ""));
346
347 t2 = strappend(NULL, "suf");
348 assert_se(streq(t2, "suf"));
349
350 t3 = strappend("pre", NULL);
351 assert_se(streq(t3, "pre"));
352
353 t4 = strappend("pre", "suf");
354 assert_se(streq(t4, "presuf"));
355 }
356
357 static void test_strstrip(void) {
358 char *r;
359 char input[] = " hello, waldo. ";
360
361 r = strstrip(input);
362 assert_se(streq(r, "hello, waldo."));
363 }
364
365 static void test_delete_chars(void) {
366 char *r;
367 char input[] = " hello, waldo. abc";
368
369 r = delete_chars(input, WHITESPACE);
370 assert_se(streq(r, "hello,waldo.abc"));
371 }
372
373 static void test_in_charset(void) {
374 assert_se(in_charset("dddaaabbbcccc", "abcd"));
375 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
376 }
377
378 static void test_hexchar(void) {
379 assert_se(hexchar(0xa) == 'a');
380 assert_se(hexchar(0x0) == '0');
381 }
382
383 static void test_unhexchar(void) {
384 assert_se(unhexchar('a') == 0xA);
385 assert_se(unhexchar('A') == 0xA);
386 assert_se(unhexchar('0') == 0x0);
387 }
388
389 static void test_octchar(void) {
390 assert_se(octchar(00) == '0');
391 assert_se(octchar(07) == '7');
392 }
393
394 static void test_unoctchar(void) {
395 assert_se(unoctchar('0') == 00);
396 assert_se(unoctchar('7') == 07);
397 }
398
399 static void test_decchar(void) {
400 assert_se(decchar(0) == '0');
401 assert_se(decchar(9) == '9');
402 }
403
404 static void test_undecchar(void) {
405 assert_se(undecchar('0') == 0);
406 assert_se(undecchar('9') == 9);
407 }
408
409 static void test_cescape(void) {
410 _cleanup_free_ char *escaped;
411
412 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
413 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
414 }
415
416 static void test_cunescape(void) {
417 _cleanup_free_ char *unescaped;
418
419 unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00");
420 assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
421
422 /* incomplete sequences */
423 unescaped = cunescape("\\x0");
424 assert_se(streq_ptr(unescaped, "\\x0"));
425
426 unescaped = cunescape("\\x");
427 assert_se(streq_ptr(unescaped, "\\x"));
428
429 unescaped = cunescape("\\");
430 assert_se(streq_ptr(unescaped, "\\"));
431
432 unescaped = cunescape("\\11");
433 assert_se(streq_ptr(unescaped, "\\11"));
434
435 unescaped = cunescape("\\1");
436 assert_se(streq_ptr(unescaped, "\\1"));
437 }
438
439 static void test_foreach_word(void) {
440 const char *word, *state;
441 size_t l;
442 int i = 0;
443 const char test[] = "test abc d\te f ";
444 const char * const expected[] = {
445 "test",
446 "abc",
447 "d",
448 "e",
449 "f",
450 "",
451 NULL
452 };
453
454 FOREACH_WORD(word, l, test, state)
455 assert_se(strneq(expected[i++], word, l));
456 }
457
458 static void check(const char *test, char** expected, bool trailing) {
459 const char *word, *state;
460 size_t l;
461 int i = 0;
462
463 printf("<<<%s>>>\n", test);
464 FOREACH_WORD_QUOTED(word, l, test, state) {
465 _cleanup_free_ char *t = NULL;
466
467 assert_se(t = strndup(word, l));
468 assert_se(strneq(expected[i++], word, l));
469 printf("<%s>\n", t);
470 }
471 printf("<<<%s>>>\n", state);
472 assert_se(expected[i] == NULL);
473 assert_se(isempty(state) == !trailing);
474 }
475
476 static void test_foreach_word_quoted(void) {
477 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
478 STRV_MAKE("test",
479 "a",
480 "b",
481 "c",
482 "d",
483 "e",
484 "",
485 "",
486 "hhh",
487 "",
488 "",
489 "a b c"),
490 false);
491
492 check("test \"xxx",
493 STRV_MAKE("test"),
494 true);
495
496 check("test\\",
497 STRV_MAKE_EMPTY,
498 true);
499 }
500
501 static void test_default_term_for_tty(void) {
502 puts(default_term_for_tty("/dev/tty23"));
503 puts(default_term_for_tty("/dev/ttyS23"));
504 puts(default_term_for_tty("/dev/tty0"));
505 puts(default_term_for_tty("/dev/pty0"));
506 puts(default_term_for_tty("/dev/pts/0"));
507 puts(default_term_for_tty("/dev/console"));
508 puts(default_term_for_tty("tty23"));
509 puts(default_term_for_tty("ttyS23"));
510 puts(default_term_for_tty("tty0"));
511 puts(default_term_for_tty("pty0"));
512 puts(default_term_for_tty("pts/0"));
513 puts(default_term_for_tty("console"));
514 }
515
516 static void test_memdup_multiply(void) {
517 int org[] = {1, 2, 3};
518 int *dup;
519
520 dup = (int*)memdup_multiply(org, sizeof(int), 3);
521
522 assert_se(dup);
523 assert_se(dup[0] == 1);
524 assert_se(dup[1] == 2);
525 assert_se(dup[2] == 3);
526 free(dup);
527 }
528
529 static void test_hostname_is_valid(void) {
530 assert_se(hostname_is_valid("foobar"));
531 assert_se(hostname_is_valid("foobar.com"));
532 assert_se(!hostname_is_valid("fööbar"));
533 assert_se(!hostname_is_valid(""));
534 assert_se(!hostname_is_valid("."));
535 assert_se(!hostname_is_valid(".."));
536 assert_se(!hostname_is_valid("foobar."));
537 assert_se(!hostname_is_valid(".foobar"));
538 assert_se(!hostname_is_valid("foo..bar"));
539 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
540 }
541
542 static void test_u64log2(void) {
543 assert_se(u64log2(0) == 0);
544 assert_se(u64log2(8) == 3);
545 assert_se(u64log2(9) == 3);
546 assert_se(u64log2(15) == 3);
547 assert_se(u64log2(16) == 4);
548 assert_se(u64log2(1024*1024) == 20);
549 assert_se(u64log2(1024*1024+5) == 20);
550 }
551
552 static void test_get_process_comm(void) {
553 struct stat st;
554 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
555 _cleanup_free_ char *env = NULL;
556 pid_t e;
557 uid_t u;
558 gid_t g;
559 dev_t h;
560 int r;
561 pid_t me;
562
563 if (stat("/proc/1/comm", &st) == 0) {
564 assert_se(get_process_comm(1, &a) >= 0);
565 log_info("pid1 comm: '%s'", a);
566 } else {
567 log_warning("/proc/1/comm does not exist.");
568 }
569
570 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
571 log_info("pid1 cmdline: '%s'", c);
572
573 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
574 log_info("pid1 cmdline truncated: '%s'", d);
575
576 assert_se(get_parent_of_pid(1, &e) >= 0);
577 log_info("pid1 ppid: "PID_FMT, e);
578 assert_se(e == 0);
579
580 assert_se(is_kernel_thread(1) == 0);
581
582 r = get_process_exe(1, &f);
583 assert_se(r >= 0 || r == -EACCES);
584 log_info("pid1 exe: '%s'", strna(f));
585
586 assert_se(get_process_uid(1, &u) == 0);
587 log_info("pid1 uid: "UID_FMT, u);
588 assert_se(u == 0);
589
590 assert_se(get_process_gid(1, &g) == 0);
591 log_info("pid1 gid: "GID_FMT, g);
592 assert_se(g == 0);
593
594 me = getpid();
595
596 r = get_process_cwd(me, &cwd);
597 assert_se(r >= 0 || r == -EACCES);
598 log_info("pid1 cwd: '%s'", cwd);
599
600 r = get_process_root(me, &root);
601 assert_se(r >= 0 || r == -EACCES);
602 log_info("pid1 root: '%s'", root);
603
604 r = get_process_environ(me, &env);
605 assert_se(r >= 0 || r == -EACCES);
606 log_info("self strlen(environ): '%zu'", strlen(env));
607
608 if (!detect_container(NULL))
609 assert_se(get_ctty_devnr(1, &h) == -ENOENT);
610
611 getenv_for_pid(1, "PATH", &i);
612 log_info("pid1 $PATH: '%s'", strna(i));
613 }
614
615 static void test_protect_errno(void) {
616 errno = 12;
617 {
618 PROTECT_ERRNO;
619 errno = 11;
620 }
621 assert_se(errno == 12);
622 }
623
624 static void test_parse_size(void) {
625 off_t bytes;
626
627 assert_se(parse_size("111", 1024, &bytes) == 0);
628 assert_se(bytes == 111);
629
630 assert_se(parse_size("111.4", 1024, &bytes) == 0);
631 assert_se(bytes == 111);
632
633 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
634 assert_se(bytes == 112);
635
636 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
637 assert_se(bytes == 112);
638
639 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
640 assert_se(bytes == 3*1024 + 512);
641
642 assert_se(parse_size("3. K", 1024, &bytes) == 0);
643 assert_se(bytes == 3*1024);
644
645 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
646 assert_se(bytes == 3*1024);
647
648 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
649
650 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
651 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
652
653 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
654
655 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
656 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
657
658 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
659 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
660
661 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
662
663 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
664 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
665
666 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
667 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
668
669 assert_se(parse_size("12P", 1024, &bytes) == 0);
670 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
671
672 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
673
674 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
675 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
676
677 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
678
679 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
680
681 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
682
683 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
684 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
685 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
686
687 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
688
689 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
690 }
691
692 static void test_config_parse_iec_off(void) {
693 off_t offset = 0;
694 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
695 assert_se(offset == 4 * 1024 * 1024);
696
697 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
698 }
699
700 static void test_strextend(void) {
701 _cleanup_free_ char *str = strdup("0123");
702 strextend(&str, "456", "78", "9", NULL);
703 assert_se(streq(str, "0123456789"));
704 }
705
706 static void test_strrep(void) {
707 _cleanup_free_ char *one, *three, *zero;
708 one = strrep("waldo", 1);
709 three = strrep("waldo", 3);
710 zero = strrep("waldo", 0);
711
712 assert_se(streq(one, "waldo"));
713 assert_se(streq(three, "waldowaldowaldo"));
714 assert_se(streq(zero, ""));
715 }
716
717 static void test_split_pair(void) {
718 _cleanup_free_ char *a = NULL, *b = NULL;
719
720 assert_se(split_pair("", "", &a, &b) == -EINVAL);
721 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
722 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
723 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
724 assert_se(streq(a, "foo"));
725 assert_se(streq(b, "bar"));
726 free(a);
727 free(b);
728 assert_se(split_pair("==", "==", &a, &b) >= 0);
729 assert_se(streq(a, ""));
730 assert_se(streq(b, ""));
731 free(a);
732 free(b);
733
734 assert_se(split_pair("===", "==", &a, &b) >= 0);
735 assert_se(streq(a, ""));
736 assert_se(streq(b, "="));
737 }
738
739 static void test_fstab_node_to_udev_node(void) {
740 char *n;
741
742 n = fstab_node_to_udev_node("LABEL=applé/jack");
743 puts(n);
744 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
745 free(n);
746
747 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
748 puts(n);
749 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
750 free(n);
751
752 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
753 puts(n);
754 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
755 free(n);
756
757 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
758 puts(n);
759 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
760 free(n);
761
762 n = fstab_node_to_udev_node("PONIES=awesome");
763 puts(n);
764 assert_se(streq(n, "PONIES=awesome"));
765 free(n);
766
767 n = fstab_node_to_udev_node("/dev/xda1");
768 puts(n);
769 assert_se(streq(n, "/dev/xda1"));
770 free(n);
771 }
772
773 static void test_get_files_in_directory(void) {
774 _cleanup_strv_free_ char **l = NULL, **t = NULL;
775
776 assert_se(get_files_in_directory("/tmp", &l) >= 0);
777 assert_se(get_files_in_directory(".", &t) >= 0);
778 assert_se(get_files_in_directory(".", NULL) >= 0);
779 }
780
781 static void test_in_set(void) {
782 assert_se(IN_SET(1, 1));
783 assert_se(IN_SET(1, 1, 2, 3, 4));
784 assert_se(IN_SET(2, 1, 2, 3, 4));
785 assert_se(IN_SET(3, 1, 2, 3, 4));
786 assert_se(IN_SET(4, 1, 2, 3, 4));
787 assert_se(!IN_SET(0, 1));
788 assert_se(!IN_SET(0, 1, 2, 3, 4));
789 }
790
791 static void test_writing_tmpfile(void) {
792 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
793 _cleanup_free_ char *contents = NULL;
794 size_t size;
795 int fd, r;
796 struct iovec iov[3];
797
798 IOVEC_SET_STRING(iov[0], "abc\n");
799 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
800 IOVEC_SET_STRING(iov[2], "");
801
802 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
803 printf("tmpfile: %s", name);
804
805 r = writev(fd, iov, 3);
806 assert_se(r >= 0);
807
808 r = read_full_file(name, &contents, &size);
809 assert_se(r == 0);
810 printf("contents: %s", contents);
811 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
812
813 unlink(name);
814 }
815
816 static void test_hexdump(void) {
817 uint8_t data[146];
818 unsigned i;
819
820 hexdump(stdout, NULL, 0);
821 hexdump(stdout, "", 0);
822 hexdump(stdout, "", 1);
823 hexdump(stdout, "x", 1);
824 hexdump(stdout, "x", 2);
825 hexdump(stdout, "foobar", 7);
826 hexdump(stdout, "f\nobar", 7);
827 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
828
829 for (i = 0; i < ELEMENTSOF(data); i++)
830 data[i] = i*2;
831
832 hexdump(stdout, data, sizeof(data));
833 }
834
835 static void test_log2i(void) {
836 assert_se(log2i(1) == 0);
837 assert_se(log2i(2) == 1);
838 assert_se(log2i(3) == 1);
839 assert_se(log2i(4) == 2);
840 assert_se(log2i(32) == 5);
841 assert_se(log2i(33) == 5);
842 assert_se(log2i(63) == 5);
843 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
844 }
845
846 static void test_foreach_string(void) {
847 const char * const t[] = {
848 "foo",
849 "bar",
850 "waldo",
851 NULL
852 };
853 const char *x;
854 unsigned i = 0;
855
856 FOREACH_STRING(x, "foo", "bar", "waldo")
857 assert_se(streq_ptr(t[i++], x));
858
859 assert_se(i == 3);
860
861 FOREACH_STRING(x, "zzz")
862 assert_se(streq(x, "zzz"));
863 }
864
865 static void test_filename_is_valid(void) {
866 char foo[FILENAME_MAX+2];
867 int i;
868
869 assert_se(!filename_is_valid(""));
870 assert_se(!filename_is_valid("/bar/foo"));
871 assert_se(!filename_is_valid("/"));
872 assert_se(!filename_is_valid("."));
873 assert_se(!filename_is_valid(".."));
874
875 for (i=0; i<FILENAME_MAX+1; i++)
876 foo[i] = 'a';
877 foo[FILENAME_MAX+1] = '\0';
878
879 assert_se(!filename_is_valid(foo));
880
881 assert_se(filename_is_valid("foo_bar-333"));
882 assert_se(filename_is_valid("o.o"));
883 }
884
885 static void test_string_has_cc(void) {
886 assert_se(string_has_cc("abc\1", NULL));
887 assert_se(string_has_cc("abc\x7f", NULL));
888 assert_se(string_has_cc("abc\x7f", NULL));
889 assert_se(string_has_cc("abc\t\x7f", "\t"));
890 assert_se(string_has_cc("abc\t\x7f", "\t"));
891 assert_se(string_has_cc("\x7f", "\t"));
892 assert_se(string_has_cc("\x7f", "\t\a"));
893
894 assert_se(!string_has_cc("abc\t\t", "\t"));
895 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
896 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
897 }
898
899 static void test_ascii_strlower(void) {
900 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
901 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
902 }
903
904 static void test_files_same(void) {
905 _cleanup_close_ int fd = -1;
906 char name[] = "/tmp/test-files_same.XXXXXX";
907 char name_alias[] = "/tmp/test-files_same.alias";
908
909 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
910 assert_se(fd >= 0);
911 assert_se(symlink(name, name_alias) >= 0);
912
913 assert_se(files_same(name, name));
914 assert_se(files_same(name, name_alias));
915
916 unlink(name);
917 unlink(name_alias);
918 }
919
920 static void test_is_valid_documentation_url(void) {
921 assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
922 assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
923 assert_se(documentation_url_is_valid("file:/foo/foo"));
924 assert_se(documentation_url_is_valid("man:systemd.special(7)"));
925 assert_se(documentation_url_is_valid("info:bar"));
926
927 assert_se(!documentation_url_is_valid("foo:"));
928 assert_se(!documentation_url_is_valid("info:"));
929 assert_se(!documentation_url_is_valid(""));
930 }
931
932 static void test_file_in_same_dir(void) {
933 char *t;
934
935 t = file_in_same_dir("/", "a");
936 assert_se(streq(t, "/a"));
937 free(t);
938
939 t = file_in_same_dir("/", "/a");
940 assert_se(streq(t, "/a"));
941 free(t);
942
943 t = file_in_same_dir("", "a");
944 assert_se(streq(t, "a"));
945 free(t);
946
947 t = file_in_same_dir("a/", "a");
948 assert_se(streq(t, "a/a"));
949 free(t);
950
951 t = file_in_same_dir("bar/foo", "bar");
952 assert_se(streq(t, "bar/bar"));
953 free(t);
954 }
955
956 static void test_endswith(void) {
957 assert_se(endswith("foobar", "bar"));
958 assert_se(endswith("foobar", ""));
959 assert_se(endswith("foobar", "foobar"));
960 assert_se(endswith("", ""));
961
962 assert_se(!endswith("foobar", "foo"));
963 assert_se(!endswith("foobar", "foobarfoofoo"));
964 }
965
966 static void test_close_nointr(void) {
967 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
968 int fd;
969
970 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
971 assert_se(fd >= 0);
972 assert_se(close_nointr(fd) >= 0);
973 assert_se(close_nointr(fd) < 0);
974
975 unlink(name);
976 }
977
978
979 static void test_unlink_noerrno(void) {
980 char name[] = "/tmp/test-close_nointr.XXXXXX";
981 int fd;
982
983 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
984 assert_se(fd >= 0);
985 assert_se(close_nointr(fd) >= 0);
986
987 {
988 PROTECT_ERRNO;
989 errno = -42;
990 assert_se(unlink_noerrno(name) >= 0);
991 assert_se(errno == -42);
992 assert_se(unlink_noerrno(name) < 0);
993 assert_se(errno == -42);
994 }
995 }
996
997 static void test_readlink_and_make_absolute(void) {
998 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
999 char name[] = "/tmp/test-readlink_and_make_absolute/original";
1000 char name2[] = "test-readlink_and_make_absolute/original";
1001 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
1002 char *r = NULL;
1003
1004 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1005 assert_se(touch(name) >= 0);
1006
1007 assert_se(symlink(name, name_alias) >= 0);
1008 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1009 assert_se(streq(r, name));
1010 free(r);
1011 assert_se(unlink(name_alias) >= 0);
1012
1013 assert_se(chdir(tempdir) >= 0);
1014 assert_se(symlink(name2, name_alias) >= 0);
1015 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1016 assert_se(streq(r, name));
1017 free(r);
1018 assert_se(unlink(name_alias) >= 0);
1019
1020 assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
1021 }
1022
1023 static void test_read_one_char(void) {
1024 _cleanup_fclose_ FILE *file = NULL;
1025 char r;
1026 bool need_nl;
1027 char name[] = "/tmp/test-read_one_char.XXXXXX";
1028 int fd;
1029
1030 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1031 assert_se(fd >= 0);
1032 file = fdopen(fd, "r+");
1033 assert_se(file);
1034 assert_se(fputs("c\n", file) >= 0);
1035 rewind(file);
1036
1037 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
1038 assert_se(!need_nl);
1039 assert_se(r == 'c');
1040 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1041
1042 rewind(file);
1043 assert_se(fputs("foobar\n", file) >= 0);
1044 rewind(file);
1045 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1046
1047 rewind(file);
1048 assert_se(fputs("\n", file) >= 0);
1049 rewind(file);
1050 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1051
1052 unlink(name);
1053 }
1054
1055 static void test_ignore_signals(void) {
1056 assert_se(ignore_signals(SIGINT, -1) >= 0);
1057 assert_se(kill(getpid(), SIGINT) >= 0);
1058 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1059 assert_se(kill(getpid(), SIGUSR1) >= 0);
1060 assert_se(kill(getpid(), SIGUSR2) >= 0);
1061 assert_se(kill(getpid(), SIGTERM) >= 0);
1062 assert_se(kill(getpid(), SIGPIPE) >= 0);
1063 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1064 }
1065
1066 static void test_strshorten(void) {
1067 char s[] = "foobar";
1068
1069 assert_se(strlen(strshorten(s, 6)) == 6);
1070 assert_se(strlen(strshorten(s, 12)) == 6);
1071 assert_se(strlen(strshorten(s, 2)) == 2);
1072 assert_se(strlen(strshorten(s, 0)) == 0);
1073 }
1074
1075 static void test_strjoina(void) {
1076 char *actual;
1077
1078 actual = strjoina("", "foo", "bar");
1079 assert_se(streq(actual, "foobar"));
1080
1081 actual = strjoina("foo", "bar", "baz");
1082 assert_se(streq(actual, "foobarbaz"));
1083
1084 actual = strjoina("foo", "", "bar", "baz");
1085 assert_se(streq(actual, "foobarbaz"));
1086
1087 actual = strjoina("foo");
1088 assert_se(streq(actual, "foo"));
1089
1090 actual = strjoina(NULL);
1091 assert_se(streq(actual, ""));
1092
1093 actual = strjoina(NULL, "foo");
1094 assert_se(streq(actual, ""));
1095
1096 actual = strjoina("foo", NULL, "bar");
1097 assert_se(streq(actual, "foo"));
1098 }
1099
1100 static void test_is_symlink(void) {
1101 char name[] = "/tmp/test-is_symlink.XXXXXX";
1102 char name_link[] = "/tmp/test-is_symlink.link";
1103 _cleanup_close_ int fd = -1;
1104
1105 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1106 assert_se(fd >= 0);
1107 assert_se(symlink(name, name_link) >= 0);
1108
1109 assert_se(is_symlink(name) == 0);
1110 assert_se(is_symlink(name_link) == 1);
1111 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1112
1113
1114 unlink(name);
1115 unlink(name_link);
1116 }
1117
1118 static void test_pid_is_unwaited(void) {
1119 pid_t pid;
1120
1121 pid = fork();
1122 assert_se(pid >= 0);
1123 if (pid == 0) {
1124 _exit(EXIT_SUCCESS);
1125 } else {
1126 int status;
1127
1128 waitpid(pid, &status, 0);
1129 assert_se(!pid_is_unwaited(pid));
1130 }
1131 assert_se(pid_is_unwaited(getpid()));
1132 assert_se(!pid_is_unwaited(-1));
1133 }
1134
1135 static void test_pid_is_alive(void) {
1136 pid_t pid;
1137
1138 pid = fork();
1139 assert_se(pid >= 0);
1140 if (pid == 0) {
1141 _exit(EXIT_SUCCESS);
1142 } else {
1143 int status;
1144
1145 waitpid(pid, &status, 0);
1146 assert_se(!pid_is_alive(pid));
1147 }
1148 assert_se(pid_is_alive(getpid()));
1149 assert_se(!pid_is_alive(-1));
1150 }
1151
1152 static void test_search_and_fopen(void) {
1153 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
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(basename(name), "r", NULL, dirs, &f);
1164 assert_se(r >= 0);
1165 fclose(f);
1166
1167 r = search_and_fopen(name, "r", NULL, dirs, &f);
1168 assert_se(r >= 0);
1169 fclose(f);
1170
1171 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1172 assert_se(r >= 0);
1173 fclose(f);
1174
1175 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1176 assert_se(r < 0);
1177 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1178 assert_se(r < 0);
1179
1180 r = unlink(name);
1181 assert_se(r == 0);
1182
1183 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1184 assert_se(r < 0);
1185 }
1186
1187
1188 static void test_search_and_fopen_nulstr(void) {
1189 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1190 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1191 int fd = -1;
1192 int r;
1193 FILE *f;
1194
1195 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1196 assert_se(fd >= 0);
1197 close(fd);
1198
1199 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1200 assert_se(r >= 0);
1201 fclose(f);
1202
1203 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1204 assert_se(r >= 0);
1205 fclose(f);
1206
1207 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1208 assert_se(r < 0);
1209 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1210 assert_se(r < 0);
1211
1212 r = unlink(name);
1213 assert_se(r == 0);
1214
1215 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1216 assert_se(r < 0);
1217 }
1218
1219 static void test_glob_exists(void) {
1220 char name[] = "/tmp/test-glob_exists.XXXXXX";
1221 int fd = -1;
1222 int r;
1223
1224 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1225 assert_se(fd >= 0);
1226 close(fd);
1227
1228 r = glob_exists("/tmp/test-glob_exists*");
1229 assert_se(r == 1);
1230
1231 r = unlink(name);
1232 assert_se(r == 0);
1233 r = glob_exists("/tmp/test-glob_exists*");
1234 assert_se(r == 0);
1235 }
1236
1237 static void test_execute_directory(void) {
1238 char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
1239 char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
1240 const char * dirs[] = {template_hi, template_lo, NULL};
1241 const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
1242
1243 assert_se(mkdtemp(template_lo));
1244 assert_se(mkdtemp(template_hi));
1245
1246 name = strjoina(template_lo, "/script");
1247 name2 = strjoina(template_hi, "/script2");
1248 name3 = strjoina(template_lo, "/useless");
1249 overridden = strjoina(template_lo, "/overridden");
1250 override = strjoina(template_hi, "/overridden");
1251 masked = strjoina(template_lo, "/masked");
1252 mask = strjoina(template_hi, "/masked");
1253
1254 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works") == 0);
1255 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2") == 0);
1256 assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1257 assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0") == 0);
1258 assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0);
1259 assert_se(symlink("/dev/null", mask) == 0);
1260 assert_se(chmod(name, 0755) == 0);
1261 assert_se(chmod(name2, 0755) == 0);
1262 assert_se(chmod(overridden, 0755) == 0);
1263 assert_se(chmod(override, 0755) == 0);
1264 assert_se(chmod(masked, 0755) == 0);
1265 assert_se(touch(name3) >= 0);
1266
1267 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
1268
1269 assert_se(chdir(template_lo) == 0);
1270 assert_se(access("it_works", F_OK) >= 0);
1271 assert_se(access("failed", F_OK) < 0);
1272
1273 assert_se(chdir(template_hi) == 0);
1274 assert_se(access("it_works2", F_OK) >= 0);
1275 assert_se(access("failed", F_OK) < 0);
1276
1277 rm_rf_dangerous(template_lo, false, true, false);
1278 rm_rf_dangerous(template_hi, false, true, false);
1279 }
1280
1281 static void test_unquote_first_word(void) {
1282 const char *p, *original;
1283 char *t;
1284
1285 p = original = "foobar waldo";
1286 assert_se(unquote_first_word(&p, &t, 0) > 0);
1287 assert_se(streq(t, "foobar"));
1288 free(t);
1289 assert_se(p == original + 7);
1290
1291 assert_se(unquote_first_word(&p, &t, 0) > 0);
1292 assert_se(streq(t, "waldo"));
1293 free(t);
1294 assert_se(p == original + 12);
1295
1296 assert_se(unquote_first_word(&p, &t, 0) == 0);
1297 assert_se(!t);
1298 assert_se(p == original + 12);
1299
1300 p = original = "\"foobar\" \'waldo\'";
1301 assert_se(unquote_first_word(&p, &t, 0) > 0);
1302 assert_se(streq(t, "foobar"));
1303 free(t);
1304 assert_se(p == original + 9);
1305
1306 assert_se(unquote_first_word(&p, &t, 0) > 0);
1307 assert_se(streq(t, "waldo"));
1308 free(t);
1309 assert_se(p == original + 16);
1310
1311 assert_se(unquote_first_word(&p, &t, 0) == 0);
1312 assert_se(!t);
1313 assert_se(p == original + 16);
1314
1315 p = original = "\"";
1316 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
1317 assert_se(p == original + 1);
1318
1319 p = original = "\'";
1320 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
1321 assert_se(p == original + 1);
1322
1323 p = original = "\'fooo";
1324 assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
1325 assert_se(p == original + 5);
1326
1327 p = original = "\'fooo";
1328 assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
1329 assert_se(streq(t, "fooo"));
1330 free(t);
1331 assert_se(p == original + 5);
1332
1333 p = original = "yay\'foo\'bar";
1334 assert_se(unquote_first_word(&p, &t, 0) > 0);
1335 assert_se(streq(t, "yayfoobar"));
1336 free(t);
1337 assert_se(p == original + 11);
1338
1339 p = original = " foobar ";
1340 assert_se(unquote_first_word(&p, &t, 0) > 0);
1341 assert_se(streq(t, "foobar"));
1342 free(t);
1343 assert_se(p == original + 12);
1344
1345 p = original = " foo\\ba\\x6ar ";
1346 assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
1347 assert_se(streq(t, "foo\ba\x6ar"));
1348 free(t);
1349 assert_se(p == original + 13);
1350
1351 p = original = " foo\\ba\\x6ar ";
1352 assert_se(unquote_first_word(&p, &t, 0) > 0);
1353 assert_se(streq(t, "foobax6ar"));
1354 free(t);
1355 assert_se(p == original + 13);
1356 }
1357
1358 static void test_unquote_many_words(void) {
1359 const char *p, *original;
1360 char *a, *b, *c;
1361
1362 p = original = "foobar waldi piep";
1363 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 3);
1364 assert_se(p == original + 17);
1365 assert_se(streq_ptr(a, "foobar"));
1366 assert_se(streq_ptr(b, "waldi"));
1367 assert_se(streq_ptr(c, "piep"));
1368 free(a);
1369 free(b);
1370 free(c);
1371
1372 p = original = "'foobar' wa\"ld\"i ";
1373 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 2);
1374 assert_se(p == original + 19);
1375 assert_se(streq_ptr(a, "foobar"));
1376 assert_se(streq_ptr(b, "waldi"));
1377 assert_se(streq_ptr(c, NULL));
1378 free(a);
1379 free(b);
1380
1381 p = original = "";
1382 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
1383 assert_se(p == original);
1384 assert_se(streq_ptr(a, NULL));
1385 assert_se(streq_ptr(b, NULL));
1386 assert_se(streq_ptr(c, NULL));
1387
1388 p = original = " ";
1389 assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
1390 assert_se(p == original+2);
1391 assert_se(streq_ptr(a, NULL));
1392 assert_se(streq_ptr(b, NULL));
1393 assert_se(streq_ptr(c, NULL));
1394
1395 p = original = "foobar";
1396 assert_se(unquote_many_words(&p, 0, NULL) == 0);
1397 assert_se(p == original);
1398
1399 p = original = "foobar waldi";
1400 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
1401 assert_se(p == original+7);
1402 assert_se(streq_ptr(a, "foobar"));
1403 free(a);
1404
1405 p = original = " foobar ";
1406 assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
1407 assert_se(p == original+15);
1408 assert_se(streq_ptr(a, "foobar"));
1409 free(a);
1410 }
1411
1412 static int parse_item(const char *key, const char *value) {
1413 assert_se(key);
1414
1415 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1416 return 0;
1417 }
1418
1419 static void test_parse_proc_cmdline(void) {
1420 assert_se(parse_proc_cmdline(parse_item) >= 0);
1421 }
1422
1423 static void test_raw_clone(void) {
1424 pid_t parent, pid, pid2;
1425
1426 parent = getpid();
1427 log_info("before clone: getpid()→"PID_FMT, parent);
1428 assert_se(raw_getpid() == parent);
1429
1430 pid = raw_clone(0, NULL);
1431 assert_se(pid >= 0);
1432
1433 pid2 = raw_getpid();
1434 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1435 pid, getpid(), pid2);
1436 if (pid == 0) {
1437 assert_se(pid2 != parent);
1438 _exit(EXIT_SUCCESS);
1439 } else {
1440 int status;
1441
1442 assert_se(pid2 == parent);
1443 waitpid(pid, &status, __WCLONE);
1444 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1445 }
1446 }
1447
1448 static void test_same_fd(void) {
1449 _cleanup_close_pair_ int p[2] = { -1, -1 };
1450 _cleanup_close_ int a = -1, b = -1, c = -1;
1451
1452 assert_se(pipe2(p, O_CLOEXEC) >= 0);
1453 assert_se((a = dup(p[0])) >= 0);
1454 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1455 assert_se((c = dup(a)) >= 0);
1456
1457 assert_se(same_fd(p[0], p[0]) > 0);
1458 assert_se(same_fd(p[1], p[1]) > 0);
1459 assert_se(same_fd(a, a) > 0);
1460 assert_se(same_fd(b, b) > 0);
1461
1462 assert_se(same_fd(a, p[0]) > 0);
1463 assert_se(same_fd(p[0], a) > 0);
1464 assert_se(same_fd(c, p[0]) > 0);
1465 assert_se(same_fd(p[0], c) > 0);
1466 assert_se(same_fd(a, c) > 0);
1467 assert_se(same_fd(c, a) > 0);
1468
1469 assert_se(same_fd(p[0], p[1]) == 0);
1470 assert_se(same_fd(p[1], p[0]) == 0);
1471 assert_se(same_fd(p[0], b) == 0);
1472 assert_se(same_fd(b, p[0]) == 0);
1473 assert_se(same_fd(p[1], a) == 0);
1474 assert_se(same_fd(a, p[1]) == 0);
1475 assert_se(same_fd(p[1], b) == 0);
1476 assert_se(same_fd(b, p[1]) == 0);
1477
1478 assert_se(same_fd(a, b) == 0);
1479 assert_se(same_fd(b, a) == 0);
1480 }
1481
1482 static void test_uid_ptr(void) {
1483
1484 assert_se(UID_TO_PTR(0) != NULL);
1485 assert_se(UID_TO_PTR(1000) != NULL);
1486
1487 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1488 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1489 }
1490
1491 static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
1492 char check[n];
1493
1494 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1495 assert_se(ftruncate(fd, 0) >= 0);
1496 assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
1497
1498 assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
1499 assert_se(ftruncate(fd, n) >= 0);
1500
1501 assert_se(lseek(fd, 0, SEEK_SET) == 0);
1502 assert_se(read(fd, check, n) == (ssize_t) n);
1503
1504 assert_se(memcmp(buffer, check, n) == 0);
1505 }
1506
1507 static void test_sparse_write(void) {
1508 const char test_a[] = "test";
1509 const char test_b[] = "\0\0\0\0test\0\0\0\0";
1510 const char test_c[] = "\0\0test\0\0\0\0";
1511 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";
1512 const char test_e[] = "test\0\0\0\0test";
1513 _cleanup_close_ int fd = -1;
1514 char fn[] = "/tmp/sparseXXXXXX";
1515
1516 fd = mkostemp(fn, O_CLOEXEC);
1517 assert_se(fd >= 0);
1518 unlink(fn);
1519
1520 test_sparse_write_one(fd, test_a, sizeof(test_a));
1521 test_sparse_write_one(fd, test_b, sizeof(test_b));
1522 test_sparse_write_one(fd, test_c, sizeof(test_c));
1523 test_sparse_write_one(fd, test_d, sizeof(test_d));
1524 test_sparse_write_one(fd, test_e, sizeof(test_e));
1525 }
1526
1527 int main(int argc, char *argv[]) {
1528 log_parse_environment();
1529 log_open();
1530
1531 test_streq_ptr();
1532 test_align_power2();
1533 test_max();
1534 test_container_of();
1535 test_alloca();
1536 test_div_round_up();
1537 test_first_word();
1538 test_close_many();
1539 test_parse_boolean();
1540 test_parse_pid();
1541 test_parse_uid();
1542 test_safe_atolli();
1543 test_safe_atod();
1544 test_strappend();
1545 test_strstrip();
1546 test_delete_chars();
1547 test_in_charset();
1548 test_hexchar();
1549 test_unhexchar();
1550 test_octchar();
1551 test_unoctchar();
1552 test_decchar();
1553 test_undecchar();
1554 test_cescape();
1555 test_cunescape();
1556 test_foreach_word();
1557 test_foreach_word_quoted();
1558 test_default_term_for_tty();
1559 test_memdup_multiply();
1560 test_hostname_is_valid();
1561 test_u64log2();
1562 test_get_process_comm();
1563 test_protect_errno();
1564 test_parse_size();
1565 test_config_parse_iec_off();
1566 test_strextend();
1567 test_strrep();
1568 test_split_pair();
1569 test_fstab_node_to_udev_node();
1570 test_get_files_in_directory();
1571 test_in_set();
1572 test_writing_tmpfile();
1573 test_hexdump();
1574 test_log2i();
1575 test_foreach_string();
1576 test_filename_is_valid();
1577 test_string_has_cc();
1578 test_ascii_strlower();
1579 test_files_same();
1580 test_is_valid_documentation_url();
1581 test_file_in_same_dir();
1582 test_endswith();
1583 test_close_nointr();
1584 test_unlink_noerrno();
1585 test_readlink_and_make_absolute();
1586 test_read_one_char();
1587 test_ignore_signals();
1588 test_strshorten();
1589 test_strjoina();
1590 test_is_symlink();
1591 test_pid_is_unwaited();
1592 test_pid_is_alive();
1593 test_search_and_fopen();
1594 test_search_and_fopen_nulstr();
1595 test_glob_exists();
1596 test_execute_directory();
1597 test_unquote_first_word();
1598 test_unquote_many_words();
1599 test_parse_proc_cmdline();
1600 test_raw_clone();
1601 test_same_fd();
1602 test_uid_ptr();
1603 test_sparse_write();
1604
1605 return 0;
1606 }