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