]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-dirent-util.c
Added a test file for the dirent-util.c
[thirdparty/systemd.git] / src / test / test-dirent-util.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <dirent.h>
4 #include <fcntl.h>
5 #include <stdio.h>
6 #include <sys/stat.h>
7
8 #include "alloc-util.h"
9 #include "dirent-util.h"
10 #include "fs-util.h"
11 #include "mkdir.h"
12 #include "path-util.h"
13 #include "rm-rf.h"
14 #include "stat-util.h"
15 #include "string-util.h"
16 #include "tmpfile-util.h"
17 #include "tests.h"
18
19 TEST (test_dirent_ensure_type) {
20 int r, dir_fd;
21 static struct dirent de = {
22 .d_type = DT_UNKNOWN,
23 .d_name = "test",
24 };
25
26 assert_se(de.d_type == DT_UNKNOWN);
27
28 dir_fd = 0;
29 dirent_ensure_type(dir_fd, &de);
30
31 /* Test when d_name is "." or ".." */
32 strcpy(de.d_name, ".");
33 r = dirent_ensure_type(dir_fd, &de);
34 assert_se(r == 0);
35 assert_se(de.d_type == DT_DIR);
36
37 strcpy(de.d_name, "..");
38 r = dirent_ensure_type(dir_fd, &de);
39 assert_se(r == 0);
40 assert_se(de.d_type == DT_DIR);
41 }
42
43 TEST (test_dirent_is_file) {
44 _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
45 const char *name, *dotfile, *name_alias, *bakfile, *tilda;
46 const struct dirent *de_reg, *de_lnk, *de_dot, *de_bak, *de_tilda;
47 DIR *dir;
48
49 static const struct dirent de_unknown = {
50 .d_type = DT_UNKNOWN,
51 .d_name = "test_unknown",
52 };
53
54 assert_se(mkdtemp_malloc(NULL, &t) >= 0);
55
56 name = strjoina(t, "/test.txt");
57 dotfile = strjoina(t, "/.hidden_file");
58 bakfile = strjoina(t, "/test.bak");
59 tilda = strjoina(t, "/test~");
60 name_alias = strjoina(t, "/test_link");
61
62 assert_se(touch(name) >= 0);
63 assert_se(touch(dotfile) >= 0);
64 assert_se(touch(bakfile) >= 0);
65 assert_se(touch(tilda) >= 0);
66
67 if (symlink(name, name_alias) < 0) {
68 assert_se(IN_SET(errno, EINVAL, ENOSYS, ENOTTY, EPERM));
69 log_tests_skipped_errno(errno, "symlink() not possible");
70 }
71
72 dir = opendir(t);
73 if (dir == NULL) {
74 log_error_errno(errno, "Failed to open directory '%s': %m", t);
75 exit(EXIT_FAILURE);
76 }
77
78 rewinddir(dir);
79 while ((de_reg = readdir_ensure_type(dir)) != NULL)
80 if (strcmp(de_reg->d_name, "test.txt") == 0)
81 break;
82
83 rewinddir(dir);
84 while ((de_lnk = readdir_ensure_type(dir)) != NULL)
85 if (strcmp(de_lnk->d_name, "test_link") == 0)
86 break;
87
88 rewinddir(dir);
89 while ((de_dot = readdir_ensure_type(dir)) != NULL)
90 if (strcmp(de_dot->d_name, ".hidden_file") == 0)
91 break;
92
93 rewinddir(dir);
94 while ((de_bak = readdir(dir)) != NULL)
95 if (strcmp(de_bak->d_name, "test.bak") == 0)
96 break;
97
98 rewinddir(dir);
99 while ((de_tilda = readdir(dir)) != NULL)
100 if (strcmp(de_tilda->d_name, "test~") == 0)
101 break;
102
103 /* Test when d_type is DT_REG, DT_LNK, or DT_UNKNOWN */
104 assert_se(dirent_is_file(de_reg) == true);
105 if (de_lnk)
106 assert_se(dirent_is_file(de_lnk) == true);
107 else
108 log_tests_skipped("de_lnk is NULL, skipping test");
109 assert_se(dirent_is_file(&de_unknown) == true);
110
111 /* Test for hidden files */
112 assert_se(dirent_is_file(de_dot) == false);
113 assert_se(dirent_is_file(de_bak) == false);
114 assert_se(dirent_is_file(de_tilda) == false);
115
116 closedir(dir);
117 }
118
119 TEST (test_dirent_is_file_with_suffix) {
120 _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
121 const char *name, *dotfile, *name_alias, *dotdot, *chr;
122 const struct dirent *de_reg, *de_lnk, *de_dot, *de_dotdot, *de_chr;
123 DIR *dir;
124
125 static const struct dirent de_unknown = {
126 .d_type = DT_UNKNOWN,
127 .d_name = "test_unknown",
128 };
129
130 assert_se(mkdtemp_malloc(NULL, &t) >= 0);
131
132 name = strjoina(t, "/test.txt");
133 dotfile = strjoina(t, "/.hidden_file");
134 dotdot = strjoina(t, "/..dotdot");
135 chr = strjoina(t, "/test_chr");
136 name_alias = strjoina(t, "/test_link");
137
138 assert_se(touch(name) >= 0);
139 assert_se(touch(dotfile) >= 0);
140 assert_se(touch(dotdot) >= 0);
141 assert_se(mknod(chr, 0775 | S_IFCHR, makedev(0, 0)) >= 0);
142
143 if (symlink(name, name_alias) < 0) {
144 assert_se(IN_SET(errno, EINVAL, ENOSYS, ENOTTY, EPERM));
145 log_tests_skipped_errno(errno, "symlink() not possible");
146 }
147
148 dir = opendir(t);
149 if (dir == NULL) {
150 log_error_errno(errno, "Failed to open directory '%s': %m", t);
151 exit(EXIT_FAILURE);
152 }
153
154 rewinddir(dir);
155 while ((de_reg = readdir_ensure_type(dir)) != NULL)
156 if (strcmp(de_reg->d_name, "test.txt") == 0)
157 break;
158
159 rewinddir(dir);
160 while ((de_lnk = readdir_ensure_type(dir)) != NULL)
161 if (strcmp(de_lnk->d_name, "test_link") == 0)
162 break;
163
164 rewinddir(dir);
165 while ((de_dot = readdir_ensure_type(dir)) != NULL)
166 if (strcmp(de_dot->d_name, ".hidden_file") == 0)
167 break;
168
169 rewinddir(dir);
170 while ((de_dotdot = readdir(dir)) != NULL)
171 if (strcmp(de_dotdot->d_name, "..dotdot") == 0)
172 break;
173
174 rewinddir(dir);
175 while ((de_chr = readdir(dir)) != NULL)
176 if (strcmp(de_chr->d_name, "test_chr") == 0)
177 break;
178
179 /* Test when d_type is not DT_REG, DT_LNK, or DT_UNKNOWN */
180 assert_se(!dirent_is_file_with_suffix(de_chr, NULL));
181
182 /* Test when suffix is NULL */
183 assert_se(dirent_is_file_with_suffix(de_reg, NULL) == true);
184 if (de_lnk)
185 assert_se(dirent_is_file_with_suffix(de_lnk, NULL) == true);
186 else
187 log_tests_skipped("de_lnk is NULL, skipping test");
188 assert_se(dirent_is_file_with_suffix(&de_unknown, NULL) == true);
189
190 /* Test for present suffix */
191 assert_se(dirent_is_file_with_suffix(de_reg, "txt") == true);
192 if (de_lnk)
193 assert_se(dirent_is_file_with_suffix(de_lnk, "link") == true);
194 else
195 log_tests_skipped("de_lnk is NULL, skipping test");
196 assert_se(dirent_is_file_with_suffix(&de_unknown, "unknown") == true);
197
198 /* Test for absent suffix */
199 assert_se(dirent_is_file_with_suffix(de_reg, "svg") == false);
200 if (de_lnk)
201 assert_se(dirent_is_file_with_suffix(de_lnk, "pdf") == false);
202 else
203 log_tests_skipped("de_lnk is NULL, skipping test");
204 assert_se(dirent_is_file_with_suffix(&de_unknown, "yes") == false);
205
206 /* Test for dot and dot-dot */
207 assert_se(dirent_is_file_with_suffix(de_dot, NULL) == false);
208 assert_se(dirent_is_file_with_suffix(de_dotdot, NULL) == false);
209
210 closedir(dir);
211 }
212
213 DEFINE_TEST_MAIN(LOG_INFO);