2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
5 Copyright 2013 Thomas H.P. Andersen
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.
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.
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/>.
25 #include <sys/types.h>
27 #include <sys/xattr.h>
30 #include "alloc-util.h"
31 #include "conf-parser.h"
32 #include "cpu-set-util.h"
37 #include "fstab-util.h"
38 #include "glob-util.h"
41 #include "parse-util.h"
42 #include "path-util.h"
43 #include "proc-cmdline.h"
44 #include "process-util.h"
46 #include "signal-util.h"
48 #include "stat-util.h"
49 #include "string-util.h"
51 #include "user-util.h"
54 #include "xattr-util.h"
56 static void test_align_power2(void) {
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);
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);
71 for (i = 1; i < 131071; ++i) {
72 for (p2 = 1; p2 < i; p2 <<= 1)
75 assert_se(ALIGN_POWER2(i) == p2);
78 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
79 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
82 assert_se(ALIGN_POWER2(i) == p2);
86 static void test_max(void) {
89 int b[CONST_MAX(10, 100)];
91 .a = CONST_MAX(10, 100),
95 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
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));
102 assert_se(val1.a == 100);
103 assert_se(MAX(++d, 0) == 1);
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));
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);
128 static void test_container_of(void) {
134 } _packed_ myval = { };
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,
146 static void test_div_round_up(void) {
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);
156 /* test multiple evaluation */
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);
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);
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);
179 static void test_close_many(void) {
181 char name0[] = "/tmp/test-close-many.XXXXXX";
182 char name1[] = "/tmp/test-close-many.XXXXXX";
183 char name2[] = "/tmp/test-close-many.XXXXXX";
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);
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);
202 static void test_parse_uid(void) {
206 r = parse_uid("100", &uid);
208 assert_se(uid == 100);
210 r = parse_uid("65535", &uid);
211 assert_se(r == -ENXIO);
213 r = parse_uid("asdsdas", &uid);
214 assert_se(r == -EINVAL);
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);
227 static void test_protect_errno(void) {
233 assert_se(errno == 12);
236 static void test_parse_cpu_set(void) {
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);
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));
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));
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));
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));
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));
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));
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);
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));
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));
330 ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
331 assert_se(ncpus < 0);
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);
341 ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
342 assert_se(ncpus == 0); /* empty string returns 0 */
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);
351 static void test_config_parse_iec_uint64(void) {
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);
356 assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
359 static void test_fstab_node_to_udev_node(void) {
362 n = fstab_node_to_udev_node("LABEL=applé/jack");
364 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
367 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
369 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
372 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
374 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
377 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
379 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
382 n = fstab_node_to_udev_node("PONIES=awesome");
384 assert_se(streq(n, "PONIES=awesome"));
387 n = fstab_node_to_udev_node("/dev/xda1");
389 assert_se(streq(n, "/dev/xda1"));
393 static void test_get_files_in_directory(void) {
394 _cleanup_strv_free_ char **l = NULL, **t = NULL;
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);
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));
411 static void test_writing_tmpfile(void) {
412 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
413 _cleanup_free_ char *contents = NULL;
418 IOVEC_SET_STRING(iov[0], "abc\n");
419 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
420 IOVEC_SET_STRING(iov[2], "");
422 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
423 printf("tmpfile: %s", name);
425 r = writev(fd, iov, 3);
428 r = read_full_file(name, &contents, &size);
430 printf("contents: %s", contents);
431 assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
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);
447 static void test_filename_is_valid(void) {
448 char foo[FILENAME_MAX+2];
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(".."));
457 for (i=0; i<FILENAME_MAX+1; i++)
459 foo[FILENAME_MAX+1] = '\0';
461 assert_se(!filename_is_valid(foo));
463 assert_se(filename_is_valid("foo_bar-333"));
464 assert_se(filename_is_valid("o.o"));
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";
472 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
474 assert_se(symlink(name, name_alias) >= 0);
476 assert_se(files_same(name, name));
477 assert_se(files_same(name, name_alias));
483 static void test_file_in_same_dir(void) {
486 t = file_in_same_dir("/", "a");
487 assert_se(streq(t, "/a"));
490 t = file_in_same_dir("/", "/a");
491 assert_se(streq(t, "/a"));
494 t = file_in_same_dir("", "a");
495 assert_se(streq(t, "a"));
498 t = file_in_same_dir("a/", "a");
499 assert_se(streq(t, "a/a"));
502 t = file_in_same_dir("bar/foo", "bar");
503 assert_se(streq(t, "bar/bar"));
507 static void test_close_nointr(void) {
508 char name[] = "/tmp/test-test-close_nointr.XXXXXX";
511 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
513 assert_se(close_nointr(fd) >= 0);
514 assert_se(close_nointr(fd) < 0);
520 static void test_unlink_noerrno(void) {
521 char name[] = "/tmp/test-close_nointr.XXXXXX";
524 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
526 assert_se(close_nointr(fd) >= 0);
531 assert_se(unlink_noerrno(name) >= 0);
532 assert_se(errno == -42);
533 assert_se(unlink_noerrno(name) < 0);
534 assert_se(errno == -42);
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";
545 assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
546 assert_se(touch(name) >= 0);
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));
552 assert_se(unlink(name_alias) >= 0);
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));
559 assert_se(unlink(name_alias) >= 0);
561 assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
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);
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;
580 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
582 assert_se(symlink(name, name_link) >= 0);
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);
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";
600 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
604 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
608 r = search_and_fopen(name, "r", NULL, dirs, &f);
612 r = search_and_fopen(basename(name), "r", "/", dirs, &f);
616 r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
618 r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
624 r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
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";
636 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
640 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
644 r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
648 r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
650 r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
656 r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
660 static void test_glob_exists(void) {
661 char name[] = "/tmp/test-glob_exists.XXXXXX";
665 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
669 r = glob_exists("/tmp/test-glob_exists*");
674 r = glob_exists("/tmp/test-glob_exists*");
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;
684 assert_se(mkdtemp(template_lo));
685 assert_se(mkdtemp(template_hi));
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");
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);
708 execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
710 assert_se(chdir(template_lo) == 0);
711 assert_se(access("it_works", F_OK) >= 0);
712 assert_se(access("failed", F_OK) < 0);
714 assert_se(chdir(template_hi) == 0);
715 assert_se(access("it_works2", F_OK) >= 0);
716 assert_se(access("failed", F_OK) < 0);
718 (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
719 (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
722 static int parse_item(const char *key, const char *value) {
725 log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
729 static void test_parse_proc_cmdline(void) {
730 assert_se(parse_proc_cmdline(parse_item) >= 0);
733 static void test_raw_clone(void) {
734 pid_t parent, pid, pid2;
737 log_info("before clone: getpid()→"PID_FMT, parent);
738 assert_se(raw_getpid() == parent);
740 pid = raw_clone(0, NULL);
744 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
745 pid, getpid(), pid2);
747 assert_se(pid2 != parent);
752 assert_se(pid2 == parent);
753 waitpid(pid, &status, __WCLONE);
754 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
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;
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);
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);
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);
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);
788 assert_se(same_fd(a, b) == 0);
789 assert_se(same_fd(b, a) == 0);
792 static void test_uid_ptr(void) {
794 assert_se(UID_TO_PTR(0) != NULL);
795 assert_se(UID_TO_PTR(1000) != NULL);
797 assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
798 assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
801 static void test_sparse_write_one(int fd, const char *buffer, size_t n) {
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);
808 assert_se(lseek(fd, 0, SEEK_CUR) == (off_t) n);
809 assert_se(ftruncate(fd, n) >= 0);
811 assert_se(lseek(fd, 0, SEEK_SET) == 0);
812 assert_se(read(fd, check, n) == (ssize_t) n);
814 assert_se(memcmp(buffer, check, n) == 0);
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";
826 fd = mkostemp(fn, O_CLOEXEC);
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));
837 static void test_tempfn(void) {
838 char *ret = NULL, *p;
840 assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
841 assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
844 assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret) >= 0);
845 assert_se(streq_ptr(ret, "/foo/bar/.#[miau]waldoXXXXXX"));
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"));
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"));
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"));
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"));
873 static void test_fgetxattrat_fake(void) {
874 char t[] = "/var/tmp/xattrtestXXXXXX";
875 _cleanup_close_ int fd = -1;
880 assert_se(mkdtemp(t));
881 x = strjoina(t, "/test");
882 assert_se(touch(x) >= 0);
884 r = setxattr(x, "user.foo", "bar", 3, 0);
885 if (r < 0 && errno == EOPNOTSUPP) /* no xattrs supported on /var/tmp... */
889 fd = open(t, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
892 assert_se(fgetxattrat_fake(fd, "test", "user.foo", v, 3, 0) >= 0);
893 assert_se(memcmp(v, "bar", 3) == 0);
896 fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
898 assert_se(fgetxattrat_fake(fd, "usr", "user.idontexist", v, 3, 0) == -ENODATA);
901 assert_se(unlink(x) >= 0);
902 assert_se(rmdir(t) >= 0);
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));
911 int main(int argc, char *argv[]) {
912 log_parse_environment();
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();
928 test_writing_tmpfile();
930 test_filename_is_valid();
932 test_file_in_same_dir();
934 test_unlink_noerrno();
935 test_readlink_and_make_absolute();
936 test_ignore_signals();
938 test_search_and_fopen();
939 test_search_and_fopen_nulstr();
941 test_execute_directory();
942 test_parse_proc_cmdline();
948 test_fgetxattrat_fake();
949 test_runlevel_to_target();