]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-async.c
Merge pull request #31000 from flatcar-hub/krnowak/mutable-overlays
[thirdparty/systemd.git] / src / test / test-async.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <fcntl.h>
4 #include <sys/prctl.h>
5 #include <sys/wait.h>
6 #include <unistd.h>
7
8 #include "async.h"
9 #include "fs-util.h"
10 #include "path-util.h"
11 #include "process-util.h"
12 #include "signal-util.h"
13 #include "tests.h"
14 #include "tmpfile-util.h"
15
16 TEST(asynchronous_sync) {
17 assert_se(asynchronous_sync(NULL) >= 0);
18 }
19
20 TEST(asynchronous_close) {
21 _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-asynchronous_close.XXXXXX";
22 int fd, r;
23
24 fd = mkostemp_safe(name);
25 assert_se(fd >= 0);
26 asynchronous_close(fd);
27
28 sleep(1);
29
30 assert_se(fcntl(fd, F_GETFD) == -1);
31 assert_se(errno == EBADF);
32
33 r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT, NULL);
34 assert(r >= 0);
35
36 if (r == 0) {
37 /* child */
38
39 assert(make_reaper_process(true) >= 0);
40
41 fd = open("/dev/null", O_RDONLY|O_CLOEXEC);
42 assert_se(fd >= 0);
43 asynchronous_close(fd);
44
45 sleep(1);
46
47 assert_se(fcntl(fd, F_GETFD) == -1);
48 assert_se(errno == EBADF);
49
50 _exit(EXIT_SUCCESS);
51 }
52 }
53
54 TEST(asynchronous_rm_rf) {
55 _cleanup_free_ char *t = NULL, *k = NULL;
56 int r;
57
58 assert_se(mkdtemp_malloc(NULL, &t) >= 0);
59 assert_se(k = path_join(t, "somefile"));
60 assert_se(touch(k) >= 0);
61 assert_se(asynchronous_rm_rf(t, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
62
63 /* Do this once more, form a subreaper. Which is nice, because we can watch the async child even
64 * though detached */
65
66 r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
67 assert_se(r >= 0);
68
69 if (r == 0) {
70 _cleanup_free_ char *tt = NULL, *kk = NULL;
71
72 /* child */
73
74 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD) >= 0);
75 assert_se(make_reaper_process(true) >= 0);
76
77 assert_se(mkdtemp_malloc(NULL, &tt) >= 0);
78 assert_se(kk = path_join(tt, "somefile"));
79 assert_se(touch(kk) >= 0);
80 assert_se(asynchronous_rm_rf(tt, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
81
82 for (;;) {
83 siginfo_t si = {};
84
85 assert_se(waitid(P_ALL, 0, &si, WEXITED) >= 0);
86
87 if (access(tt, F_OK) < 0) {
88 assert_se(errno == ENOENT);
89 break;
90 }
91
92 /* wasn't the rm_rf() call. let's wait longer */
93 }
94
95 _exit(EXIT_SUCCESS);
96 }
97 }
98
99
100 DEFINE_TEST_MAIN(LOG_DEBUG);