Wise&mystical  1.0
Project about Europe
Loading...
Searching...
No Matches
dirent.h
Go to the documentation of this file.
1
22#ifndef DIRENT_H
23#define DIRENT_H
24
25// Allow custom memory allocators
26#ifndef DIRENT_MALLOC
27 #define DIRENT_MALLOC(sz) malloc(sz)
28#endif
29#ifndef DIRENT_FREE
30 #define DIRENT_FREE(p) free(p)
31#endif
32
33//----------------------------------------------------------------------------------
34// Types and Structures Definition
35//----------------------------------------------------------------------------------
36
37// Fordward declaration of DIR, implementation below
38typedef struct DIR DIR;
39
40struct dirent {
41 char *d_name;
42};
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48//------------------------------------------------------------------------------------
49// Functions Declaration
50//------------------------------------------------------------------------------------
51DIR *opendir(const char *name);
52int closedir(DIR *dir);
53struct dirent *readdir(DIR *dir);
54void rewinddir(DIR *dir);
55
56#ifdef __cplusplus
57}
58#endif
59
60#endif // DIRENT_H
61
62
83#include <io.h> // _findfirst and _findnext set errno iff they return -1
84#include <stdlib.h>
85#include <string.h>
86#include <errno.h>
87
88//----------------------------------------------------------------------------------
89// Types and Structures Definition
90//----------------------------------------------------------------------------------
91typedef ptrdiff_t handle_type; // C99's intptr_t not sufficiently portable
92
93struct DIR {
94 handle_type handle; // -1 for failed rewind
95 struct _finddata_t info;
96 struct dirent result; // d_name null iff first time
97 char *name; // null-terminated char string
98};
99
100DIR *opendir(const char *name)
101{
102 DIR *dir = 0;
103
104 if (name && name[0])
105 {
106 size_t base_length = strlen(name);
107
108 // Search pattern must end with suitable wildcard
109 const char *all = strchr("/\\", name[base_length - 1]) ? "*" : "/*";
110
111 if ((dir = (DIR *)DIRENT_MALLOC(sizeof *dir)) != 0 &&
112 (dir->name = (char *)DIRENT_MALLOC(base_length + strlen(all) + 1)) != 0)
113 {
114 strcat(strcpy(dir->name, name), all);
115
116 if ((dir->handle = (handle_type) _findfirst(dir->name, &dir->info)) != -1)
117 {
118 dir->result.d_name = 0;
119 }
120 else // rollback
121 {
122 DIRENT_FREE(dir->name);
123 DIRENT_FREE(dir);
124 dir = 0;
125 }
126 }
127 else // rollback
128 {
129 DIRENT_FREE(dir);
130 dir = 0;
131 errno = ENOMEM;
132 }
133 }
134 else errno = EINVAL;
135
136 return dir;
137}
138
139int closedir(DIR *dir)
140{
141 int result = -1;
142
143 if (dir)
144 {
145 if (dir->handle != -1) result = _findclose(dir->handle);
146
147 DIRENT_FREE(dir->name);
148 DIRENT_FREE(dir);
149 }
150
151 // NOTE: All errors ampped to EBADF
152 if (result == -1) errno = EBADF;
153
154 return result;
155}
156
157struct dirent *readdir(DIR *dir)
158{
159 struct dirent *result = 0;
160
161 if (dir && dir->handle != -1)
162 {
163 if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
164 {
165 result = &dir->result;
166 result->d_name = dir->info.name;
167 }
168 }
169 else errno = EBADF;
170
171 return result;
172}
173
174void rewinddir(DIR *dir)
175{
176 if (dir && dir->handle != -1)
177 {
178 _findclose(dir->handle);
179 dir->handle = (handle_type) _findfirst(dir->name, &dir->info);
180 dir->result.d_name = 0;
181 }
182 else errno = EBADF;
183}
ptrdiff_t handle_type
Implementation of POSIX directory browsing functions and types for Win32.
Definition: dirent.h:91
DIR * opendir(const char *name)
Definition: dirent.h:100
#define DIRENT_FREE(p)
Definition: dirent.h:30
void rewinddir(DIR *dir)
Definition: dirent.h:174
struct dirent * readdir(DIR *dir)
Definition: dirent.h:157
int closedir(DIR *dir)
Definition: dirent.h:139
#define DIRENT_MALLOC(sz)
Declaration of POSIX directory browsing functions and types for Win32.
Definition: dirent.h:27
Definition: dirent.h:93
handle_type handle
Definition: dirent.h:94
struct dirent result
Definition: dirent.h:96
struct _finddata_t info
Definition: dirent.h:95
char * name
Definition: dirent.h:97
Definition: dirent.h:40
char * d_name
Definition: dirent.h:41