1172
fputs("\n", stderr);
1173
return strbuf_detach(&buf, NULL);
1174
}
1175
+
1176
+#ifndef NO_MINGW_REPLACE_READDIR
1177
+/* MinGW readdir implementation to avoid extra lstats for Git */
1178
+struct mingw_DIR
1179
+{
1180
+ struct _finddata_t dd_dta; /* disk transfer area for this dir */
1181
+ struct mingw_dirent dd_dir; /* Our own implementation, including d_type */
1182
+ long dd_handle; /* _findnext handle */
1183
+ int dd_stat; /* 0 = next entry to read is first entry, -1 = off the end, positive = 0 based index of next entry */
1184
+ char dd_name[1]; /* given path for dir with search pattern (struct is extended) */
1185
+};
1186
+
1187
+struct dirent *mingw_readdir(DIR *dir)
1188
+{
1189
+ WIN32_FIND_DATAA buf;
1190
+ HANDLE handle;
1191
+ struct mingw_DIR *mdir = (struct mingw_DIR*)dir;
1192
+
1193
+ if (!dir->dd_handle) {
1194
+ errno = EBADF; /* No set_errno for mingw */
1195
+ return NULL;
1196
+ }
1197
+
1198
+ if (dir->dd_handle == (long)INVALID_HANDLE_VALUE && dir->dd_stat == 0)
1199
+ {
1200
+ handle = FindFirstFileA(dir->dd_name, &buf);
1201
+ DWORD lasterr = GetLastError();
1202
+ dir->dd_handle = (long)handle;
1203
+ if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES)) {
1204
+ errno = err_win_to_posix(lasterr);
1205
+ return NULL;
1206
+ }
1207
+ } else if (dir->dd_handle == (long)INVALID_HANDLE_VALUE) {
1208
+ return NULL;
1209
+ } else if (!FindNextFileA((HANDLE)dir->dd_handle, &buf)) {
1210
+ DWORD lasterr = GetLastError();
1211
+ FindClose((HANDLE)dir->dd_handle);
1212
+ dir->dd_handle = (long)INVALID_HANDLE_VALUE;
1213
+ /* POSIX says you shouldn't set errno when readdir can't
1214
+ find any more files; so, if another error we leave it set. */
1215
+ if (lasterr != ERROR_NO_MORE_FILES)
1216
+ errno = err_win_to_posix(lasterr);
1217
+ return NULL;
1218
+ }
1219
+
1220
+ /* We get here if `buf' contains valid data. */
1221
+ strcpy(dir->dd_dir.d_name, buf.cFileName);
1222
+ ++dir->dd_stat;
1223
+
1224
+ /* Set file type, based on WIN32_FIND_DATA */
1225
+ mdir->dd_dir.d_type = 0;
1226
+ if (buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1227
+ mdir->dd_dir.d_type |= DT_DIR;
1228
+ else
1229
+ mdir->dd_dir.d_type |= DT_REG;
1230
+
1231
+ return (struct dirent*)&dir->dd_dir;
1232
+}
1233
+#endif // !NO_MINGW_REPLACE_READDIR