3
* This file has no copyright assigned and is placed in the Public Domain.
4
* This file is a part of the mingw-runtime package.
5
* No warranty is given; refer to the file DISCLAIMER within the package.
7
* Derived from DIRLIB.C by Matt J. Weinstein
8
* This note appears in the DIRLIB.H
9
* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
11
* Updated by Jeremy Bettis <jeremy@hksys.com>
12
* Significantly revised and rewinddir, seekdir and telldir added by Colin
13
* Peters <colin@fu.is.saga-u.ac.jp>
24
#define WIN32_LEAN_AND_MEAN
25
#include <windows.h> /* for GetFileAttributes */
30
#define _tdirent _wdirent
32
#define _topendir _wopendir
33
#define _tclosedir _wclosedir
34
#define _treaddir _wreaddir
35
#define _trewinddir _wrewinddir
36
#define _ttelldir _wtelldir
37
#define _tseekdir _wseekdir
39
#define _tdirent dirent
41
#define _topendir opendir
42
#define _tclosedir closedir
43
#define _treaddir readdir
44
#define _trewinddir rewinddir
45
#define _ttelldir telldir
46
#define _tseekdir seekdir
49
#define SUFFIX _T("*")
50
#define SLASH _T("\\")
56
* Returns a pointer to a DIR structure appropriately filled in to begin
57
* searching a directory.
60
_topendir (const _TCHAR *szPath)
64
_TCHAR szFullPath[MAX_PATH];
74
if (szPath[0] == _T('\0'))
80
/* Attempt to determine if the given path really is a directory. */
81
rc = GetFileAttributes (szPath);
82
if (rc == (unsigned int)-1)
84
/* call GetLastError for more error info */
88
if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
90
/* Error, entry exists but not a directory. */
95
/* Make an absolute pathname. */
96
_tfullpath (szFullPath, szPath, MAX_PATH);
98
/* Allocate enough space to store DIR structure and the complete
99
* directory path given. */
100
nd = (_TDIR *) malloc (sizeof (_TDIR) + (_tcslen(szFullPath) + _tcslen (SLASH) +
101
_tcslen(SUFFIX) + 1) * sizeof(_TCHAR));
105
/* Error, out of memory. */
110
/* Create the search expression. */
111
_tcscpy (nd->dd_name, szFullPath);
113
/* Add on a slash if the path does not end with one. */
114
if (nd->dd_name[0] != _T('\0') &&
115
nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('/') &&
116
nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('\\'))
118
_tcscat (nd->dd_name, SLASH);
121
/* Add on the search pattern */
122
_tcscat (nd->dd_name, SUFFIX);
124
/* Initialize handle to -1 so that a premature closedir doesn't try
125
* to call _findclose on it. */
128
/* Initialize the status. */
131
/* Initialize the dirent structure. ino and reclen are invalid under
132
* Win32, and name simply points at the appropriate part of the
133
* findfirst_t structure. */
134
nd->dd_dir.d_ino = 0;
135
nd->dd_dir.d_reclen = 0;
136
nd->dd_dir.d_namlen = 0;
137
memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
146
* Return a pointer to a dirent structure filled with the information on the
147
* next entry in the directory.
150
_treaddir (_TDIR * dirp)
154
/* Check for valid DIR struct. */
158
return (struct _tdirent *) 0;
161
if (dirp->dd_stat < 0)
163
/* We have already returned all files in the directory
164
* (or the structure has an invalid dd_stat). */
165
return (struct _tdirent *) 0;
167
else if (dirp->dd_stat == 0)
169
/* We haven't started the search yet. */
170
/* Start the search */
171
dirp->dd_handle = _tfindfirst (dirp->dd_name, &(dirp->dd_dta));
173
if (dirp->dd_handle == -1)
175
/* Whoops! Seems there are no files in that
186
/* Get the next search entry. */
187
if (_tfindnext (dirp->dd_handle, &(dirp->dd_dta)))
189
/* We are off the end or otherwise error.
190
_findnext sets errno to ENOENT if no more file
192
DWORD winerr = GetLastError();
193
if (winerr == ERROR_NO_MORE_FILES)
195
_findclose (dirp->dd_handle);
196
dirp->dd_handle = -1;
201
/* Update the status to indicate the correct
207
if (dirp->dd_stat > 0)
209
/* Successfully got an entry. Everything about the file is
210
* already appropriately filled in except the length of the
212
dirp->dd_dir.d_namlen = _tcslen (dirp->dd_dta.name);
213
_tcscpy (dirp->dd_dir.d_name, dirp->dd_dta.name);
214
return &dirp->dd_dir;
217
return (struct _tdirent *) 0;
224
* Frees up resources allocated by opendir.
227
_tclosedir (_TDIR * dirp)
240
if (dirp->dd_handle != -1)
242
rc = _findclose (dirp->dd_handle);
245
/* Delete the dir structure. */
254
* Return to the beginning of the directory "stream". We simply call findclose
255
* and then reset things like an opendir.
258
_trewinddir (_TDIR * dirp)
268
if (dirp->dd_handle != -1)
270
_findclose (dirp->dd_handle);
273
dirp->dd_handle = -1;
280
* Returns the "position" in the "directory stream" which can be used with
281
* seekdir to go back to an old entry. We simply return the value in stat.
284
_ttelldir (_TDIR * dirp)
293
return dirp->dd_stat;
299
* Seek to an entry previously returned by telldir. We rewind the directory
300
* and call readdir repeatedly until either dd_stat is the position number
301
* or -1 (off the end). This is not perfect, in that the directory may
302
* have changed while we weren't looking. But that is probably the case with
306
_tseekdir (_TDIR * dirp, long lPos)
318
/* Seeking to an invalid position. */
325
if (dirp->dd_handle != -1)
327
_findclose (dirp->dd_handle);
329
dirp->dd_handle = -1;
334
/* Rewind and read forward to the appropriate index. */
337
while ((dirp->dd_stat < lPos) && _treaddir (dirp))
3
* This file has no copyright assigned and is placed in the Public Domain.
4
* This file is a part of the mingw-runtime package.
5
* No warranty is given; refer to the file DISCLAIMER within the package.
7
* Derived from DIRLIB.C by Matt J. Weinstein
8
* This note appears in the DIRLIB.H
9
* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
11
* Updated by Jeremy Bettis <jeremy@hksys.com>
12
* Significantly revised and rewinddir, seekdir and telldir added by Colin
13
* Peters <colin@fu.is.saga-u.ac.jp>
25
#define WIN32_LEAN_AND_MEAN
26
#include <windows.h> /* for GetFileAttributes */
31
#define _tdirent _wdirent
33
#define _topendir _wopendir
34
#define _tclosedir _wclosedir
35
#define _treaddir _wreaddir
36
#define _trewinddir _wrewinddir
37
#define _ttelldir _wtelldir
38
#define _tseekdir _wseekdir
40
#define _tdirent dirent
42
#define _topendir opendir
43
#define _tclosedir closedir
44
#define _treaddir readdir
45
#define _trewinddir rewinddir
46
#define _ttelldir telldir
47
#define _tseekdir seekdir
50
#define SUFFIX _T("*")
51
#define SLASH _T("\\")
57
* Returns a pointer to a DIR structure appropriately filled in to begin
58
* searching a directory.
61
_topendir (const _TCHAR *szPath)
65
_TCHAR szFullPath[MAX_PATH];
75
if (szPath[0] == _T('\0'))
81
/* Attempt to determine if the given path really is a directory. */
82
rc = GetFileAttributes (szPath);
83
if (rc == (unsigned int)-1)
85
/* call GetLastError for more error info */
89
if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
91
/* Error, entry exists but not a directory. */
96
/* Make an absolute pathname. */
97
_tfullpath (szFullPath, szPath, MAX_PATH);
99
/* Allocate enough space to store DIR structure and the complete
100
* directory path given. */
101
nd = (_TDIR *) malloc (sizeof (_TDIR) + (_tcslen(szFullPath) + _tcslen (SLASH) +
102
_tcslen(SUFFIX) + 1) * sizeof(_TCHAR));
106
/* Error, out of memory. */
111
/* Create the search expression. */
112
_tcscpy (nd->dd_name, szFullPath);
114
/* Add on a slash if the path does not end with one. */
115
if (nd->dd_name[0] != _T('\0') &&
116
nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('/') &&
117
nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('\\'))
119
_tcscat (nd->dd_name, SLASH);
122
/* Add on the search pattern */
123
_tcscat (nd->dd_name, SUFFIX);
125
/* Initialize handle to -1 so that a premature closedir doesn't try
126
* to call _findclose on it. */
129
/* Initialize the status. */
132
/* Initialize the dirent structure. ino and reclen are invalid under
133
* Win32, and name simply points at the appropriate part of the
134
* findfirst_t structure. */
135
nd->dd_dir.d_ino = 0;
136
nd->dd_dir.d_reclen = 0;
137
nd->dd_dir.d_namlen = 0;
138
memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
147
* Return a pointer to a dirent structure filled with the information on the
148
* next entry in the directory.
151
_treaddir (_TDIR * dirp)
155
/* Check for valid DIR struct. */
159
return (struct _tdirent *) 0;
162
if (dirp->dd_stat < 0)
164
/* We have already returned all files in the directory
165
* (or the structure has an invalid dd_stat). */
166
return (struct _tdirent *) 0;
168
else if (dirp->dd_stat == 0)
170
/* We haven't started the search yet. */
171
/* Start the search */
172
dirp->dd_handle = _tfindfirst (dirp->dd_name, &(dirp->dd_dta));
174
if (dirp->dd_handle == -1)
176
/* Whoops! Seems there are no files in that
187
/* Get the next search entry. */
188
if (_tfindnext (dirp->dd_handle, &(dirp->dd_dta)))
190
/* We are off the end or otherwise error.
191
_findnext sets errno to ENOENT if no more file
193
DWORD winerr = GetLastError();
194
if (winerr == ERROR_NO_MORE_FILES)
196
_findclose (dirp->dd_handle);
197
dirp->dd_handle = -1;
202
/* Update the status to indicate the correct
208
if (dirp->dd_stat > 0)
210
/* Successfully got an entry. Everything about the file is
211
* already appropriately filled in except the length of the
213
dirp->dd_dir.d_namlen = _tcslen (dirp->dd_dta.name);
214
_tcscpy (dirp->dd_dir.d_name, dirp->dd_dta.name);
215
return &dirp->dd_dir;
218
return (struct _tdirent *) 0;
225
* Frees up resources allocated by opendir.
228
_tclosedir (_TDIR * dirp)
241
if (dirp->dd_handle != -1)
243
rc = _findclose (dirp->dd_handle);
246
/* Delete the dir structure. */
255
* Return to the beginning of the directory "stream". We simply call findclose
256
* and then reset things like an opendir.
259
_trewinddir (_TDIR * dirp)
269
if (dirp->dd_handle != -1)
271
_findclose (dirp->dd_handle);
274
dirp->dd_handle = -1;
281
* Returns the "position" in the "directory stream" which can be used with
282
* seekdir to go back to an old entry. We simply return the value in stat.
285
_ttelldir (_TDIR * dirp)
294
return dirp->dd_stat;
300
* Seek to an entry previously returned by telldir. We rewind the directory
301
* and call readdir repeatedly until either dd_stat is the position number
302
* or -1 (off the end). This is not perfect, in that the directory may
303
* have changed while we weren't looking. But that is probably the case with
307
_tseekdir (_TDIR * dirp, long lPos)
319
/* Seeking to an invalid position. */
326
if (dirp->dd_handle != -1)
328
_findclose (dirp->dd_handle);
330
dirp->dd_handle = -1;
335
/* Rewind and read forward to the appropriate index. */
338
while ((dirp->dd_stat < lPos) && _treaddir (dirp))