@@ -206,22 +206,41 @@ bool find_files::find_internal(const char* pBasepath, const char* pRelpath, cons
206
206
if ((strcmp (ep->d_name , " ." ) == 0 ) || (strcmp (ep->d_name , " .." ) == 0 ))
207
207
continue ;
208
208
209
- bool is_directory = 0 ;
210
- bool is_file = 0 ;
211
-
212
- if ( ep->d_type != 0 ) {
209
+ bool is_directory = false ;
210
+ bool is_file = false ;
211
+ bool known = false ;
212
+
213
+ /* This is the faster implementation as it doesn't require any
214
+ extra IO as everything is already read. But the standard doesn't
215
+ require filesystems to set d_type. */
216
+ if (ep->d_type != DT_UNKNOWN) {
213
217
is_directory = (ep->d_type & DT_DIR) != 0 ;
214
218
is_file = (ep->d_type & DT_REG) != 0 ;
215
- } else {
219
+ known = true ;
220
+ }
221
+
222
+ /* Not all filesystems set d_type which is optional,
223
+ especially network file systems and non-native ones.
224
+ This is the standard and portable implementation.
225
+ See https://github.com/DaemonEngine/crunch/issues/37 */
226
+ if (!known) {
227
+ dynamic_string filepath = pathname + dynamic_string (" /" ) + dynamic_string (ep->d_name );
216
228
struct stat s;
217
- if (stat (ep-> d_name , &s) == 0 ) {
229
+ if (stat (filepath. get_ptr () , &s) == 0 ) {
218
230
is_directory = S_ISDIR (s.st_mode );
219
231
is_file = S_ISREG (s.st_mode );
232
+ known = true ;
220
233
}
221
- else {
222
- console::error (" Cannot detect if given path is a file or a directory" );
223
- return false ;
224
- }
234
+ }
235
+
236
+ if (!known) {
237
+ console::error (" Cannot detect if the given path is a file or a directory" );
238
+ return false ;
239
+ }
240
+
241
+ if (!is_file && !is_directory) {
242
+ console::error (" The given path is not a file neither a directory" );
243
+ return false ;
225
244
}
226
245
227
246
dynamic_string filename (ep->d_name );
0 commit comments