56 #if (!defined(_WIN32) && !defined(_WIN64))
58 #else // #if (!defined(_WIN32) && !defined(_WIN64))
68 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
71 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
83 #include <sys/types.h>
90 #define _DIRENT_HAVE_D_TYPE
93 #define _DIRENT_HAVE_D_NAMLEN
96 #if !defined(FILE_ATTRIBUTE_DEVICE)
97 # define FILE_ATTRIBUTE_DEVICE 0x40
102 # define S_IFMT _S_IFMT
104 #if !defined(S_IFDIR)
105 # define S_IFDIR _S_IFDIR
107 #if !defined(S_IFCHR)
108 # define S_IFCHR _S_IFCHR
110 #if !defined(S_IFFIFO)
111 # define S_IFFIFO _S_IFFIFO
113 #if !defined(S_IFREG)
114 # define S_IFREG _S_IFREG
116 #if !defined(S_IREAD)
117 # define S_IREAD _S_IREAD
119 #if !defined(S_IWRITE)
120 # define S_IWRITE _S_IWRITE
122 #if !defined(S_IEXEC)
123 # define S_IEXEC _S_IEXEC
125 #if !defined(S_IFIFO)
126 # define S_IFIFO _S_IFIFO
128 #if !defined(S_IFBLK)
131 #if !defined(S_IFLNK)
134 #if !defined(S_IFSOCK)
138 #if defined(_MSC_VER)
139 # define S_IRUSR S_IREAD
140 # define S_IWUSR S_IWRITE
151 #ifdef DIRENT_USES_UTF8_CHARS
154 # define PATH_MAX (MAX_PATH*4)
156 # define FILENAME_MAX MAX_PATH
158 # define NAME_MAX FILENAME_MAX
159 #else //DIRENT_USES_UTF8_CHARS
160 # if !defined(PATH_MAX)
161 # define PATH_MAX MAX_PATH
163 # if !defined(FILENAME_MAX)
164 # define FILENAME_MAX MAX_PATH
166 # if !defined(NAME_MAX)
167 # define NAME_MAX FILENAME_MAX
169 #endif //DIRENT_USES_UTF8_CHARS
173 #define DT_REG S_IFREG
174 #define DT_DIR S_IFDIR
175 #define DT_FIFO S_IFIFO
176 #define DT_SOCK S_IFSOCK
177 #define DT_CHR S_IFCHR
178 #define DT_BLK S_IFBLK
179 #define DT_LNK S_IFLNK
182 #define IFTODT(mode) ((mode) & S_IFMT)
183 #define DTTOIF(type) (type)
202 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
203 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
204 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
205 #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
206 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
207 #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
208 #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
211 #define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
214 #define _D_ALLOC_NAMLEN(p) (PATH_MAX)
225 unsigned short d_reclen;
228 wchar_t d_name[PATH_MAX];
230 typedef struct _wdirent _wdirent;
234 WIN32_FIND_DATAW data;
239 typedef struct _WDIR _WDIR;
241 static _WDIR *_wopendir (
const wchar_t *dirname);
242 static struct _wdirent *_wreaddir (_WDIR *dirp);
243 static int _wclosedir (_WDIR *dirp);
244 static void _wrewinddir (_WDIR* dirp);
248 #define wdirent _wdirent
250 #define wopendir _wopendir
251 #define wreaddir _wreaddir
252 #define wclosedir _wclosedir
253 #define wrewinddir _wrewinddir
259 unsigned short d_reclen;
262 char d_name[PATH_MAX];
264 typedef struct dirent dirent;
270 typedef struct DIR DIR;
272 static DIR *opendir (
const char *dirname);
273 static struct dirent *readdir (DIR *dirp);
274 static int closedir (DIR *dirp);
275 static void rewinddir (DIR* dirp);
279 static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
280 static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
282 static int dirent_mbstowcs_s(
283 size_t *pReturnValue,
289 static int dirent_wcstombs_s(
290 size_t *pReturnValue,
293 const wchar_t *wcstr,
296 static void dirent_set_errno (
int error);
305 const wchar_t *dirname)
311 if (dirname == NULL || dirname[0] ==
'\0') {
312 dirent_set_errno (ENOENT);
317 dirp = (_WDIR*) malloc (
sizeof (
struct _WDIR));
322 dirp->handle = INVALID_HANDLE_VALUE;
327 n = GetFullPathNameW (dirname, 0, NULL, NULL);
330 dirp->patt = (
wchar_t*) malloc (
sizeof (
wchar_t) * n + 16);
338 n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
344 if (dirp->patt < p) {
362 if (dirent_first (dirp)) {
368 dirent_set_errno (ENOENT);
373 dirent_set_errno (ENOENT);
402 static struct _wdirent*
406 WIN32_FIND_DATAW *datap;
407 struct _wdirent *entp;
410 datap = dirent_next (dirp);
424 while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
425 entp->d_name[n] = datap->cFileName[n];
428 dirp->ent.d_name[n] = 0;
434 attr = datap->dwFileAttributes;
435 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
436 entp->d_type = DT_CHR;
437 }
else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
438 entp->d_type = DT_DIR;
440 entp->d_type = DT_REG;
445 entp->d_reclen =
sizeof (
struct _wdirent);
470 if (dirp->handle != INVALID_HANDLE_VALUE) {
471 FindClose (dirp->handle);
472 dirp->handle = INVALID_HANDLE_VALUE;
487 dirent_set_errno (EBADF);
503 if (dirp->handle != INVALID_HANDLE_VALUE) {
504 FindClose (dirp->handle);
513 static WIN32_FIND_DATAW*
517 WIN32_FIND_DATAW *datap;
520 dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
521 if (dirp->handle != INVALID_HANDLE_VALUE) {
538 static WIN32_FIND_DATAW*
545 if (dirp->cached != 0) {
551 }
else if (dirp->handle != INVALID_HANDLE_VALUE) {
554 if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
559 FindClose (dirp->handle);
560 dirp->handle = INVALID_HANDLE_VALUE;
585 if (dirname == NULL || dirname[0] ==
'\0') {
586 dirent_set_errno (ENOENT);
591 dirp = (DIR*) malloc (
sizeof (
struct DIR));
593 wchar_t wname[PATH_MAX];
597 error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
601 dirp->wdirp = _wopendir (wname);
647 static struct dirent*
651 WIN32_FIND_DATAW *datap;
655 datap = dirent_next (dirp->wdirp);
661 error = dirent_wcstombs_s(
662 &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
674 if (error && datap->cAlternateFileName[0] !=
'\0') {
675 error = dirent_wcstombs_s(
676 &n, dirp->ent.d_name, PATH_MAX,
677 datap->cAlternateFileName, PATH_MAX);
687 entp->d_namlen = n - 1;
690 attr = datap->dwFileAttributes;
691 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
692 entp->d_type = DT_CHR;
693 }
else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
694 entp->d_type = DT_DIR;
696 entp->d_type = DT_REG;
701 entp->d_reclen =
sizeof (
struct dirent);
711 entp->d_name[0] =
'?';
712 entp->d_name[1] =
'\0';
714 entp->d_type = DT_UNKNOWN;
738 ok = _wclosedir (dirp->wdirp);
747 dirent_set_errno (EBADF);
762 _wrewinddir (dirp->wdirp);
768 size_t *pReturnValue,
775 #ifdef DIRENT_USES_UTF8_CHARS
777 size_t n = (size_t) MultiByteToWideChar (CP_UTF8, 0, mbstr, -1, wcstr, 0);
780 if (sizeInWords>0) wcstr[0]=L
'\0';
781 if (pReturnValue) *pReturnValue = 0;
783 else if (n<=sizeInWords) {
784 error = MultiByteToWideChar (CP_UTF8, 0, mbstr, -1, wcstr, n) == 0 ? 1 : 0;
785 if (pReturnValue) *pReturnValue = n;
790 if (sizeInWords>1) MultiByteToWideChar (CP_UTF8, 0, mbstr, -1, wcstr, sizeInWords-1);
791 wcstr[sizeInWords-1] = L
'\0';
793 if (pReturnValue) *pReturnValue = sizeInWords;
822 #else //DIRENT_USES_UTF8_CHARS
823 #if defined(_MSC_VER) && _MSC_VER >= 1400
826 error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
834 n = mbstowcs (wcstr, mbstr, sizeInWords);
835 if (!wcstr || n < count) {
838 if (wcstr && sizeInWords) {
839 if (n >= sizeInWords) {
847 *pReturnValue = n + 1;
861 #endif //DIRENT_USES_UTF8_CHARS
869 size_t *pReturnValue,
872 const wchar_t *wcstr,
877 #ifdef DIRENT_USES_UTF8_CHARS
879 size_t n = (size_t) WideCharToMultiByte (CP_UTF8, 0, wcstr, -1, mbstr, 0,NULL,NULL);
882 if (sizeInBytes>0) mbstr[0]=
'\0';
883 if (pReturnValue) *pReturnValue = 0;
885 else if (n<=sizeInBytes) {
886 error = WideCharToMultiByte (CP_UTF8, 0, wcstr, -1, mbstr, n, NULL, NULL) == 0 ? 1 : 0;
887 if (pReturnValue) *pReturnValue = n;
892 if (sizeInBytes>1) WideCharToMultiByte (CP_UTF8, 0, wcstr, -1, mbstr, sizeInBytes-1, NULL, NULL);
893 mbstr[sizeInBytes-1] =
'\0';
895 if (pReturnValue) *pReturnValue = sizeInBytes;
925 #else //DIRENT_USES_UTF8_CHARS
926 #if defined(_MSC_VER) && _MSC_VER >= 1400
929 error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
937 n = wcstombs (mbstr, wcstr, sizeInBytes);
938 if (!mbstr || n < count) {
941 if (mbstr && sizeInBytes) {
942 if (n >= sizeInBytes) {
950 *pReturnValue = n + 1;
964 #endif //DIRENT_USES_UTF8_CHARS
973 #if defined(_MSC_VER) && _MSC_VER >= 1400
989 inline static int scandir(
const char *path,
struct dirent ***res,
990 int (*sel)(
const struct dirent *),
991 int (*cmp)(
const struct dirent **,
const struct dirent **))
993 DIR *d = opendir(path);
994 struct dirent *de, **names=0, **tmp;
996 int old_errno = errno;
1000 while ((errno=0), (de = readdir(d))) {
1001 if (sel && !sel(de))
continue;
1004 if (len > SIZE_MAX/
sizeof *names)
break;
1005 tmp = (dirent**)realloc(names, len *
sizeof *names);
1009 names[cnt] = (dirent*)malloc(de->d_reclen);
1010 if (!names[cnt])
break;
1011 memcpy(names[cnt++], de, de->d_reclen);
1017 if (names)
while (cnt-->0) free(names[cnt]);
1023 if (cmp) qsort(names, cnt,
sizeof *names, (
int (*)(
const void *,
const void *))cmp);
1030 inline static int alphasort (
const struct dirent **e1,
const struct dirent **e2) {
1031 return strcmp((*e1)->d_name,(*e2)->d_name);
1040 #endif //#if (!defined(_WIN32) && !defined(_WIN64))
static void error(char *msg)