@@ -206,22 +206,41 @@ bool find_files::find_internal(const char* pBasepath, const char* pRelpath, cons
206206 if ((strcmp (ep->d_name , " ." ) == 0 ) || (strcmp (ep->d_name , " .." ) == 0 ))
207207 continue ;
208208
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) {
213217 is_directory = (ep->d_type & DT_DIR) != 0 ;
214218 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 );
216228 struct stat s;
217- if (stat (ep-> d_name , &s) == 0 ) {
229+ if (stat (filepath. get_ptr () , &s) == 0 ) {
218230 is_directory = S_ISDIR (s.st_mode );
219231 is_file = S_ISREG (s.st_mode );
232+ known = true ;
220233 }
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 ;
225244 }
226245
227246 dynamic_string filename (ep->d_name );
0 commit comments