From: Eli Zaretskii Date: Sat, 30 Sep 2017 07:56:39 +0000 (+0300) Subject: Fix checking existence of directories on MS-Windows X-Git-Tag: 4.2.90~78 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=baa57d2cf9fda82deb2a86960ddcb2dcab6a3917;p=thirdparty%2Fmake.git 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/.". --- diff --git a/remake.c b/remake.c index 037ee738..b4bf1cba 100644 --- a/remake.c +++ b/remake.c @@ -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)