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
= {
27 assert_se(dirent_ensure_type(dir_fd
, &de
) == -ENOTDIR
);
29 /* Test when d_name is "." or ".." */
30 strcpy(de
.d_name
, ".");
31 r
= dirent_ensure_type(dir_fd
, &de
);
33 assert_se(de
.d_type
== DT_DIR
);
35 strcpy(de
.d_name
, "..");
36 r
= dirent_ensure_type(dir_fd
, &de
);
38 assert_se(de
.d_type
== DT_DIR
);
41 TEST (test_dirent_is_file
) {
42 _cleanup_(rm_rf_physical_and_freep
) char *t
= NULL
;
43 const char *name
, *dotfile
, *name_alias
, *bakfile
, *tilda
;
44 const struct dirent
*de_reg
, *de_lnk
, *de_dot
, *de_bak
, *de_tilda
;
47 static const struct dirent de_unknown
= {
49 .d_name
= "test_unknown",
52 assert_se(mkdtemp_malloc(NULL
, &t
) >= 0);
54 name
= strjoina(t
, "/test.txt");
55 dotfile
= strjoina(t
, "/.hidden_file");
56 bakfile
= strjoina(t
, "/test.bak");
57 tilda
= strjoina(t
, "/test~");
58 name_alias
= strjoina(t
, "/test_link");
60 assert_se(touch(name
) >= 0);
61 assert_se(touch(dotfile
) >= 0);
62 assert_se(touch(bakfile
) >= 0);
63 assert_se(touch(tilda
) >= 0);
65 if (symlink(name
, name_alias
) < 0) {
66 assert_se(IN_SET(errno
, EINVAL
, ENOSYS
, ENOTTY
, EPERM
));
67 log_tests_skipped_errno(errno
, "symlink() not possible");
72 log_error_errno(errno
, "Failed to open directory '%s': %m", t
);
77 while ((de_reg
= readdir_ensure_type(dir
)) != NULL
)
78 if (strcmp(de_reg
->d_name
, "test.txt") == 0)
82 while ((de_lnk
= readdir_ensure_type(dir
)) != NULL
)
83 if (strcmp(de_lnk
->d_name
, "test_link") == 0)
87 while ((de_dot
= readdir_ensure_type(dir
)) != NULL
)
88 if (strcmp(de_dot
->d_name
, ".hidden_file") == 0)
92 while ((de_bak
= readdir(dir
)) != NULL
)
93 if (strcmp(de_bak
->d_name
, "test.bak") == 0)
97 while ((de_tilda
= readdir(dir
)) != NULL
)
98 if (strcmp(de_tilda
->d_name
, "test~") == 0)
101 /* Test when d_type is DT_REG, DT_LNK, or DT_UNKNOWN */
102 assert_se(dirent_is_file(de_reg
) == true);
104 assert_se(dirent_is_file(de_lnk
) == true);
106 log_tests_skipped("de_lnk is NULL, skipping test");
107 assert_se(dirent_is_file(&de_unknown
) == true);
109 /* Test for hidden files */
110 assert_se(dirent_is_file(de_dot
) == false);
111 assert_se(dirent_is_file(de_bak
) == false);
112 assert_se(dirent_is_file(de_tilda
) == false);
117 TEST (test_dirent_is_file_with_suffix
) {
118 _cleanup_(rm_rf_physical_and_freep
) char *t
= NULL
;
119 const char *name
, *dotfile
, *name_alias
, *dotdot
, *chr
;
120 const struct dirent
*de_reg
, *de_lnk
, *de_dot
, *de_dotdot
, *de_chr
;
123 static const struct dirent de_unknown
= {
124 .d_type
= DT_UNKNOWN
,
125 .d_name
= "test_unknown",
128 assert_se(mkdtemp_malloc(NULL
, &t
) >= 0);
130 name
= strjoina(t
, "/test.txt");
131 dotfile
= strjoina(t
, "/.hidden_file");
132 dotdot
= strjoina(t
, "/..dotdot");
133 chr
= strjoina(t
, "/test_chr");
134 name_alias
= strjoina(t
, "/test_link");
136 assert_se(touch(name
) >= 0);
137 assert_se(touch(dotfile
) >= 0);
138 assert_se(touch(dotdot
) >= 0);
139 assert_se(mknod(chr
, 0775 | S_IFCHR
, makedev(0, 0)) >= 0);
141 if (symlink(name
, name_alias
) < 0) {
142 assert_se(IN_SET(errno
, EINVAL
, ENOSYS
, ENOTTY
, EPERM
));
143 log_tests_skipped_errno(errno
, "symlink() not possible");
148 log_error_errno(errno
, "Failed to open directory '%s': %m", t
);
153 while ((de_reg
= readdir_ensure_type(dir
)) != NULL
)
154 if (strcmp(de_reg
->d_name
, "test.txt") == 0)
158 while ((de_lnk
= readdir_ensure_type(dir
)) != NULL
)
159 if (strcmp(de_lnk
->d_name
, "test_link") == 0)
163 while ((de_dot
= readdir_ensure_type(dir
)) != NULL
)
164 if (strcmp(de_dot
->d_name
, ".hidden_file") == 0)
168 while ((de_dotdot
= readdir(dir
)) != NULL
)
169 if (strcmp(de_dotdot
->d_name
, "..dotdot") == 0)
173 while ((de_chr
= readdir(dir
)) != NULL
)
174 if (strcmp(de_chr
->d_name
, "test_chr") == 0)
177 /* Test when d_type is not DT_REG, DT_LNK, or DT_UNKNOWN */
178 assert_se(!dirent_is_file_with_suffix(de_chr
, NULL
));
180 /* Test when suffix is NULL */
181 assert_se(dirent_is_file_with_suffix(de_reg
, NULL
) == true);
183 assert_se(dirent_is_file_with_suffix(de_lnk
, NULL
) == true);
185 log_tests_skipped("de_lnk is NULL, skipping test");
186 assert_se(dirent_is_file_with_suffix(&de_unknown
, NULL
) == true);
188 /* Test for present suffix */
189 assert_se(dirent_is_file_with_suffix(de_reg
, "txt") == true);
191 assert_se(dirent_is_file_with_suffix(de_lnk
, "link") == true);
193 log_tests_skipped("de_lnk is NULL, skipping test");
194 assert_se(dirent_is_file_with_suffix(&de_unknown
, "unknown") == true);
196 /* Test for absent suffix */
197 assert_se(dirent_is_file_with_suffix(de_reg
, "svg") == false);
199 assert_se(dirent_is_file_with_suffix(de_lnk
, "pdf") == false);
201 log_tests_skipped("de_lnk is NULL, skipping test");
202 assert_se(dirent_is_file_with_suffix(&de_unknown
, "yes") == false);
204 /* Test for dot and dot-dot */
205 assert_se(dirent_is_file_with_suffix(de_dot
, NULL
) == false);
206 assert_se(dirent_is_file_with_suffix(de_dotdot
, NULL
) == false);
211 DEFINE_TEST_MAIN(LOG_INFO
);