2832b923b821436ec7ca0614ee21562f703e1852
4 * Derived from DIRLIB.C by Matt J. Weinstein
5 * This note appears in the DIRLIB.H
6 * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
8 * Updated by Jeremy Bettis <jeremy@hksys.com>
9 * Significantly revised and rewinddir, seekdir and telldir added by Colin
10 * Peters <colin@fu.is.saga-u.ac.jp>
18 #include <msvcrt/stdlib.h>
19 /* #include <msvcrt/ctype.h> */
20 #include <msvcrt/errno.h>
21 #include <msvcrt/string.h>
22 #include <msvcrt/dir.h>
23 #include <msvcrt/direct.h>
24 #include <msvcrt/sys/stat.h>
26 #include <msvcrt/dirent.h>
30 #define streq(a,b) (strcmp(a,b)==0)
35 * Returns a pointer to a DIR structure appropriately filled in to begin
36 * searching a directory.
39 opendir(const char* szPath
)
52 if (szPath
[0] == '\0')
58 /* Attempt to determine if the given path really is a directory. */
59 if (_stat (szPath
, &statDir
))
61 /* Error, stat should have set an error value. */
65 if (!S_ISDIR(statDir
.st_mode
))
67 /* Error, stat reports not a directory. */
72 /* Allocate enough space to store DIR structure and the complete
73 * directory path given. */
74 nd
= (DIR*) malloc (sizeof(DIR) + strlen(szPath
) + strlen(SLASH
) +
79 /* Error, out of memory. */
84 /* Create the search expression. */
85 strcpy(nd
->dd_name
, szPath
);
87 /* Add on a slash if the path does not end with one. */
88 if (nd
->dd_name
[0] != '\0' &&
89 nd
->dd_name
[strlen(nd
->dd_name
)-1] != '/' &&
90 nd
->dd_name
[strlen(nd
->dd_name
)-1] != '\\')
92 strcat(nd
->dd_name
, SLASH
);
95 /* Add on the search pattern */
96 strcat(nd
->dd_name
, SUFFIX
);
98 /* Initialize handle to -1 so that a premature closedir doesn't try
99 * to call _findclose on it. */
102 /* Initialize the status. */
105 /* Initialize the dirent structure. ino and reclen are invalid under
106 * Win32, and name simply points at the appropriate part of the
107 * findfirst_t structure. */
108 nd
->dd_dir
.d_ino
= 0;
109 nd
->dd_dir
.d_reclen
= 0;
110 nd
->dd_dir
.d_namlen
= 0;
111 nd
->dd_dir
.d_name
= nd
->dd_dta
.name
;
120 * Return a pointer to a dirent structure filled with the information on the
121 * next entry in the directory.
128 /* Check for valid DIR struct. */
132 return (struct dirent
*) 0;
135 if (dirp
->dd_dir
.d_name
!= dirp
->dd_dta
.name
)
137 /* The structure does not seem to be set up correctly. */
139 return (struct dirent
*) 0;
142 if (dirp
->dd_stat
< 0)
144 /* We have already returned all files in the directory
145 * (or the structure has an invalid dd_stat). */
146 return (struct dirent
*) 0;
148 else if (dirp
->dd_stat
== 0)
150 /* We haven't started the search yet. */
151 /* Start the search */
152 dirp
->dd_handle
= _findfirst(dirp
->dd_name
, &(dirp
->dd_dta
));
154 if (dirp
->dd_handle
== -1)
156 /* Whoops! Seems there are no files in that
167 /* Get the next search entry. */
168 if (_findnext(dirp
->dd_handle
, &(dirp
->dd_dta
)))
170 /* We are off the end or otherwise error. */
171 _findclose (dirp
->dd_handle
);
172 dirp
->dd_handle
= -1;
177 /* Update the status to indicate the correct
183 if (dirp
->dd_stat
> 0)
185 /* Successfully got an entry. Everything about the file is
186 * already appropriately filled in except the length of the
188 dirp
->dd_dir
.d_namlen
= strlen(dirp
->dd_dir
.d_name
);
189 return &dirp
->dd_dir
;
192 return (struct dirent
*) 0;
199 * Frees up resources allocated by opendir.
215 if (dirp
->dd_handle
!= -1)
217 rc
= _findclose(dirp
->dd_handle
);
220 /* Delete the dir structure. */
229 * Return to the beginning of the directory "stream". We simply call findclose
230 * and then reset things like an opendir.
233 rewinddir (DIR* dirp
)
243 if (dirp
->dd_handle
!= -1)
245 _findclose(dirp
->dd_handle
);
248 dirp
->dd_handle
= -1;
255 * Returns the "position" in the "directory stream" which can be used with
256 * seekdir to go back to an old entry. We simply return the value in stat.
268 return dirp
->dd_stat
;
274 * Seek to an entry previously returned by telldir. We rewind the directory
275 * and call readdir repeatedly until either dd_stat is the position number
276 * or -1 (off the end). This is not perfect, in that the directory may
277 * have changed while we weren't looking. But that is probably the case with
281 seekdir (DIR* dirp
, long lPos
)
293 /* Seeking to an invalid position. */
300 if (dirp
->dd_handle
!= -1)
302 _findclose (dirp
->dd_handle
);
304 dirp
->dd_handle
= -1;
309 /* Rewind and read forward to the appropriate index. */
312 while ((dirp
->dd_stat
< lPos
) && readdir(dirp
))