source: libcf++/trunk/src/dirent.win32.hpp@ 4

Last change on this file since 4 was 4, checked in by cheese, 9 years ago

#1 commit prototype

File size: 23.2 KB
Line 
1/*
2 * dirent.h - dirent API for Microsoft Visual Studio
3 *
4 * Copyright (C) 2006-2012 Toni Ronkko
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * ``Software''), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * $Id: dirent.h,v 1.20 2014/03/19 17:52:23 tronkko Exp $
26 */
27#ifndef DIRENT_H
28#define DIRENT_H
29
30/*
31 * Define architecture flags so we don't need to include windows.h.
32 * Avoiding windows.h makes it simpler to use windows sockets in conjunction
33 * with dirent.h.
34 */
35#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
36# define _X86_
37#endif
38#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
39#define _AMD64_
40#endif
41
42#include <stdio.h>
43#include <stdarg.h>
44#include <windef.h>
45#include <winbase.h>
46#include <wchar.h>
47#include <string.h>
48#include <stdlib.h>
49#include <malloc.h>
50#include <sys/types.h>
51#include <sys/stat.h>
52#include <errno.h>
53
54/* Indicates that d_type field is available in dirent structure */
55#define _DIRENT_HAVE_D_TYPE
56
57/* Indicates that d_namlen field is available in dirent structure */
58#define _DIRENT_HAVE_D_NAMLEN
59
60/* Entries missing from MSVC 6.0 */
61#if !defined(FILE_ATTRIBUTE_DEVICE)
62# define FILE_ATTRIBUTE_DEVICE 0x40
63#endif
64
65/* File type and permission flags for stat() */
66#if !defined(S_IFMT)
67# define S_IFMT _S_IFMT /* File type mask */
68#endif
69#if !defined(S_IFDIR)
70# define S_IFDIR _S_IFDIR /* Directory */
71#endif
72#if !defined(S_IFCHR)
73# define S_IFCHR _S_IFCHR /* Character device */
74#endif
75#if !defined(S_IFFIFO)
76# define S_IFFIFO _S_IFFIFO /* Pipe */
77#endif
78#if !defined(S_IFREG)
79# define S_IFREG _S_IFREG /* Regular file */
80#endif
81#if !defined(S_IREAD)
82# define S_IREAD _S_IREAD /* Read permission */
83#endif
84#if !defined(S_IWRITE)
85# define S_IWRITE _S_IWRITE /* Write permission */
86#endif
87#if !defined(S_IEXEC)
88# define S_IEXEC _S_IEXEC /* Execute permission */
89#endif
90#if !defined(S_IFIFO)
91# define S_IFIFO _S_IFIFO /* Pipe */
92#endif
93#if !defined(S_IFBLK)
94# define S_IFBLK 0 /* Block device */
95#endif
96#if !defined(S_IFLNK)
97# define S_IFLNK 0 /* Link */
98#endif
99#if !defined(S_IFSOCK)
100# define S_IFSOCK 0 /* Socket */
101#endif
102
103#if 0 /* not used in dirent */
104#if defined(_MSC_VER)
105# define S_IRUSR S_IREAD /* Read user */
106# define S_IWUSR S_IWRITE /* Write user */
107# define S_IXUSR 0 /* Execute user */
108# define S_IRGRP 0 /* Read group */
109# define S_IWGRP 0 /* Write group */
110# define S_IXGRP 0 /* Execute group */
111# define S_IROTH 0 /* Read others */
112# define S_IWOTH 0 /* Write others */
113# define S_IXOTH 0 /* Execute others */
114#endif
115#endif
116
117/* Maximum length of file name */
118#if !defined(PATH_MAX)
119# define PATH_MAX MAX_PATH
120#endif
121#if !defined(FILENAME_MAX)
122# define FILENAME_MAX MAX_PATH
123#endif
124#if !defined(NAME_MAX)
125# define NAME_MAX FILENAME_MAX
126#endif
127
128/* File type flags for d_type */
129#define DT_UNKNOWN 0
130#define DT_REG S_IFREG
131#define DT_DIR S_IFDIR
132#define DT_FIFO S_IFIFO
133#define DT_SOCK S_IFSOCK
134#define DT_CHR S_IFCHR
135#define DT_BLK S_IFBLK
136#define DT_LNK S_IFLNK
137
138/* Macros for converting between st_mode and d_type */
139#define IFTODT(mode) ((mode) & S_IFMT)
140#define DTTOIF(type) (type)
141
142/*
143 * File type macros. Note that block devices, sockets and links cannot be
144 * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
145 * only defined for compatibility. These macros should always return false
146 * on Windows.
147 */
148#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
149#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
150#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
151#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
152#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
153#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
154#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
155
156/* Return the exact length of d_namlen without zero terminator */
157#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
158
159/* Return number of bytes needed to store d_namlen */
160#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
161
162
163#ifdef __cplusplus
164extern "C" {
165#endif
166
167
168/* Wide-character version */
169struct _wdirent {
170 long d_ino; /* Always zero */
171 unsigned short d_reclen; /* Structure size */
172 size_t d_namlen; /* Length of name without \0 */
173 int d_type; /* File type */
174 wchar_t d_name[PATH_MAX]; /* File name */
175};
176typedef struct _wdirent _wdirent;
177
178struct _WDIR {
179 struct _wdirent ent; /* Current directory entry */
180 WIN32_FIND_DATAW data; /* Private file data */
181 int cached; /* True if data is valid */
182 HANDLE handle; /* Win32 search handle */
183 wchar_t *patt; /* Initial directory name */
184};
185typedef struct _WDIR _WDIR;
186
187static _WDIR *_wopendir (const wchar_t *dirname);
188static struct _wdirent *_wreaddir (_WDIR *dirp);
189static int _wclosedir (_WDIR *dirp);
190static void _wrewinddir (_WDIR* dirp);
191
192
193/* For compatibility with Symbian */
194#define wdirent _wdirent
195#define WDIR _WDIR
196#define wopendir _wopendir
197#define wreaddir _wreaddir
198#define wclosedir _wclosedir
199#define wrewinddir _wrewinddir
200
201
202/* Multi-byte character versions */
203struct dirent {
204 long d_ino; /* Always zero */
205 unsigned short d_reclen; /* Structure size */
206 size_t d_namlen; /* Length of name without \0 */
207 int d_type; /* File type */
208 char d_name[PATH_MAX]; /* File name */
209};
210typedef struct dirent dirent;
211
212struct DIR {
213 struct dirent ent;
214 struct _WDIR *wdirp;
215};
216typedef struct DIR DIR;
217
218static DIR *opendir (const char *dirname);
219static struct dirent *readdir (DIR *dirp);
220static int closedir (DIR *dirp);
221static void rewinddir (DIR* dirp);
222
223
224/* Internal utility functions */
225static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
226static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
227
228static int dirent_mbstowcs_s(
229 size_t *pReturnValue,
230 wchar_t *wcstr,
231 size_t sizeInWords,
232 const char *mbstr,
233 size_t count);
234
235static int dirent_wcstombs_s(
236 size_t *pReturnValue,
237 char *mbstr,
238 size_t sizeInBytes,
239 const wchar_t *wcstr,
240 size_t count);
241
242static void dirent_set_errno (int error);
243
244/*
245 * Open directory stream DIRNAME for read and return a pointer to the
246 * internal working area that is used to retrieve individual directory
247 * entries.
248 */
249static _WDIR*
250_wopendir(
251 const wchar_t *dirname)
252{
253 _WDIR *dirp = NULL;
254 int error;
255
256 /* Must have directory name */
257 if (dirname == NULL || dirname[0] == '\0') {
258 dirent_set_errno (ENOENT);
259 return NULL;
260 }
261
262 /* Allocate new _WDIR structure */
263 dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
264 if (dirp != NULL) {
265 DWORD n;
266
267 /* Reset _WDIR structure */
268 dirp->handle = INVALID_HANDLE_VALUE;
269 dirp->patt = NULL;
270 dirp->cached = 0;
271
272 /* Compute the length of full path plus zero terminator */
273 n = GetFullPathNameW (dirname, 0, NULL, NULL);
274
275 /* Allocate room for absolute directory name and search pattern */
276 dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
277 if (dirp->patt) {
278
279 /*
280 * Convert relative directory name to an absolute one. This
281 * allows rewinddir() to function correctly even when current
282 * working directory is changed between opendir() and rewinddir().
283 */
284 n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
285 if (n > 0) {
286 wchar_t *p;
287
288 /* Append search pattern \* to the directory name */
289 p = dirp->patt + n;
290 if (dirp->patt < p) {
291 switch (p[-1]) {
292 case '\\':
293 case '/':
294 case ':':
295 /* Directory ends in path separator, e.g. c:\temp\ */
296 /*NOP*/;
297 break;
298
299 default:
300 /* Directory name doesn't end in path separator */
301 *p++ = '\\';
302 }
303 }
304 *p++ = '*';
305 *p = '\0';
306
307 /* Open directory stream and retrieve the first entry */
308 if (dirent_first (dirp)) {
309 /* Directory stream opened successfully */
310 error = 0;
311 } else {
312 /* Cannot retrieve first entry */
313 error = 1;
314 dirent_set_errno (ENOENT);
315 }
316
317 } else {
318 /* Cannot retrieve full path name */
319 dirent_set_errno (ENOENT);
320 error = 1;
321 }
322
323 } else {
324 /* Cannot allocate memory for search pattern */
325 error = 1;
326 }
327
328 } else {
329 /* Cannot allocate _WDIR structure */
330 error = 1;
331 }
332
333 /* Clean up in case of error */
334 if (error && dirp) {
335 _wclosedir (dirp);
336 dirp = NULL;
337 }
338
339 return dirp;
340}
341
342/*
343 * Read next directory entry. The directory entry is returned in dirent
344 * structure in the d_name field. Individual directory entries returned by
345 * this function include regular files, sub-directories, pseudo-directories
346 * "." and ".." as well as volume labels, hidden files and system files.
347 */
348static struct _wdirent*
349_wreaddir(
350 _WDIR *dirp)
351{
352 WIN32_FIND_DATAW *datap;
353 struct _wdirent *entp;
354
355 /* Read next directory entry */
356 datap = dirent_next (dirp);
357 if (datap) {
358 size_t n;
359 DWORD attr;
360
361 /* Pointer to directory entry to return */
362 entp = &dirp->ent;
363
364 /*
365 * Copy file name as wide-character string. If the file name is too
366 * long to fit in to the destination buffer, then truncate file name
367 * to PATH_MAX characters and zero-terminate the buffer.
368 */
369 n = 0;
370 while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
371 entp->d_name[n] = datap->cFileName[n];
372 n++;
373 }
374 dirp->ent.d_name[n] = 0;
375
376 /* Length of file name excluding zero terminator */
377 entp->d_namlen = n;
378
379 /* File type */
380 attr = datap->dwFileAttributes;
381 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
382 entp->d_type = DT_CHR;
383 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
384 entp->d_type = DT_DIR;
385 } else {
386 entp->d_type = DT_REG;
387 }
388
389 /* Reset dummy fields */
390 entp->d_ino = 0;
391 entp->d_reclen = sizeof (struct _wdirent);
392
393 } else {
394
395 /* Last directory entry read */
396 entp = NULL;
397
398 }
399
400 return entp;
401}
402
403/*
404 * Close directory stream opened by opendir() function. This invalidates the
405 * DIR structure as well as any directory entry read previously by
406 * _wreaddir().
407 */
408static int
409_wclosedir(
410 _WDIR *dirp)
411{
412 int ok;
413 if (dirp) {
414
415 /* Release search handle */
416 if (dirp->handle != INVALID_HANDLE_VALUE) {
417 FindClose (dirp->handle);
418 dirp->handle = INVALID_HANDLE_VALUE;
419 }
420
421 /* Release search pattern */
422 if (dirp->patt) {
423 free (dirp->patt);
424 dirp->patt = NULL;
425 }
426
427 /* Release directory structure */
428 free (dirp);
429 ok = /*success*/0;
430
431 } else {
432 /* Invalid directory stream */
433 dirent_set_errno (EBADF);
434 ok = /*failure*/-1;
435 }
436 return ok;
437}
438
439/*
440 * Rewind directory stream such that _wreaddir() returns the very first
441 * file name again.
442 */
443static void
444_wrewinddir(
445 _WDIR* dirp)
446{
447 if (dirp) {
448 /* Release existing search handle */
449 if (dirp->handle != INVALID_HANDLE_VALUE) {
450 FindClose (dirp->handle);
451 }
452
453 /* Open new search handle */
454 dirent_first (dirp);
455 }
456}
457
458/* Get first directory entry (internal) */
459static WIN32_FIND_DATAW*
460dirent_first(
461 _WDIR *dirp)
462{
463 WIN32_FIND_DATAW *datap;
464
465 /* Open directory and retrieve the first entry */
466 dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
467 if (dirp->handle != INVALID_HANDLE_VALUE) {
468
469 /* a directory entry is now waiting in memory */
470 datap = &dirp->data;
471 dirp->cached = 1;
472
473 } else {
474
475 /* Failed to re-open directory: no directory entry in memory */
476 dirp->cached = 0;
477 datap = NULL;
478
479 }
480 return datap;
481}
482
483/* Get next directory entry (internal) */
484static WIN32_FIND_DATAW*
485dirent_next(
486 _WDIR *dirp)
487{
488 WIN32_FIND_DATAW *p;
489
490 /* Get next directory entry */
491 if (dirp->cached != 0) {
492
493 /* A valid directory entry already in memory */
494 p = &dirp->data;
495 dirp->cached = 0;
496
497 } else if (dirp->handle != INVALID_HANDLE_VALUE) {
498
499 /* Get the next directory entry from stream */
500 if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
501 /* Got a file */
502 p = &dirp->data;
503 } else {
504 /* The very last entry has been processed or an error occured */
505 FindClose (dirp->handle);
506 dirp->handle = INVALID_HANDLE_VALUE;
507 p = NULL;
508 }
509
510 } else {
511
512 /* End of directory stream reached */
513 p = NULL;
514
515 }
516
517 return p;
518}
519
520/*
521 * Open directory stream using plain old C-string.
522 */
523static DIR*
524opendir(
525 const char *dirname)
526{
527 struct DIR *dirp;
528 int error;
529
530 /* Must have directory name */
531 if (dirname == NULL || dirname[0] == '\0') {
532 dirent_set_errno (ENOENT);
533 return NULL;
534 }
535
536 /* Allocate memory for DIR structure */
537 dirp = (DIR*) malloc (sizeof (struct DIR));
538 if (dirp) {
539 wchar_t wname[PATH_MAX];
540 size_t n;
541
542 /* Convert directory name to wide-character string */
543 error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
544 if (!error) {
545
546 /* Open directory stream using wide-character name */
547 dirp->wdirp = _wopendir (wname);
548 if (dirp->wdirp) {
549 /* Directory stream opened */
550 error = 0;
551 } else {
552 /* Failed to open directory stream */
553 error = 1;
554 }
555
556 } else {
557 /*
558 * Cannot convert file name to wide-character string. This
559 * occurs if the string contains invalid multi-byte sequences or
560 * the output buffer is too small to contain the resulting
561 * string.
562 */
563 error = 1;
564 }
565
566 } else {
567 /* Cannot allocate DIR structure */
568 error = 1;
569 }
570
571 /* Clean up in case of error */
572 if (error && dirp) {
573 free (dirp);
574 dirp = NULL;
575 }
576
577 return dirp;
578}
579
580/*
581 * Read next directory entry.
582 *
583 * When working with text consoles, please note that file names returned by
584 * readdir() are represented in the default ANSI code page while any output to
585 * console is typically formatted on another code page. Thus, non-ASCII
586 * characters in file names will not usually display correctly on console. The
587 * problem can be fixed in two ways: (1) change the character set of console
588 * to 1252 using chcp utility and use Lucida Console font, or (2) use
589 * _cprintf function when writing to console. The _cprinf() will re-encode
590 * ANSI strings to the console code page so many non-ASCII characters will
591 * display correcly.
592 */
593static struct dirent*
594readdir(
595 DIR *dirp)
596{
597 WIN32_FIND_DATAW *datap;
598 struct dirent *entp;
599
600 /* Read next directory entry */
601 datap = dirent_next (dirp->wdirp);
602 if (datap) {
603 size_t n;
604 int error;
605
606 /* Attempt to convert file name to multi-byte string */
607 error = dirent_wcstombs_s(
608 &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
609
610 /*
611 * If the file name cannot be represented by a multi-byte string,
612 * then attempt to use old 8+3 file name. This allows traditional
613 * Unix-code to access some file names despite of unicode
614 * characters, although file names may seem unfamiliar to the user.
615 *
616 * Be ware that the code below cannot come up with a short file
617 * name unless the file system provides one. At least
618 * VirtualBox shared folders fail to do this.
619 */
620 if (error && datap->cAlternateFileName[0] != '\0') {
621 error = dirent_wcstombs_s(
622 &n, dirp->ent.d_name, PATH_MAX,
623 datap->cAlternateFileName, PATH_MAX);
624 }
625
626 if (!error) {
627 DWORD attr;
628
629 /* Initialize directory entry for return */
630 entp = &dirp->ent;
631
632 /* Length of file name excluding zero terminator */
633 entp->d_namlen = n - 1;
634
635 /* File attributes */
636 attr = datap->dwFileAttributes;
637 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
638 entp->d_type = DT_CHR;
639 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
640 entp->d_type = DT_DIR;
641 } else {
642 entp->d_type = DT_REG;
643 }
644
645 /* Reset dummy fields */
646 entp->d_ino = 0;
647 entp->d_reclen = sizeof (struct dirent);
648
649 } else {
650 /*
651 * Cannot convert file name to multi-byte string so construct
652 * an errornous directory entry and return that. Note that
653 * we cannot return NULL as that would stop the processing
654 * of directory entries completely.
655 */
656 entp = &dirp->ent;
657 entp->d_name[0] = '?';
658 entp->d_name[1] = '\0';
659 entp->d_namlen = 1;
660 entp->d_type = DT_UNKNOWN;
661 entp->d_ino = 0;
662 entp->d_reclen = 0;
663 }
664
665 } else {
666 /* No more directory entries */
667 entp = NULL;
668 }
669
670 return entp;
671}
672
673/*
674 * Close directory stream.
675 */
676static int
677closedir(
678 DIR *dirp)
679{
680 int ok;
681 if (dirp) {
682
683 /* Close wide-character directory stream */
684 ok = _wclosedir (dirp->wdirp);
685 dirp->wdirp = NULL;
686
687 /* Release multi-byte character version */
688 free (dirp);
689
690 } else {
691
692 /* Invalid directory stream */
693 dirent_set_errno (EBADF);
694 ok = /*failure*/-1;
695
696 }
697 return ok;
698}
699
700/*
701 * Rewind directory stream to beginning.
702 */
703static void
704rewinddir(
705 DIR* dirp)
706{
707 /* Rewind wide-character string directory stream */
708 _wrewinddir (dirp->wdirp);
709}
710
711/* Convert multi-byte string to wide character string */
712static int
713dirent_mbstowcs_s(
714 size_t *pReturnValue,
715 wchar_t *wcstr,
716 size_t sizeInWords,
717 const char *mbstr,
718 size_t count)
719{
720 int error;
721
722#if defined(_MSC_VER) && _MSC_VER >= 1400
723
724 /* Microsoft Visual Studio 2005 or later */
725 error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
726
727#else
728
729 /* Older Visual Studio or non-Microsoft compiler */
730 size_t n;
731
732 /* Convert to wide-character string (or count characters) */
733 n = mbstowcs (wcstr, mbstr, sizeInWords);
734 if (!wcstr || n < count) {
735
736 /* Zero-terminate output buffer */
737 if (wcstr && sizeInWords) {
738 if (n >= sizeInWords) {
739 n = sizeInWords - 1;
740 }
741 wcstr[n] = 0;
742 }
743
744 /* Length of resuting multi-byte string WITH zero terminator */
745 if (pReturnValue) {
746 *pReturnValue = n + 1;
747 }
748
749 /* Success */
750 error = 0;
751
752 } else {
753
754 /* Could not convert string */
755 error = 1;
756
757 }
758
759#endif
760
761 return error;
762}
763
764/* Convert wide-character string to multi-byte string */
765static int
766dirent_wcstombs_s(
767 size_t *pReturnValue,
768 char *mbstr,
769 size_t sizeInBytes, /* max size of mbstr */
770 const wchar_t *wcstr,
771 size_t count)
772{
773 int error;
774
775#if defined(_MSC_VER) && _MSC_VER >= 1400
776
777 /* Microsoft Visual Studio 2005 or later */
778 error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
779
780#else
781
782 /* Older Visual Studio or non-Microsoft compiler */
783 size_t n;
784
785 /* Convert to multi-byte string (or count the number of bytes needed) */
786 n = wcstombs (mbstr, wcstr, sizeInBytes);
787 if (!mbstr || n < count) {
788
789 /* Zero-terminate output buffer */
790 if (mbstr && sizeInBytes) {
791 if (n >= sizeInBytes) {
792 n = sizeInBytes - 1;
793 }
794 mbstr[n] = '\0';
795 }
796
797 /* Lenght of resulting multi-bytes string WITH zero-terminator */
798 if (pReturnValue) {
799 *pReturnValue = n + 1;
800 }
801
802 /* Success */
803 error = 0;
804
805 } else {
806
807 /* Cannot convert string */
808 error = 1;
809
810 }
811
812#endif
813
814 return error;
815}
816
817/* Set errno variable */
818static void
819dirent_set_errno(
820 int error)
821{
822#if defined(_MSC_VER) && _MSC_VER >= 1400
823
824 /* Microsoft Visual Studio 2005 and later */
825 _set_errno (error);
826
827#else
828
829 /* Non-Microsoft compiler or older Microsoft compiler */
830 errno = error;
831
832#endif
833}
834
835
836#ifdef __cplusplus
837}
838#endif
839#endif /*DIRENT_H*/
840
Note: See TracBrowser for help on using the repository browser.