1 #include "../../git-compat-util.h"
4 struct dirent dd_dir
; /* includes d_type */
5 HANDLE dd_handle
; /* FindFirstFile handle */
6 int dd_stat
; /* 0-based index */
7 char dd_name
[1]; /* extend struct */
10 DIR *opendir(const char *name
)
12 DWORD attrs
= GetFileAttributesA(name
);
16 /* check for valid path */
17 if (attrs
== INVALID_FILE_ATTRIBUTES
) {
22 /* check if it's a directory */
23 if (!(attrs
& FILE_ATTRIBUTE_DIRECTORY
)) {
28 /* check that the pattern won't be too long for FindFirstFileA */
30 if (is_dir_sep(name
[len
- 1]))
32 if (len
+ 2 >= MAX_PATH
) {
37 p
= malloc(sizeof(DIR) + len
+ 2);
41 memset(p
, 0, sizeof(DIR) + len
+ 2);
42 strcpy(p
->dd_name
, name
);
43 p
->dd_name
[len
] = '/';
44 p
->dd_name
[len
+1] = '*';
46 p
->dd_handle
= INVALID_HANDLE_VALUE
;
50 struct dirent
*readdir(DIR *dir
)
55 if (!dir
|| !dir
->dd_handle
) {
56 errno
= EBADF
; /* No set_errno for mingw */
60 if (dir
->dd_handle
== INVALID_HANDLE_VALUE
&& dir
->dd_stat
== 0) {
62 handle
= FindFirstFileA(dir
->dd_name
, &buf
);
63 lasterr
= GetLastError();
64 dir
->dd_handle
= handle
;
65 if (handle
== INVALID_HANDLE_VALUE
&& (lasterr
!= ERROR_NO_MORE_FILES
)) {
66 errno
= err_win_to_posix(lasterr
);
69 } else if (dir
->dd_handle
== INVALID_HANDLE_VALUE
) {
71 } else if (!FindNextFileA(dir
->dd_handle
, &buf
)) {
72 DWORD lasterr
= GetLastError();
73 FindClose(dir
->dd_handle
);
74 dir
->dd_handle
= INVALID_HANDLE_VALUE
;
75 /* POSIX says you shouldn't set errno when readdir can't
76 find any more files; so, if another error we leave it set. */
77 if (lasterr
!= ERROR_NO_MORE_FILES
)
78 errno
= err_win_to_posix(lasterr
);
82 /* We get here if `buf' contains valid data. */
83 strcpy(dir
->dd_dir
.d_name
, buf
.cFileName
);
86 /* Set file type, based on WIN32_FIND_DATA */
87 dir
->dd_dir
.d_type
= 0;
88 if (buf
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
89 dir
->dd_dir
.d_type
|= DT_DIR
;
91 dir
->dd_dir
.d_type
|= DT_REG
;
96 int closedir(DIR *dir
)
103 if (dir
->dd_handle
!= INVALID_HANDLE_VALUE
)
104 FindClose(dir
->dd_handle
);