tests: move escape related tests to test-escape.c
[platform/upstream/systemd.git] / src / test / test-util.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2010 Lennart Poettering
5   Copyright 2013 Thomas H.P. Andersen
6
7   systemd is free software; you can redistribute it and/or modify it
8   under the terms of the GNU Lesser General Public License as published by
9   the Free Software Foundation; either version 2.1 of the License, or
10   (at your option) any later version.
11
12   systemd is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <signal.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/wait.h>
27 #include <sys/xattr.h>
28 #include <unistd.h>
29
30 #include "alloc-util.h"
31 #include "conf-parser.h"
32 #include "cpu-set-util.h"
33 #include "def.h"
34 #include "fd-util.h"
35 #include "fileio.h"
36 #include "fs-util.h"
37 #include "fstab-util.h"
38 #include "glob-util.h"
39 #include "io-util.h"
40 #include "mkdir.h"
41 #include "parse-util.h"
42 #include "path-util.h"
43 #include "proc-cmdline.h"
44 #include "process-util.h"
45 #include "rm-rf.h"
46 #include "signal-util.h"
47 #include "special.h"
48 #include "stat-util.h"
49 #include "string-util.h"
50 #include "strv.h"
51 #include "user-util.h"
52 #include "util.h"
53 #include "virt.h"
54 #include "web-util.h"
55 #include "xattr-util.h"
56
57 static void test_align_power2(void) {
58         unsigned long i, p2;
59
60         assert_se(ALIGN_POWER2(0) == 0);
61         assert_se(ALIGN_POWER2(1) == 1);
62         assert_se(ALIGN_POWER2(2) == 2);
63         assert_se(ALIGN_POWER2(3) == 4);
64         assert_se(ALIGN_POWER2(12) == 16);
65
66         assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
67         assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
68         assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
69         assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
70         assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
71
72         for (i = 1; i < 131071; ++i) {
73                 for (p2 = 1; p2 < i; p2 <<= 1)
74                         /* empty */ ;
75
76                 assert_se(ALIGN_POWER2(i) == p2);
77         }
78
79         for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
80                 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
81                         /* empty */ ;
82
83                 assert_se(ALIGN_POWER2(i) == p2);
84         }
85 }
86
87 static void test_max(void) {
88         static const struct {
89                 int a;
90                 int b[CONST_MAX(10, 100)];
91         } val1 = {
92                 .a = CONST_MAX(10, 100),
93         };
94         int d = 0;
95
96         assert_cc(sizeof(val1.b) == sizeof(int) * 100);
97
98         /* CONST_MAX returns (void) instead of a value if the passed arguments
99          * are not of the same type or not constant expressions. */
100         assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
101         assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
102
103         assert_se(val1.a == 100);
104         assert_se(MAX(++d, 0) == 1);
105         assert_se(d == 1);
106
107         assert_cc(MAXSIZE(char[3], uint16_t) == 3);
108         assert_cc(MAXSIZE(char[3], uint32_t) == 4);
109         assert_cc(MAXSIZE(char, long) == sizeof(long));
110
111         assert_se(MAX(-5, 5) == 5);
112         assert_se(MAX(5, 5) == 5);
113         assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
114         assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
115         assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
116         assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
117         assert_se(LESS_BY(8, 4) == 4);
118         assert_se(LESS_BY(8, 8) == 0);
119         assert_se(LESS_BY(4, 8) == 0);
120         assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
121         assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
122         assert_se(CLAMP(-5, 0, 1) == 0);
123         assert_se(CLAMP(5, 0, 1) == 1);
124         assert_se(CLAMP(5, -10, 1) == 1);
125         assert_se(CLAMP(5, -10, 10) == 5);
126         assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
127 }
128
129 static void test_container_of(void) {
130         struct mytype {
131                 uint8_t pad1[3];
132                 uint64_t v1;
133                 uint8_t pad2[2];
134                 uint32_t v2;
135         } _packed_ myval = { };
136
137         assert_cc(sizeof(myval) == 17);
138         assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
139         assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
140         assert_se(container_of(&container_of(&myval.v2,
141                                              struct mytype,
142                                              v2)->v1,
143                                struct mytype,
144                                v1) == &myval);
145 }
146
147 static void test_alloca(void) {
148         static const uint8_t zero[997] = { };
149         char *t;
150
151         t = alloca_align(17, 512);
152         assert_se(!((uintptr_t)t & 0xff));
153         memzero(t, 17);
154
155         t = alloca0_align(997, 1024);
156         assert_se(!((uintptr_t)t & 0x1ff));
157         assert_se(!memcmp(t, zero, 997));
158 }
159
160 static void test_div_round_up(void) {
161         int div;
162
163         /* basic tests */
164         assert_se(DIV_ROUND_UP(0, 8) == 0);
165         assert_se(DIV_ROUND_UP(1, 8) == 1);
166         assert_se(DIV_ROUND_UP(8, 8) == 1);
167         assert_se(DIV_ROUND_UP(12, 8) == 2);
168         assert_se(DIV_ROUND_UP(16, 8) == 2);
169
170         /* test multiple evaluation */
171         div = 0;
172         assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
173         assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
174         assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
175         assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
176
177         /* overflow test with exact division */
178         assert_se(sizeof(0U) == 4);
179         assert_se(0xfffffffaU % 10U == 0U);
180         assert_se(0xfffffffaU / 10U == 429496729U);
181         assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
182         assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
183         assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
184
185         /* overflow test with rounded division */
186         assert_se(0xfffffffdU % 10U == 3U);
187         assert_se(0xfffffffdU / 10U == 429496729U);
188         assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
189         assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
190         assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
191 }
192
193 static void test_close_many(void) {
194         int fds[3];
195         char name0[] = "/tmp/test-close-many.XXXXXX";
196         char name1[] = "/tmp/test-close-many.XXXXXX";
197         char name2[] = "/tmp/test-close-many.XXXXXX";
198
199         fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
200         fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
201         fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
202
203         close_many(fds, 2);
204
205         assert_se(fcntl(fds[0], F_GETFD) == -1);
206         assert_se(fcntl(fds[1], F_GETFD) == -1);
207         assert_se(fcntl(fds[2], F_GETFD) >= 0);
208
209         safe_close(fds[2]);
210
211         unlink(name0);
212         unlink(name1);
213         unlink(name2);
214 }
215
216 static void test_parse_uid(void) {
217         int r;
218         uid_t uid;
219
220         r = parse_uid("100", &uid);
221         assert_se(r == 0);
222         assert_se(uid == 100);
223
224         r = parse_uid("65535", &uid);
225         assert_se(r == -ENXIO);
226
227         r = parse_uid("asdsdas", &uid);
228         assert_se(r == -EINVAL);
229 }
230
231 static void test_memdup_multiply(void) {
232         int org[] = {1, 2, 3};
233         int *dup;
234
235         dup = (int*)memdup_multiply(org, sizeof(int), 3);
236
237         assert_se(dup);
238         assert_se(dup[0] == 1);
239         assert_se(dup[1] == 2);
240         assert_se(dup[2] == 3);
241         free(dup);
242 }
243
244 static void test_u64log2(void) {
245         assert_se(u64log2(0) == 0);
246         assert_se(u64log2(8) == 3);
247         assert_se(u64log2(9) == 3);
248         assert_se(u64log2(15) == 3);
249         assert_se(u64log2(16) == 4);
250         assert_se(u64log2(1024*1024) == 20);
251         assert_se(u64log2(1024*1024+5) == 20);
252 }
253
254 static void test_protect_errno(void) {
255         errno = 12;
256         {
257                 PROTECT_ERRNO;
258                 errno = 11;
259         }
260         assert_se(errno == 12);
261 }
262
263 static void test_parse_cpu_set(void) {
264         cpu_set_t *c = NULL;
265         int ncpus;
266         int cpu;
267
268         /* Simple range (from CPUAffinity example) */
269         ncpus = parse_cpu_set_and_warn("1 2", &c, NULL, "fake", 1, "CPUAffinity");
270         assert_se(ncpus >= 1024);
271         assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
272         assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
273         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
274         c = mfree(c);
275
276         /* A more interesting range */
277         ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity");
278         assert_se(ncpus >= 1024);
279         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
280         for (cpu = 0; cpu < 4; cpu++)
281                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
282         for (cpu = 8; cpu < 12; cpu++)
283                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
284         c = mfree(c);
285
286         /* Quoted strings */
287         ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity");
288         assert_se(ncpus >= 1024);
289         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
290         for (cpu = 8; cpu < 12; cpu++)
291                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
292         c = mfree(c);
293
294         /* Use commas as separators */
295         ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity");
296         assert_se(ncpus >= 1024);
297         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
298         for (cpu = 0; cpu < 4; cpu++)
299                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
300         for (cpu = 8; cpu < 12; cpu++)
301                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
302         c = mfree(c);
303
304         /* Commas with spaces (and trailing comma, space) */
305         ncpus = parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c, NULL, "fake", 1, "CPUAffinity");
306         assert_se(ncpus >= 1024);
307         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
308         for (cpu = 0; cpu < 8; cpu++)
309                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
310         c = mfree(c);
311
312         /* Ranges */
313         ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
314         assert_se(ncpus >= 1024);
315         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
316         for (cpu = 0; cpu < 4; cpu++)
317                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
318         for (cpu = 8; cpu < 12; cpu++)
319                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
320         c = mfree(c);
321
322         /* Ranges with trailing comma, space */
323         ncpus = parse_cpu_set_and_warn("0-3  8-11, ", &c, NULL, "fake", 1, "CPUAffinity");
324         assert_se(ncpus >= 1024);
325         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
326         for (cpu = 0; cpu < 4; cpu++)
327                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
328         for (cpu = 8; cpu < 12; cpu++)
329                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
330         c = mfree(c);
331
332         /* Negative range (returns empty cpu_set) */
333         ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity");
334         assert_se(ncpus >= 1024);
335         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0);
336         c = mfree(c);
337
338         /* Overlapping ranges */
339         ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity");
340         assert_se(ncpus >= 1024);
341         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
342         for (cpu = 0; cpu < 12; cpu++)
343                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
344         c = mfree(c);
345
346         /* Mix ranges and individual CPUs */
347         ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity");
348         assert_se(ncpus >= 1024);
349         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 10);
350         assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus), c));
351         assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
352         for (cpu = 4; cpu < 12; cpu++)
353                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
354         c = mfree(c);
355
356         /* Garbage */
357         ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
358         assert_se(ncpus < 0);
359         assert_se(!c);
360
361         /* Range with garbage */
362         ncpus = parse_cpu_set_and_warn("0-3 8-garbage", &c, NULL, "fake", 1, "CPUAffinity");
363         assert_se(ncpus < 0);
364         assert_se(!c);
365
366         /* Empty string */
367         c = NULL;
368         ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
369         assert_se(ncpus == 0);  /* empty string returns 0 */
370         assert_se(!c);
371
372         /* Runnaway quoted string */
373         ncpus = parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c, NULL, "fake", 1, "CPUAffinity");
374         assert_se(ncpus < 0);
375         assert_se(!c);
376 }
377
378 static void test_config_parse_iec_uint64(void) {
379         uint64_t offset = 0;
380         assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
381         assert_se(offset == 4 * 1024 * 1024);
382
383         assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
384 }
385
386 static void test_fstab_node_to_udev_node(void) {
387         char *n;
388
389         n = fstab_node_to_udev_node("LABEL=applé/jack");
390         puts(n);
391         assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
392         free(n);
393
394         n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
395         puts(n);
396         assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
397         free(n);
398
399         n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
400         puts(n);
401         assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
402         free(n);
403
404         n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
405         puts(n);
406         assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
407         free(n);
408
409         n = fstab_node_to_udev_node("PONIES=awesome");
410         puts(n);
411         assert_se(streq(n, "PONIES=awesome"));
412         free(n);
413
414         n = fstab_node_to_udev_node("/dev/xda1");
415         puts(n);
416         assert_se(streq(n, "/dev/xda1"));
417         free(n);
418 }
419
420 static void test_get_files_in_directory(void) {
421         _cleanup_strv_free_ char **l = NULL, **t = NULL;
422
423         assert_se(get_files_in_directory("/tmp", &l) >= 0);
424         assert_se(get_files_in_directory(".", &t) >= 0);
425         assert_se(get_files_in_directory(".", NULL) >= 0);
426 }
427
428 static void test_in_set(void) {
429         assert_se(IN_SET(1, 1));
430         assert_se(IN_SET(1, 1, 2, 3, 4));
431         assert_se(IN_SET(2, 1, 2, 3, 4));
432         assert_se(IN_SET(3, 1, 2, 3, 4));
433         assert_se(IN_SET(4, 1, 2, 3, 4));
434         assert_se(!IN_SET(0, 1));
435         assert_se(!IN_SET(0, 1, 2, 3, 4));
436 }
437
438 static void test_writing_tmpfile(void) {
439         char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
440         _cleanup_free_ char *contents = NULL;
441         size_t size;
442         int fd, r;
443         struct iovec iov[3];
444
445         IOVEC_SET_STRING(iov[0], "abc\n");
446         IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
447         IOVEC_SET_STRING(iov[2], "");
448
449         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
450         printf("tmpfile: %s", name);
451
452         r = writev(fd, iov, 3);
453         assert_se(r >= 0);
454
455         r = read_full_file(name, &contents, &size);
456         assert_se(r == 0);
457         printf("contents: %s", contents);
458         assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
459
460         unlink(name);
461 }
462
463 static void test_log2i(void) {
464         assert_se(log2i(1) == 0);
465         assert_se(log2i(2) == 1);
466         assert_se(log2i(3) == 1);
467         assert_se(log2i(4) == 2);
468         assert_se(log2i(32) == 5);
469         assert_se(log2i(33) == 5);
470         assert_se(log2i(63) == 5);
471         assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
472 }
473
474 static void test_filename_is_valid(void) {
475         char foo[FILENAME_MAX+2];
476         int i;
477
478         assert_se(!filename_is_valid(""));
479         assert_se(!filename_is_valid("/bar/foo"));
480         assert_se(!filename_is_valid("/"));
481         assert_se(!filename_is_valid("."));
482         assert_se(!filename_is_valid(".."));
483
484         for (i=0; i<FILENAME_MAX+1; i++)
485                 foo[i] = 'a';
486         foo[FILENAME_MAX+1] = '\0';
487
488         assert_se(!filename_is_valid(foo));
489
490         assert_se(filename_is_valid("foo_bar-333"));
491         assert_se(filename_is_valid("o.o"));
492 }
493
494 static void test_files_same(void) {
495         _cleanup_close_ int fd = -1;
496         char name[] = "/tmp/test-files_same.XXXXXX";
497         char name_alias[] = "/tmp/test-files_same.alias";
498
499         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
500         assert_se(fd >= 0);
501         assert_se(symlink(name, name_alias) >= 0);
502
503         assert_se(files_same(name, name));
504         assert_se(files_same(name, name_alias));
505
506         unlink(name);
507         unlink(name_alias);
508 }
509
510 static void test_is_valid_documentation_url(void) {
511         assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
512         assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
513         assert_se(documentation_url_is_valid("file:/foo/foo"));
514         assert_se(documentation_url_is_valid("man:systemd.special(7)"));
515         assert_se(documentation_url_is_valid("info:bar"));
516
517         assert_se(!documentation_url_is_valid("foo:"));
518         assert_se(!documentation_url_is_valid("info:"));
519         assert_se(!documentation_url_is_valid(""));
520 }
521
522 static void test_file_in_same_dir(void) {
523         char *t;
524
525         t = file_in_same_dir("/", "a");
526         assert_se(streq(t, "/a"));
527         free(t);
528
529         t = file_in_same_dir("/", "/a");
530         assert_se(streq(t, "/a"));
531         free(t);
532
533         t = file_in_same_dir("", "a");
534         assert_se(streq(t, "a"));
535         free(t);
536
537         t = file_in_same_dir("a/", "a");
538         assert_se(streq(t, "a/a"));
539         free(t);
540
541         t = file_in_same_dir("bar/foo", "bar");
542         assert_se(streq(t, "bar/bar"));
543         free(t);
544 }
545
546 static void test_close_nointr(void) {
547         char name[] = "/tmp/test-test-close_nointr.XXXXXX";
548         int fd;
549
550         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
551         assert_se(fd >= 0);
552         assert_se(close_nointr(fd) >= 0);
553         assert_se(close_nointr(fd) < 0);
554
555         unlink(name);
556 }
557
558
559 static void test_unlink_noerrno(void) {
560         char name[] = "/tmp/test-close_nointr.XXXXXX";
561         int fd;
562
563         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
564         assert_se(fd >= 0);
565         assert_se(close_nointr(fd) >= 0);
566
567         {
568                 PROTECT_ERRNO;
569                 errno = -42;
570                 assert_se(unlink_noerrno(name) >= 0);
571                 assert_se(errno == -42);
572                 assert_se(unlink_noerrno(name) < 0);
573                 assert_se(errno == -42);
574         }
575 }
576
577 static void test_readlink_and_make_absolute(void) {
578         char tempdir[] = "/tmp/test-readlink_and_make_absolute";
579         char name[] = "/tmp/test-readlink_and_make_absolute/original";
580         char name2[] = "test-readlink_and_make_absolute/original";
581         char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
582         char *r = NULL;
583
584         assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
585         assert_se(touch(name) >= 0);
586
587         assert_se(symlink(name, name_alias) >= 0);
588         assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
589         assert_se(streq(r, name));
590         free(r);
591         assert_se(unlink(name_alias) >= 0);
592
593         assert_se(chdir(tempdir) >= 0);
594         assert_se(symlink(name2, name_alias) >= 0);
595         assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
596         assert_se(streq(r, name));
597         free(r);
598         assert_se(unlink(name_alias) >= 0);
599
600         assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
601 }
602
603 static void test_ignore_signals(void) {
604         assert_se(ignore_signals(SIGINT, -1) >= 0);
605         assert_se(kill(getpid(), SIGINT) >= 0);
606         assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
607         assert_se(kill(getpid(), SIGUSR1) >= 0);
608         assert_se(kill(getpid(), SIGUSR2) >= 0);
609         assert_se(kill(getpid(), SIGTERM) >= 0);
610         assert_se(kill(getpid(), SIGPIPE) >= 0);
611         assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
612 }
613
614 static void test_is_symlink(void) {
615         char name[] = "/tmp/test-is_symlink.XXXXXX";
616         char name_link[] = "/tmp/test-is_symlink.link";
617         _cleanup_close_ int fd = -1;
618
619         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
620         assert_se(fd >= 0);
621         assert_se(symlink(name, name_link) >= 0);
622
623         assert_se(is_symlink(name) == 0);
624         assert_se(is_symlink(name_link) == 1);
625         assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
626
627
628         unlink(name);
629         unlink(name_link);
630 }
631
632 static void test_search_and_fopen(void) {
633         const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
634         char name[] = "/tmp/test-search_and_fopen.XXXXXX";
635         int fd = -1;
636         int r;
637         FILE *f;
638
639         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
640         assert_se(fd >= 0);
641         close(fd);
642
643         r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
644         assert_se(r >= 0);
645         fclose(f);
646
647         r = search_and_fopen(name, "r", NULL, dirs, &f);
648         assert_se(r >= 0);
649         fclose(f);
650
651         r = search_and_fopen(basename(name), "r", "/", dirs, &f);
652         assert_se(r >= 0);
653         fclose(f);
654
655         r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
656         assert_se(r < 0);
657         r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
658         assert_se(r < 0);
659
660         r = unlink(name);
661         assert_se(r == 0);
662
663         r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
664         assert_se(r < 0);
665 }
666
667
668 static void test_search_and_fopen_nulstr(void) {
669         const char dirs[] = "/tmp/foo/bar\0/tmp\0";
670         char name[] = "/tmp/test-search_and_fopen.XXXXXX";
671         int fd = -1;
672         int r;
673         FILE *f;
674
675         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
676         assert_se(fd >= 0);
677         close(fd);
678
679         r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
680         assert_se(r >= 0);
681         fclose(f);
682
683         r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
684         assert_se(r >= 0);
685         fclose(f);
686
687         r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
688         assert_se(r < 0);
689         r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
690         assert_se(r < 0);
691
692         r = unlink(name);
693         assert_se(r == 0);
694
695         r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
696         assert_se(r < 0);
697 }
698
699 static void test_glob_exists(void) {
700         char name[] = "/tmp/test-glob_exists.XXXXXX";
701         int fd = -1;
702         int r;
703
704         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
705         assert_se(fd >= 0);
706         close(fd);
707
708         r = glob_exists("/tmp/test-glob_exists*");
709         assert_se(r == 1);
710
711         r = unlink(name);
712         assert_se(r == 0);
713         r = glob_exists("/tmp/test-glob_exists*");
714         assert_se(r == 0);
715 }
716
717 static void test_execute_directory(void) {
718         char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
719         char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
720         const char * dirs[] = {template_hi, template_lo, NULL};
721         const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
722
723         assert_se(mkdtemp(template_lo));
724         assert_se(mkdtemp(template_hi));
725
726         name = strjoina(template_lo, "/script");
727         name2 = strjoina(template_hi, "/script2");
728         name3 = strjoina(template_lo, "/useless");
729         overridden = strjoina(template_lo, "/overridden");
730         override = strjoina(template_hi, "/overridden");
731         masked = strjoina(template_lo, "/masked");
732         mask = strjoina(template_hi, "/masked");
733
734         assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE) == 0);
735         assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE) == 0);
736         assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
737         assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE) == 0);
738         assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
739         assert_se(symlink("/dev/null", mask) == 0);
740         assert_se(chmod(name, 0755) == 0);
741         assert_se(chmod(name2, 0755) == 0);
742         assert_se(chmod(overridden, 0755) == 0);
743         assert_se(chmod(override, 0755) == 0);
744         assert_se(chmod(masked, 0755) == 0);
745         assert_se(touch(name3) >= 0);
746
747         execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
748
749         assert_se(chdir(template_lo) == 0);
750         assert_se(access("it_works", F_OK) >= 0);
751         assert_se(access("failed", F_OK) < 0);
752
753         assert_se(chdir(template_hi) == 0);
754         assert_se(access("it_works2", F_OK) >= 0);
755         assert_se(access("failed", F_OK) < 0);
756
757         (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
758         (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
759 }
760
761 static int parse_item(const char *key, const char *value) {
762         assert_se(key);
763
764         log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
765         return 0;
766 }
767
768 static void test_parse_proc_cmdline(void) {
769         assert_se(parse_proc_cmdline(parse_item) >= 0);
770 }
771
772 static void test_raw_clone(void) {
773         pid_t parent, pid, pid2;
774
775         parent = getpid();
776         log_info("before clone: getpid()→"PID_FMT, parent);
777         assert_se(raw_getpid() == parent);
778
779         pid = raw_clone(0, NULL);
780         assert_se(pid >= 0);
781
782         pid2 = raw_getpid();
783         log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
784                  pid, getpid(), pid2);
785         if (pid == 0) {
786                 assert_se(pid2 != parent);
787                 _exit(EXIT_SUCCESS);
788         } else {
789                 int status;
790
791                 assert_se(pid2 == parent);
792                 waitpid(pid, &status, __WCLONE);
793                 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
794         }
795 }
796
797 static void test_same_fd(void) {
798         _cleanup_close_pair_ int p[2] = { -1, -1 };
799         _cleanup_close_ int a = -1, b = -1, c = -1;
800
801         assert_se(pipe2(p, O_CLOEXEC) >= 0);
802         assert_se((a = dup(p[0])) >= 0);
803         assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
804         assert_se((c = dup(a)) >= 0);
805
806         assert_se(same_fd(p[0], p[0]) > 0);
807         assert_se(same_fd(p[1], p[1]) > 0);
808         assert_se(same_fd(a, a) > 0);
809         assert_se(same_fd(b, b) > 0);
810
811         assert_se(same_fd(a, p[0]) > 0);
812         assert_se(same_fd(p[0], a) > 0);
813         assert_se(same_fd(c, p[0]) > 0);
814         assert_se(same_fd(p[0], c) > 0);
815         assert_se(same_fd(a, c) > 0);
816         assert_se(same_fd(c, a) > 0);
817
818         assert_se(same_fd(p[0], p[1]) == 0);
819         assert_se(same_fd(p[1], p[0]) == 0);
820         assert_se(same_fd(p[0], b) == 0);
821         assert_se(same_fd(b, p[0]) == 0);
822         assert_se(same_fd(p[1], a) == 0);
823         assert_se(same_fd(a, p[1]) == 0);
824         assert_se(same_fd(p[1], b) == 0);
825         assert_se(same_fd(b, p[1]) == 0);
826
827         assert_se(same_fd(a, b) == 0);
828         assert_se(same_fd(b, a) == 0);
829 }
830
831 static void test_uid_ptr(void) {
832
833         assert_se(UID_TO_PTR(0) != NULL);
834         assert_se(UID_TO_PTR(1000) != NULL);
835
836         assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
837         assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
838 }
839
840 static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
841         char check[n];
842
843         assert_se(lseek(fd, 0, SEEK_SET) == 0);
844         assert_se(ftruncate(fd, 0) >= 0);
845         assert_se(sparse_write(fd, buffer, n, 4) == (ssize_t) n);
846
847         assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
848         assert_se(ftruncate(fd, n) >= 0);
849
850         assert_se(lseek(fd, 0, SEEK_SET) == 0);
851         assert_se(read(fd, check, n) == (ssize_t) n);
852
853         assert_se(memcmp(buffer, check, n) == 0);
854 }
855
856 static void test_sparse_write(void) {
857         const char test_a[] = "test";
858         const char test_b[] = "\0\0\0\0test\0\0\0\0";
859         const char test_c[] = "\0\0test\0\0\0\0";
860         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";
861         const char test_e[] = "test\0\0\0\0test";
862         _cleanup_close_ int fd = -1;
863         char fn[] = "/tmp/sparseXXXXXX";
864
865         fd = mkostemp(fn, O_CLOEXEC);
866         assert_se(fd >= 0);
867         unlink(fn);
868
869         test_sparse_write_one(fd, test_a, sizeof(test_a));
870         test_sparse_write_one(fd, test_b, sizeof(test_b));
871         test_sparse_write_one(fd, test_c, sizeof(test_c));
872         test_sparse_write_one(fd, test_d, sizeof(test_d));
873         test_sparse_write_one(fd, test_e, sizeof(test_e));
874 }
875
876 static void test_tempfn(void) {
877         char *ret = NULL, *p;
878
879         assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
880         assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
881         free(ret);
882
883         assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret) >= 0);
884         assert_se(streq_ptr(ret, "/foo/bar/.#[miau]waldoXXXXXX"));
885         free(ret);
886
887         assert_se(tempfn_random("/foo/bar/waldo", NULL, &ret) >= 0);
888         assert_se(p = startswith(ret, "/foo/bar/.#waldo"));
889         assert_se(strlen(p) == 16);
890         assert_se(in_charset(p, "0123456789abcdef"));
891         free(ret);
892
893         assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret) >= 0);
894         assert_se(p = startswith(ret, "/foo/bar/.#[wuff]waldo"));
895         assert_se(strlen(p) == 16);
896         assert_se(in_charset(p, "0123456789abcdef"));
897         free(ret);
898
899         assert_se(tempfn_random_child("/foo/bar/waldo", NULL, &ret) >= 0);
900         assert_se(p = startswith(ret, "/foo/bar/waldo/.#"));
901         assert_se(strlen(p) == 16);
902         assert_se(in_charset(p, "0123456789abcdef"));
903         free(ret);
904
905         assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret) >= 0);
906         assert_se(p = startswith(ret, "/foo/bar/waldo/.#[kikiriki]"));
907         assert_se(strlen(p) == 16);
908         assert_se(in_charset(p, "0123456789abcdef"));
909         free(ret);
910 }
911
912 static void test_fgetxattrat_fake(void) {
913         char t[] = "/var/tmp/xattrtestXXXXXX";
914         _cleanup_close_ int fd = -1;
915         const char *x;
916         char v[3] = {};
917         int r;
918
919         assert_se(mkdtemp(t));
920         x = strjoina(t, "/test");
921         assert_se(touch(x) >= 0);
922
923         r = setxattr(x, "user.foo", "bar", 3, 0);
924         if (r < 0 && errno == EOPNOTSUPP) /* no xattrs supported on /var/tmp... */
925                 goto cleanup;
926         assert_se(r >= 0);
927
928         fd = open(t, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
929         assert_se(fd >= 0);
930
931         assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0) >= 0);
932         assert_se(memcmp(v, "bar", 3) == 0);
933
934         safe_close(fd);
935         fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
936         assert_se(fd >= 0);
937         assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0) == -ENODATA);
938
939 cleanup:
940         assert_se(unlink(x) >= 0);
941         assert_se(rmdir(t) >= 0);
942 }
943
944 static void test_runlevel_to_target(void) {
945         assert_se(streq_ptr(runlevel_to_target(NULL), NULL));
946         assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL));
947         assert_se(streq_ptr(runlevel_to_target("3"), SPECIAL_MULTI_USER_TARGET));
948 }
949
950 int main(int argc, char *argv[]) {
951         log_parse_environment();
952         log_open();
953
954         test_align_power2();
955         test_max();
956         test_container_of();
957         test_alloca();
958         test_div_round_up();
959         test_close_many();
960         test_parse_uid();
961         test_memdup_multiply();
962         test_u64log2();
963         test_protect_errno();
964         test_parse_cpu_set();
965         test_config_parse_iec_uint64();
966         test_fstab_node_to_udev_node();
967         test_get_files_in_directory();
968         test_in_set();
969         test_writing_tmpfile();
970         test_log2i();
971         test_filename_is_valid();
972         test_files_same();
973         test_is_valid_documentation_url();
974         test_file_in_same_dir();
975         test_close_nointr();
976         test_unlink_noerrno();
977         test_readlink_and_make_absolute();
978         test_ignore_signals();
979         test_is_symlink();
980         test_search_and_fopen();
981         test_search_and_fopen_nulstr();
982         test_glob_exists();
983         test_execute_directory();
984         test_parse_proc_cmdline();
985         test_raw_clone();
986         test_same_fd();
987         test_uid_ptr();
988         test_sparse_write();
989         test_tempfn();
990         test_fgetxattrat_fake();
991         test_runlevel_to_target();
992
993         return 0;
994 }