2 * dirent.h - operating system independent dirent implementation
4 * Copyright (C) 1998-2002 Toni Ronkko
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * ``Software''), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
26 * Aug 20, 2006, Toni Ronkko
27 * Removed all remarks about MSVC 1.0, which is antiqued now. Simplified
28 * comments by removing SGML tags.
30 * May 14 2002, Toni Ronkko
31 * Embedded the function definitions directly to the header so that no source
32 * modules must be included in the MS Visual C project for using the
33 * interface. Removed all the dependencies to other projects so
34 * that this very header can be used independently.
36 * May 28 1998, Toni Ronkko
41 #define DIRENT_H_INCLUDED
43 /* find out platform */
44 #if defined(MSDOS) /* MS-DOS */
45 #elif defined(__MSDOS__) /* Turbo C/Borland */
47 #elif defined(__DOS__) /* Watcom */
51 #if defined(WIN32) /* MS-Windows */
52 #elif defined(__NT__) /* Watcom */
54 #elif defined(_WIN32) /* Microsoft */
56 #elif defined(__WIN32__) /* Borland */
61 * See what kind of dirent interface we have unless autoconf has already
64 #if !defined(HAVE_DIRENT_H) && !defined(HAVE_DIRECT_H) && !defined(HAVE_SYS_DIR_H) && !defined(HAVE_NDIR_H) && !defined(HAVE_SYS_NDIR_H) && !defined(HAVE_DIR_H)
65 # if defined(_MSC_VER) /* Microsoft C/C++ */
67 # elif defined(__BORLANDC__) /* Borland C/C++ */
68 # define HAVE_DIRENT_H
69 # define VOID_CLOSEDIR
70 # elif defined(__TURBOC__) /* Borland Turbo C */
72 # elif defined(__WATCOMC__) /* Watcom C/C++ */
73 # define HAVE_DIRECT_H
74 # elif defined(__apollo) /* Apollo */
75 # define HAVE_SYS_DIR_H
76 # elif defined(__hpux) /* HP-UX */
77 # define HAVE_DIRENT_H
78 # elif defined(__alpha) || defined(__alpha__) /* Alpha OSF1 */
79 # error "not implemented"
80 # elif defined(__sgi) /* Silicon Graphics */
81 # define HAVE_DIRENT_H
82 # elif defined(sun) || defined(_sun) /* Sun Solaris */
83 # define HAVE_DIRENT_H
84 # elif defined(__FreeBSD__) /* FreeBSD */
85 # define HAVE_DIRENT_H
86 # elif defined(__linux__) /* Linux */
87 # define HAVE_DIRENT_H
88 # elif defined(__GNUC__) /* GNU C/C++ */
89 # define HAVE_DIRENT_H
91 # error "not implemented"
95 /* include proper interface headers */
96 #if defined(HAVE_DIRENT_H)
99 # define NAMLEN(dp) ((int)((dp)->d_namlen))
101 # define NAMLEN(dp) ((int)(strlen((dp)->d_name)))
104 #elif defined(HAVE_NDIR_H)
106 # define NAMLEN(dp) ((int)((dp)->d_namlen))
108 #elif defined(HAVE_SYS_NDIR_H)
109 # include <sys/ndir.h>
110 # define NAMLEN(dp) ((int)((dp)->d_namlen))
112 #elif defined(HAVE_DIRECT_H)
114 # define NAMLEN(dp) ((int)((dp)->d_namlen))
116 #elif defined(HAVE_DIR_H)
118 # define NAMLEN(dp) ((int)((dp)->d_namlen))
120 #elif defined(HAVE_SYS_DIR_H)
121 # include <sys/types.h>
122 # include <sys/dir.h>
124 # define dirent direct
126 # define NAMLEN(dp) ((int)((dp)->d_namlen))
128 #elif defined(MSDOS) || defined(WIN32)
130 /* figure out type of underlaying directory interface to be used */
132 # define DIRENT_WIN32_INTERFACE
133 # elif defined(MSDOS)
134 # define DIRENT_MSDOS_INTERFACE
136 # error "missing native dirent interface"
139 /*** WIN32 specifics ***/
140 # if defined(DIRENT_WIN32_INTERFACE)
141 # include <windows.h>
142 # if !defined(DIRENT_MAXNAMLEN)
143 # define DIRENT_MAXNAMLEN (MAX_PATH)
147 /*** MS-DOS specifics ***/
148 # elif defined(DIRENT_MSDOS_INTERFACE)
151 /* Borland defines file length macros in dir.h */
152 # if defined(__BORLANDC__)
154 # if !defined(DIRENT_MAXNAMLEN)
155 # define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT))
157 # if !defined(_find_t)
158 # define _find_t find_t
161 /* Turbo C defines ffblk structure in dir.h */
162 # elif defined(__TURBOC__)
164 # if !defined(DIRENT_MAXNAMLEN)
165 # define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT))
167 # define DIRENT_USE_FFBLK
170 # elif defined(_MSC_VER)
171 # if !defined(DIRENT_MAXNAMLEN)
172 # define DIRENT_MAXNAMLEN (12)
176 # elif defined(__WATCOMC__)
177 # if !defined(DIRENT_MAXNAMLEN)
178 # if defined(__OS2__) || defined(__NT__)
179 # define DIRENT_MAXNAMLEN (255)
181 # define DIRENT_MAXNAMLEN (12)
188 /*** generic MS-DOS and MS-Windows stuff ***/
189 # if !defined(NAME_MAX) && defined(DIRENT_MAXNAMLEN)
190 # define NAME_MAX DIRENT_MAXNAMLEN
192 # if NAME_MAX < DIRENT_MAXNAMLEN
193 # error "assertion failed: NAME_MAX >= DIRENT_MAXNAMLEN"
198 * Substitute for real dirent structure. Note that d_name field is a
199 * true character array although we have it copied in the implementation
200 * dependent data. We could save some memory if we had declared d_name
201 * as a pointer refering the name within implementation dependent data.
202 * We have not done that since some code may rely on sizeof(d_name) to be
203 * something other than four. Besides, directory entries are typically so
204 * small that it takes virtually no time to copy them from place to place.
206 typedef struct dirent {
207 char d_name[NAME_MAX + 1];
209 /*** Operating system specific part ***/
210 # if defined(DIRENT_WIN32_INTERFACE) /*WIN32*/
211 WIN32_FIND_DATA data;
212 # elif defined(DIRENT_MSDOS_INTERFACE) /*MSDOS*/
213 # if defined(DIRENT_USE_FFBLK)
222 * DIR substitute structure containing directory name. The name is
223 * essential for the operation of rewinndir() function.
226 char *dirname; /* directory being scanned */
227 dirent current; /* current entry */
228 int dirent_filled; /* is current un-processed? */
230 /*** Operating system specific part ***/
231 # if defined(DIRENT_WIN32_INTERFACE)
232 HANDLE search_handle;
233 # elif defined(DIRENT_MSDOS_INTERFACE)
241 /* prototypes of public dirent functions */
242 static DIR *opendir (const char *dirname);
243 static struct dirent *readdir (DIR *dirp);
244 static int closedir (DIR *dirp);
245 static void rewinddir (DIR *dirp);
248 * Implement dirent interface as static functions so that the user does not
249 * need to change his project in any way to use dirent function. With this
250 * it is sufficient to include this very header from source modules using
251 * dirent functions and the functions will be pulled in automatically.
259 /* use ffblk instead of _find_t if requested */
260 #if defined(DIRENT_USE_FFBLK)
261 # define _A_ARCH (FA_ARCH)
262 # define _A_HIDDEN (FA_HIDDEN)
263 # define _A_NORMAL (0)
264 # define _A_RDONLY (FA_RDONLY)
265 # define _A_SUBDIR (FA_DIREC)
266 # define _A_SYSTEM (FA_SYSTEM)
267 # define _A_VOLID (FA_LABEL)
268 # define _dos_findnext(dest) findnext(dest)
269 # define _dos_findfirst(name,flags,dest) findfirst(name,dest,flags)
272 /* internal prototypes */
273 static int _initdir (DIR *p);
274 static const char *_getdirname (const struct dirent *dp);
275 static void _setdirname (struct DIR *dirp);
279 * Open directory stream DIRNAME for read and return pointer to the
280 * internal working area that is used for retrieving individual directory
281 * entries. The internal working area has no fields of your interest.
288 assert (dirname != NULL);
290 dirp = (DIR*)malloc (sizeof (struct DIR));
294 /* allocate room for directory name */
295 dirp->dirname = (char*) malloc (strlen (dirname) + 1 + strlen ("\\*.*"));
296 if (dirp->dirname == NULL) {
297 /* failed to duplicate directory name. errno set by malloc() */
303 * Copy directory name while appending directory separator and "*.*".
304 * Directory separator is not appended if the name already ends with
305 * drive or directory separator. Directory separator is assumed to be
306 * '/' or '\' and drive separator is assumed to be ':'.
308 strcpy (dirp->dirname, dirname);
309 p = strchr (dirp->dirname, '\0');
310 if (dirp->dirname < p &&
311 *(p - 1) != '\\' && *(p - 1) != '/' && *(p - 1) != ':')
315 # ifdef DIRENT_WIN32_INTERFACE
316 strcpy (p, "*"); /*scan files with and without extension in win32*/
318 strcpy (p, "*.*"); /*scan files with and without extension in DOS*/
322 if (_initdir (dirp) == 0) {
323 /* initialization failed */
324 free (dirp->dirname);
335 * Read a directory entry and return pointer to a structure containing the
336 * name of the entry. Individual directory entries returned by this very
337 * function include normal files, sub-directories, pseudo-directories "."
338 * and ".." and also volume labels, hidden files and system files in MS-DOS
339 * and MS-Windows. You might want to use stat(2) function to determinate
340 * which one you are dealing with.
342 * The dirent structure contains several system dependent fields that
343 * generally have no interest to you. The only interesting one is char
344 * d_name[] that is also portable across different systems. The d_name
345 * field contains the name of the directory entry without leading path.
346 * While d_name is portable across different systems, the actual storage
347 * capacity of d_name varies from system to system and there is no portable
348 * way to find out it at compile time. Different systems define the
349 * capacity of d_name with different macros and some systems do not define
350 * capacity at all (besides actual declaration of the field). If you really
351 * need to find out storage capacity of d_name then you might want to try
352 * NAME_MAX macro. The NAME_MAX is defined in POSIX standard althought
353 * there are many MS-DOS and MS-Windows implementations those do not define
354 * it. There are also systems that declare d_name as "char d_name[1]" and
355 * then allocate suitable amount of memory at run-time. Thanks to Alain
356 * Decamps (Alain dot Decamps atsign advalvas dot be) for pointing it out to
359 * This all leads to the fact that it is difficult to allocate space
360 * for the directory names when the very same program is being compiled on
361 * number of operating systems. Therefore I suggest that you always
362 * allocate space for directory names dynamically.
364 static struct dirent *
367 assert (dirp != NULL);
373 #if defined(DIRENT_WIN32_INTERFACE)
374 if (dirp->search_handle == INVALID_HANDLE_VALUE) {
375 /* directory stream was opened/rewound incorrectly or it ended normally */
381 if (dirp->dirent_filled != 0) {
383 * Directory entry has already been retrieved and there is no need to
384 * retrieve a new one. Directory entry will be retrieved in advance
385 * when the user calls readdir function for the first time. This is so
386 * because real dirent has separate functions for opening and reading
387 * the stream whereas Win32 and DOS dirents open the stream
388 * automatically when we retrieve the first file. Therefore, we have to
389 * save the first file when opening the stream and later we have to
390 * return the saved entry when the user tries to read the first entry.
392 dirp->dirent_filled = 0;
394 /* fill in entry and return that */
395 #if defined(DIRENT_WIN32_INTERFACE)
396 if (FindNextFile (dirp->search_handle, &dirp->current.data) == FALSE) {
397 /* Last file has been processed or an error occured */
398 FindClose (dirp->search_handle);
399 dirp->search_handle = INVALID_HANDLE_VALUE;
404 # elif defined(DIRENT_MSDOS_INTERFACE)
405 if (_dos_findnext (&dirp->current.data) != 0) {
406 /* _dos_findnext and findnext will set errno to ENOENT when no
407 * more entries could be retrieved. */
413 assert (dirp->dirent_filled == 0);
415 return &dirp->current;
421 * Close directory stream opened by opendir() function. Close of the
422 * directory stream invalidates the DIR structure as well as any previously
423 * read directory entry.
425 * Usually, the function returns 0 on success and -1 on failure. However,
426 * on some systems, the function has been declared to return void. If you
427 * want to keep your code portable, it may be better to ignore the return
435 /* make sure that dirp points to legal structure */
436 assert (dirp != NULL);
442 /* free directory name */
443 if (dirp->dirname != NULL) {
444 free (dirp->dirname);
447 /* release search handle */
448 #if defined(DIRENT_WIN32_INTERFACE)
449 if (dirp->search_handle != INVALID_HANDLE_VALUE) {
450 if (FindClose (dirp->search_handle) == FALSE) {
458 /* clear dirp structure to make sure that it cannot be used anymore*/
459 memset (dirp, 0, sizeof (*dirp));
460 # if defined(DIRENT_WIN32_INTERFACE)
461 dirp->search_handle = INVALID_HANDLE_VALUE;
471 * Rewind the directory stream to re-read the directory entries. If new
472 * files or directories have been created since opendir(), then also these
473 * new files will be available with readdir().
475 * Almost every dirent implementation ensures that rewinddir() updates its
476 * internal caches to reflect the current directory structure on disk.
477 * However, if you really depend on this feature, it may be better to close
478 * and re-open the directory stream. I recall one particual dirent
479 * interface, where rewinddir() did not update its internal cache.
481 * BUGS: If the current working directory is changed between opendir() and
482 * rewinddir(), then the rewound directory stream may refer a non-existent
483 * directory, or at worst case, to another directory.
486 rewinddir (DIR *dirp)
488 /* make sure that dirp is legal */
489 assert (dirp != NULL);
494 assert (dirp->dirname != NULL);
496 /* close previous stream */
497 #if defined(DIRENT_WIN32_INTERFACE)
498 if (dirp->search_handle != INVALID_HANDLE_VALUE) {
499 if (FindClose (dirp->search_handle) == FALSE) {
506 /* re-open previous stream */
507 if (_initdir (dirp) == 0) {
508 /* initialization failed but we cannot deal with error. User will notice
509 * error later when she tries to retrieve first directory enty. */
517 * Open native directory stream object and retrieve first file.
518 * Be sure to close previous stream before opening new one.
523 assert (dirp != NULL);
524 assert (dirp->dirname != NULL);
525 dirp->dirent_filled = 0;
527 # if defined(DIRENT_WIN32_INTERFACE)
528 /* Open stream and retrieve first file */
529 dirp->search_handle = FindFirstFile (dirp->dirname, &dirp->current.data);
530 if (dirp->search_handle == INVALID_HANDLE_VALUE) {
531 /* something went wrong but we don't know what. GetLastError() could
532 * give us more information about the error, but then we should map
533 * the error code into errno. */
538 # elif defined(DIRENT_MSDOS_INTERFACE)
539 if (_dos_findfirst (dirp->dirname,
540 _A_SUBDIR | _A_RDONLY | _A_ARCH | _A_SYSTEM | _A_HIDDEN,
541 &dirp->current.data) != 0)
543 /* _dos_findfirst and findfirst will set errno to ENOENT when no
544 * more entries could be retrieved. */
549 /* initialize DIR and it's first entry */
551 dirp->dirent_filled = 1;
558 * Return implementation dependent name of the current directory entry.
561 _getdirname (const struct dirent *dp)
563 #if defined(DIRENT_WIN32_INTERFACE)
564 return dp->data.cFileName;
566 #elif defined(DIRENT_USE_FFBLK)
567 return dp->data.ff_name;
570 return dp->data.name;
577 * Copy name of implementation dependent directory entry to the d_name field.
580 _setdirname (struct DIR *dirp) {
581 /* make sure that d_name is long enough */
582 assert (strlen (_getdirname (&dirp->current)) <= NAME_MAX);
584 strncpy (dirp->current.d_name,
585 _getdirname (&dirp->current),
587 dirp->current.d_name[NAME_MAX] = '\0'; /*char d_name[NAME_MAX+1]*/
593 # define NAMLEN(dp) ((int)(strlen((dp)->d_name)))
596 # error "missing dirent interface"