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