Fix checking existence of directories on MS-Windows

* remake.c (name_mtime) [WINDOWS32]: Emulate Posix behavior of
'stat' with the likes of "foo/" and "foo/.".
This commit is contained in:
Eli Zaretskii 2017-09-30 10:56:39 +03:00
parent 7ef56bc8dc
commit baa57d2cf9

View file

@ -1469,7 +1469,45 @@ name_mtime (const char *name)
struct stat st;
int e;
#if defined(WINDOWS32)
{
char tem[MAXPATHLEN], *tstart, *tend;
const char *p = name + strlen (name);
/* Remove any trailing slashes and "."/"..". MS-Windows stat
fails on valid directories if NAME ends in a slash, and we need
to emulate the Posix behavior where stat on "foo/" or "foo/."
succeeds ONLY if "foo" is a directory. */
if (p > name)
{
memcpy (tem, name, p - name + 1);
tstart = tem;
if (tstart[1] == ':')
tstart += 2;
tend = tem + (p - name - 1);
if (*tend == '.' && tend > tstart)
tend--;
if (*tend == '.' && tend > tstart)
tend--;
for ( ; tend > tstart && (*tend == '/' || *tend == '\\'); tend--)
*tend = '\0';
}
else
{
tem[0] = '\0';
tend = &tem[0];
}
e = stat (tem, &st);
if (e == 0 && !_S_ISDIR (st.st_mode) && tend < tem + (p - name - 1))
{
errno = ENOTDIR;
e = -1;
}
}
#else
EINTRLOOP (e, stat (name, &st));
#endif
if (e == 0)
mtime = FILE_TIMESTAMP_STAT_MODTIME (name, st);
else if (errno == ENOENT || errno == ENOTDIR)