~ubuntu-branches/debian/squeeze/glib2.0/squeeze

« back to all changes in this revision

Viewing changes to build/win32/dirent/dirent.c

  • Committer: Bazaar Package Importer
  • Author(s): Gustavo Noronha Silva
  • Date: 2009-02-15 13:00:43 UTC
  • mfrom: (1.3.1 upstream) (69.1.10 intrepid)
  • Revision ID: james.westby@ubuntu.com-20090215130043-q47fbt3owmt42m2f
Tags: 2.18.4-2
* Release to unstable
* debian/rules:
- bump SHVER, since we are already forcing a 2.18.0 dependecy on the
  symbols introduced in the development versions
* debian/control.in:
- added Homepage and Vcs-* control fields

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * dirent.c
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.
6
 
 *
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
10
 
 *
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>
14
 
 *      
15
 
 */
16
 
 
17
 
#include <stdlib.h>
18
 
#include <errno.h>
19
 
#include <string.h>
20
 
#include <io.h>
21
 
#include <direct.h>
22
 
#include <dirent.h>
23
 
 
24
 
#define WIN32_LEAN_AND_MEAN
25
 
#include <windows.h> /* for GetFileAttributes */
26
 
 
27
 
#include <tchar.h>
28
 
 
29
 
#ifdef _UNICODE
30
 
#define _tdirent        _wdirent
31
 
#define _TDIR           _WDIR
32
 
#define _topendir       _wopendir
33
 
#define _tclosedir      _wclosedir
34
 
#define _treaddir       _wreaddir
35
 
#define _trewinddir     _wrewinddir
36
 
#define _ttelldir       _wtelldir
37
 
#define _tseekdir       _wseekdir
38
 
#else
39
 
#define _tdirent        dirent
40
 
#define _TDIR           DIR
41
 
#define _topendir       opendir
42
 
#define _tclosedir      closedir
43
 
#define _treaddir       readdir
44
 
#define _trewinddir     rewinddir
45
 
#define _ttelldir       telldir
46
 
#define _tseekdir       seekdir
47
 
#endif
48
 
 
49
 
#define SUFFIX  _T("*")
50
 
#define SLASH   _T("\\")
51
 
 
52
 
 
53
 
/*
54
 
 * opendir
55
 
 *
56
 
 * Returns a pointer to a DIR structure appropriately filled in to begin
57
 
 * searching a directory.
58
 
 */
59
 
_TDIR *
60
 
_topendir (const _TCHAR *szPath)
61
 
{
62
 
  _TDIR *nd;
63
 
  unsigned int rc;
64
 
  _TCHAR szFullPath[MAX_PATH];
65
 
        
66
 
  errno = 0;
67
 
 
68
 
  if (!szPath)
69
 
    {
70
 
      errno = EFAULT;
71
 
      return (_TDIR *) 0;
72
 
    }
73
 
 
74
 
  if (szPath[0] == _T('\0'))
75
 
    {
76
 
      errno = ENOTDIR;
77
 
      return (_TDIR *) 0;
78
 
    }
79
 
 
80
 
  /* Attempt to determine if the given path really is a directory. */
81
 
  rc = GetFileAttributes (szPath);
82
 
  if (rc == (unsigned int)-1)
83
 
    {
84
 
      /* call GetLastError for more error info */
85
 
      errno = ENOENT;
86
 
      return (_TDIR *) 0;
87
 
    }
88
 
  if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
89
 
    {
90
 
      /* Error, entry exists but not a directory. */
91
 
      errno = ENOTDIR;
92
 
      return (_TDIR *) 0;
93
 
    }
94
 
 
95
 
  /* Make an absolute pathname.  */
96
 
  _tfullpath (szFullPath, szPath, MAX_PATH);
97
 
 
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));
102
 
 
103
 
  if (!nd)
104
 
    {
105
 
      /* Error, out of memory. */
106
 
      errno = ENOMEM;
107
 
      return (_TDIR *) 0;
108
 
    }
109
 
 
110
 
  /* Create the search expression. */
111
 
  _tcscpy (nd->dd_name, szFullPath);
