OLD | NEW |
| (Empty) |
1 /* | |
2 | |
3 Implementation of POSIX directory browsing functions and types for Win32. | |
4 | |
5 Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) | |
6 History: Created March 1997. Updated June 2003. | |
7 Rights: See end of file. | |
8 | |
9 */ | |
10 | |
11 #include <dirent.h> | |
12 #include <errno.h> | |
13 #include <io.h> /* _findfirst and _findnext set errno iff they return -1 */ | |
14 #include <stdlib.h> | |
15 #include <string.h> | |
16 | |
17 #ifdef __cplusplus | |
18 extern "C" | |
19 { | |
20 #endif | |
21 | |
22 struct DIR | |
23 { | |
24 long handle; /* -1 for failed rewind */ | |
25 struct _finddata_t info; | |
26 struct dirent result; /* d_name null iff first time */ | |
27 char *name; /* null-terminated char string */ | |
28 }; | |
29 | |
30 DIR *opendir(const char *name) | |
31 { | |
32 DIR *dir = 0; | |
33 | |
34 if(name && name[0]) | |
35 { | |
36 size_t base_length = strlen(name); | |
37 const char *all = /* search pattern must end with suitable wildcard */ | |
38 strchr("/\\", name[base_length - 1]) ? "*" : "/*"; | |
39 | |
40 if((dir = (DIR *) malloc(sizeof *dir)) != 0 && | |
41 (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) | |
42 { | |
43 strcat(strcpy(dir->name, name), all); | |
44 | |
45 if((dir->handle = (long) _findfirst(dir->name, &dir->info)) != -1) | |
46 { | |
47 dir->result.d_name = 0; | |
48 } | |
49 else /* rollback */ | |
50 { | |
51 free(dir->name); | |
52 free(dir); | |
53 dir = 0; | |
54 } | |
55 } | |
56 else /* rollback */ | |
57 { | |
58 free(dir); | |
59 dir = 0; | |
60 errno = ENOMEM; | |
61 } | |
62 } | |
63 else | |
64 { | |
65 errno = EINVAL; | |
66 } | |
67 | |
68 return dir; | |
69 } | |
70 | |
71 int closedir(DIR *dir) | |
72 { | |
73 int result = -1; | |
74 | |
75 if(dir) | |
76 { | |
77 if(dir->handle != -1) | |
78 { | |
79 result = _findclose(dir->handle); | |
80 } | |
81 | |
82 free(dir->name); | |
83 free(dir); | |
84 } | |
85 | |
86 if(result == -1) /* map all errors to EBADF */ | |
87 { | |
88 errno = EBADF; | |
89 } | |
90 | |
91 return result; | |
92 } | |
93 | |
94 struct dirent *readdir(DIR *dir) | |
95 { | |
96 struct dirent *result = 0; | |
97 | |
98 if(dir && dir->handle != -1) | |
99 { | |
100 if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) | |
101 { | |
102 result = &dir->result; | |
103 result->d_name = dir->info.name; | |
104 } | |
105 } | |
106 else | |
107 { | |
108 errno = EBADF; | |
109 } | |
110 | |
111 return result; | |
112 } | |
113 | |
114 void rewinddir(DIR *dir) | |
115 { | |
116 if(dir && dir->handle != -1) | |
117 { | |
118 _findclose(dir->handle); | |
119 dir->handle = (long) _findfirst(dir->name, &dir->info); | |
120 dir->result.d_name = 0; | |
121 } | |
122 else | |
123 { | |
124 errno = EBADF; | |
125 } | |
126 } | |
127 | |
128 #ifdef __cplusplus | |
129 } | |
130 #endif | |
131 | |
132 /* | |
133 | |
134 Copyright Kevlin Henney, 1997, 2003. All rights reserved. | |
135 | |
136 Permission to use, copy, modify, and distribute this software and its | |
137 documentation for any purpose is hereby granted without fee, provided | |
138 that this copyright and permissions notice appear in all copies and | |
139 derivatives. | |
140 | |
141 This software is supplied "as is" without express or implied warranty. | |
142 | |
143 But that said, if there are any problems please get in touch. | |
144 | |
145 */ | |
OLD | NEW |