]> git.ipfire.org Git - thirdparty/make.git/commitdiff
* src/dir.c: Preserve glob d_type field
authorspagoveanu@gmail.com <spagoveanu@gmail.com>
Tue, 19 Jun 2018 23:03:48 +0000 (02:03 +0300)
committerPaul Smith <psmith@gnu.org>
Fri, 3 Aug 2018 00:59:02 +0000 (20:59 -0400)
When using GNU make on a system with glibc glob a pattern ending in
a slash is also matching regular files, but only in subdirectories:

$ mkdir -p dir/subdir
$ cd dir
$ touch file1 subdir/file2
$ echo 'test:; @echo $(wildcard */ */*/)' | make -f -
subdir/ subdir/file2
$ echo 'test: */ */*/; @echo "$?" != */ */*/' | make -f -
subdir/ subdir/file2 != subdir/ */*/

It happens because in the gl->gl_readdir callback supplied to glob(),
dirent->d_type is set to DT_UNKNOWN, and the glob() implementation
in glibc assumes that such a directory entry *cannot* possibly be a
regular file.

Pass the actual d_type down to glob(); this is the right thing to do
even if glibc is fixed, because it saves an extra stat() syscall for
each dirent.

Copyright-paperwork-exempt: yes

src/dir.c

index 0e64113837249f5ba73af6833b982443ab1790ad..7b0ea1b7185199b7d87a49368fe8c96116123b55 100644 (file)
--- a/src/dir.c
+++ b/src/dir.c
@@ -407,6 +407,7 @@ struct dirfile
     const char *name;           /* Name of the file.  */
     size_t length;
     short impossible;           /* This file is impossible.  */
+    unsigned char type;
   };
 
 static unsigned long
@@ -730,6 +731,9 @@ dir_contents_file_exists_p (struct directory_contents *dir,
           df->name = strcache_add_len (downcase_inplace (d->d_name), len);
 #else
           df->name = strcache_add_len (d->d_name, len);
+#endif
+#ifdef _DIRENT_HAVE_D_TYPE
+          df->type = d->d_type;
 #endif
           df->length = len;
           df->impossible = 0;
@@ -1242,7 +1246,7 @@ read_dirstream (__ptr_t stream)
           d->d_namlen = len - 1;
 #endif
 #ifdef _DIRENT_HAVE_D_TYPE
-          d->d_type = DT_UNKNOWN;
+          d->d_type = df->type;
 #endif
           memcpy (d->d_name, df->name, len);
           return d;