112
 
 
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('\\'))
117
 
    {
118
 
      _tcscat (nd->dd_name, SLASH);
119
 
    }
120
 
 
121
 
  /* Add on the search pattern */
122
 
  _tcscat (nd->dd_name, SUFFIX);
123
 
 
124
 
  /* Initialize handle to -1 so that a premature closedir doesn't try
125
 
   * to call _findclose on it. */
126
 
  nd->dd_handle = -1;
127
 
 
128
 
  /* Initialize the status. */
129
 
  nd->dd_stat = 0;
130
 
 
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);
138
 
 
139
 
  return nd;
140
 
}
141
 
 
142
 
 
143
 
/*
144
 
 * readdir
145
 
 *
146
 
 * Return a pointer to a dirent structure filled with the information on the
147
 
 * next entry in the directory.
148
 
 */
149
 
struct _tdirent *
150
 
_treaddir (_TDIR * dirp)
151
 
{
152
 
  errno = 0;
153
 
 
154
 
  /* Check for valid DIR struct. */
155
 
  if (!dirp)
156
 
    {
157
 
      errno = EFAULT;
158
 
      return (struct _tdirent *) 0;
159
 
    }
160
 
 
161
 
  if (dirp->dd_stat < 0)
162
 
    {
163
 
      /* We have already returned all files in the directory
164
 
       * (or the structure has an invalid dd_stat). */
165
 
      return (struct _tdirent *) 0;
166
 
    }
167
 
  else if (dirp->dd_stat == 0)
168
 
    {
169
 
      /* We haven't started the search yet. */
170
 
      /* Start the search */
171
 
      dirp->dd_handle = _tfindfirst (dirp->dd_name, &(dirp->dd_dta));
172
 
 
173
 
          if (dirp->dd_handle == -1)
174
 
        {
175
 
          /* Whoops! Seems there are no files in that
176
 
           * directory. */
177
 
          dirp->dd_stat = -1;
178
 
        }
179
 
      else
180
 
        {
181
 
          dirp->dd_stat = 1;
182
 
        }
183
 
    }
184
 
  else
185
 
    {
186
 
      /* Get the next search entry. */
187
 
      if (_tfindnext (dirp->dd_handle, &(dirp->dd_dta)))
188
 
        {
189
 
          /* We are off the end or otherwise error.     
190
 
             _findnext sets errno to ENOENT if no more file
191
 
             Undo this. */
192
 
          DWORD winerr = GetLastError();
193
 
          if (winerr == ERROR_NO_MORE_FILES)
194
 
            errno = 0;  
195
 
          _findclose (dirp->dd_handle);
196
 
          dirp->dd_handle = -1;
197
 
          dirp->dd_stat = -1;
198
 
        }
199
 
      else
200
 
        {
201
 
          /* Update the status to indicate the correct
202
 
           * number. */
203
 
          dirp->dd_stat++;
204
 
        }
205
 
    }
206
 
 
207
 
  if (dirp->dd_stat > 0)
208
 
    {
209
 
      /* Successfully got an entry. Everything about the file is
210
 
       * already appropriately filled in except the length of the
211
 
       * file name. */
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;
215
 
    }
216
 
 
217
 
  return (struct _tdirent *) 0;
218
 
}
219
 
 
220
 
 
221
 
/*
222
 
 * closedir
223
 
 *
224
 
 * Frees up resources allocated by opendir.
225
 
 */
226
 
int
227
 
_tclosedir (_TDIR * dirp)
228
 
{
229
 
  int rc;
230
 
 
231
 
  errno = 0;
232
 
  rc = 0;
233
 
 
234
 
  if (!dirp)
235
 
    {
236
 
      errno = EFAULT;
237
 
      return -1;
238
 
    }
239
 
 
240
 
  if (dirp->dd_handle != -1)
241
 
    {
242
 
      rc = _findclose (dirp->dd_handle);
243
 
    }
244
 
 
245
 
  /* Delete the dir structure. */
246
 
  free (dirp);
247
 
 
248
 
  return rc;
249
 
}
250
 
 
251
 
