1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
8 #include "alloc-util.h"
9 #include "dirent-util.h"
12 #include "path-util.h"
14 #include "stat-util.h"
15 #include "string-util.h"
16 #include "tmpfile-util.h"
19 TEST (test_dirent_ensure_type
) {
21 static struct dirent de
= {
26 assert_se(de
.d_type
== DT_UNKNOWN
);
29 dirent_ensure_type(dir_fd
, &de
);
31 /* Test when d_name is "." or ".." */
32 strcpy(de
.d_name
, ".");
33 r
= dirent_ensure_type(dir_fd
, &de
);
35 assert_se(de
.d_type
== DT_DIR
);
37 strcpy(de
.d_name
, "..");
38 r
= dirent_ensure_type(dir_fd
, &de
);
40 assert_se(de
.d_type
== DT_DIR
);
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
;
49 static const struct dirent de_unknown
= {
51 .d_name
= "test_unknown",
54 assert_se(mkdtemp_malloc(NULL
, &t
) >= 0);
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");
62 assert_se(touch(name
) >= 0);
63 assert_se(touch(dotfile
) >= 0);
64 assert_se(touch(bakfile
) >= 0);
65 assert_se(touch(tilda
) >= 0);
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");
74 log_error_errno(errno
, "Failed to open directory '%s': %m", t
);
79 while ((de_reg
= readdir_ensure_type(dir
)) != NULL
)
80 if (strcmp(de_reg
->d_name
, "test.txt") == 0)
84 while ((de_lnk
= readdir_ensure_type(dir
)) != NULL
)
85 if (strcmp(de_lnk
->d_name
, "test_link") == 0)
89 while ((de_dot
= readdir_ensure_type(dir
)) != NULL
)
90 if (strcmp(de_dot
->d_name
, ".hidden_file") == 0)
94 while ((de_bak
= readdir(dir
)) != NULL
)
95 if (strcmp(de_bak
->d_name
, "test.bak") == 0)
99 while ((de_tilda
= readdir(dir
)) != NULL
)
100 if (strcmp(de_tilda
->d_name
, "test~") == 0)
103 /* Test when d_type is DT_REG, DT_LNK, or DT_UNKNOWN */
104 assert_se(dirent_is_file(de_reg
) == true);
106 assert_se(dirent_is_file(de_lnk
) == true);
108 log_tests_skipped("de_lnk is NULL, skipping test");
109 assert_se(dirent_is_file(&de_unknown
) == true);
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);
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
;
125 static const struct dirent de_unknown
= {
126 .d_type
= DT_UNKNOWN
,
127 .d_name
= "test_unknown",
130 assert_se(mkdtemp_malloc(NULL
, &t
) >= 0);
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");
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);
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");
150 log_error_errno(errno
, "Failed to open directory '%s': %m", t
);
155 while ((de_reg
= readdir_ensure_type(dir
)) != NULL
)
156 if (strcmp(de_reg
->d_name
, "test.txt") == 0)
160 while ((de_lnk
= readdir_ensure_type(dir
)) != NULL
)
161 if (strcmp(de_lnk
->d_name
, "test_link") == 0)
165 while ((de_dot
= readdir_ensure_type(dir
)) != NULL
)
166 if (strcmp(de_dot
->d_name
, ".hidden_file") == 0)
170 while ((de_dotdot
= readdir(dir
)) != NULL
)
171 if (strcmp(de_dotdot
->d_name
, "..dotdot") == 0)
175 while ((de_chr
= readdir(dir
)) != NULL
)
176 if (strcmp(de_chr
->d_name
, "test_chr") == 0)
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
));
182 /* Test when suffix is NULL */
183 assert_se(dirent_is_file_with_suffix(de_reg
, NULL
) == true);
185 assert_se(dirent_is_file_with_suffix(de_lnk
, NULL
) == true);
187 log_tests_skipped("de_lnk is NULL, skipping test");
188 assert_se(dirent_is_file_with_suffix(&de_unknown
, NULL
) == true);
190 /* Test for present suffix */
191 assert_se(dirent_is_file_with_suffix(de_reg
, "txt") == true);
193 assert_se(dirent_is_file_with_suffix(de_lnk
, "link") == true);
195 log_tests_skipped("de_lnk is NULL, skipping test");
196 assert_se(dirent_is_file_with_suffix(&de_unknown
, "unknown") == true);
198 /* Test for absent suffix */
199 assert_se(dirent_is_file_with_suffix(de_reg
, "svg") == false);
201 assert_se(dirent_is_file_with_suffix(de_lnk
, "pdf") == false);
203 log_tests_skipped("de_lnk is NULL, skipping test");
204 assert_se(dirent_is_file_with_suffix(&de_unknown
, "yes") == false);
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);
213 DEFINE_TEST_MAIN(LOG_INFO
);