aboutsummaryrefslogtreecommitdiff
path: root/include/compat/dirent_msvc.h
diff options
context:
space:
mode:
authorBrent Cook <bcook@openbsd.org>2015-09-09 06:01:52 -0500
committerBrent Cook <bcook@openbsd.org>2015-09-09 06:03:52 -0500
commit5dc630371487d483a53f1ed7193ba8e8c73492a2 (patch)
tree6cd7cd591a515589bc6d8f9965cbe15d19e274b1 /include/compat/dirent_msvc.h
parentadfb2bf72257c4d622f4be8f897c5ddafa4e58ae (diff)
downloadportable-5dc630371487d483a53f1ed7193ba8e8c73492a2.tar.gz
portable-5dc630371487d483a53f1ed7193ba8e8c73492a2.tar.bz2
portable-5dc630371487d483a53f1ed7193ba8e8c73492a2.zip
remove support for old MSVC versions, KNF
Diffstat (limited to 'include/compat/dirent_msvc.h')
-rw-r--r--include/compat/dirent_msvc.h956
1 files changed, 405 insertions, 551 deletions
diff --git a/include/compat/dirent_msvc.h b/include/compat/dirent_msvc.h
index e5c5c41..67f295f 100644
--- a/include/compat/dirent_msvc.h
+++ b/include/compat/dirent_msvc.h
@@ -54,11 +54,6 @@
54/* Indicates that d_namlen field is available in dirent structure */ 54/* Indicates that d_namlen field is available in dirent structure */
55#define _DIRENT_HAVE_D_NAMLEN 55#define _DIRENT_HAVE_D_NAMLEN
56 56
57/* Entries missing from MSVC 6.0 */
58#if !defined(FILE_ATTRIBUTE_DEVICE)
59# define FILE_ATTRIBUTE_DEVICE 0x40
60#endif
61
62/* Maximum length of file name */ 57/* Maximum length of file name */
63#if !defined(PATH_MAX) 58#if !defined(PATH_MAX)
64# define PATH_MAX MAX_PATH 59# define PATH_MAX MAX_PATH
@@ -71,92 +66,73 @@
71#endif 66#endif
72 67
73/* Return the exact length of d_namlen without zero terminator */ 68/* Return the exact length of d_namlen without zero terminator */
74#define _D_EXACT_NAMLEN(p) ((p)->d_namlen) 69#define _D_EXACT_NAMLEN(p)((p)->d_namlen)
75 70
76/* Return number of bytes needed to store d_namlen */ 71/* Return number of bytes needed to store d_namlen */
77#define _D_ALLOC_NAMLEN(p) (PATH_MAX) 72#define _D_ALLOC_NAMLEN(p)(PATH_MAX)
78
79
80#ifdef __cplusplus
81extern "C" {
82#endif
83
84 73
85/* Wide-character version */ 74/* Wide-character version */
86struct _wdirent { 75struct _wdirent {
87 long d_ino; /* Always zero */ 76 long d_ino; /* Always zero */
88 unsigned short d_reclen; /* Structure size */ 77 unsigned short d_reclen; /* Structure size */
89 size_t d_namlen; /* Length of name without \0 */ 78 size_t d_namlen; /* Length of name without \0 */
90 int d_type; /* File type */ 79 int d_type; /* File type */
91 wchar_t d_name[PATH_MAX]; /* File name */ 80 wchar_t d_name[PATH_MAX]; /* File name */
92}; 81};
93typedef struct _wdirent _wdirent; 82typedef struct _wdirent _wdirent;
94 83
95struct _WDIR { 84struct _WDIR {
96 struct _wdirent ent; /* Current directory entry */ 85 struct _wdirent ent; /* Current directory entry */
97 WIN32_FIND_DATAW data; /* Private file data */ 86 WIN32_FIND_DATAW data; /* Private file data */
98 int cached; /* True if data is valid */ 87 int cached; /* True if data is valid */
99 HANDLE handle; /* Win32 search handle */ 88 HANDLE handle; /* Win32 search handle */
100 wchar_t *patt; /* Initial directory name */ 89 wchar_t *patt; /* Initial directory name */
101}; 90};
102typedef struct _WDIR _WDIR; 91typedef struct _WDIR _WDIR;
103 92
104static _WDIR *_wopendir (const wchar_t *dirname); 93static _WDIR *_wopendir(const wchar_t *dirname);
105static struct _wdirent *_wreaddir (_WDIR *dirp); 94static struct _wdirent *_wreaddir(_WDIR *dirp);
106static int _wclosedir (_WDIR *dirp); 95static int _wclosedir(_WDIR *dirp);
107static void _wrewinddir (_WDIR* dirp); 96static void _wrewinddir(_WDIR* dirp);
108
109
110/* For compatibility with Symbian */
111#define wdirent _wdirent
112#define WDIR _WDIR
113#define wopendir _wopendir
114#define wreaddir _wreaddir
115#define wclosedir _wclosedir
116#define wrewinddir _wrewinddir
117
118 97
119/* Multi-byte character versions */ 98/* Multi-byte character versions */
120struct dirent { 99struct dirent {
121 long d_ino; /* Always zero */ 100 long d_ino; /* Always zero */
122 unsigned short d_reclen; /* Structure size */ 101 unsigned short d_reclen; /* Structure size */
123 size_t d_namlen; /* Length of name without \0 */ 102 size_t d_namlen; /* Length of name without \0 */
124 int d_type; /* File type */ 103 int d_type; /* File type */
125 char d_name[PATH_MAX]; /* File name */ 104 char d_name[PATH_MAX]; /* File name */
126}; 105};
127typedef struct dirent dirent; 106typedef struct dirent dirent;
128 107
129struct DIR { 108struct DIR {
130 struct dirent ent; 109 struct dirent ent;
131 struct _WDIR *wdirp; 110 struct _WDIR *wdirp;
132}; 111};
133typedef struct DIR DIR; 112typedef struct DIR DIR;
134 113
135static DIR *opendir (const char *dirname); 114static DIR *opendir(const char *dirname);
136static struct dirent *readdir (DIR *dirp); 115static struct dirent *readdir(DIR *dirp);
137static int closedir (DIR *dirp); 116static int closedir(DIR *dirp);
138static void rewinddir (DIR* dirp); 117static void rewinddir(DIR* dirp);
139
140 118
141/* Internal utility functions */ 119/* Internal utility functions */
142static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp); 120static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp);
143static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp); 121static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp);
144 122
145static int dirent_mbstowcs_s( 123static int dirent_mbstowcs_s(
146 size_t *pReturnValue, 124 size_t *pReturnValue,
147 wchar_t *wcstr, 125 wchar_t *wcstr,
148 size_t sizeInWords, 126 size_t sizeInWords,
149 const char *mbstr, 127 const char *mbstr,
150 size_t count); 128 size_t count);
151 129
152static int dirent_wcstombs_s( 130static int dirent_wcstombs_s(
153 size_t *pReturnValue, 131 size_t *pReturnValue,
154 char *mbstr, 132 char *mbstr,
155 size_t sizeInBytes, 133 size_t sizeInBytes,
156 const wchar_t *wcstr, 134 const wchar_t *wcstr,
157 size_t count); 135 size_t count);
158
159static void dirent_set_errno (int error);
160 136
161/* 137/*
162 * Open directory stream DIRNAME for read and return a pointer to the 138 * Open directory stream DIRNAME for read and return a pointer to the
@@ -164,96 +140,95 @@ static void dirent_set_errno (int error);
164 * entries. 140 * entries.
165 */ 141 */
166static _WDIR* 142static _WDIR*
167_wopendir( 143_wopendir(const wchar_t *dirname)
168 const wchar_t *dirname)
169{ 144{
170 _WDIR *dirp = NULL; 145 _WDIR *dirp = NULL;
171 int error; 146 int error;
172 147
173 /* Must have directory name */ 148 /* Must have directory name */
174 if (dirname == NULL || dirname[0] == '\0') { 149 if (dirname == NULL || dirname[0] == '\0') {
175 dirent_set_errno (ENOENT); 150 _set_errno(ENOENT);
176 return NULL; 151 return NULL;
177 } 152 }
178 153
179 /* Allocate new _WDIR structure */ 154 /* Allocate new _WDIR structure */
180 dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); 155 dirp =(_WDIR*) malloc(sizeof(struct _WDIR));
181 if (dirp != NULL) { 156 if (dirp != NULL) {
182 DWORD n; 157 DWORD n;
183 158
184 /* Reset _WDIR structure */ 159 /* Reset _WDIR structure */
185 dirp->handle = INVALID_HANDLE_VALUE; 160 dirp->handle = INVALID_HANDLE_VALUE;
186 dirp->patt = NULL; 161 dirp->patt = NULL;
187 dirp->cached = 0; 162 dirp->cached = 0;
188 163
189 /* Compute the length of full path plus zero terminator */ 164 /* Compute the length of full path plus zero terminator */
190 n = GetFullPathNameW (dirname, 0, NULL, NULL); 165 n = GetFullPathNameW(dirname, 0, NULL, NULL);
191 166
192 /* Allocate room for absolute directory name and search pattern */ 167 /* Allocate room for absolute directory name and search pattern */
193 dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); 168 dirp->patt =(wchar_t*) malloc(sizeof(wchar_t) * n + 16);
194 if (dirp->patt) { 169 if (dirp->patt) {
195 170
196 /* 171 /*
197 * Convert relative directory name to an absolute one. This 172 * Convert relative directory name to an absolute one. This
198 * allows rewinddir() to function correctly even when current 173 * allows rewinddir() to function correctly even when current
199 * working directory is changed between opendir() and rewinddir(). 174 * working directory is changed between opendir() and rewinddir().
200 */ 175 */
201 n = GetFullPathNameW (dirname, n, dirp->patt, NULL); 176 n = GetFullPathNameW(dirname, n, dirp->patt, NULL);
202 if (n > 0) { 177 if (n > 0) {
203 wchar_t *p; 178 wchar_t *p;
204 179
205 /* Append search pattern \* to the directory name */ 180 /* Append search pattern \* to the directory name */
206 p = dirp->patt + n; 181 p = dirp->patt + n;
207 if (dirp->patt < p) { 182 if (dirp->patt < p) {
208 switch (p[-1]) { 183 switch(p[-1]) {
209 case '\\': 184 case '\\':
210 case '/': 185 case '/':
211 case ':': 186 case ':':
212 /* Directory ends in path separator, e.g. c:\temp\ */ 187 /* Directory ends in path separator, e.g. c:\temp\ */
213 /*NOP*/; 188 /*NOP*/;
214 break; 189 break;
215 190
216 default: 191 default:
217 /* Directory name doesn't end in path separator */ 192 /* Directory name doesn't end in path separator */
218 *p++ = '\\'; 193 *p++ = '\\';
219 } 194 }
220 } 195 }
221 *p++ = '*'; 196 *p++ = '*';
222 *p = '\0'; 197 *p = '\0';
223 198
224 /* Open directory stream and retrieve the first entry */ 199 /* Open directory stream and retrieve the first entry */
225 if (dirent_first (dirp)) { 200 if (dirent_first(dirp)) {
226 /* Directory stream opened successfully */ 201 /* Directory stream opened successfully */
227 error = 0; 202 error = 0;
228 } else { 203 } else {
229 /* Cannot retrieve first entry */ 204 /* Cannot retrieve first entry */
230 error = 1; 205 error = 1;
231 dirent_set_errno (ENOENT); 206 _set_errno(ENOENT);
232 } 207 }
233 208
234 } else { 209 } else {
235 /* Cannot retrieve full path name */ 210 /* Cannot retrieve full path name */
236 dirent_set_errno (ENOENT); 211 _set_errno(ENOENT);
237 error = 1; 212 error = 1;
238 } 213 }
239 214
240 } else { 215 } else {
241 /* Cannot allocate memory for search pattern */ 216 /* Cannot allocate memory for search pattern */
242 error = 1; 217 error = 1;
243 } 218 }
244 219
245 } else { 220 } else {
246 /* Cannot allocate _WDIR structure */ 221 /* Cannot allocate _WDIR structure */
247 error = 1; 222 error = 1;
248 } 223 }
249 224
250 /* Clean up in case of error */ 225 /* Clean up in case of error */
251 if (error && dirp) { 226 if (error && dirp) {
252 _wclosedir (dirp); 227 _wclosedir(dirp);
253 dirp = NULL; 228 dirp = NULL;
254 } 229 }
255 230
256 return dirp; 231 return dirp;
257} 232}
258 233
259/* 234/*
@@ -263,58 +238,57 @@ _wopendir(
263 * "." and ".." as well as volume labels, hidden files and system files. 238 * "." and ".." as well as volume labels, hidden files and system files.
264 */ 239 */
265static struct _wdirent* 240static struct _wdirent*
266_wreaddir( 241_wreaddir(_WDIR *dirp)
267 _WDIR *dirp)
268{ 242{
269 WIN32_FIND_DATAW *datap; 243 WIN32_FIND_DATAW *datap;
270 struct _wdirent *entp; 244 struct _wdirent *entp;
271 245
272 /* Read next directory entry */ 246 /* Read next directory entry */
273 datap = dirent_next (dirp); 247 datap = dirent_next(dirp);
274 if (datap) { 248 if (datap) {
275 size_t n; 249 size_t n;
276 DWORD attr; 250 DWORD attr;
277 251
278 /* Pointer to directory entry to return */ 252 /* Pointer to directory entry to return */
279 entp = &dirp->ent; 253 entp = &dirp->ent;
280 254
281 /* 255 /*
282 * Copy file name as wide-character string. If the file name is too 256 * Copy file name as wide-character string. If the file name is too
283 * long to fit in to the destination buffer, then truncate file name 257 * long to fit in to the destination buffer, then truncate file name
284 * to PATH_MAX characters and zero-terminate the buffer. 258 * to PATH_MAX characters and zero-terminate the buffer.
285 */ 259 */
286 n = 0; 260 n = 0;
287 while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) { 261 while(n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
288 entp->d_name[n] = datap->cFileName[n]; 262 entp->d_name[n] = datap->cFileName[n];
289 n++; 263 n++;
290 } 264 }
291 dirp->ent.d_name[n] = 0; 265 dirp->ent.d_name[n] = 0;
292 266
293 /* Length of file name excluding zero terminator */ 267 /* Length of file name excluding zero terminator */
294 entp->d_namlen = n; 268 entp->d_namlen = n;
295 269
296 /* File type */ 270 /* File type */
297 attr = datap->dwFileAttributes; 271 attr = datap->dwFileAttributes;
298 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { 272 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
299 entp->d_type = DT_CHR; 273 entp->d_type = DT_CHR;
300 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { 274 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
301 entp->d_type = DT_DIR; 275 entp->d_type = DT_DIR;
302 } else { 276 } else {
303 entp->d_type = DT_REG; 277 entp->d_type = DT_REG;
304 } 278 }
305 279
306 /* Reset dummy fields */ 280 /* Reset dummy fields */
307 entp->d_ino = 0; 281 entp->d_ino = 0;
308 entp->d_reclen = sizeof (struct _wdirent); 282 entp->d_reclen = sizeof(struct _wdirent);
309 283
310 } else { 284 } else {
311 285
312 /* Last directory entry read */ 286 /* Last directory entry read */
313 entp = NULL; 287 entp = NULL;
314 288
315 } 289 }
316 290
317 return entp; 291 return entp;
318} 292}
319 293
320/* 294/*
@@ -323,34 +297,33 @@ _wreaddir(
323 * _wreaddir(). 297 * _wreaddir().
324 */ 298 */
325static int 299static int
326_wclosedir( 300_wclosedir(_WDIR *dirp)
327 _WDIR *dirp)
328{ 301{
329 int ok; 302 int ok;
330 if (dirp) { 303 if (dirp) {
331 304
332 /* Release search handle */ 305 /* Release search handle */
333 if (dirp->handle != INVALID_HANDLE_VALUE) { 306 if (dirp->handle != INVALID_HANDLE_VALUE) {
334 FindClose (dirp->handle); 307 FindClose(dirp->handle);
335 dirp->handle = INVALID_HANDLE_VALUE; 308 dirp->handle = INVALID_HANDLE_VALUE;
336 } 309 }
337 310
338 /* Release search pattern */ 311 /* Release search pattern */
339 if (dirp->patt) { 312 if (dirp->patt) {
340 free (dirp->patt); 313 free(dirp->patt);
341 dirp->patt = NULL; 314 dirp->patt = NULL;
342 } 315 }
343 316
344 /* Release directory structure */ 317 /* Release directory structure */
345 free (dirp); 318 free(dirp);
346 ok = /*success*/0; 319 ok = /*success*/0;
347 320
348 } else { 321 } else {
349 /* Invalid directory stream */ 322 /* Invalid directory stream */
350 dirent_set_errno (EBADF); 323 _set_errno(EBADF);
351 ok = /*failure*/-1; 324 ok = /*failure*/-1;
352 } 325 }
353 return ok; 326 return ok;
354} 327}
355 328
356/* 329/*
@@ -358,140 +331,136 @@ _wclosedir(
358 * file name again. 331 * file name again.
359 */ 332 */
360static void 333static void
361_wrewinddir( 334_wrewinddir(_WDIR* dirp)
362 _WDIR* dirp)
363{ 335{
364 if (dirp) { 336 if (dirp) {
365 /* Release existing search handle */ 337 /* Release existing search handle */
366 if (dirp->handle != INVALID_HANDLE_VALUE) { 338 if (dirp->handle != INVALID_HANDLE_VALUE) {
367 FindClose (dirp->handle); 339 FindClose(dirp->handle);
368 } 340 }
369 341
370 /* Open new search handle */ 342 /* Open new search handle */
371 dirent_first (dirp); 343 dirent_first(dirp);
372 } 344 }
373} 345}
374 346
375/* Get first directory entry (internal) */ 347/* Get first directory entry(internal) */
376static WIN32_FIND_DATAW* 348static WIN32_FIND_DATAW*
377dirent_first( 349dirent_first(_WDIR *dirp)
378 _WDIR *dirp)
379{ 350{
380 WIN32_FIND_DATAW *datap; 351 WIN32_FIND_DATAW *datap;
381 352
382 /* Open directory and retrieve the first entry */ 353 /* Open directory and retrieve the first entry */
383 dirp->handle = FindFirstFileW (dirp->patt, &dirp->data); 354 dirp->handle = FindFirstFileW(dirp->patt, &dirp->data);
384 if (dirp->handle != INVALID_HANDLE_VALUE) { 355 if (dirp->handle != INVALID_HANDLE_VALUE) {
385 356
386 /* a directory entry is now waiting in memory */ 357 /* a directory entry is now waiting in memory */
387 datap = &dirp->data; 358 datap = &dirp->data;
388 dirp->cached = 1; 359 dirp->cached = 1;
389 360
390 } else { 361 } else {
391 362
392 /* Failed to re-open directory: no directory entry in memory */ 363 /* Failed to re-open directory: no directory entry in memory */
393 dirp->cached = 0; 364 dirp->cached = 0;
394 datap = NULL; 365 datap = NULL;
395 366
396 } 367 }
397 return datap; 368 return datap;
398} 369}
399 370
400/* Get next directory entry (internal) */ 371/* Get next directory entry(internal) */
401static WIN32_FIND_DATAW* 372static WIN32_FIND_DATAW*
402dirent_next( 373dirent_next(_WDIR *dirp)
403 _WDIR *dirp)
404{ 374{
405 WIN32_FIND_DATAW *p; 375 WIN32_FIND_DATAW *p;
406 376
407 /* Get next directory entry */ 377 /* Get next directory entry */
408 if (dirp->cached != 0) { 378 if (dirp->cached != 0) {
409 379
410 /* A valid directory entry already in memory */ 380 /* A valid directory entry already in memory */
411 p = &dirp->data; 381 p = &dirp->data;
412 dirp->cached = 0; 382 dirp->cached = 0;
413 383
414 } else if (dirp->handle != INVALID_HANDLE_VALUE) { 384 } else if (dirp->handle != INVALID_HANDLE_VALUE) {
415 385
416 /* Get the next directory entry from stream */ 386 /* Get the next directory entry from stream */
417 if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) { 387 if (FindNextFileW(dirp->handle, &dirp->data) != FALSE) {
418 /* Got a file */ 388 /* Got a file */
419 p = &dirp->data; 389 p = &dirp->data;
420 } else { 390 } else {
421 /* The very last entry has been processed or an error occured */ 391 /* The very last entry has been processed or an error occured */
422 FindClose (dirp->handle); 392 FindClose(dirp->handle);
423 dirp->handle = INVALID_HANDLE_VALUE; 393 dirp->handle = INVALID_HANDLE_VALUE;
424 p = NULL; 394 p = NULL;
425 } 395 }
426 396
427 } else { 397 } else {
428 398
429 /* End of directory stream reached */ 399 /* End of directory stream reached */
430 p = NULL; 400 p = NULL;
431 401
432 } 402 }
433 403
434 return p; 404 return p;
435} 405}
436 406
437/* 407/*
438 * Open directory stream using plain old C-string. 408 * Open directory stream using plain old C-string.
439 */ 409 */
440static DIR* 410static DIR*
441opendir( 411opendir(const char *dirname)
442 const char *dirname)
443{ 412{
444 struct DIR *dirp; 413 struct DIR *dirp;
445 int error; 414 int error;
446 415
447 /* Must have directory name */ 416 /* Must have directory name */
448 if (dirname == NULL || dirname[0] == '\0') { 417 if (dirname == NULL || dirname[0] == '\0') {
449 dirent_set_errno (ENOENT); 418 _set_errno(ENOENT);
450 return NULL; 419 return NULL;
451 } 420 }
452 421
453 /* Allocate memory for DIR structure */ 422 /* Allocate memory for DIR structure */
454 dirp = (DIR*) malloc (sizeof (struct DIR)); 423 dirp =(DIR*) malloc(sizeof(struct DIR));
455 if (dirp) { 424 if (dirp) {
456 wchar_t wname[PATH_MAX]; 425 wchar_t wname[PATH_MAX];
457 size_t n; 426 size_t n;
458 427
459 /* Convert directory name to wide-character string */ 428 /* Convert directory name to wide-character string */
460 error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX); 429 error = dirent_mbstowcs_s(&n, wname, PATH_MAX, dirname, PATH_MAX);
461 if (!error) { 430 if (!error) {
462 431
463 /* Open directory stream using wide-character name */ 432 /* Open directory stream using wide-character name */
464 dirp->wdirp = _wopendir (wname); 433 dirp->wdirp = _wopendir(wname);
465 if (dirp->wdirp) { 434 if (dirp->wdirp) {
466 /* Directory stream opened */ 435 /* Directory stream opened */
467 error = 0; 436 error = 0;
468 } else { 437 } else {
469 /* Failed to open directory stream */ 438 /* Failed to open directory stream */
470 error = 1; 439 error = 1;
471 } 440 }
472 441
473 } else { 442 } else {
474 /* 443 /*
475 * Cannot convert file name to wide-character string. This 444 * Cannot convert file name to wide-character string. This
476 * occurs if the string contains invalid multi-byte sequences or 445 * occurs if the string contains invalid multi-byte sequences or
477 * the output buffer is too small to contain the resulting 446 * the output buffer is too small to contain the resulting
478 * string. 447 * string.
479 */ 448 */
480 error = 1; 449 error = 1;
481 } 450 }
482 451
483 } else { 452 } else {
484 /* Cannot allocate DIR structure */ 453 /* Cannot allocate DIR structure */
485 error = 1; 454 error = 1;
486 } 455 }
487 456
488 /* Clean up in case of error */ 457 /* Clean up in case of error */
489 if (error && dirp) { 458 if (error && dirp) {
490 free (dirp); 459 free(dirp);
491 dirp = NULL; 460 dirp = NULL;
492 } 461 }
493 462
494 return dirp; 463 return dirp;
495} 464}
496 465
497/* 466/*
@@ -501,257 +470,142 @@ opendir(
501 * readdir() are represented in the default ANSI code page while any output to 470 * readdir() are represented in the default ANSI code page while any output to
502 * console is typically formatted on another code page. Thus, non-ASCII 471 * console is typically formatted on another code page. Thus, non-ASCII
503 * characters in file names will not usually display correctly on console. The 472 * characters in file names will not usually display correctly on console. The
504 * problem can be fixed in two ways: (1) change the character set of console 473 * problem can be fixed in two ways:(1) change the character set of console
505 * to 1252 using chcp utility and use Lucida Console font, or (2) use 474 * to 1252 using chcp utility and use Lucida Console font, or(2) use
506 * _cprintf function when writing to console. The _cprinf() will re-encode 475 * _cprintf function when writing to console. The _cprinf() will re-encode
507 * ANSI strings to the console code page so many non-ASCII characters will 476 * ANSI strings to the console code page so many non-ASCII characters will
508 * display correcly. 477 * display correcly.
509 */ 478 */
510static struct dirent* 479static struct dirent*
511readdir( 480readdir(DIR *dirp)
512 DIR *dirp)
513{ 481{
514 WIN32_FIND_DATAW *datap; 482 WIN32_FIND_DATAW *datap;
515 struct dirent *entp; 483 struct dirent *entp;
516 484
517 /* Read next directory entry */ 485 /* Read next directory entry */
518 datap = dirent_next (dirp->wdirp); 486 datap = dirent_next(dirp->wdirp);
519 if (datap) { 487 if (datap) {
520 size_t n; 488 size_t n;
521 int error; 489 int error;
522 490
523 /* Attempt to convert file name to multi-byte string */ 491 /* Attempt to convert file name to multi-byte string */
524 error = dirent_wcstombs_s( 492 error = dirent_wcstombs_s(
525 &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX); 493 &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
526 494
527 /* 495 /*
528 * If the file name cannot be represented by a multi-byte string, 496 * If the file name cannot be represented by a multi-byte string,
529 * then attempt to use old 8+3 file name. This allows traditional 497 * then attempt to use old 8+3 file name. This allows traditional
530 * Unix-code to access some file names despite of unicode 498 * Unix-code to access some file names despite of unicode
531 * characters, although file names may seem unfamiliar to the user. 499 * characters, although file names may seem unfamiliar to the user.
532 * 500 *
533 * Be ware that the code below cannot come up with a short file 501 * Be ware that the code below cannot come up with a short file
534 * name unless the file system provides one. At least 502 * name unless the file system provides one. At least
535 * VirtualBox shared folders fail to do this. 503 * VirtualBox shared folders fail to do this.
536 */ 504 */
537 if (error && datap->cAlternateFileName[0] != '\0') { 505 if (error && datap->cAlternateFileName[0] != '\0') {
538 error = dirent_wcstombs_s( 506 error = dirent_wcstombs_s(
539 &n, dirp->ent.d_name, PATH_MAX, 507 &n, dirp->ent.d_name, PATH_MAX,
540 datap->cAlternateFileName, PATH_MAX); 508 datap->cAlternateFileName, PATH_MAX);
541 } 509 }
542 510
543 if (!error) { 511 if (!error) {
544 DWORD attr; 512 DWORD attr;
545 513
546 /* Initialize directory entry for return */ 514 /* Initialize directory entry for return */
547 entp = &dirp->ent; 515 entp = &dirp->ent;
548 516
549 /* Length of file name excluding zero terminator */ 517 /* Length of file name excluding zero terminator */
550 entp->d_namlen = n - 1; 518 entp->d_namlen = n - 1;
551 519
552 /* File attributes */ 520 /* File attributes */
553 attr = datap->dwFileAttributes; 521 attr = datap->dwFileAttributes;
554 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { 522 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
555 entp->d_type = DT_CHR; 523 entp->d_type = DT_CHR;
556 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { 524 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
557 entp->d_type = DT_DIR; 525 entp->d_type = DT_DIR;
558 } else { 526 } else {
559 entp->d_type = DT_REG; 527 entp->d_type = DT_REG;
560 } 528 }
561 529
562 /* Reset dummy fields */ 530 /* Reset dummy fields */
563 entp->d_ino = 0; 531 entp->d_ino = 0;
564 entp->d_reclen = sizeof (struct dirent); 532 entp->d_reclen = sizeof(struct dirent);
565 533
566 } else { 534 } else {
567 /* 535 /*
568 * Cannot convert file name to multi-byte string so construct 536 * Cannot convert file name to multi-byte string so construct
569 * an errornous directory entry and return that. Note that 537 * an errornous directory entry and return that. Note that
570 * we cannot return NULL as that would stop the processing 538 * we cannot return NULL as that would stop the processing
571 * of directory entries completely. 539 * of directory entries completely.
572 */ 540 */
573 entp = &dirp->ent; 541 entp = &dirp->ent;
574 entp->d_name[0] = '?'; 542 entp->d_name[0] = '?';
575 entp->d_name[1] = '\0'; 543 entp->d_name[1] = '\0';
576 entp->d_namlen = 1; 544 entp->d_namlen = 1;
577 entp->d_type = DT_UNKNOWN; 545 entp->d_type = DT_UNKNOWN;
578 entp->d_ino = 0; 546 entp->d_ino = 0;
579 entp->d_reclen = 0; 547 entp->d_reclen = 0;
580 } 548 }
581 549
582 } else { 550 } else {
583 /* No more directory entries */ 551 /* No more directory entries */
584 entp = NULL; 552 entp = NULL;
585 } 553 }
586 554
587 return entp; 555 return entp;
588} 556}
589 557
590/* 558/*
591 * Close directory stream. 559 * Close directory stream.
592 */ 560 */
593static int 561static int
594closedir( 562closedir(DIR *dirp)
595 DIR *dirp)
596{ 563{
597 int ok; 564 int ok;
598 if (dirp) { 565 if (dirp) {
599 566
600 /* Close wide-character directory stream */ 567 /* Close wide-character directory stream */
601 ok = _wclosedir (dirp->wdirp); 568 ok = _wclosedir(dirp->wdirp);
602 dirp->wdirp = NULL; 569 dirp->wdirp = NULL;
603 570
604 /* Release multi-byte character version */ 571 /* Release multi-byte character version */
605 free (dirp); 572 free(dirp);
606 573
607 } else { 574 } else {
608 575
609 /* Invalid directory stream */ 576 /* Invalid directory stream */
610 dirent_set_errno (EBADF); 577 _set_errno(EBADF);
611 ok = /*failure*/-1; 578 ok = /*failure*/-1;
612 579
613 } 580 }
614 return ok; 581 return ok;
615} 582}
616 583
617/* 584/*
618 * Rewind directory stream to beginning. 585 * Rewind directory stream to beginning.
619 */ 586 */
620static void 587static void
621rewinddir( 588rewinddir(DIR* dirp)
622 DIR* dirp)
623{ 589{
624 /* Rewind wide-character string directory stream */ 590 /* Rewind wide-character string directory stream */
625 _wrewinddir (dirp->wdirp); 591 _wrewinddir(dirp->wdirp);
626} 592}
627 593
628/* Convert multi-byte string to wide character string */ 594/* Convert multi-byte string to wide character string */
629static int 595static int
630dirent_mbstowcs_s( 596dirent_mbstowcs_s(size_t *pReturnValue, wchar_t *wcstr,
631 size_t *pReturnValue, 597 size_t sizeInWords, const char *mbstr, size_t count)
632 wchar_t *wcstr,
633 size_t sizeInWords,
634 const char *mbstr,
635 size_t count)
636{ 598{
637 int error; 599 return mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count);
638
639#if defined(_MSC_VER) && _MSC_VER >= 1400
640
641 /* Microsoft Visual Studio 2005 or later */
642 error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
643
644#else
645
646 /* Older Visual Studio or non-Microsoft compiler */
647 size_t n;
648
649 /* Convert to wide-character string (or count characters) */
650 n = mbstowcs (wcstr, mbstr, sizeInWords);
651 if (!wcstr || n < count) {
652
653 /* Zero-terminate output buffer */
654 if (wcstr && sizeInWords) {
655 if (n >= sizeInWords) {
656 n = sizeInWords - 1;
657 }
658 wcstr[n] = 0;
659 }
660
661 /* Length of resuting multi-byte string WITH zero terminator */
662 if (pReturnValue) {
663 *pReturnValue = n + 1;
664 }
665
666 /* Success */
667 error = 0;
668
669 } else {
670
671 /* Could not convert string */
672 error = 1;
673
674 }
675
676#endif
677
678 return error;
679} 600}
680 601
681/* Convert wide-character string to multi-byte string */ 602/* Convert wide-character string to multi-byte string */
682static int 603static int
683dirent_wcstombs_s( 604dirent_wcstombs_s(size_t *pReturnValue, char *mbstr,
684 size_t *pReturnValue, 605 size_t sizeInBytes, /* max size of mbstr */
685 char *mbstr, 606 const wchar_t *wcstr, size_t count)
686 size_t sizeInBytes, /* max size of mbstr */
687 const wchar_t *wcstr,
688 size_t count)
689{ 607{
690 int error; 608 return wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count);
691
692#if defined(_MSC_VER) && _MSC_VER >= 1400
693
694 /* Microsoft Visual Studio 2005 or later */
695 error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
696
697#else
698
699 /* Older Visual Studio or non-Microsoft compiler */
700 size_t n;
701
702 /* Convert to multi-byte string (or count the number of bytes needed) */
703 n = wcstombs (mbstr, wcstr, sizeInBytes);
704 if (!mbstr || n < count) {
705
706 /* Zero-terminate output buffer */
707 if (mbstr && sizeInBytes) {
708 if (n >= sizeInBytes) {
709 n = sizeInBytes - 1;
710 }
711 mbstr[n] = '\0';
712 }
713
714 /* Lenght of resulting multi-bytes string WITH zero-terminator */
715 if (pReturnValue) {
716 *pReturnValue = n + 1;
717 }
718
719 /* Success */
720 error = 0;
721
722 } else {
723
724 /* Cannot convert string */
725 error = 1;
726
727 }
728
729#endif
730
731 return error;
732} 609}
733 610
734/* Set errno variable */
735static void
736dirent_set_errno(
737 int error)
738{
739#if defined(_MSC_VER) && _MSC_VER >= 1400
740
741 /* Microsoft Visual Studio 2005 and later */
742 _set_errno (error);
743
744#else
745
746 /* Non-Microsoft compiler or older Microsoft compiler */
747 errno = error;
748
749#endif
750}
751
752
753#ifdef __cplusplus
754}
755#endif
756#endif /*DIRENT_H*/ 611#endif /*DIRENT_H*/
757