/*
252
 
 * rewinddir
253
 
 *
254
 
 * Return to the beginning of the directory "stream". We simply call findclose
255
 
 * and then reset things like an opendir.
256
 
 */
257
 
void
258
 
_trewinddir (_TDIR * dirp)
259
 
{
260
 
  errno = 0;
261
 
 
262
 
  if (!dirp)
263
 
    {
264
 
      errno = EFAULT;
265
 
      return;
266
 
    }
267
 
 
268
 
  if (dirp->dd_handle != -1)
269
 
    {
270
 
      _findclose (dirp->dd_handle);
271
 
    }
272
 
 
273
 
  dirp->dd_handle = -1;
274
 
  dirp->dd_stat = 0;
275
 
}
276
 
 
277
 
/*
278
 
 * telldir
279
 
 *
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.
282
 
 */
283
 
long
284
 
_ttelldir (_TDIR * dirp)
285
 
{
286
 
  errno = 0;
287
 
 
288
 
  if (!dirp)
289
 
    {
290
 
      errno = EFAULT;
291
 
      return -1;
292
 
    }
293
 
  return dirp->dd_stat;
294
 
}
295
 
 
296
 
/*
297
 
 * seekdir
298
 
 *
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
303
 
 * any such system.
304
 
 */
305
 
void
306
 
_tseekdir (_TDIR * dirp, long lPos)
307
 
{
308
 
  errno = 0;
309
 
 
310
 
  if (!dirp)
311
 
    {
312
 
      errno = EFAULT;
313
 
      return;
314
 
    }
315
 
 
316
 
  if (lPos < -1)
317
 
    {
318
 
      /* Seeking to an invalid position. */
319
 
      errno = EINVAL;
320
 
      return;
321
 
    }
322
 
  else if (lPos == -1)
323
 
    {
324
 
      /* Seek past end. */
325
 
      if (dirp->dd_handle != -1)
326
 
        {
327
 
          _findclose (dirp->dd_handle);
328
 
        }
329
 
      dirp->dd_handle = -1;
330
 
      dirp->dd_stat = -1;
331
 
    }
332
 
  else
333
 
    {
334
 
      /* Rewind and read forward to the appropriate index. */
335
 
      _trewinddir (dirp);
336
 
 
337
 
      while ((dirp->dd_stat < lPos) && _treaddir (dirp))
338
 
        ;
339
 
    }
340
 
}
 
1
/*
 
2
 * dirent.c
 
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.
 
6
 *
 
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
 
10
 *
 
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>
 
14
 *      
 
15
 */
 
16
 
 
17
#include <stdlib.h>
 
18
#include <errno.h>
 
19
#include <string.h>
 
20
#include <io.h>
 
21
#include <direct.h>
 
22
 
 
23
#include "dirent.h"
 
24
 
 
25
#define WIN32_LEAN_AND_MEAN
 
26
#include <windows.h> /* for GetFileAttributes */
 
27
 
 
28
#include <tchar.h>
 
29
 
 
30
#ifdef _UNICODE
 
31
#define _tdirent        _wdirent
 
32
#define _TDIR           _WDIR
 
33
#define _topendir       _wopendir
 
34
#define _tclosedir      _wclosedir
 
35
#define _treaddir       _wreaddir
 
36
#define _trewinddir     _wrewinddir
 
37
#define _ttelldir       _wtelldir
 
38
#define _tseekdir       _wseekdir
 
39
#else
 
40
#define _tdirent        dirent
 
41
#define _TDIR           DIR
 
42
#define _topendir       opendir
 
43
#define _tclosedir      closedir
 
44
#define _treaddir       readdir
 
45
#define _trewinddir     rewinddir
 
46
#define _ttelldir       telldir
 
47
#define _tseekdir       seekdir
 
48
#endif
 
49
 
 
50
#define SUFFIX  _T("*")
 
51
#define SLASH   _T("\\")
 
52
 
 
53
 
 
54
/*
 
55
 * opendir
 
56
 *
 
57
 * Returns a pointer to a DIR structure appropriately filled in to begin
 
58
 * searching a directory.
 
59
 */
 
