13 #ifndef DOXYGEN_SHOULD_SKIP_THIS 20 # if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) 21 && !defined(_AMD64_) && defined(_M_IX86) 24 # if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) 25 && !defined(_AMD64_) && defined(_M_AMD64) 39 #include <sys/types.h> 45 # define _DIRENT_HAVE_D_TYPE 48 # define _DIRENT_HAVE_D_NAMLEN 51 # if !defined(FILE_ATTRIBUTE_DEVICE) 52 # define FILE_ATTRIBUTE_DEVICE 0x40
57 # define S_IFMT _S_IFMT 61 # if !defined(S_IFDIR
) 62 # define S_IFDIR _S_IFDIR 66 # if !defined(S_IFCHR
) 67 # define S_IFCHR _S_IFCHR 71 # if !defined(S_IFFIFO) 72 # define S_IFFIFO _S_IFFIFO 76 # if !defined(S_IFREG
) 77 # define S_IFREG _S_IFREG 81 # if !defined(S_IREAD
) 82 # define S_IREAD _S_IREAD 86 # if !defined(S_IWRITE
) 87 # define S_IWRITE _S_IWRITE 91 # if !defined(S_IEXEC
) 92 # define S_IEXEC _S_IEXEC 96 # if !defined(S_IFIFO
) 97 # define S_IFIFO _S_IFIFO 101 # if !defined(S_IFBLK
) 106 # if !defined(S_IFLNK
) 111 # if !defined(S_IFSOCK
) 116 # if !defined(S_IRUSR
) 117 # define S_IRUSR S_IREAD 121 # if !defined(S_IWUSR
) 122 # define S_IWUSR S_IWRITE 126 # if !defined(S_IXUSR
) 131 # if !defined(S_IRGRP
) 136 # if !defined(S_IWGRP
) 141 # if !defined(S_IXGRP
) 146 # if !defined(S_IROTH
) 151 # if !defined(S_IWOTH
) 156 # if !defined(S_IXOTH
) 161 # if !defined(PATH_MAX) 162 # define PATH_MAX MAX_PATH 164 # if !defined(FILENAME_MAX
) 165 # define FILENAME_MAX MAX_PATH 167 # if !defined(NAME_MAX) 168 # define NAME_MAX FILENAME_MAX
172 # define DT_UNKNOWN 0
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) 191 # if !defined(S_ISFIFO
) 192 # define S_ISFIFO(mode) (((mode)&S_IFMT) == S_IFIFO) 194 # if !defined(S_ISDIR
) 195 # define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) 197 # if !defined(S_ISREG
) 198 # define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) 200 # if !defined(S_ISLNK
) 201 # define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK) 203 # if !defined(S_ISSOCK
) 204 # define S_ISSOCK(mode) (((mode)&S_IFMT) == S_IFSOCK) 206 # if !defined(S_ISCHR
) 207 # define S_ISCHR(mode) (((mode)&S_IFMT) == S_IFCHR) 209 # if !defined(S_ISBLK
) 210 # define S_ISBLK(mode) (((mode)&S_IFMT) == S_IFBLK) 214 # define _D_EXACT_NAMLEN(p) ((p)->d_namlen) 217 # define _D_ALLOC_NAMLEN(p) (PATH_MAX
) 231 unsigned short d_reclen;
240 wchar_t d_name[PATH_MAX];
242 typedef struct _wdirent _wdirent;
249 WIN32_FIND_DATAW data;
260 typedef struct _WDIR _WDIR;
262 static _WDIR* _wopendir(
const wchar_t* dirname);
263 static struct _wdirent* _wreaddir(_WDIR* dirp);
264 static int _wclosedir(_WDIR* dirp);
265 static void _wrewinddir(_WDIR* dirp);
269 # define wdirent _wdirent 271 # define wopendir _wopendir 272 # define wreaddir _wreaddir 273 # define wclosedir _wclosedir 274 # define wrewinddir _wrewinddir 283 unsigned short d_reclen;
292 char d_name[PATH_MAX];
294 typedef struct dirent dirent;
300 typedef struct DIR DIR;
302 static DIR* opendir(
const char* dirname);
303 static struct dirent* readdir(DIR* dirp);
304 static int closedir(DIR* dirp);
305 static void rewinddir(DIR* dirp);
309 static WIN32_FIND_DATAW* dirent_first(_WDIR* dirp);
310 static WIN32_FIND_DATAW* dirent_next(_WDIR* dirp);
312 static int dirent_mbstowcs_s(size_t* pReturnValue,
318 static int dirent_wcstombs_s(size_t* pReturnValue,
321 const wchar_t* wcstr,
324 static void dirent_set_errno(
int error);
331 static _WDIR* _wopendir(
const wchar_t* dirname) {
336 if (dirname == NULL || dirname[0] ==
'\0') {
337 dirent_set_errno(ENOENT);
342 dirp = (_WDIR*)malloc(
sizeof(
struct _WDIR));
347 dirp->handle = INVALID_HANDLE_VALUE;
352 n = GetFullPathNameW(dirname, 0, NULL, NULL);
355 dirp->patt = (
wchar_t*)malloc(
sizeof(
wchar_t) * n + 16);
362 n = GetFullPathNameW(dirname, n, dirp->patt, NULL);
368 if (dirp->patt < p) {
386 if (dirent_first(dirp)) {
392 dirent_set_errno(ENOENT);
397 dirent_set_errno(ENOENT);
426 static struct _wdirent* _wreaddir(_WDIR* dirp) {
427 WIN32_FIND_DATAW* datap;
428 struct _wdirent* entp;
431 datap = dirent_next(dirp);
445 while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
446 entp->d_name[n] = datap->cFileName[n];
449 dirp->ent.d_name[n] = 0;
455 attr = datap->dwFileAttributes;
456 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
457 entp->d_type = DT_CHR;
458 }
else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
459 entp->d_type = DT_DIR;
461 entp->d_type = DT_REG;
466 entp->d_reclen =
sizeof(
struct _wdirent);
481 static int _wclosedir(_WDIR* dirp) {
485 if (dirp->handle != INVALID_HANDLE_VALUE) {
486 FindClose(dirp->handle);
487 dirp->handle = INVALID_HANDLE_VALUE;
502 dirent_set_errno(EBADF);
512 static void _wrewinddir(_WDIR* dirp) {
515 if (dirp->handle != INVALID_HANDLE_VALUE) { FindClose(dirp->handle); }
523 static WIN32_FIND_DATAW* dirent_first(_WDIR* dirp) {
524 WIN32_FIND_DATAW* datap;
527 dirp->handle = FindFirstFileW(dirp->patt, &dirp->data);
528 if (dirp->handle != INVALID_HANDLE_VALUE) {
542 static WIN32_FIND_DATAW* dirent_next(_WDIR* dirp) {
546 if (dirp->cached != 0) {
551 }
else if (dirp->handle != INVALID_HANDLE_VALUE) {
553 if (FindNextFileW(dirp->handle, &dirp->data) != FALSE) {
558 FindClose(dirp->handle);
559 dirp->handle = INVALID_HANDLE_VALUE;
574 static DIR* opendir(
const char* dirname) {
579 if (dirname == NULL || dirname[0] ==
'\0') {
580 dirent_set_errno(ENOENT);
585 dirp = (DIR*)malloc(
sizeof(
struct DIR));
587 wchar_t wname[PATH_MAX];
591 error = dirent_mbstowcs_s(&n, wname, PATH_MAX, dirname, PATH_MAX);
594 dirp->wdirp = _wopendir(wname);
640 static struct dirent* readdir(DIR* dirp) {
641 WIN32_FIND_DATAW* datap;
645 datap = dirent_next(dirp->wdirp);
651 error = dirent_wcstombs_s(&n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
663 if (error && datap->cAlternateFileName[0] !=
'\0') {
665 = dirent_wcstombs_s(&n, dirp->ent.d_name, PATH_MAX, datap->cAlternateFileName, PATH_MAX);
675 entp->d_namlen = n - 1;
678 attr = datap->dwFileAttributes;
679 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
680 entp->d_type = DT_CHR;
681 }
else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
682 entp->d_type = DT_DIR;
684 entp->d_type = DT_REG;
689 entp->d_reclen =
sizeof(
struct dirent);
699 entp->d_name[0] =
'?';
700 entp->d_name[1] =
'\0';
702 entp->d_type = DT_UNKNOWN;
718 static int closedir(DIR* dirp) {
722 ok = _wclosedir(dirp->wdirp);
730 dirent_set_errno(EBADF);
739 static void rewinddir(DIR* dirp) {
741 _wrewinddir(dirp->wdirp);
745 static int dirent_mbstowcs_s(size_t* pReturnValue,
752 # if defined(_MSC_VER) && _MSC_VER >= 1400
755 error = mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count);
763 n = mbstowcs(wcstr, mbstr, sizeInWords);
764 if (!wcstr || n < count) {
766 if (wcstr && sizeInWords) {
767 if (n >= sizeInWords) { n = sizeInWords - 1; }
772 if (pReturnValue) { *pReturnValue = n + 1; }
788 static int dirent_wcstombs_s(size_t* pReturnValue,
791 const wchar_t* wcstr,
795 # if defined(_MSC_VER) && _MSC_VER >= 1400
798 error = wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count);
806 n = wcstombs(mbstr, wcstr, sizeInBytes);
807 if (!mbstr || n < count) {
809 if (mbstr && sizeInBytes) {
810 if (n >= sizeInBytes) { n = sizeInBytes - 1; }
815 if (pReturnValue) { *pReturnValue = n + 1; }
831 static void dirent_set_errno(
int error) {
832 # if defined(_MSC_VER) && _MSC_VER >= 1400