]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
f4c13ad7 RC |
2 | |
3 | #include <fcntl.h> | |
436e916e | 4 | #include <linux/magic.h> |
54c2459d | 5 | #include <sched.h> |
a70581ff | 6 | #include <unistd.h> |
f4c13ad7 RC |
7 | |
8 | #include "alloc-util.h" | |
d8d0da1f | 9 | #include "errno-list.h" |
f4c13ad7 | 10 | #include "fd-util.h" |
bfc569b0 | 11 | #include "fs-util.h" |
f4c13ad7 | 12 | #include "macro.h" |
049af8ad | 13 | #include "mountpoint-util.h" |
0cb8e3d1 | 14 | #include "namespace-util.h" |
846b3bd6 | 15 | #include "path-util.h" |
bfc569b0 | 16 | #include "rm-rf.h" |
e4de7287 | 17 | #include "stat-util.h" |
b845894c | 18 | #include "tests.h" |
e4de7287 | 19 | #include "tmpfile-util.h" |
f4c13ad7 | 20 | |
48542eac ZJS |
21 | TEST(null_or_empty_path) { |
22 | assert_se(null_or_empty_path("/dev/null") == 1); | |
23 | assert_se(null_or_empty_path("/dev/tty") == 1); /* We assume that any character device is "empty", bleh. */ | |
24 | assert_se(null_or_empty_path("../../../../../../../../../../../../../../../../../../../../dev/null") == 1); | |
25 | assert_se(null_or_empty_path("/proc/self/exe") == 0); | |
26 | assert_se(null_or_empty_path("/nosuchfileordir") == -ENOENT); | |
27 | } | |
28 | ||
29 | TEST(null_or_empty_path_with_root) { | |
30 | assert_se(null_or_empty_path_with_root("/dev/null", NULL) == 1); | |
31 | assert_se(null_or_empty_path_with_root("/dev/null", "/") == 1); | |
32 | assert_se(null_or_empty_path_with_root("/dev/null", "/.././../") == 1); | |
33 | assert_se(null_or_empty_path_with_root("/dev/null", "/.././..") == 1); | |
34 | assert_se(null_or_empty_path_with_root("../../../../../../../../../../../../../../../../../../../../dev/null", NULL) == 1); | |
35 | assert_se(null_or_empty_path_with_root("../../../../../../../../../../../../../../../../../../../../dev/null", "/") == 1); | |
36 | assert_se(null_or_empty_path_with_root("/proc/self/exe", NULL) == 0); | |
37 | assert_se(null_or_empty_path_with_root("/proc/self/exe", "/") == 0); | |
38 | assert_se(null_or_empty_path_with_root("/nosuchfileordir", NULL) == -ENOENT); | |
39 | assert_se(null_or_empty_path_with_root("/nosuchfileordir", "/.././../") == -ENOENT); | |
40 | assert_se(null_or_empty_path_with_root("/nosuchfileordir", "/.././..") == -ENOENT); | |
41 | assert_se(null_or_empty_path_with_root("/foobar/barbar/dev/null", "/foobar/barbar") == 1); | |
42 | assert_se(null_or_empty_path_with_root("/foobar/barbar/dev/null", "/foobar/barbar/") == 1); | |
43 | } | |
44 | ||
4f7452a8 | 45 | TEST(files_same) { |
254d1313 | 46 | _cleanup_close_ int fd = -EBADF; |
f4c13ad7 RC |
47 | char name[] = "/tmp/test-files_same.XXXXXX"; |
48 | char name_alias[] = "/tmp/test-files_same.alias"; | |
49 | ||
646853bd | 50 | fd = mkostemp_safe(name); |
f4c13ad7 RC |
51 | assert_se(fd >= 0); |
52 | assert_se(symlink(name, name_alias) >= 0); | |
53 | ||
e3f791a2 ZJS |
54 | assert_se(files_same(name, name, 0)); |
55 | assert_se(files_same(name, name, AT_SYMLINK_NOFOLLOW)); | |
56 | assert_se(files_same(name, name_alias, 0)); | |
57 | assert_se(!files_same(name, name_alias, AT_SYMLINK_NOFOLLOW)); | |
f4c13ad7 RC |
58 | |
59 | unlink(name); | |
60 | unlink(name_alias); | |
61 | } | |
62 | ||
4f7452a8 | 63 | TEST(is_symlink) { |
f4c13ad7 RC |
64 | char name[] = "/tmp/test-is_symlink.XXXXXX"; |
65 | char name_link[] = "/tmp/test-is_symlink.link"; | |
254d1313 | 66 | _cleanup_close_ int fd = -EBADF; |
f4c13ad7 | 67 | |
646853bd | 68 | fd = mkostemp_safe(name); |
f4c13ad7 RC |
69 | assert_se(fd >= 0); |
70 | assert_se(symlink(name, name_link) >= 0); | |
71 | ||
72 | assert_se(is_symlink(name) == 0); | |
73 | assert_se(is_symlink(name_link) == 1); | |
74 | assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0); | |
75 | ||
f4c13ad7 RC |
76 | unlink(name); |
77 | unlink(name_link); | |
78 | } | |
79 | ||
4f7452a8 | 80 | TEST(path_is_fs_type) { |
cc390161 MP |
81 | /* run might not be a mount point in build chroots */ |
82 | if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0) { | |
40fd52f2 ZJS |
83 | assert_se(path_is_fs_type("/run", TMPFS_MAGIC) > 0); |
84 | assert_se(path_is_fs_type("/run", BTRFS_SUPER_MAGIC) == 0); | |
cc390161 | 85 | } |
51db8fdb ZJS |
86 | if (path_is_mount_point("/proc", NULL, AT_SYMLINK_FOLLOW) > 0) { |
87 | assert_se(path_is_fs_type("/proc", PROC_SUPER_MAGIC) > 0); | |
88 | assert_se(path_is_fs_type("/proc", BTRFS_SUPER_MAGIC) == 0); | |
89 | } | |
40fd52f2 | 90 | assert_se(path_is_fs_type("/i-dont-exist", BTRFS_SUPER_MAGIC) == -ENOENT); |
436e916e LP |
91 | } |
92 | ||
4f7452a8 | 93 | TEST(path_is_temporary_fs) { |
d8d0da1f ZJS |
94 | int r; |
95 | ||
d8d0da1f ZJS |
96 | FOREACH_STRING(s, "/", "/run", "/sys", "/sys/", "/proc", "/i-dont-exist", "/var", "/var/lib") { |
97 | r = path_is_temporary_fs(s); | |
98 | ||
99 | log_info_errno(r, "path_is_temporary_fs(\"%s\"): %d, %s", | |
100 | s, r, r < 0 ? errno_to_name(r) : yes_no(r)); | |
101 | } | |
102 | ||
8dfc2f40 MP |
103 | /* run might not be a mount point in build chroots */ |
104 | if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0) | |
105 | assert_se(path_is_temporary_fs("/run") > 0); | |
436e916e LP |
106 | assert_se(path_is_temporary_fs("/proc") == 0); |
107 | assert_se(path_is_temporary_fs("/i-dont-exist") == -ENOENT); | |
108 | } | |
109 | ||
4f7452a8 | 110 | TEST(path_is_read_only_fs) { |
d8d0da1f ZJS |
111 | int r; |
112 | ||
d8d0da1f ZJS |
113 | FOREACH_STRING(s, "/", "/run", "/sys", "/sys/", "/proc", "/i-dont-exist", "/var", "/var/lib") { |
114 | r = path_is_read_only_fs(s); | |
115 | ||
116 | log_info_errno(r, "path_is_read_only_fs(\"%s\"): %d, %s", | |
117 | s, r, r < 0 ? errno_to_name(r) : yes_no(r)); | |
118 | } | |
119 | ||
120 | if (path_is_mount_point("/sys", NULL, AT_SYMLINK_FOLLOW) > 0) | |
121 | assert_se(IN_SET(path_is_read_only_fs("/sys"), 0, 1)); | |
122 | ||
123 | assert_se(path_is_read_only_fs("/proc") == 0); | |
124 | assert_se(path_is_read_only_fs("/i-dont-exist") == -ENOENT); | |
125 | } | |
126 | ||
4f7452a8 | 127 | TEST(fd_is_ns) { |
254d1313 | 128 | _cleanup_close_ int fd = -EBADF; |
b845894c | 129 | |
54c2459d XR |
130 | assert_se(fd_is_ns(STDIN_FILENO, CLONE_NEWNET) == 0); |
131 | assert_se(fd_is_ns(STDERR_FILENO, CLONE_NEWNET) == 0); | |
132 | assert_se(fd_is_ns(STDOUT_FILENO, CLONE_NEWNET) == 0); | |
6619ad88 | 133 | |
51db8fdb ZJS |
134 | fd = open("/proc/self/ns/mnt", O_CLOEXEC|O_RDONLY); |
135 | if (fd < 0) { | |
136 | assert_se(errno == ENOENT); | |
137 | log_notice("Path %s not found, skipping test", "/proc/self/ns/mnt"); | |
138 | return; | |
139 | } | |
140 | assert_se(fd >= 0); | |
54c2459d XR |
141 | assert_se(IN_SET(fd_is_ns(fd, CLONE_NEWNET), 0, -EUCLEAN)); |
142 | fd = safe_close(fd); | |
143 | ||
144 | assert_se((fd = open("/proc/self/ns/ipc", O_CLOEXEC|O_RDONLY)) >= 0); | |
145 | assert_se(IN_SET(fd_is_ns(fd, CLONE_NEWIPC), 1, -EUCLEAN)); | |
6619ad88 LP |
146 | fd = safe_close(fd); |
147 | ||
148 | assert_se((fd = open("/proc/self/ns/net", O_CLOEXEC|O_RDONLY)) >= 0); | |
54c2459d | 149 | assert_se(IN_SET(fd_is_ns(fd, CLONE_NEWNET), 1, -EUCLEAN)); |
6619ad88 LP |
150 | } |
151 | ||
4f7452a8 | 152 | TEST(dir_is_empty) { |
bfc569b0 | 153 | _cleanup_(rm_rf_physical_and_freep) char *empty_dir = NULL; |
f470cb6d | 154 | _cleanup_free_ char *j = NULL, *jj = NULL, *jjj = NULL; |
bfc569b0 | 155 | |
db55bbf2 LP |
156 | assert_se(dir_is_empty_at(AT_FDCWD, "/proc", /* ignore_hidden_or_backup= */ true) == 0); |
157 | assert_se(dir_is_empty_at(AT_FDCWD, "/icertainlydontexistdoi", /* ignore_hidden_or_backup= */ true) == -ENOENT); | |
bfc569b0 LP |
158 | |
159 | assert_se(mkdtemp_malloc("/tmp/emptyXXXXXX", &empty_dir) >= 0); | |
db55bbf2 | 160 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ true) > 0); |
bfc569b0 LP |
161 | |
162 | j = path_join(empty_dir, "zzz"); | |
163 | assert_se(j); | |
164 | assert_se(touch(j) >= 0); | |
165 | ||
db55bbf2 | 166 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ true) == 0); |
bfc569b0 LP |
167 | |
168 | jj = path_join(empty_dir, "ppp"); | |
169 | assert_se(jj); | |
170 | assert_se(touch(jj) >= 0); | |
171 | ||
f470cb6d LB |
172 | jjj = path_join(empty_dir, ".qqq"); |
173 | assert_se(jjj); | |
174 | assert_se(touch(jjj) >= 0); | |
175 | ||
db55bbf2 LP |
176 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ true) == 0); |
177 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ false) == 0); | |
bfc569b0 | 178 | assert_se(unlink(j) >= 0); |
db55bbf2 LP |
179 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ true) == 0); |
180 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ false) == 0); | |
bfc569b0 | 181 | assert_se(unlink(jj) >= 0); |
db55bbf2 LP |
182 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ true) > 0); |
183 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ false) == 0); | |
f470cb6d | 184 | assert_se(unlink(jjj) >= 0); |
db55bbf2 LP |
185 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ true) > 0); |
186 | assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ false) > 0); | |
bfc569b0 LP |
187 | } |
188 | ||
99839c7e LP |
189 | static int intro(void) { |
190 | log_show_color(true); | |
191 | return EXIT_SUCCESS; | |
192 | } | |
193 | ||
e85fdacc | 194 | DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro); |