14# pragma clang diagnostic ignored "-Wunused-function"
15#elif defined(_MSC_VER)
16# pragma warning(disable:4505)
17#elif defined(__GNUC__)
18# pragma GCC diagnostic ignored "-Wunused-function"
25#ifndef WIN32_LEAN_AND_MEAN
26# define WIN32_LEAN_AND_MEAN
41#define _DIRENT_HAVE_D_TYPE
44#define _DIRENT_HAVE_D_NAMLEN
47#if !defined(FILE_ATTRIBUTE_DEVICE)
48# define FILE_ATTRIBUTE_DEVICE 0x40
53# define S_IFMT _S_IFMT
58# define S_IFDIR _S_IFDIR
63# define S_IFCHR _S_IFCHR
68# define S_IFFIFO _S_IFFIFO
73# define S_IFREG _S_IFREG
78# define S_IREAD _S_IREAD
83# define S_IWRITE _S_IWRITE
88# define S_IEXEC _S_IEXEC
93# define S_IFIFO _S_IFIFO
107#if !defined(S_IFSOCK)
113# define S_IRUSR S_IREAD
118# define S_IWUSR S_IWRITE
157#if !defined(PATH_MAX)
158# define PATH_MAX MAX_PATH
160#if !defined(FILENAME_MAX)
161# define FILENAME_MAX MAX_PATH
163#if !defined(NAME_MAX)
164# define NAME_MAX FILENAME_MAX
169#define DT_REG S_IFREG
170#define DT_DIR S_IFDIR
171#define DT_FIFO S_IFIFO
172#define DT_SOCK S_IFSOCK
173#define DT_CHR S_IFCHR
174#define DT_BLK S_IFBLK
175#define DT_LNK S_IFLNK
178#define IFTODT(mode) ((mode) & S_IFMT)
179#define DTTOIF(type) (type)
187#if !defined(S_ISFIFO)
188# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
191# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
194# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
197# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
199#if !defined(S_ISSOCK)
200# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
203# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
206# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
210#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
213#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1)
294 static struct dirent* readdir(
DIR* dirp);
297 static int readdir_r(
299 static int _wreaddir_r(
302 static int closedir(
DIR* dirp);
303 static int _wclosedir(
_WDIR* dirp);
305 static void rewinddir(
DIR* dirp);
306 static void _wrewinddir(
_WDIR* dirp);
308 static int scandir(
const char*
dirname,
struct dirent*** namelist,
309 int (*filter)(
const struct dirent*),
310 int (*compare)(
const struct dirent**,
const struct dirent**));
312 static int alphasort(
const struct dirent** a,
const struct dirent** b);
314 static int versionsort(
const struct dirent** a,
const struct dirent** b);
318#define wdirent _wdirent
320#define wopendir _wopendir
321#define wreaddir _wreaddir
322#define wclosedir _wclosedir
323#define wrewinddir _wrewinddir
327 static WIN32_FIND_DATAW* dirent_first(
_WDIR* dirp);
328 static WIN32_FIND_DATAW* dirent_next(
_WDIR* dirp);
330 static int dirent_mbstowcs_s(
331 size_t* pReturnValue,
337 static int dirent_wcstombs_s(
338 size_t* pReturnValue,
341 const wchar_t* wcstr,
344 static void dirent_set_errno(
int error);
357#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
368 dirent_set_errno(ENOENT);
379 dirp->
handle = INVALID_HANDLE_VALUE;
389#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
391 n = GetFullPathNameW(
dirname, 0, NULL, NULL);
398 dirp->
patt = (
wchar_t*)malloc(
sizeof(
wchar_t) * n + 16);
399 if (dirp->
patt == NULL) {
411#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
413 n = GetFullPathNameW(
dirname, n, dirp->
patt, NULL);
440 if (!dirent_first(dirp)) {
469 (void)_wreaddir_r(dirp, &dirp->
ent, &entry);
487 WIN32_FIND_DATAW* datap;
490 datap = dirent_next(dirp);
501 while (n < PATH_MAX && datap->cFileName[n] != 0) {
502 entry->
d_name[n] = datap->cFileName[n];
511 attr = datap->dwFileAttributes;
515 else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
554 if (dirp->
handle != INVALID_HANDLE_VALUE) {
569 dirent_set_errno(EBADF);
586 if (dirp->
handle != INVALID_HANDLE_VALUE) {
596 static WIN32_FIND_DATAW*
600 WIN32_FIND_DATAW* datap;
604 dirp->
handle = FindFirstFileExW(
605 dirp->
patt, FindExInfoStandard, &dirp->
data,
606 FindExSearchNameMatch, NULL, 0);
607 if (dirp->
handle != INVALID_HANDLE_VALUE) {
621 error = GetLastError();
623 case ERROR_ACCESS_DENIED:
625 dirent_set_errno(EACCES);
628 case ERROR_DIRECTORY:
630 dirent_set_errno(ENOTDIR);
633 case ERROR_PATH_NOT_FOUND:
636 dirent_set_errno(ENOENT);
648 static WIN32_FIND_DATAW*
662 else if (dirp->
handle != INVALID_HANDLE_VALUE) {
665 if (FindNextFileW(dirp->
handle, &dirp->
data) != FALSE) {
672 dirp->
handle = INVALID_HANDLE_VALUE;
698 dirent_set_errno(ENOENT);
703 dirp = (
DIR*)malloc(
sizeof(
struct DIR));
713 error = dirent_mbstowcs_s(
727 dirp->
wdirp = _wopendir(wname);
756 (void)readdir_r(dirp, &dirp->
ent, &entry);
774 WIN32_FIND_DATAW* datap;
777 datap = dirent_next(dirp->
wdirp);
783 error = dirent_wcstombs_s(
796 if (error && datap->cAlternateFileName[0] !=
'\0') {
797 error = dirent_wcstombs_s(
799 datap->cAlternateFileName,
PATH_MAX + 1);
809 attr = datap->dwFileAttributes;
813 else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
869 ok = _wclosedir(dirp->
wdirp);
879 dirent_set_errno(EBADF);
894 _wrewinddir(dirp->
wdirp);
903 struct dirent*** namelist,
904 int (*filter)(
const struct dirent*),
905 int (*compare)(
const struct dirent**,
const struct dirent**))
907 struct dirent** files = NULL;
909 size_t allocated = 0;
910 const size_t init_size = 1;
913 struct dirent* tmp = NULL;
925 if (size >= allocated) {
930 if (size < init_size) {
932 num_entries = init_size;
936 num_entries = size * 2;
940 p = realloc(files,
sizeof(
void*) * num_entries);
944 allocated = num_entries;
965 if (readdir_r(dir, tmp, &entry) == 0) {
997 qsort(files, size,
sizeof(
void*),
998 (
int (*) (
const void*,
const void*)) compare);
1023 for (i = 0; i < size; i++) {
1047 return strcoll((*a)->d_name, (*b)->d_name);
1056 return alphasort(a, b);
1062 size_t* pReturnValue,
1070#if defined(_MSC_VER) && _MSC_VER >= 1400
1073 error = mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count);
1081 n = mbstowcs(wcstr, mbstr, sizeInWords);
1082 if (!wcstr || n < count) {
1085 if (wcstr && sizeInWords) {
1086 if (n >= sizeInWords) {
1087 n = sizeInWords - 1;
1094 *pReturnValue = n + 1;
1115 size_t* pReturnValue,
1118 const wchar_t* wcstr,
1123#if defined(_MSC_VER) && _MSC_VER >= 1400
1126 error = wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count);
1134 n = wcstombs(mbstr, wcstr, sizeInBytes);
1135 if (!mbstr || n < count) {
1138 if (mbstr && sizeInBytes) {
1139 if (n >= sizeInBytes) {
1140 n = sizeInBytes - 1;
1147 *pReturnValue = n + 1;
1170#if defined(_MSC_VER) && _MSC_VER >= 1400
#define FILE_ATTRIBUTE_DEVICE
std::string dirname(const std::string &path)
Extract the directory component of a pathname.
wchar_t d_name[PATH_MAX+1]