56#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)
86#if (!defined(SIZE_MAX) && !defined(INT_MAX))
94#define _DIRENT_HAVE_D_TYPE
97#define _DIRENT_HAVE_D_NAMLEN
100#if !defined(FILE_ATTRIBUTE_DEVICE)
101# define FILE_ATTRIBUTE_DEVICE 0x40
106# define S_IFMT _S_IFMT
109# define S_IFDIR _S_IFDIR
112# define S_IFCHR _S_IFCHR
114#if !defined(S_IFFIFO)
115# define S_IFFIFO _S_IFFIFO
118# define S_IFREG _S_IFREG
121# define S_IREAD _S_IREAD
123#if !defined(S_IWRITE)
124# define S_IWRITE _S_IWRITE
127# define S_IEXEC _S_IEXEC
130# define S_IFIFO _S_IFIFO
138#if !defined(S_IFSOCK)
143# define S_IRUSR S_IREAD
144# define S_IWUSR S_IWRITE
155#ifndef DIRENT_MAX_PATH
157# define MAX_PATH PATH_MAX
159# ifndef DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
160# define DIRENT_MAX_PATH (MAX_PATH*4)
162# define DIRENT_MAX_PATH (MAX_PATH)
168#define DT_REG S_IFREG
169#define DT_DIR S_IFDIR
170#define DT_FIFO S_IFIFO
171#define DT_SOCK S_IFSOCK
172#define DT_CHR S_IFCHR
173#define DT_BLK S_IFBLK
174#define DT_LNK S_IFLNK
177#define IFTODT(mode) ((mode) & S_IFMT)
178#define DTTOIF(type) (type)
197#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
198#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
199#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
200#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
201#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
202#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
203#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
206#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
209#define _D_ALLOC_NAMLEN(p) (DIRENT_MAX_PATH)
220 unsigned short d_reclen;
225typedef struct _wdirent _wdirent;
229 WIN32_FIND_DATAW data;
234typedef struct _WDIR _WDIR;
236static _WDIR *_wopendir (
const wchar_t *dirname);
237static struct _wdirent *_wreaddir (_WDIR *dirp);
238static int _wclosedir (_WDIR *dirp);
239static void _wrewinddir (_WDIR* dirp);
243#define wdirent _wdirent
245#define wopendir _wopendir
246#define wreaddir _wreaddir
247#define wclosedir _wclosedir
248#define wrewinddir _wrewinddir
254 unsigned short d_reclen;
259typedef struct dirent dirent;
265typedef struct DIR DIR;
267static DIR *opendir (
const char *dirname);
268static struct dirent *readdir (DIR *dirp);
269static int closedir (DIR *dirp);
270static void rewinddir (DIR* dirp);
274static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
275static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
277static int dirent_mbstowcs_s(
278 size_t *pReturnValue,
284static int dirent_wcstombs_s(
285 size_t *pReturnValue,
288 const wchar_t *wcstr,
291static void dirent_set_errno (
int error);
300 const wchar_t *dirname)
306 if (dirname == NULL || dirname[0] ==
'\0') {
307 dirent_set_errno (ENOENT);
312 dirp = (_WDIR*) malloc (
sizeof (
struct _WDIR));
317 dirp->handle = INVALID_HANDLE_VALUE;
322 n = GetFullPathNameW (dirname, 0, NULL, NULL);
325 dirp->patt = (
wchar_t*) malloc (
sizeof (
wchar_t) * n + 16);
333 n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
339 if (dirp->patt < p) {
357 if (dirent_first (dirp)) {
363 dirent_set_errno (ENOENT);
368 dirent_set_errno (ENOENT);
397static struct _wdirent*
401 WIN32_FIND_DATAW *datap;
402 struct _wdirent *entp;
405 datap = dirent_next (dirp);
420 entp->d_name[n] = datap->cFileName[n];
423 dirp->ent.d_name[n] = 0;
429 attr = datap->dwFileAttributes;
430 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
431 entp->d_type = DT_CHR;
432 }
else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
433 entp->d_type = DT_DIR;
435 entp->d_type = DT_REG;
440 entp->d_reclen =
sizeof (
struct _wdirent);
465 if (dirp->handle != INVALID_HANDLE_VALUE) {
466 FindClose (dirp->handle);
467 dirp->handle = INVALID_HANDLE_VALUE;
482 dirent_set_errno (EBADF);
498 if (dirp->handle != INVALID_HANDLE_VALUE) {
499 FindClose (dirp->handle);
508static WIN32_FIND_DATAW*
512 WIN32_FIND_DATAW *datap;
515 dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
516 if (dirp->handle != INVALID_HANDLE_VALUE) {
533static WIN32_FIND_DATAW*
540 if (dirp->cached != 0) {
546 }
else if (dirp->handle != INVALID_HANDLE_VALUE) {
549 if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
554 FindClose (dirp->handle);
555 dirp->handle = INVALID_HANDLE_VALUE;
580 if (dirname == NULL || dirname[0] ==
'\0') {
581 dirent_set_errno (ENOENT);
586 dirp = (DIR*) malloc (
sizeof (
struct DIR));
596 dirp->wdirp = _wopendir (wname);
646 WIN32_FIND_DATAW *datap;
650 datap = dirent_next (dirp->wdirp);
656 error = dirent_wcstombs_s(
669 if (error && datap->cAlternateFileName[0] !=
'\0') {
670 error = dirent_wcstombs_s(
682 entp->d_namlen = n - 1;
685 attr = datap->dwFileAttributes;
686 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
687 entp->d_type = DT_CHR;
688 }
else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
689 entp->d_type = DT_DIR;
691 entp->d_type = DT_REG;
696 entp->d_reclen =
sizeof (
struct dirent);
706 entp->d_name[0] =
'?';
707 entp->d_name[1] =
'\0';
709 entp->d_type = DT_UNKNOWN;
733 ok = _wclosedir (dirp->wdirp);
742 dirent_set_errno (EBADF);
757 _wrewinddir (dirp->wdirp);
763 size_t *pReturnValue,
770#ifndef DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
772 size_t n = (size_t) MultiByteToWideChar (CP_UTF8, 0, mbstr, -1, wcstr, 0);
775 if (sizeInWords>0) wcstr[0]=L
'\0';
776 if (pReturnValue) *pReturnValue = 0;
778 else if (n<=sizeInWords) {
779 error = MultiByteToWideChar (CP_UTF8, 0, mbstr, -1, wcstr, n) == 0 ? 1 : 0;
780 if (pReturnValue) *pReturnValue = n;
785 if (sizeInWords>1) MultiByteToWideChar (CP_UTF8, 0, mbstr, -1, wcstr, sizeInWords-1);
786 wcstr[sizeInWords-1] = L
'\0';
788 if (pReturnValue) *pReturnValue = sizeInWords;
818#if defined(_MSC_VER) && _MSC_VER >= 1400
821 error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
829 n = mbstowcs (wcstr, mbstr, sizeInWords);
830 if (!wcstr || n < count) {
833 if (wcstr && sizeInWords) {
834 if (n >= sizeInWords) {
842 *pReturnValue = n + 1;
864 size_t *pReturnValue,
867 const wchar_t *wcstr,
872#ifndef DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
874 size_t n = (size_t) WideCharToMultiByte (CP_UTF8, 0, wcstr, -1, mbstr, 0,NULL,NULL);
877 if (sizeInBytes>0) mbstr[0]=
'\0';
878 if (pReturnValue) *pReturnValue = 0;
880 else if (n<=sizeInBytes) {
881 error = WideCharToMultiByte (CP_UTF8, 0, wcstr, -1, mbstr, n, NULL, NULL) == 0 ? 1 : 0;
882 if (pReturnValue) *pReturnValue = n;
887 if (sizeInBytes>1) WideCharToMultiByte (CP_UTF8, 0, wcstr, -1, mbstr, sizeInBytes-1, NULL, NULL);
888 mbstr[sizeInBytes-1] =
'\0';
890 if (pReturnValue) *pReturnValue = sizeInBytes;
921#if defined(_MSC_VER) && _MSC_VER >= 1400
924 error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
932 n = wcstombs (mbstr, wcstr, sizeInBytes);
933 if (!mbstr || n < count) {
936 if (mbstr && sizeInBytes) {
937 if (n >= sizeInBytes) {
945 *pReturnValue = n + 1;
968#if defined(_MSC_VER) && _MSC_VER >= 1400
985# define SIZE_MAX_WAS_NOT_DEFINED
986# define SIZE_MAX INT_MAX
988inline static int scandir(
const char *path,
struct dirent ***res,
989 int (*sel)(
const struct dirent *),
990 int (*cmp)(
const struct dirent **,
const struct dirent **))
992 DIR *d = opendir(path);
993 struct dirent *de, **names=0, **tmp;
995 int old_errno = errno;
999 while ((errno=0), (de = readdir(d))) {
1000 if (sel && !sel(de))
continue;
1003 if (len > SIZE_MAX/
sizeof *names)
break;
1004 tmp = (dirent**)realloc(names, len *
sizeof *names);
1008 names[cnt] = (dirent*)malloc(de->d_reclen);
1009 if (!names[cnt])
break;
1010 memcpy(names[cnt++], de, de->d_reclen);
1016 if (names)
while (cnt-->0) free(names[cnt]);
1022 if (cmp) qsort(names, cnt,
sizeof *names, (
int (*)(
const void *,
const void *))cmp);
1026#ifdef SIZE_MAX_WAS_NOT_DEFINED
1028# undef SIZE_MAX_WAS_NOT_DEFINED
1032inline static int alphasort (
const struct dirent **e1,
const struct dirent **e2) {
1033 return strcmp((*e1)->d_name,(*e2)->d_name);