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