Fix Savannah bug #37065 with $(wildcard foo/*/.) returning non-directories.

dir.c (local_stat) [WINDOWS32]: Use the wrapper on MS-Windows.
 If the argument ends in "dir/.", make sure the parent dir exists
 and is indeed a directory.  Fixes Savannah bug #37065.
This commit is contained in:
Eli Zaretskii 2013-04-28 20:53:36 +03:00
parent 7f01830927
commit 5667376edc
2 changed files with 27 additions and 1 deletions

View File

@ -1,3 +1,9 @@
2013-04-28 Eli Zaretskii <eliz@gnu.org>
* dir.c (local_stat) [WINDOWS32]: Use the wrapper on MS-Windows.
If the argument ends in "dir/.", make sure the parent dir exists
and is indeed a directory. Fixes Savannah bug #37065.
2013-04-28 Paul Smith <psmith@gnu.org> 2013-04-28 Paul Smith <psmith@gnu.org>
Implement a "per-job" output synchronization option. Implement a "per-job" output synchronization option.

22
dir.c
View File

@ -1185,8 +1185,11 @@ ansi_free (void *p)
/* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a /* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a
* macro for stat64(). If stat is a macro, make a local wrapper function to * macro for stat64(). If stat is a macro, make a local wrapper function to
* invoke it. * invoke it.
*
* On MS-Windows, stat() "succeeds" for foo/bar/. where foo/bar is a
* regular file; fix that here.
*/ */
#ifndef stat #if !defined(stat) && !defined(WINDOWS32)
# ifndef VMS # ifndef VMS
int stat (const char *path, struct stat *sbuf); int stat (const char *path, struct stat *sbuf);
# endif # endif
@ -1196,6 +1199,23 @@ static int
local_stat (const char *path, struct stat *buf) local_stat (const char *path, struct stat *buf)
{ {
int e; int e;
#ifdef WINDOWS32
size_t plen = strlen (path);
/* Make sure the parent of "." exists and is a directory, not a
file. This is because 'stat' on Windows normalizes the argument
foo/. => foo without checking first that foo is a directory. */
if (plen > 1 && path[plen - 1] == '.'
&& (path[plen - 2] == '/' || path[plen - 2] == '\\'))
{
char parent[MAXPATHLEN];
strncpy (parent, path, plen - 2);
parent[plen - 2] = '\0';
if (stat (parent, buf) < 0 || !_S_ISDIR (buf->st_mode))
return -1;
}
#endif
EINTRLOOP (e, stat (path, buf)); EINTRLOOP (e, stat (path, buf));
return e; return e;