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