]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-util.c
Simplify execute_directory()
[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 assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
420 assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
421 }
422
423 static void test_foreach_word(void) {
424 const char *word, *state;
425 size_t l;
426 int i = 0;
427 const char test[] = "test abc d\te f ";
428 const char * const expected[] = {
429 "test",
430 "abc",
431 "d",
432 "e",
433 "f",
434 "",
435 NULL
436 };
437
438 FOREACH_WORD(word, l, test, state)
439 assert_se(strneq(expected[i++], word, l));
440 }
441
442 static void check(const char *test, char** expected, bool trailing) {
443 const char *word, *state;
444 size_t l;
445 int i = 0;
446
447 printf("<<<%s>>>\n", test);
448 FOREACH_WORD_QUOTED(word, l, test, state) {
449 _cleanup_free_ char *t = NULL;
450
451 assert_se(t = strndup(word, l));
452 assert_se(strneq(expected[i++], word, l));
453 printf("<%s>\n", t);
454 }
455 printf("<<<%s>>>\n", state);
456 assert_se(expected[i] == NULL);
457 assert_se(isempty(state) == !trailing);
458 }
459
460 static void test_foreach_word_quoted(void) {
461 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
462 STRV_MAKE("test",
463 "a",
464 "b",
465 "c",
466 "d",
467 "e",
468 "",
469 "",
470 "hhh",
471 "",
472 "",
473 "a b c"),
474 false);
475
476 check("test \"xxx",
477 STRV_MAKE("test"),
478 true);
479
480 check("test\\",
481 STRV_MAKE_EMPTY,
482 true);
483 }
484
485 static void test_default_term_for_tty(void) {
486 puts(default_term_for_tty("/dev/tty23"));
487 puts(default_term_for_tty("/dev/ttyS23"));
488 puts(default_term_for_tty("/dev/tty0"));
489 puts(default_term_for_tty("/dev/pty0"));
490 puts(default_term_for_tty("/dev/pts/0"));
491 puts(default_term_for_tty("/dev/console"));
492 puts(default_term_for_tty("tty23"));
493 puts(default_term_for_tty("ttyS23"));
494 puts(default_term_for_tty("tty0"));
495 puts(default_term_for_tty("pty0"));
496 puts(default_term_for_tty("pts/0"));
497 puts(default_term_for_tty("console"));
498 }
499
500 static void test_memdup_multiply(void) {
501 int org[] = {1, 2, 3};
502 int *dup;
503
504 dup = (int*)memdup_multiply(org, sizeof(int), 3);
505
506 assert_se(dup);
507 assert_se(dup[0] == 1);
508 assert_se(dup[1] == 2);
509 assert_se(dup[2] == 3);
510 free(dup);
511 }
512
513 static void test_hostname_is_valid(void) {
514 assert_se(hostname_is_valid("foobar"));
515 assert_se(hostname_is_valid("foobar.com"));
516 assert_se(!hostname_is_valid("fööbar"));
517 assert_se(!hostname_is_valid(""));
518 assert_se(!hostname_is_valid("."));
519 assert_se(!hostname_is_valid(".."));
520 assert_se(!hostname_is_valid("foobar."));
521 assert_se(!hostname_is_valid(".foobar"));
522 assert_se(!hostname_is_valid("foo..bar"));
523 assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
524 }
525
526 static void test_u64log2(void) {
527 assert_se(u64log2(0) == 0);
528 assert_se(u64log2(8) == 3);
529 assert_se(u64log2(9) == 3);
530 assert_se(u64log2(15) == 3);
531 assert_se(u64log2(16) == 4);
532 assert_se(u64log2(1024*1024) == 20);
533 assert_se(u64log2(1024*1024+5) == 20);
534 }
535
536 static void test_get_process_comm(void) {
537 struct stat st;
538 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
539 _cleanup_free_ char *env = NULL;
540 pid_t e;
541 uid_t u;
542 gid_t g;
543 dev_t h;
544 int r;
545 pid_t me;
546
547 if (stat("/proc/1/comm", &st) == 0) {
548 assert_se(get_process_comm(1, &a) >= 0);
549 log_info("pid1 comm: '%s'", a);
550 } else {
551 log_warning("/proc/1/comm does not exist.");
552 }
553
554 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
555 log_info("pid1 cmdline: '%s'", c);
556
557 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
558 log_info("pid1 cmdline truncated: '%s'", d);
559
560 assert_se(get_parent_of_pid(1, &e) >= 0);
561 log_info("pid1 ppid: "PID_FMT, e);
562 assert_se(e == 0);
563
564 assert_se(is_kernel_thread(1) == 0);
565
566 r = get_process_exe(1, &f);
567 assert_se(r >= 0 || r == -EACCES);
568 log_info("pid1 exe: '%s'", strna(f));
569
570 assert_se(get_process_uid(1, &u) == 0);
571 log_info("pid1 uid: "UID_FMT, u);
572 assert_se(u == 0);
573
574 assert_se(get_process_gid(1, &g) == 0);
575 log_info("pid1 gid: "GID_FMT, g);
576 assert_se(g == 0);
577
578 me = getpid();
579
580 r = get_process_cwd(me, &cwd);
581 assert_se(r >= 0 || r == -EACCES);
582 log_info("pid1 cwd: '%s'", cwd);
583
584 r = get_process_root(me, &root);
585 assert_se(r >= 0 || r == -EACCES);
586 log_info("pid1 root: '%s'", root);
587
588 r = get_process_environ(me, &env);
589 assert_se(r >= 0 || r == -EACCES);
590 log_info("self strlen(environ): '%zd'", strlen(env));
591
592 if (!detect_container(NULL))
593 assert_se(get_ctty_devnr(1, &h) == -ENOENT);
594
595 getenv_for_pid(1, "PATH", &i);
596 log_info("pid1 $PATH: '%s'", strna(i));
597 }
598
599 static void test_protect_errno(void) {
600 errno = 12;
601 {
602 PROTECT_ERRNO;
603 errno = 11;
604 }
605 assert_se(errno == 12);
606 }
607
608 static void test_parse_size(void) {
609 off_t bytes;
610
611 assert_se(parse_size("111", 1024, &bytes) == 0);
612 assert_se(bytes == 111);
613
614 assert_se(parse_size("111.4", 1024, &bytes) == 0);
615 assert_se(bytes == 111);
616
617 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
618 assert_se(bytes == 112);
619
620 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
621 assert_se(bytes == 112);
622
623 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
624 assert_se(bytes == 3*1024 + 512);
625
626 assert_se(parse_size("3. K", 1024, &bytes) == 0);
627 assert_se(bytes == 3*1024);
628
629 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
630 assert_se(bytes == 3*1024);
631
632 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
633
634 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
635 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
636
637 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
638
639 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
640 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
641
642 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
643 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
644
645 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
646
647 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
648 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
649
650 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
651 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
652
653 assert_se(parse_size("12P", 1024, &bytes) == 0);
654 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
655
656 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
657
658 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
659 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
660
661 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
662
663 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
664
665 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
666
667 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
668 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
669 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
670
671 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
672
673 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
674 }
675
676 static void test_config_parse_iec_off(void) {
677 off_t offset = 0;
678 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
679 assert_se(offset == 4 * 1024 * 1024);
680
681 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
682 }
683
684 static void test_strextend(void) {
685 _cleanup_free_ char *str = strdup("0123");
686 strextend(&str, "456", "78", "9", NULL);
687 assert_se(streq(str, "0123456789"));
688 }
689
690 static void test_strrep(void) {
691 _cleanup_free_ char *one, *three, *zero;
692 one = strrep("waldo", 1);
693 three = strrep("waldo", 3);
694 zero = strrep("waldo", 0);
695
696 assert_se(streq(one, "waldo"));
697 assert_se(streq(three, "waldowaldowaldo"));
698 assert_se(streq(zero, ""));
699 }
700
701 static void test_split_pair(void) {
702 _cleanup_free_ char *a = NULL, *b = NULL;
703
704 assert_se(split_pair("", "", &a, &b) == -EINVAL);
705 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
706 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
707 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
708 assert_se(streq(a, "foo"));
709 assert_se(streq(b, "bar"));
710 free(a);
711 free(b);
712 assert_se(split_pair("==", "==", &a, &b) >= 0);
713 assert_se(streq(a, ""));
714 assert_se(streq(b, ""));
715 free(a);
716 free(b);
717
718 assert_se(split_pair("===", "==", &a, &b) >= 0);
719 assert_se(streq(a, ""));
720 assert_se(streq(b, "="));
721 }
722
723 static void test_fstab_node_to_udev_node(void) {
724 char *n;
725
726 n = fstab_node_to_udev_node("LABEL=applé/jack");
727 puts(n);
728 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
729 free(n);
730
731 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
732 puts(n);
733 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
734 free(n);
735
736 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
737 puts(n);
738 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
739 free(n);
740
741 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
742 puts(n);
743 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
744 free(n);
745
746 n = fstab_node_to_udev_node("PONIES=awesome");
747 puts(n);
748 assert_se(streq(n, "PONIES=awesome"));
749 free(n);
750
751 n = fstab_node_to_udev_node("/dev/xda1");
752 puts(n);
753 assert_se(streq(n, "/dev/xda1"));
754 free(n);
755 }
756
757 static void test_get_files_in_directory(void) {
758 _cleanup_strv_free_ char **l = NULL, **t = NULL;
759
760 assert_se(get_files_in_directory("/tmp", &l) >= 0);
761 assert_se(get_files_in_directory(".", &t) >= 0);
762 assert_se(get_files_in_directory(".", NULL) >= 0);
763 }
764
765 static void test_in_set(void) {
766 assert_se(IN_SET(1, 1));
767 assert_se(IN_SET(1, 1, 2, 3, 4));
768 assert_se(IN_SET(2, 1, 2, 3, 4));
769 assert_se(IN_SET(3, 1, 2, 3, 4));
770 assert_se(IN_SET(4, 1, 2, 3, 4));
771 assert_se(!IN_SET(0, 1));
772 assert_se(!IN_SET(0, 1, 2, 3, 4));
773 }
774
775 static void test_writing_tmpfile(void) {
776 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
777 _cleanup_free_ char *contents = NULL;
778 size_t size;
779 int fd, r;
780 struct iovec iov[3];
781
782 IOVEC_SET_STRING(iov[0], "abc\n");
783 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
784 IOVEC_SET_STRING(iov[2], "");
785
786 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
787 printf("tmpfile: %s", name);
788
789 r = writev(fd, iov, 3);
790 assert_se(r >= 0);
791
792 r = read_full_file(name, &contents, &size);
793 assert_se(r == 0);
794 printf("contents: %s", contents);
795 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
796
797 unlink(name);
798 }
799
800 static void test_hexdump(void) {
801 uint8_t data[146];
802 unsigned i;
803
804 hexdump(stdout, NULL, 0);
805 hexdump(stdout, "", 0);
806 hexdump(stdout, "", 1);
807 hexdump(stdout, "x", 1);
808 hexdump(stdout, "x", 2);
809 hexdump(stdout, "foobar", 7);
810 hexdump(stdout, "f\nobar", 7);
811 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
812
813 for (i = 0; i < ELEMENTSOF(data); i++)
814 data[i] = i*2;
815
816 hexdump(stdout, data, sizeof(data));
817 }
818
819 static void test_log2i(void) {
820 assert_se(log2i(1) == 0);
821 assert_se(log2i(2) == 1);
822 assert_se(log2i(3) == 1);
823 assert_se(log2i(4) == 2);
824 assert_se(log2i(32) == 5);
825 assert_se(log2i(33) == 5);
826 assert_se(log2i(63) == 5);
827 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
828 }
829
830 static void test_foreach_string(void) {
831 const char * const t[] = {
832 "foo",
833 "bar",
834 "waldo",
835 NULL
836 };
837 const char *x;
838 unsigned i = 0;
839
840 FOREACH_STRING(x, "foo", "bar", "waldo")
841 assert_se(streq_ptr(t[i++], x));
842
843 assert_se(i == 3);
844
845 FOREACH_STRING(x, "zzz")
846 assert_se(streq(x, "zzz"));
847 }
848
849 static void test_filename_is_valid(void) {
850 char foo[FILENAME_MAX+2];
851 int i;
852
853 assert_se(!filename_is_valid(""));
854 assert_se(!filename_is_valid("/bar/foo"));
855 assert_se(!filename_is_valid("/"));
856 assert_se(!filename_is_valid("."));
857 assert_se(!filename_is_valid(".."));
858
859 for (i=0; i<FILENAME_MAX+1; i++)
860 foo[i] = 'a';
861 foo[FILENAME_MAX+1] = '\0';
862
863 assert_se(!filename_is_valid(foo));
864
865 assert_se(filename_is_valid("foo_bar-333"));
866 assert_se(filename_is_valid("o.o"));
867 }
868
869 static void test_string_has_cc(void) {
870 assert_se(string_has_cc("abc\1", NULL));
871 assert_se(string_has_cc("abc\x7f", NULL));
872 assert_se(string_has_cc("abc\x7f", NULL));
873 assert_se(string_has_cc("abc\t\x7f", "\t"));
874 assert_se(string_has_cc("abc\t\x7f", "\t"));
875 assert_se(string_has_cc("\x7f", "\t"));
876 assert_se(string_has_cc("\x7f", "\t\a"));
877
878 assert_se(!string_has_cc("abc\t\t", "\t"));
879 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
880 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
881 }
882
883 static void test_ascii_strlower(void) {
884 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
885 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
886 }
887
888 static void test_files_same(void) {
889 _cleanup_close_ int fd = -1;
890 char name[] = "/tmp/test-files_same.XXXXXX";
891 char name_alias[] = "/tmp/test-files_same.alias";
892
893 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
894 assert_se(fd >= 0);
895 assert_se(symlink(name, name_alias) >= 0);
896
897 assert_se(files_same(name, name));
898 assert_se(files_same(name, name_alias));
899
900 unlink(name);
901 unlink(name_alias);
902 }
903
904 static void test_is_valid_documentation_url(void) {
905 assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
906 assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
907 assert_se(is_valid_documentation_url("file:foo"));
908 assert_se(is_valid_documentation_url("man:systemd.special(7)"));
909 assert_se(is_valid_documentation_url("info:bar"));
910
911 assert_se(!is_valid_documentation_url("foo:"));
912 assert_se(!is_valid_documentation_url("info:"));
913 assert_se(!is_valid_documentation_url(""));
914 }
915
916 static void test_file_in_same_dir(void) {
917 char *t;
918
919 t = file_in_same_dir("/", "a");
920 assert_se(streq(t, "/a"));
921 free(t);
922
923 t = file_in_same_dir("/", "/a");
924 assert_se(streq(t, "/a"));
925 free(t);
926
927 t = file_in_same_dir("", "a");
928 assert_se(streq(t, "a"));
929 free(t);
930
931 t = file_in_same_dir("a/", "a");
932 assert_se(streq(t, "a/a"));
933 free(t);
934
935 t = file_in_same_dir("bar/foo", "bar");
936 assert_se(streq(t, "bar/bar"));
937 free(t);
938 }
939
940 static void test_endswith(void) {
941 assert_se(endswith("foobar", "bar"));
942 assert_se(endswith("foobar", ""));
943 assert_se(endswith("foobar", "foobar"));
944 assert_se(endswith("", ""));
945
946 assert_se(!endswith("foobar", "foo"));
947 assert_se(!endswith("foobar", "foobarfoofoo"));
948 }
949
950 static void test_close_nointr(void) {
951 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
952 int fd;
953
954 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
955 assert_se(fd >= 0);
956 assert_se(close_nointr(fd) >= 0);
957 assert_se(close_nointr(fd) < 0);
958
959 unlink(name);
960 }
961
962
963 static void test_unlink_noerrno(void) {
964 char name[] = "/tmp/test-close_nointr.XXXXXX";
965 int fd;
966
967 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
968 assert_se(fd >= 0);
969 assert_se(close_nointr(fd) >= 0);
970
971 {
972 PROTECT_ERRNO;
973 errno = -42;
974 assert_se(unlink_noerrno(name) >= 0);
975 assert_se(errno == -42);
976 assert_se(unlink_noerrno(name) < 0);
977 assert_se(errno == -42);
978 }
979 }
980
981 static void test_readlink_and_make_absolute(void) {
982 char tempdir[] = "/tmp/test-readlink_and_make_absolute";
983 char name[] = "/tmp/test-readlink_and_make_absolute/original";
984 char name2[] = "test-readlink_and_make_absolute/original";
985 char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
986 char *r = NULL;
987
988 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
989 assert_se(touch(name) >= 0);
990
991 assert_se(symlink(name, name_alias) >= 0);
992 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
993 assert_se(streq(r, name));
994 free(r);
995 assert_se(unlink(name_alias) >= 0);
996
997 assert_se(chdir(tempdir) >= 0);
998 assert_se(symlink(name2, name_alias) >= 0);
999 assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
1000 assert_se(streq(r, name));
1001 free(r);
1002 assert_se(unlink(name_alias) >= 0);
1003
1004 assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
1005 }
1006
1007 static void test_read_one_char(void) {
1008 _cleanup_fclose_ FILE *file = NULL;
1009 char r;
1010 bool need_nl;
1011 char name[] = "/tmp/test-read_one_char.XXXXXX";
1012 int fd;
1013
1014 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1015 assert_se(fd >= 0);
1016 file = fdopen(fd, "r+");
1017 assert_se(file);
1018 assert_se(fputs("c\n", file) >= 0);
1019 rewind(file);
1020
1021 assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
1022 assert_se(!need_nl);
1023 assert_se(r == 'c');
1024 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1025
1026 rewind(file);
1027 assert_se(fputs("foobar\n", file) >= 0);
1028 rewind(file);
1029 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1030
1031 rewind(file);
1032 assert_se(fputs("\n", file) >= 0);
1033 rewind(file);
1034 assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
1035
1036 unlink(name);
1037 }
1038
1039 static void test_ignore_signals(void) {
1040 assert_se(ignore_signals(SIGINT, -1) >= 0);
1041 assert_se(kill(getpid(), SIGINT) >= 0);
1042 assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1043 assert_se(kill(getpid(), SIGUSR1) >= 0);
1044 assert_se(kill(getpid(), SIGUSR2) >= 0);
1045 assert_se(kill(getpid(), SIGTERM) >= 0);
1046 assert_se(kill(getpid(), SIGPIPE) >= 0);
1047 assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
1048 }
1049
1050 static void test_strshorten(void) {
1051 char s[] = "foobar";
1052
1053 assert_se(strlen(strshorten(s, 6)) == 6);
1054 assert_se(strlen(strshorten(s, 12)) == 6);
1055 assert_se(strlen(strshorten(s, 2)) == 2);
1056 assert_se(strlen(strshorten(s, 0)) == 0);
1057 }
1058
1059 static void test_strappenda(void) {
1060 char *actual;
1061
1062 actual = strappenda("", "foo", "bar");
1063 assert_se(streq(actual, "foobar"));
1064
1065 actual = strappenda("foo", "bar", "baz");
1066 assert_se(streq(actual, "foobarbaz"));
1067
1068 actual = strappenda("foo", "", "bar", "baz");
1069 assert_se(streq(actual, "foobarbaz"));
1070 }
1071
1072 static void test_is_symlink(void) {
1073 char name[] = "/tmp/test-is_symlink.XXXXXX";
1074 char name_link[] = "/tmp/test-is_symlink.link";
1075 _cleanup_close_ int fd = -1;
1076
1077 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1078 assert_se(fd >= 0);
1079 assert_se(symlink(name, name_link) >= 0);
1080
1081 assert_se(is_symlink(name) == 0);
1082 assert_se(is_symlink(name_link) == 1);
1083 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
1084
1085
1086 unlink(name);
1087 unlink(name_link);
1088 }
1089
1090 static void test_pid_is_unwaited(void) {
1091 pid_t pid;
1092
1093 pid = fork();
1094 assert_se(pid >= 0);
1095 if (pid == 0) {
1096 _exit(EXIT_SUCCESS);
1097 } else {
1098 int status;
1099
1100 waitpid(pid, &status, 0);
1101 assert_se(!pid_is_unwaited(pid));
1102 }
1103 assert_se(pid_is_unwaited(getpid()));
1104 assert_se(!pid_is_unwaited(-1));
1105 }
1106
1107 static void test_pid_is_alive(void) {
1108 pid_t pid;
1109
1110 pid = fork();
1111 assert_se(pid >= 0);
1112 if (pid == 0) {
1113 _exit(EXIT_SUCCESS);
1114 } else {
1115 int status;
1116
1117 waitpid(pid, &status, 0);
1118 assert_se(!pid_is_alive(pid));
1119 }
1120 assert_se(pid_is_alive(getpid()));
1121 assert_se(!pid_is_alive(-1));
1122 }
1123
1124 static void test_search_and_fopen(void) {
1125 const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
1126 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1127 int fd = -1;
1128 int r;
1129 FILE *f;
1130
1131 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1132 assert_se(fd >= 0);
1133 close(fd);
1134
1135 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1136 assert_se(r >= 0);
1137 fclose(f);
1138
1139 r = search_and_fopen(name, "r", NULL, dirs, &f);
1140 assert_se(r >= 0);
1141 fclose(f);
1142
1143 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
1144 assert_se(r >= 0);
1145 fclose(f);
1146
1147 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1148 assert_se(r < 0);
1149 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1150 assert_se(r < 0);
1151
1152 r = unlink(name);
1153 assert_se(r == 0);
1154
1155 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
1156 assert_se(r < 0);
1157 }
1158
1159
1160 static void test_search_and_fopen_nulstr(void) {
1161 const char dirs[] = "/tmp/foo/bar\0/tmp\0";
1162 char name[] = "/tmp/test-search_and_fopen.XXXXXX";
1163 int fd = -1;
1164 int r;
1165 FILE *f;
1166
1167 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1168 assert_se(fd >= 0);
1169 close(fd);
1170
1171 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1172 assert_se(r >= 0);
1173 fclose(f);
1174
1175 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
1176 assert_se(r >= 0);
1177 fclose(f);
1178
1179 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
1180 assert_se(r < 0);
1181 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
1182 assert_se(r < 0);
1183
1184 r = unlink(name);
1185 assert_se(r == 0);
1186
1187 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
1188 assert_se(r < 0);
1189 }
1190
1191 static void test_glob_exists(void) {
1192 char name[] = "/tmp/test-glob_exists.XXXXXX";
1193 int fd = -1;
1194 int r;
1195
1196 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
1197 assert_se(fd >= 0);
1198 close(fd);
1199
1200 r = glob_exists("/tmp/test-glob_exists*");
1201 assert_se(r == 1);
1202
1203 r = unlink(name);
1204 assert_se(r == 0);
1205 r = glob_exists("/tmp/test-glob_exists*");
1206 assert_se(r == 0);
1207 }
1208
1209 static void test_execute_directory(void) {
1210 char name[] = "/tmp/test-execute_directory/script1";
1211 char name2[] = "/tmp/test-execute_directory/script2";
1212 char name3[] = "/tmp/test-execute_directory/useless";
1213 char tempdir[] = "/tmp/test-execute_directory/";
1214
1215 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
1216 assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
1217 assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
1218 assert_se(chmod(name, 0755) == 0);
1219 assert_se(chmod(name2, 0755) == 0);
1220 assert_se(touch(name3) >= 0);
1221
1222 execute_directory(tempdir, DEFAULT_TIMEOUT_USEC, NULL);
1223 assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
1224 assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
1225
1226 rm_rf_dangerous(tempdir, false, true, false);
1227 }
1228
1229 static void test_unquote_first_word(void) {
1230 const char *p, *original;
1231 char *t;
1232
1233 p = original = "foobar waldo";
1234 assert_se(unquote_first_word(&p, &t, false) > 0);
1235 assert_se(streq(t, "foobar"));
1236 free(t);
1237 assert_se(p == original + 7);
1238
1239 assert_se(unquote_first_word(&p, &t, false) > 0);
1240 assert_se(streq(t, "waldo"));
1241 free(t);
1242 assert_se(p == original + 12);
1243
1244 assert_se(unquote_first_word(&p, &t, false) == 0);
1245 assert_se(!t);
1246 assert_se(p == original + 12);
1247
1248 p = original = "\"foobar\" \'waldo\'";
1249 assert_se(unquote_first_word(&p, &t, false) > 0);
1250 assert_se(streq(t, "foobar"));
1251 free(t);
1252 assert_se(p == original + 9);
1253
1254 assert_se(unquote_first_word(&p, &t, false) > 0);
1255 assert_se(streq(t, "waldo"));
1256 free(t);
1257 assert_se(p == original + 16);
1258
1259 assert_se(unquote_first_word(&p, &t, false) == 0);
1260 assert_se(!t);
1261 assert_se(p == original + 16);
1262
1263 p = original = "\"";
1264 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1265 assert_se(p == original + 1);
1266
1267 p = original = "\'";
1268 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1269 assert_se(p == original + 1);
1270
1271 p = original = "\'fooo";
1272 assert_se(unquote_first_word(&p, &t, false) == -EINVAL);
1273 assert_se(p == original + 5);
1274
1275 p = original = "\'fooo";
1276 assert_se(unquote_first_word(&p, &t, true) > 0);
1277 assert_se(streq(t, "fooo"));
1278 free(t);
1279 assert_se(p == original + 5);
1280
1281 p = original = "yay\'foo\'bar";
1282 assert_se(unquote_first_word(&p, &t, false) > 0);
1283 assert_se(streq(t, "yayfoobar"));
1284 free(t);
1285 assert_se(p == original + 11);
1286
1287 p = original = " foobar ";
1288 assert_se(unquote_first_word(&p, &t, false) > 0);
1289 assert_se(streq(t, "foobar"));
1290 free(t);
1291 assert_se(p == original + 12);
1292 }
1293
1294 static void test_unquote_many_words(void) {
1295 const char *p, *original;
1296 char *a, *b, *c;
1297
1298 p = original = "foobar waldi piep";
1299 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
1300 assert_se(p == original + 17);
1301 assert_se(streq_ptr(a, "foobar"));
1302 assert_se(streq_ptr(b, "waldi"));
1303 assert_se(streq_ptr(c, "piep"));
1304 free(a);
1305 free(b);
1306 free(c);
1307
1308 p = original = "'foobar' wa\"ld\"i ";
1309 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
1310 assert_se(p == original + 19);
1311 assert_se(streq_ptr(a, "foobar"));
1312 assert_se(streq_ptr(b, "waldi"));
1313 assert_se(streq_ptr(c, NULL));
1314 free(a);
1315 free(b);
1316
1317 p = original = "";
1318 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1319 assert_se(p == original);
1320 assert_se(streq_ptr(a, NULL));
1321 assert_se(streq_ptr(b, NULL));
1322 assert_se(streq_ptr(c, NULL));
1323
1324 p = original = " ";
1325 assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
1326 assert_se(p == original+2);
1327 assert_se(streq_ptr(a, NULL));
1328 assert_se(streq_ptr(b, NULL));
1329 assert_se(streq_ptr(c, NULL));
1330
1331 p = original = "foobar";
1332 assert_se(unquote_many_words(&p, NULL) == 0);
1333 assert_se(p == original);
1334
1335 p = original = "foobar waldi";
1336 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1337 assert_se(p == original+7);
1338 assert_se(streq_ptr(a, "foobar"));
1339 free(a);
1340
1341 p = original = " foobar ";
1342 assert_se(unquote_many_words(&p, &a, NULL) == 1);
1343 assert_se(p == original+15);
1344 assert_se(streq_ptr(a, "foobar"));
1345 free(a);
1346 }
1347
1348 static int parse_item(const char *key, const char *value) {
1349 assert_se(key);
1350
1351 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
1352 return 0;
1353 }
1354
1355 static void test_parse_proc_cmdline(void) {
1356 assert_se(parse_proc_cmdline(parse_item) >= 0);
1357 }
1358
1359 static void test_raw_clone(void) {
1360 pid_t parent, pid, pid2;
1361
1362 parent = getpid();
1363 log_info("before clone: getpid()→"PID_FMT, parent);
1364 assert_se(raw_getpid() == parent);
1365
1366 pid = raw_clone(0, NULL);
1367 assert_se(pid >= 0);
1368
1369 pid2 = raw_getpid();
1370 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
1371 pid, getpid(), pid2);
1372 if (pid == 0) {
1373 assert_se(pid2 != parent);
1374 _exit(EXIT_SUCCESS);
1375 } else {
1376 int status;
1377
1378 assert_se(pid2 == parent);
1379 waitpid(pid, &status, __WCLONE);
1380 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
1381 }
1382 }
1383
1384 static void test_same_fd(void) {
1385 _cleanup_close_pair_ int p[2] = { -1, -1 };
1386 _cleanup_close_ int a = -1, b = -1, c = -1;
1387
1388 assert_se(pipe2(p, O_CLOEXEC) >= 0);
1389 assert_se((a = dup(p[0])) >= 0);
1390 assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
1391 assert_se((c = dup(a)) >= 0);
1392
1393 assert_se(same_fd(p[0], p[0]) > 0);
1394 assert_se(same_fd(p[1], p[1]) > 0);
1395 assert_se(same_fd(a, a) > 0);
1396 assert_se(same_fd(b, b) > 0);
1397
1398 assert_se(same_fd(a, p[0]) > 0);
1399 assert_se(same_fd(p[0], a) > 0);
1400 assert_se(same_fd(c, p[0]) > 0);
1401 assert_se(same_fd(p[0], c) > 0);
1402 assert_se(same_fd(a, c) > 0);
1403 assert_se(same_fd(c, a) > 0);
1404
1405 assert_se(same_fd(p[0], p[1]) == 0);
1406 assert_se(same_fd(p[1], p[0]) == 0);
1407 assert_se(same_fd(p[0], b) == 0);
1408 assert_se(same_fd(b, p[0]) == 0);
1409 assert_se(same_fd(p[1], a) == 0);
1410 assert_se(same_fd(a, p[1]) == 0);
1411 assert_se(same_fd(p[1], b) == 0);
1412 assert_se(same_fd(b, p[1]) == 0);
1413
1414 assert_se(same_fd(a, b) == 0);
1415 assert_se(same_fd(b, a) == 0);
1416 }
1417
1418 static void test_uid_ptr(void) {
1419
1420 assert_se(UID_TO_PTR(0) != NULL);
1421 assert_se(UID_TO_PTR(1000) != NULL);
1422
1423 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
1424 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
1425 }
1426
1427 int main(int argc, char *argv[]) {
1428 log_parse_environment();
1429 log_open();
1430
1431 test_streq_ptr();
1432 test_align_power2();
1433 test_max();
1434 test_container_of();
1435 test_alloca();
1436 test_div_round_up();
1437 test_first_word();
1438 test_close_many();
1439 test_parse_boolean();
1440 test_parse_pid();
1441 test_parse_uid();
1442 test_safe_atolli();
1443 test_safe_atod();
1444 test_strappend();
1445 test_strstrip();
1446 test_delete_chars();
1447 test_in_charset();
1448 test_hexchar();
1449 test_unhexchar();
1450 test_octchar();
1451 test_unoctchar();
1452 test_decchar();
1453 test_undecchar();
1454 test_cescape();
1455 test_cunescape();
1456 test_foreach_word();
1457 test_foreach_word_quoted();
1458 test_default_term_for_tty();
1459 test_memdup_multiply();
1460 test_hostname_is_valid();
1461 test_u64log2();
1462 test_get_process_comm();
1463 test_protect_errno();
1464 test_parse_size();
1465 test_config_parse_iec_off();
1466 test_strextend();
1467 test_strrep();
1468 test_split_pair();
1469 test_fstab_node_to_udev_node();
1470 test_get_files_in_directory();
1471 test_in_set();
1472 test_writing_tmpfile();
1473 test_hexdump();
1474 test_log2i();
1475 test_foreach_string();
1476 test_filename_is_valid();
1477 test_string_has_cc();
1478 test_ascii_strlower();
1479 test_files_same();
1480 test_is_valid_documentation_url();
1481 test_file_in_same_dir();
1482 test_endswith();
1483 test_close_nointr();
1484 test_unlink_noerrno();
1485 test_readlink_and_make_absolute();
1486 test_read_one_char();
1487 test_ignore_signals();
1488 test_strshorten();
1489 test_strappenda();
1490 test_is_symlink();
1491 test_pid_is_unwaited();
1492 test_pid_is_alive();
1493 test_search_and_fopen();
1494 test_search_and_fopen_nulstr();
1495 test_glob_exists();
1496 test_execute_directory();
1497 test_unquote_first_word();
1498 test_unquote_many_words();
1499 test_parse_proc_cmdline();
1500 test_raw_clone();
1501 test_same_fd();
1502 test_uid_ptr();
1503
1504 return 0;
1505 }