1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <linux/magic.h>
8 #include "alloc-util.h"
9 #include "errno-list.h"
13 #include "mountpoint-util.h"
14 #include "namespace-util.h"
15 #include "path-util.h"
17 #include "stat-util.h"
19 #include "tmpfile-util.h"
22 _cleanup_close_
int fd
= -1;
23 char name
[] = "/tmp/test-files_same.XXXXXX";
24 char name_alias
[] = "/tmp/test-files_same.alias";
26 fd
= mkostemp_safe(name
);
28 assert_se(symlink(name
, name_alias
) >= 0);
30 assert_se(files_same(name
, name
, 0));
31 assert_se(files_same(name
, name
, AT_SYMLINK_NOFOLLOW
));
32 assert_se(files_same(name
, name_alias
, 0));
33 assert_se(!files_same(name
, name_alias
, AT_SYMLINK_NOFOLLOW
));
40 char name
[] = "/tmp/test-is_symlink.XXXXXX";
41 char name_link
[] = "/tmp/test-is_symlink.link";
42 _cleanup_close_
int fd
= -1;
44 fd
= mkostemp_safe(name
);
46 assert_se(symlink(name
, name_link
) >= 0);
48 assert_se(is_symlink(name
) == 0);
49 assert_se(is_symlink(name_link
) == 1);
50 assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
56 TEST(path_is_fs_type
) {
57 /* run might not be a mount point in build chroots */
58 if (path_is_mount_point("/run", NULL
, AT_SYMLINK_FOLLOW
) > 0) {
59 assert_se(path_is_fs_type("/run", TMPFS_MAGIC
) > 0);
60 assert_se(path_is_fs_type("/run", BTRFS_SUPER_MAGIC
) == 0);
62 if (path_is_mount_point("/proc", NULL
, AT_SYMLINK_FOLLOW
) > 0) {
63 assert_se(path_is_fs_type("/proc", PROC_SUPER_MAGIC
) > 0);
64 assert_se(path_is_fs_type("/proc", BTRFS_SUPER_MAGIC
) == 0);
66 assert_se(path_is_fs_type("/i-dont-exist", BTRFS_SUPER_MAGIC
) == -ENOENT
);
69 TEST(path_is_temporary_fs
) {
73 FOREACH_STRING(s
, "/", "/run", "/sys", "/sys/", "/proc", "/i-dont-exist", "/var", "/var/lib") {
74 r
= path_is_temporary_fs(s
);
76 log_info_errno(r
, "path_is_temporary_fs(\"%s\"): %d, %s",
77 s
, r
, r
< 0 ? errno_to_name(r
) : yes_no(r
));
80 /* run might not be a mount point in build chroots */
81 if (path_is_mount_point("/run", NULL
, AT_SYMLINK_FOLLOW
) > 0)
82 assert_se(path_is_temporary_fs("/run") > 0);
83 assert_se(path_is_temporary_fs("/proc") == 0);
84 assert_se(path_is_temporary_fs("/i-dont-exist") == -ENOENT
);
87 TEST(path_is_read_only_fs
) {
91 FOREACH_STRING(s
, "/", "/run", "/sys", "/sys/", "/proc", "/i-dont-exist", "/var", "/var/lib") {
92 r
= path_is_read_only_fs(s
);
94 log_info_errno(r
, "path_is_read_only_fs(\"%s\"): %d, %s",
95 s
, r
, r
< 0 ? errno_to_name(r
) : yes_no(r
));
98 if (path_is_mount_point("/sys", NULL
, AT_SYMLINK_FOLLOW
) > 0)
99 assert_se(IN_SET(path_is_read_only_fs("/sys"), 0, 1));
101 assert_se(path_is_read_only_fs("/proc") == 0);
102 assert_se(path_is_read_only_fs("/i-dont-exist") == -ENOENT
);
106 _cleanup_close_
int fd
= -1;
108 assert_se(fd_is_ns(STDIN_FILENO
, CLONE_NEWNET
) == 0);
109 assert_se(fd_is_ns(STDERR_FILENO
, CLONE_NEWNET
) == 0);
110 assert_se(fd_is_ns(STDOUT_FILENO
, CLONE_NEWNET
) == 0);
112 fd
= open("/proc/self/ns/mnt", O_CLOEXEC
|O_RDONLY
);
114 assert_se(errno
== ENOENT
);
115 log_notice("Path %s not found, skipping test", "/proc/self/ns/mnt");
119 assert_se(IN_SET(fd_is_ns(fd
, CLONE_NEWNET
), 0, -EUCLEAN
));
122 assert_se((fd
= open("/proc/self/ns/ipc", O_CLOEXEC
|O_RDONLY
)) >= 0);
123 assert_se(IN_SET(fd_is_ns(fd
, CLONE_NEWIPC
), 1, -EUCLEAN
));
126 assert_se((fd
= open("/proc/self/ns/net", O_CLOEXEC
|O_RDONLY
)) >= 0);
127 assert_se(IN_SET(fd_is_ns(fd
, CLONE_NEWNET
), 1, -EUCLEAN
));
130 TEST(device_major_minor_valid
) {
131 /* on glibc dev_t is 64bit, even though in the kernel it is only 32bit */
132 assert_cc(sizeof(dev_t
) == sizeof(uint64_t));
134 assert_se(DEVICE_MAJOR_VALID(0U));
135 assert_se(DEVICE_MINOR_VALID(0U));
137 assert_se(DEVICE_MAJOR_VALID(1U));
138 assert_se(DEVICE_MINOR_VALID(1U));
140 assert_se(!DEVICE_MAJOR_VALID(-1U));
141 assert_se(!DEVICE_MINOR_VALID(-1U));
143 assert_se(DEVICE_MAJOR_VALID(1U << 10));
144 assert_se(DEVICE_MINOR_VALID(1U << 10));
146 assert_se(DEVICE_MAJOR_VALID((1U << 12) - 1));
147 assert_se(DEVICE_MINOR_VALID((1U << 20) - 1));
149 assert_se(!DEVICE_MAJOR_VALID((1U << 12)));
150 assert_se(!DEVICE_MINOR_VALID((1U << 20)));
152 assert_se(!DEVICE_MAJOR_VALID(1U << 25));
153 assert_se(!DEVICE_MINOR_VALID(1U << 25));
155 assert_se(!DEVICE_MAJOR_VALID(UINT32_MAX
));
156 assert_se(!DEVICE_MINOR_VALID(UINT32_MAX
));
158 assert_se(!DEVICE_MAJOR_VALID(UINT64_MAX
));
159 assert_se(!DEVICE_MINOR_VALID(UINT64_MAX
));
161 assert_se(DEVICE_MAJOR_VALID(major(0)));
162 assert_se(DEVICE_MINOR_VALID(minor(0)));
165 static void test_device_path_make_canonical_one(const char *path
) {
166 _cleanup_free_
char *resolved
= NULL
, *raw
= NULL
;
172 log_debug("> %s", path
);
174 if (stat(path
, &st
) < 0) {
175 assert_se(errno
== ENOENT
);
176 log_notice("Path %s not found, skipping test", path
);
180 r
= device_path_make_canonical(st
.st_mode
, st
.st_rdev
, &resolved
);
182 /* maybe /dev/char/x:y and /dev/block/x:y are missing in this test environment, because we
183 * run in a container or so? */
184 log_notice("Device %s cannot be resolved, skipping test", path
);
189 assert_se(path_equal(path
, resolved
));
191 assert_se(device_path_make_major_minor(st
.st_mode
, st
.st_rdev
, &raw
) >= 0);
192 assert_se(device_path_parse_major_minor(raw
, &mode
, &devno
) >= 0);
194 assert_se(st
.st_rdev
== devno
);
195 assert_se((st
.st_mode
& S_IFMT
) == (mode
& S_IFMT
));
198 TEST(device_path_make_canonical
) {
199 test_device_path_make_canonical_one("/dev/null");
200 test_device_path_make_canonical_one("/dev/zero");
201 test_device_path_make_canonical_one("/dev/full");
202 test_device_path_make_canonical_one("/dev/random");
203 test_device_path_make_canonical_one("/dev/urandom");
204 test_device_path_make_canonical_one("/dev/tty");
206 if (is_device_node("/run/systemd/inaccessible/blk") > 0) {
207 test_device_path_make_canonical_one("/run/systemd/inaccessible/chr");
208 test_device_path_make_canonical_one("/run/systemd/inaccessible/blk");
213 _cleanup_(rm_rf_physical_and_freep
) char *empty_dir
= NULL
;
214 _cleanup_free_
char *j
= NULL
, *jj
= NULL
;
216 assert_se(dir_is_empty_at(AT_FDCWD
, "/proc") == 0);
217 assert_se(dir_is_empty_at(AT_FDCWD
, "/icertainlydontexistdoi") == -ENOENT
);
219 assert_se(mkdtemp_malloc("/tmp/emptyXXXXXX", &empty_dir
) >= 0);
220 assert_se(dir_is_empty_at(AT_FDCWD
, empty_dir
) > 0);
222 j
= path_join(empty_dir
, "zzz");
224 assert_se(touch(j
) >= 0);
226 assert_se(dir_is_empty_at(AT_FDCWD
, empty_dir
) == 0);
228 jj
= path_join(empty_dir
, "ppp");
230 assert_se(touch(jj
) >= 0);
232 assert_se(dir_is_empty_at(AT_FDCWD
, empty_dir
) == 0);
233 assert_se(unlink(j
) >= 0);
234 assert_se(dir_is_empty_at(AT_FDCWD
, empty_dir
) == 0);
235 assert_se(unlink(jj
) >= 0);
236 assert_se(dir_is_empty_at(AT_FDCWD
, empty_dir
) > 0);
239 DEFINE_CUSTOM_TEST_MAIN(LOG_INFO
, log_show_color(true), /* no outro */);