Initialize Tizen 2.3
[framework/multimedia/gstreamer0.10.git] / mobile / win32 / common / dirent.c
1 /*
2
3  * dirent.c
4
5  *
6
7  * Derived from DIRLIB.C by Matt J. Weinstein 
8
9  * This note appears in the DIRLIB.H
10
11  * DIRLIB.H by M. J. Weinstein   Released to public domain 1-Jan-89
12
13  *
14
15  * Updated by Jeremy Bettis <jeremy@hksys.com>
16
17  * Significantly revised and rewinddir, seekdir and telldir added by Colin
18
19  * Peters <colin@fu.is.saga-u.ac.jp>
20
21  *
22
23  * Resource leaks fixed by <steve.lhomme@free.fr>
24
25  *
26
27  *      
28
29  * $Revision$
30
31  * $Author$
32
33  * $Date$
34
35  *
36
37  */
38
39
40
41 #include <stdlib.h>
42
43 #include <errno.h>
44
45 #include <string.h>
46
47 #include <io.h>
48
49 #include <direct.h>
50
51 #include <dirent.h>
52
53 #include <gtchar.h>
54
55 #define SUFFIX  _T("*")
56
57 #define SLASH   _T("\\")
58
59
60
61 #include <stdio.h>
62
63
64
65 #define WIN32_LEAN_AND_MEAN
66
67 #include <windows.h>            /* for GetFileAttributes */
68
69
70
71 /*
72
73  * opendir
74
75  *
76
77  * Returns a pointer to a DIR structure appropriately filled in to begin
78
79  * searching a directory.
80
81  */
82
83 _TDIR *
84 _topendir (const _TCHAR * szPath)
85 {
86
87   _TDIR *nd;
88
89   unsigned int rc;
90
91
92   _TCHAR szFullPath[MAX_PATH];
93
94
95   errno = 0;
96
97
98   if (!szPath) {
99
100     errno = EFAULT;
101
102     return (_TDIR *) 0;
103
104   }
105
106
107   if (szPath[0] == _T ('\0')) {
108
109     errno = ENOTDIR;
110
111     return (_TDIR *) 0;
112
113   }
114
115
116
117   /* Attempt to determine if the given path really is a directory. */
118
119   rc = GetFileAttributes (szPath);
120
121   if (rc == (unsigned int) -1) {
122
123
124     /* call GetLastError for more error info */
125
126     errno = ENOENT;
127
128     return (_TDIR *) 0;
129
130   }
131
132   if (!(rc & FILE_ATTRIBUTE_DIRECTORY)) {
133
134
135     /* Error, entry exists but not a directory. */
136
137     errno = ENOTDIR;
138
139     return (_TDIR *) 0;
140
141   }
142
143
144
145   /* Make an absolute pathname.  */
146
147   _tfullpath (szFullPath, szPath, MAX_PATH);
148
149
150
151   /* Allocate enough space to store DIR structure and the complete
152
153    * directory path given. */
154
155   nd = (_TDIR *) malloc (sizeof (_TDIR) + (_tcslen (szFullPath) +
156           _tcslen (SLASH) + _tcslen (SUFFIX) + 1) * sizeof (_TCHAR));
157
158
159   if (!nd) {
160
161
162     /* Error, out of memory. */
163
164     errno = ENOMEM;
165
166     return (_TDIR *) 0;
167
168   }
169
170
171
172   /* Create the search expression. */
173
174   _tcscpy (nd->dd_name, szFullPath);
175
176
177
178   /* Add on a slash if the path does not end with one. */
179
180   if (nd->dd_name[0] != _T ('\0')
181       && nd->dd_name[_tcslen (nd->dd_name) - 1] != _T ('/')
182       && nd->dd_name[_tcslen (nd->dd_name) - 1] != _T ('\\')) {
183
184     _tcscat (nd->dd_name, SLASH);
185
186   }
187
188
189
190   /* Add on the search pattern */
191
192   _tcscat (nd->dd_name, SUFFIX);
193
194
195
196   /* Initialize handle to -1 so that a premature closedir doesn't try
197
198    * to call _findclose on it. */
199
200   nd->dd_handle = -1;
201
202
203
204   /* Initialize the status. */
205
206   nd->dd_stat = 0;
207
208
209
210   /* Initialize the dirent structure. ino and reclen are invalid under
211
212    * Win32, and name simply points at the appropriate part of the
213
214    * findfirst_t structure. */
215
216   nd->dd_dir.d_ino = 0;
217
218   nd->dd_dir.d_reclen = 0;
219
220   nd->dd_dir.d_namlen = 0;
221
222
223   // Added by jcsston 02/04/2004, memset was writing to a bad pointer
224
225   nd->dd_dir.d_name = malloc (FILENAME_MAX);
226
227
228   // End add
229
230   memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
231
232
233   return nd;
234
235 }
236
237
238
239
240
241 /*
242
243  * readdir
244
245  *
246
247  * Return a pointer to a dirent structure filled with the information on the
248
249  * next entry in the directory.
250
251  */
252
253 struct _tdirent *
254 _treaddir (_TDIR * dirp)
255 {
256
257   errno = 0;
258
259
260
261   /* Check for valid DIR struct. */
262
263   if (!dirp) {
264
265     errno = EFAULT;
266
267     return (struct _tdirent *) 0;
268
269   }
270
271
272   if (dirp->dd_stat < 0) {
273
274
275     /* We have already returned all files in the directory
276
277      * (or the structure has an invalid dd_stat). */
278
279     return (struct _tdirent *) 0;
280
281   } else if (dirp->dd_stat == 0) {
282
283
284     /* We haven't started the search yet. */
285
286     /* Start the search */
287
288     dirp->dd_handle = (long) _tfindfirst (dirp->dd_name, &(dirp->dd_dta));
289
290
291     if (dirp->dd_handle == -1) {
292
293
294       /* Whoops! Seems there are no files in that
295
296        * directory. */
297
298       dirp->dd_stat = -1;
299
300     } else {
301
302       dirp->dd_stat = 1;
303
304     }
305
306   } else {
307
308
309     /* Get the next search entry. */
310
311     if (_tfindnext (dirp->dd_handle, &(dirp->dd_dta))) {
312
313
314       /* We are off the end or otherwise error.     
315
316          _findnext sets errno to ENOENT if no more file
317
318          Undo this. */
319
320       DWORD winerr = GetLastError ();
321
322
323       if (winerr == ERROR_NO_MORE_FILES)
324
325         errno = 0;
326
327       _findclose (dirp->dd_handle);
328
329       dirp->dd_handle = -1;
330
331       dirp->dd_stat = -1;
332
333     } else {
334
335
336       /* Update the status to indicate the correct
337
338        * number. */
339
340       dirp->dd_stat++;
341
342     }
343
344   }
345
346
347   if (dirp->dd_stat > 0) {
348
349
350     /* Successfully got an entry. Everything about the file is
351
352      * already appropriately filled in except the length of the
353
354      * file name. */
355
356     dirp->dd_dir.d_namlen = (unsigned short) _tcslen (dirp->dd_dta.name);
357
358     _tcscpy (dirp->dd_dir.d_name, dirp->dd_dta.name);
359
360     return &dirp->dd_dir;
361
362   }
363
364
365   return (struct _tdirent *) 0;
366
367 }
368
369
370
371
372 /*
373
374  * closedir
375
376  *
377
378  * Frees up resources allocated by opendir.
379
380  */
381
382 int
383 _tclosedir (_TDIR * dirp)
384 {
385
386   int rc;
387
388
389
390   errno = 0;
391
392   rc = 0;
393
394
395   if (!dirp) {
396
397     errno = EFAULT;
398
399     return -1;
400
401   }
402
403
404   if (dirp->dd_handle != -1) {
405
406     rc = _findclose (dirp->dd_handle);
407
408   }
409
410
411   if (dirp->dd_dir.d_name)
412
413     free (dirp->dd_dir.d_name);
414
415
416
417   /* Delete the dir structure. */
418
419   free (dirp);
420
421
422   return rc;
423
424 }
425
426
427
428
429 /*
430
431  * rewinddir
432
433  *
434
435  * Return to the beginning of the directory "stream". We simply call findclose
436
437  * and then reset things like an opendir.
438
439  */
440
441 void
442 _trewinddir (_TDIR * dirp)
443 {
444
445   errno = 0;
446
447
448   if (!dirp) {
449
450     errno = EFAULT;
451
452     return;
453
454   }
455
456
457   if (dirp->dd_handle != -1) {
458
459     _findclose (dirp->dd_handle);
460
461   }
462
463
464   dirp->dd_handle = -1;
465
466   dirp->dd_stat = 0;
467
468 }
469
470
471
472
473 /*
474
475  * telldir
476
477  *
478
479  * Returns the "position" in the "directory stream" which can be used with
480
481  * seekdir to go back to an old entry. We simply return the value in stat.
482
483  */
484
485 long
486 _ttelldir (_TDIR * dirp)
487 {
488
489   errno = 0;
490
491
492   if (!dirp) {
493
494     errno = EFAULT;
495
496     return -1;
497
498   }
499
500   return dirp->dd_stat;
501
502 }
503
504
505
506
507 /*
508
509  * seekdir
510
511  *
512
513  * Seek to an entry previously returned by telldir. We rewind the directory
514
515  * and call readdir repeatedly until either dd_stat is the position number
516
517  * or -1 (off the end). This is not perfect, in that the directory may
518
519  * have changed while we weren't looking. But that is probably the case with
520
521  * any such system.
522
523  */
524
525 void
526 _tseekdir (_TDIR * dirp, long lPos)
527 {
528
529   errno = 0;
530
531
532   if (!dirp) {
533
534     errno = EFAULT;
535
536     return;
537
538   }
539
540
541   if (lPos < -1) {
542
543
544     /* Seeking to an invalid position. */
545
546     errno = EINVAL;
547
548     return;
549
550   } else if (lPos == -1) {
551
552
553     /* Seek past end. */
554
555     if (dirp->dd_handle != -1) {
556
557       _findclose (dirp->dd_handle);
558
559     }
560
561     dirp->dd_handle = -1;
562
563     dirp->dd_stat = -1;
564
565   } else {
566
567
568     /* Rewind and read forward to the appropriate index. */
569
570     _trewinddir (dirp);
571
572
573     while ((dirp->dd_stat < lPos) && _treaddir (dirp));
574
575   }
576
577 }