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