]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
f4c13ad7 RC |
2 | |
3 | #include <fcntl.h> | |
436e916e | 4 | #include <linux/magic.h> |
f4c13ad7 RC |
5 | #include <unistd.h> |
6 | ||
7 | #include "alloc-util.h" | |
8 | #include "fd-util.h" | |
f4c13ad7 | 9 | #include "macro.h" |
049af8ad | 10 | #include "mountpoint-util.h" |
0cb8e3d1 | 11 | #include "namespace-util.h" |
846b3bd6 | 12 | #include "path-util.h" |
e4de7287 LP |
13 | #include "stat-util.h" |
14 | #include "tmpfile-util.h" | |
f4c13ad7 RC |
15 | |
16 | static void test_files_same(void) { | |
17 | _cleanup_close_ int fd = -1; | |
18 | char name[] = "/tmp/test-files_same.XXXXXX"; | |
19 | char name_alias[] = "/tmp/test-files_same.alias"; | |
20 | ||
646853bd | 21 | fd = mkostemp_safe(name); |
f4c13ad7 RC |
22 | assert_se(fd >= 0); |
23 | assert_se(symlink(name, name_alias) >= 0); | |
24 | ||
e3f791a2 ZJS |
25 | assert_se(files_same(name, name, 0)); |
26 | assert_se(files_same(name, name, AT_SYMLINK_NOFOLLOW)); | |
27 | assert_se(files_same(name, name_alias, 0)); | |
28 | assert_se(!files_same(name, name_alias, AT_SYMLINK_NOFOLLOW)); | |
f4c13ad7 RC |
29 | |
30 | unlink(name); | |
31 | unlink(name_alias); | |
32 | } | |
33 | ||
34 | static void test_is_symlink(void) { | |
35 | char name[] = "/tmp/test-is_symlink.XXXXXX"; | |
36 | char name_link[] = "/tmp/test-is_symlink.link"; | |
37 | _cleanup_close_ int fd = -1; | |
38 | ||
646853bd | 39 | fd = mkostemp_safe(name); |
f4c13ad7 RC |
40 | assert_se(fd >= 0); |
41 | assert_se(symlink(name, name_link) >= 0); | |
42 | ||
43 | assert_se(is_symlink(name) == 0); | |
44 | assert_se(is_symlink(name_link) == 1); | |
45 | assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0); | |
46 | ||
f4c13ad7 RC |
47 | unlink(name); |
48 | unlink(name_link); | |
49 | } | |
50 | ||
40fd52f2 | 51 | static void test_path_is_fs_type(void) { |
cc390161 MP |
52 | /* run might not be a mount point in build chroots */ |
53 | if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0) { | |
40fd52f2 ZJS |
54 | assert_se(path_is_fs_type("/run", TMPFS_MAGIC) > 0); |
55 | assert_se(path_is_fs_type("/run", BTRFS_SUPER_MAGIC) == 0); | |
cc390161 | 56 | } |
40fd52f2 ZJS |
57 | assert_se(path_is_fs_type("/proc", PROC_SUPER_MAGIC) > 0); |
58 | assert_se(path_is_fs_type("/proc", BTRFS_SUPER_MAGIC) == 0); | |
40fd52f2 | 59 | assert_se(path_is_fs_type("/i-dont-exist", BTRFS_SUPER_MAGIC) == -ENOENT); |
436e916e LP |
60 | } |
61 | ||
62 | static void test_path_is_temporary_fs(void) { | |
8dfc2f40 MP |
63 | /* run might not be a mount point in build chroots */ |
64 | if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0) | |
65 | assert_se(path_is_temporary_fs("/run") > 0); | |
436e916e LP |
66 | assert_se(path_is_temporary_fs("/proc") == 0); |
67 | assert_se(path_is_temporary_fs("/i-dont-exist") == -ENOENT); | |
68 | } | |
69 | ||
6619ad88 LP |
70 | static void test_fd_is_network_ns(void) { |
71 | _cleanup_close_ int fd = -1; | |
72 | assert_se(fd_is_network_ns(STDIN_FILENO) == 0); | |
73 | assert_se(fd_is_network_ns(STDERR_FILENO) == 0); | |
74 | assert_se(fd_is_network_ns(STDOUT_FILENO) == 0); | |
75 | ||
76 | assert_se((fd = open("/proc/self/ns/mnt", O_CLOEXEC|O_RDONLY)) >= 0); | |
77 | assert_se(IN_SET(fd_is_network_ns(fd), 0, -EUCLEAN)); | |
78 | fd = safe_close(fd); | |
79 | ||
80 | assert_se((fd = open("/proc/self/ns/net", O_CLOEXEC|O_RDONLY)) >= 0); | |
81 | assert_se(IN_SET(fd_is_network_ns(fd), 1, -EUCLEAN)); | |
82 | } | |
83 | ||
fb2430c6 LP |
84 | static void test_device_major_minor_valid(void) { |
85 | /* on glibc dev_t is 64bit, even though in the kernel it is only 32bit */ | |
86 | assert_cc(sizeof(dev_t) == sizeof(uint64_t)); | |
87 | ||
88 | assert_se(DEVICE_MAJOR_VALID(0U)); | |
89 | assert_se(DEVICE_MINOR_VALID(0U)); | |
90 | ||
91 | assert_se(DEVICE_MAJOR_VALID(1U)); | |
92 | assert_se(DEVICE_MINOR_VALID(1U)); | |
93 | ||
94 | assert_se(!DEVICE_MAJOR_VALID(-1U)); | |
95 | assert_se(!DEVICE_MINOR_VALID(-1U)); | |
96 | ||
97 | assert_se(DEVICE_MAJOR_VALID(1U << 10)); | |
98 | assert_se(DEVICE_MINOR_VALID(1U << 10)); | |
99 | ||
100 | assert_se(DEVICE_MAJOR_VALID((1U << 12) - 1)); | |
101 | assert_se(DEVICE_MINOR_VALID((1U << 20) - 1)); | |
102 | ||
103 | assert_se(!DEVICE_MAJOR_VALID((1U << 12))); | |
104 | assert_se(!DEVICE_MINOR_VALID((1U << 20))); | |
105 | ||
106 | assert_se(!DEVICE_MAJOR_VALID(1U << 25)); | |
107 | assert_se(!DEVICE_MINOR_VALID(1U << 25)); | |
108 | ||
109 | assert_se(!DEVICE_MAJOR_VALID(UINT32_MAX)); | |
110 | assert_se(!DEVICE_MINOR_VALID(UINT32_MAX)); | |
111 | ||
112 | assert_se(!DEVICE_MAJOR_VALID(UINT64_MAX)); | |
113 | assert_se(!DEVICE_MINOR_VALID(UINT64_MAX)); | |
114 | ||
115 | assert_se(DEVICE_MAJOR_VALID(major(0))); | |
116 | assert_se(DEVICE_MINOR_VALID(minor(0))); | |
117 | } | |
118 | ||
846b3bd6 LP |
119 | static void test_device_path_make_canonical_one(const char *path) { |
120 | _cleanup_free_ char *resolved = NULL, *raw = NULL; | |
121 | struct stat st; | |
122 | dev_t devno; | |
123 | mode_t mode; | |
124 | int r; | |
125 | ||
126 | assert_se(stat(path, &st) >= 0); | |
127 | r = device_path_make_canonical(st.st_mode, st.st_rdev, &resolved); | |
128 | if (r == -ENOENT) /* maybe /dev/char/x:y and /dev/block/x:y are missing in this test environment, because we | |
129 | * run in a container or so? */ | |
130 | return; | |
131 | ||
132 | assert_se(r >= 0); | |
133 | assert_se(path_equal(path, resolved)); | |
134 | ||
135 | assert_se(device_path_make_major_minor(st.st_mode, st.st_rdev, &raw) >= 0); | |
136 | assert_se(device_path_parse_major_minor(raw, &mode, &devno) >= 0); | |
137 | ||
138 | assert_se(st.st_rdev == devno); | |
139 | assert_se((st.st_mode & S_IFMT) == (mode & S_IFMT)); | |
140 | } | |
141 | ||
142 | static void test_device_path_make_canonical(void) { | |
143 | ||
144 | test_device_path_make_canonical_one("/dev/null"); | |
145 | test_device_path_make_canonical_one("/dev/zero"); | |
146 | test_device_path_make_canonical_one("/dev/full"); | |
147 | test_device_path_make_canonical_one("/dev/random"); | |
148 | test_device_path_make_canonical_one("/dev/urandom"); | |
149 | test_device_path_make_canonical_one("/dev/tty"); | |
150 | ||
5b5ce629 | 151 | if (is_device_node("/run/systemd/inaccessible/blk") > 0) { |
846b3bd6 LP |
152 | test_device_path_make_canonical_one("/run/systemd/inaccessible/chr"); |
153 | test_device_path_make_canonical_one("/run/systemd/inaccessible/blk"); | |
154 | } | |
155 | } | |
156 | ||
f4c13ad7 RC |
157 | int main(int argc, char *argv[]) { |
158 | test_files_same(); | |
159 | test_is_symlink(); | |
40fd52f2 | 160 | test_path_is_fs_type(); |
436e916e | 161 | test_path_is_temporary_fs(); |
6619ad88 | 162 | test_fd_is_network_ns(); |
fb2430c6 | 163 | test_device_major_minor_valid(); |
846b3bd6 | 164 | test_device_path_make_canonical(); |
f4c13ad7 RC |
165 | |
166 | return 0; | |
167 | } |