1 /* A GNU-like <dirent.h>.
2 Copyright (C) 2006-2023 Free Software Foundation, Inc.
3
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
8
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17 #ifndef _@GUARD_PREFIX@_DIRENT_H
18
19 #if __GNUC__ >= 3
20 @PRAGMA_SYSTEM_HEADER@
21 #endif
22 @PRAGMA_COLUMNS@
23
24 /* The include_next requires a split double-inclusion guard. */
25 #if @HAVE_DIRENT_H@
26 # @INCLUDE_NEXT@ @NEXT_DIRENT_H@
27 #endif
28
29 #ifndef _@GUARD_PREFIX@_DIRENT_H
30 #define _@GUARD_PREFIX@_DIRENT_H
31
32 /* This file uses _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_MALLOC,
33 _GL_ATTRIBUTE_PURE, GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */
34 #if !_GL_CONFIG_H_INCLUDED
35 #error "Please include config.h first."
36 #endif
37
38 /* Get ino_t. Needed on some systems, including glibc 2.8. */
39 #include <sys/types.h>
40
41 #if !@HAVE_DIRENT_H@
42 /* Define types DIR and 'struct dirent'. */
43 # if !GNULIB_defined_struct_dirent
44 struct dirent
45 {
46 char d_type;
47 char d_name[1];
48 };
49 /* Possible values for 'd_type'. */
50 # define DT_UNKNOWN 0
51 # define DT_FIFO 1 /* FIFO */
52 # define DT_CHR 2 /* character device */
53 # define DT_DIR 4 /* directory */
54 # define DT_BLK 6 /* block device */
55 # define DT_REG 8 /* regular file */
56 # define DT_LNK 10 /* symbolic link */
57 # define DT_SOCK 12 /* socket */
58 # define DT_WHT 14 /* whiteout */
59 # define GNULIB_defined_struct_dirent 1
60 # endif
61 #endif
62
63 #if !@DIR_HAS_FD_MEMBER@
64 # if !GNULIB_defined_DIR
65 /* struct gl_directory is a type with a field 'int fd_to_close'.
66 It is needed for implementing fdopendir(). */
67 struct gl_directory;
68 # if @HAVE_DIRENT_H@
69 # define DIR struct gl_directory
70 # else
71 typedef struct gl_directory DIR;
72 # endif
73 # define GNULIB_defined_DIR 1
74 # endif
75 #endif
76
77 /* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
78 that can be freed by passing them as the Ith argument to the
79 function F. */
80 #ifndef _GL_ATTRIBUTE_DEALLOC
81 # if __GNUC__ >= 11
82 # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
83 # else
84 # define _GL_ATTRIBUTE_DEALLOC(f, i)
85 # endif
86 #endif
87
88 /* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
89 allocated memory. */
90 /* Applies to: functions. */
91 #ifndef _GL_ATTRIBUTE_MALLOC
92 # if __GNUC__ >= 3 || defined __clang__
93 # define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
94 # else
95 # define _GL_ATTRIBUTE_MALLOC
96 # endif
97 #endif
98
99 /* The __attribute__ feature is available in gcc versions 2.5 and later.
100 The attribute __pure__ was added in gcc 2.96. */
101 #ifndef _GL_ATTRIBUTE_PURE
102 # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__
103 # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
104 # else
105 # define _GL_ATTRIBUTE_PURE /* empty */
106 # endif
107 #endif
108
109 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
110
111 /* The definition of _GL_ARG_NONNULL is copied here. */
112
113 /* The definition of _GL_WARN_ON_USE is copied here. */
114
115
116 /* Declare overridden functions. */
117
118 #if @GNULIB_CLOSEDIR@
119 # if @REPLACE_CLOSEDIR@
120 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
121 # undef closedir
122 # define closedir rpl_closedir
123 # define GNULIB_defined_closedir 1
124 # endif
125 _GL_FUNCDECL_RPL (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
126 _GL_CXXALIAS_RPL (closedir, int, (DIR *dirp));
127 # else
128 # if !@HAVE_CLOSEDIR@
129 _GL_FUNCDECL_SYS (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
130 # endif
131 _GL_CXXALIAS_SYS (closedir, int, (DIR *dirp));
132 # endif
133 _GL_CXXALIASWARN (closedir);
134 #elif defined GNULIB_POSIXCHECK
135 # undef closedir
136 # if HAVE_RAW_DECL_CLOSEDIR
137 _GL_WARN_ON_USE (closedir, "closedir is not portable - "
138 "use gnulib module closedir for portability");
139 # endif
140 #endif
141
142 #if @GNULIB_OPENDIR@
143 # if @REPLACE_OPENDIR@
144 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
145 # undef opendir
146 # define opendir rpl_opendir
147 # define GNULIB_defined_opendir 1
148 # endif
149 _GL_FUNCDECL_RPL (opendir, DIR *,
150 (const char *dir_name)
151 _GL_ARG_NONNULL ((1))
152 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
153 _GL_CXXALIAS_RPL (opendir, DIR *, (const char *dir_name));
154 # else
155 # if !@HAVE_OPENDIR@ || __GNUC__ >= 11
156 _GL_FUNCDECL_SYS (opendir, DIR *,
157 (const char *dir_name)
158 _GL_ARG_NONNULL ((1))
159 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
160 # endif
161 _GL_CXXALIAS_SYS (opendir, DIR *, (const char *dir_name));
162 # endif
163 _GL_CXXALIASWARN (opendir);
164 #else
165 # if @GNULIB_CLOSEDIR@ && !GNULIB_defined_DIR && __GNUC__ >= 11 && !defined opendir
166 /* For -Wmismatched-dealloc: Associate opendir with closedir or
167 rpl_closedir. */
168 _GL_FUNCDECL_SYS (opendir, DIR *,
169 (const char *dir_name)
170 _GL_ARG_NONNULL ((1))
171 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
172 # endif
173 # if defined GNULIB_POSIXCHECK
174 # undef opendir
175 # if HAVE_RAW_DECL_OPENDIR
176 _GL_WARN_ON_USE (opendir, "opendir is not portable - "
177 "use gnulib module opendir for portability");
178 # endif
179 # endif
180 #endif
181
182 #if @GNULIB_READDIR@
183 # if @REPLACE_READDIR@
184 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
185 # undef readdir
186 # define readdir rpl_readdir
187 # endif
188 _GL_FUNCDECL_RPL (readdir, struct dirent *, (DIR *dirp) _GL_ARG_NONNULL ((1)));
189 _GL_CXXALIAS_RPL (readdir, struct dirent *, (DIR *dirp));
190 # else
191 # if !@HAVE_READDIR@
192 _GL_FUNCDECL_SYS (readdir, struct dirent *, (DIR *dirp) _GL_ARG_NONNULL ((1)));
193 # endif
194 _GL_CXXALIAS_SYS (readdir, struct dirent *, (DIR *dirp));
195 # endif
196 _GL_CXXALIASWARN (readdir);
197 #elif defined GNULIB_POSIXCHECK
198 # undef readdir
199 # if HAVE_RAW_DECL_READDIR
200 _GL_WARN_ON_USE (readdir, "readdir is not portable - "
201 "use gnulib module readdir for portability");
202 # endif
203 #endif
204
205 #if @GNULIB_REWINDDIR@
206 # if @REPLACE_REWINDDIR@
207 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
208 # undef rewinddir
209 # define rewinddir rpl_rewinddir
210 # endif
211 _GL_FUNCDECL_RPL (rewinddir, void, (DIR *dirp) _GL_ARG_NONNULL ((1)));
212 _GL_CXXALIAS_RPL (rewinddir, void, (DIR *dirp));
213 # else
214 # if !@HAVE_REWINDDIR@
215 _GL_FUNCDECL_SYS (rewinddir, void, (DIR *dirp) _GL_ARG_NONNULL ((1)));
216 # endif
217 _GL_CXXALIAS_SYS (rewinddir, void, (DIR *dirp));
218 # endif
219 _GL_CXXALIASWARN (rewinddir);
220 #elif defined GNULIB_POSIXCHECK
221 # undef rewinddir
222 # if HAVE_RAW_DECL_REWINDDIR
223 _GL_WARN_ON_USE (rewinddir, "rewinddir is not portable - "
224 "use gnulib module rewinddir for portability");
225 # endif
226 #endif
227
228 #if @GNULIB_DIRFD@
229 /* Return the file descriptor associated with the given directory stream,
230 or -1 if none exists. */
231 # if @REPLACE_DIRFD@
232 /* On kLIBC, dirfd() is a macro that does not work. Undefine it. */
233 # if !(defined __cplusplus && defined GNULIB_NAMESPACE) || defined dirfd
234 # undef dirfd
235 # define dirfd rpl_dirfd
236 # endif
237 _GL_FUNCDECL_RPL (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1)));
238 _GL_CXXALIAS_RPL (dirfd, int, (DIR *));
239
240 # ifdef __KLIBC__
241 /* Gnulib internal hooks needed to maintain the dirfd metadata. */
242 _GL_EXTERN_C int _gl_register_dirp_fd (int fd, DIR *dirp)
243 _GL_ARG_NONNULL ((2));
244 _GL_EXTERN_C void _gl_unregister_dirp_fd (int fd);
245 # endif
246 # else
247 # if defined __cplusplus && defined GNULIB_NAMESPACE && defined dirfd
248 /* dirfd is defined as a macro and not as a function.
249 Turn it into a function and get rid of the macro. */
250 static inline int (dirfd) (DIR *dp) { return dirfd (dp); }
251 # undef dirfd
252 # endif
253 # if !(@HAVE_DECL_DIRFD@ || defined dirfd)
254 _GL_FUNCDECL_SYS (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1)));
255 # endif
256 _GL_CXXALIAS_SYS (dirfd, int, (DIR *));
257 # endif
258 _GL_CXXALIASWARN (dirfd);
259 #elif defined GNULIB_POSIXCHECK
260 # undef dirfd
261 # if HAVE_RAW_DECL_DIRFD
262 _GL_WARN_ON_USE (dirfd, "dirfd is unportable - "
263 "use gnulib module dirfd for portability");
264 # endif
265 #endif
266
267 #if @GNULIB_FDOPENDIR@
268 /* Open a directory stream visiting the given directory file
269 descriptor. Return NULL and set errno if fd is not visiting a
270 directory. On success, this function consumes fd (it will be
271 implicitly closed either by this function or by a subsequent
272 closedir). */
273 # if @REPLACE_FDOPENDIR@
274 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
275 # undef fdopendir
276 # define fdopendir rpl_fdopendir
277 # endif
278 _GL_FUNCDECL_RPL (fdopendir, DIR *,
279 (int fd)
280 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
281 _GL_CXXALIAS_RPL (fdopendir, DIR *, (int fd));
282 # else
283 # if !@HAVE_FDOPENDIR@ || !@HAVE_DECL_FDOPENDIR@ || __GNUC__ >= 11
284 _GL_FUNCDECL_SYS (fdopendir, DIR *,
285 (int fd)
286 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
287 # endif
288 _GL_CXXALIAS_SYS (fdopendir, DIR *, (int fd));
289 # endif
290 _GL_CXXALIASWARN (fdopendir);
291 #else
292 # if @GNULIB_CLOSEDIR@ && __GNUC__ >= 11 && !defined fdopendir
293 /* For -Wmismatched-dealloc: Associate fdopendir with closedir or
294 rpl_closedir. */
295 _GL_FUNCDECL_SYS (fdopendir, DIR *,
296 (int fd)
297 _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1));
298 # endif
299 # if defined GNULIB_POSIXCHECK
300 # undef fdopendir
301 # if HAVE_RAW_DECL_FDOPENDIR
302 _GL_WARN_ON_USE (fdopendir, "fdopendir is unportable - "
303 "use gnulib module fdopendir for portability");
304 # endif
305 # endif
306 #endif
307
308 #if @GNULIB_SCANDIR@
309 /* Scan the directory DIR, calling FILTER on each directory entry.
310 Entries for which FILTER returns nonzero are individually malloc'd,
311 sorted using qsort with CMP, and collected in a malloc'd array in
312 *NAMELIST. Returns the number of entries selected, or -1 on error. */
313 # if !@HAVE_SCANDIR@
314 _GL_FUNCDECL_SYS (scandir, int,
315 (const char *dir, struct dirent ***namelist,
316 int (*filter) (const struct dirent *),
317 int (*cmp) (const struct dirent **, const struct dirent **))
318 _GL_ARG_NONNULL ((1, 2, 4)));
319 # endif
320 /* Need to cast, because on glibc systems, the fourth parameter is
321 int (*cmp) (const void *, const void *). */
322 _GL_CXXALIAS_SYS_CAST (scandir, int,
323 (const char *dir, struct dirent ***namelist,
324 int (*filter) (const struct dirent *),
325 int (*cmp) (const struct dirent **, const struct dirent **)));
326 _GL_CXXALIASWARN (scandir);
327 #elif defined GNULIB_POSIXCHECK
328 # undef scandir
329 # if HAVE_RAW_DECL_SCANDIR
330 _GL_WARN_ON_USE (scandir, "scandir is unportable - "
331 "use gnulib module scandir for portability");
332 # endif
333 #endif
334
335 #if @GNULIB_ALPHASORT@
336 /* Compare two 'struct dirent' entries alphabetically. */
337 # if !@HAVE_ALPHASORT@
338 _GL_FUNCDECL_SYS (alphasort, int,
339 (const struct dirent **, const struct dirent **)
340 _GL_ATTRIBUTE_PURE
341 _GL_ARG_NONNULL ((1, 2)));
342 # endif
343 /* Need to cast, because on glibc systems, the parameters are
344 (const void *, const void *). */
345 _GL_CXXALIAS_SYS_CAST (alphasort, int,
346 (const struct dirent **, const struct dirent **));
347 _GL_CXXALIASWARN (alphasort);
348 #elif defined GNULIB_POSIXCHECK
349 # undef alphasort
350 # if HAVE_RAW_DECL_ALPHASORT
351 _GL_WARN_ON_USE (alphasort, "alphasort is unportable - "
352 "use gnulib module alphasort for portability");
353 # endif
354 #endif
355
356
357 #endif /* _@GUARD_PREFIX@_DIRENT_H */
358 #endif /* _@GUARD_PREFIX@_DIRENT_H */