60
_TDIR *
 
61
_topendir (const _TCHAR *szPath)
 
62
{
 
63
  _TDIR *nd;
 
64
  unsigned int rc;
 
65
  _TCHAR szFullPath[MAX_PATH];
 
66
        
 
67
  errno = 0;
 
68
 
 
69
  if (!szPath)
 
70
    {
 
71
      errno = EFAULT;
 
72
      return (_TDIR *) 0;
 
73
    }
 
74
 
 
75
  if (szPath[0] == _T('\0'))
 
76
    {
 
77
      errno = ENOTDIR;
 
78
      return (_TDIR *) 0;
 
79
    }
 
80
 
 
81
  /* Attempt to determine if the given path really is a directory. */
 
82
  rc = GetFileAttributes (szPath);
 
83
  if (rc == (unsigned int)-1)
 
84
    {
 
85
      /* call GetLastError for more error info */
 
86
      errno = ENOENT;
 
87
      return (_TDIR *) 0;
 
88
    }
 
89
  if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
 
90
    {
 
91
      /* Error, entry exists but not a directory. */
 
92
      errno = ENOTDIR;
 
93
      return (_TDIR *) 0;
 
94
    }
 
95
 
 
96
  /* Make an absolute pathname.  */
 
97
  _tfullpath (szFullPath, szPath, MAX_PATH);
 
98
 
 
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));
 
103
 
 
104
  if (!nd)
 
105
    {
 
106
      /* Error, out of memory. */
 
107
      errno = ENOMEM;
 
108
      return (_TDIR *) 0;
 
109
    }
 
110
 
 
111
  /* Create the search expression. */
 
112
  _tcscpy (nd->dd_name, szFullPath);
 
113
 
 
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('\\'))
 
118
    {
 
119
      _tcscat (nd->dd_name, SLASH);
 
120
    }
 
121
 
 
122
  /* Add on the search pattern */
 
123
  _tcscat (nd->dd_name, SUFFIX);
 
124
 
 
125
  /* Initialize handle to -1 so that a premature closedir doesn't try
 
126
   * to call _findclose on it. */
 
127
  nd->dd_handle = -1;
 
128
 
 
129
  /* Initialize the status. */
 
130
  nd->dd_stat = 0;
 
131
 
 
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);
 
139
 
 
140
  return nd;
 
141
}
 
142
 
 
143
 
 
144
/*
 
145
 * readdir
 
146
 *
 
147
 * Return a pointer to a dirent structure filled with the information on the
 
148
 * next entry in the directory.
 
149
 */
 
150
struct _tdirent *
 
151
_treaddir (_TDIR * dirp)
 
152
{
 
153
  errno = 0;
 
154
 
 
155
  /* Check for valid DIR struct. */
 
156
  if (!dirp)
 
157
    {
 
158
      errno = EFAULT;
 
159
      return (struct _tdirent *) 0;
 
160
    }
 
161
 
 
162
  if (dirp->dd_stat < 0)
 
163
    {
 
164
      /* We have already returned all files in the directory
 
165
       * (or the structure has an invalid dd_stat). */
 
166
      return (struct _tdirent *) 0;
 
167
    }
 
168
  else if (dirp->dd_stat == 0)
 
169
    {
 
170
      /* We haven't started the search yet. */
 
171
      /* Start the search */
 
172
      dirp->dd_handle = _tfindfirst (dirp->dd_name, &(dirp->dd_dta));
 
173
 
 
174
          if (dirp->dd_handle == -1)
 
175
        {
 
176
          /* Whoops! Seems there are no files in that
 
177
           * directory. */
 
178
          dirp->dd_stat = -1;
 
179
        }
 
180
      else
 
181
        {
 
182
          dirp->dd_stat = 1;
 
183
        }
 
184
    }
 
185
  else
 
186
    {
 
187
      /* Get the next search entry. */
 
188
      if (_tfindnext (dirp->dd_handle, &(dirp->dd_dta)))
 
189
        {
 
190
          /* We are off the end or otherwise error.     
 
191
             _findnext sets errno to ENOENT if no more file
 
192
             Undo this. */
 
193
          DWORD winerr = GetLastError();
 
194
          if (winerr == ERROR_NO_MORE_FILES)
 
195
            errno = 0;  
 
196
          _findclose (dirp->dd_handle);
 
197
          dirp->dd_handle = -1;
 
198
          dirp->dd_stat = -1;
 
199
        }
 
200
      else
 
201
        {
 
202
          /* Update the status to indicate the correct
 
203
           * number. */
 
204
          dirp->dd_stat++;
 
205
        }
 
206
    }
 
207
 
 
208
  if (dirp->dd_stat > 0)
 
209
    {
 
210
      /* Successfully got an entry. Everything about the file is
 
211
       * already appropriately filled in except the length of the
 
212
       * file name. */
 
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;
 
216
    }
 
217
 
 
218
  return (struct _tdirent *) 0;
 
219
}
 
