* src/dir.c: Preserve glob d_type field

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
This commit is contained in:
spagoveanu@gmail.com 2018-06-20 02:03:48 +03:00 committed by Paul Smith
parent b36a8ec92a
commit b7acb10e86

View file

@ -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;