220
 
 
221
 
 
222
/*
 
223
 * closedir
 
224
 *
 
225
 * Frees up resources allocated by opendir.
 
226
 */
 
227
int
 
228
_tclosedir (_TDIR * dirp)
 
229
{
 
230
  int rc;
 
231
 
 
232
  errno = 0;
 
233
  rc = 0;
 
234
 
 
235
  if (!dirp)
 
236
    {
 
237
      errno = EFAULT;
 
238
      return -1;
 
239
    }
 
240
 
 
241
  if (dirp->dd_handle != -1)
 
242
    {
 
243
      rc = _findclose (dirp->dd_handle);
 
244
    }
 
245
 
 
246
  /* Delete the dir structure. */
 
247
  free (dirp);
 
248
 
 
249
  return rc;
 
250
}
 
251
 
 
252
/*
 
253
 * rewinddir
 
254
 *
 
255
 * Return to the beginning of the directory "stream". We simply call findclose
 
256
 * and then reset things like an opendir.
 
257
 */
 
258
void
 
259
_trewinddir (_TDIR * dirp)
 
260
{
 
261
  errno = 0;
 
262
 
 
263
  if (!dirp)
 
264
    {
 
265
      errno = EFAULT;
 
266
      return;
 
267
    }
 
268
 
 
269
  if (dirp->dd_handle != -1)
 
270
    {
 
271
      _findclose (dirp->dd_handle);
 
272
    }
 
273
 
 
274
  dirp->dd_handle = -1;
 
275
  dirp->dd_stat = 0;
 
276
}
 
277
 
 
278
/*
 
279
 * telldir
 
280
 *
 
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.
 
283
 */
 
284
long
 
285
_ttelldir (_TDIR * dirp)
 
286
{
 
287
  errno = 0;
 
288
 
 
289
  if (!dirp)
 
290
    {
 
291
      errno = EFAULT;
 
292
      return -1;
 
293
    }
 
294
  return dirp->dd_stat;
 
295
}
 
296
 
 
297
/*
 
298
 * seekdir
 
299
 *
 
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
 
304
 * any such system.
 
305
 */
 
306
void
 
307
_tseekdir (_TDIR * dirp, long lPos)
 
308
{
 
309
  errno = 0;
 
310
 
 
311
  if (!dirp)
 
312
    {
 
313
      errno = EFAULT;
 
314
      return;
 
315
    }
 
316
 
 
317
  if (lPos < -1)
 
318
    {
 
319
      /* Seeking to an invalid position. */
 
320
      errno = EINVAL;
 
321
      return;
 
322
    }
 
323
  else if (lPos == -1)
 
324
    {
 
325
      /* Seek past end. */
 
326
      if (dirp->dd_handle != -1)
 
327
        {
 
328
          _findclose (dirp->dd_handle);
 
329
        }
 
330
      dirp->dd_handle = -1;
 
331
      dirp->dd_stat = -1;
 
332
    }
 
333
  else
 
334
    {
 
335
      /* Rewind and read forward to the appropriate index. */
 
336
      _trewinddir (dirp);
 
337
 
 
338
      while ((dirp->dd_stat < lPos) && _treaddir (dirp))
 
339
        ;
 
340
    }
 
341
}