Merge pull request #1142 from MikeWey/Issue8298

Fix Issue #8298, Don't throw exceptions on broken symlinks.
This commit is contained in:
Andrej Mitrovic 2014-01-07 16:23:42 -08:00
commit 1d7912c679

View file

@ -876,7 +876,7 @@ bool exists(in char[] name) @trusted
*/ */
stat_t statbuf = void; stat_t statbuf = void;
return stat(toStringz(name), &statbuf) == 0; return lstat(toStringz(name), &statbuf) == 0;
} }
} }
@ -2065,14 +2065,14 @@ else version(Posix)
@property bool isDir() @property bool isDir()
{ {
_ensureStatDone(); _ensureStatOrLStatDone();
return (_statBuf.st_mode & S_IFMT) == S_IFDIR; return (_statBuf.st_mode & S_IFMT) == S_IFDIR;
} }
@property bool isFile() @property bool isFile()
{ {
_ensureStatDone(); _ensureStatOrLStatDone();
return (_statBuf.st_mode & S_IFMT) == S_IFREG; return (_statBuf.st_mode & S_IFMT) == S_IFREG;
} }
@ -2147,6 +2147,31 @@ else version(Posix)
_didStat = true; _didStat = true;
} }
/++
This is to support lazy evaluation, because doing stat's is
expensive and not always needed.
Try both stat and lstat for isFile and isDir
to detect broken symlinks.
+/
void _ensureStatOrLStatDone()
{
if(_didStat)
return;
if( stat(toStringz(_name), &_statBuf) != 0 )
{
_ensureLStatDone();
_statBuf = stat_t.init;
_statBuf.st_mode = S_IFLNK;
}
else
{
_didStat = true;
}
}
/++ /++
This is to support lazy evaluation, because doing stat's is This is to support lazy evaluation, because doing stat's is
@ -2228,6 +2253,26 @@ unittest
assert(de.isDir); assert(de.isDir);
assert(de.isSymlink); assert(de.isSymlink);
} }
symfile.remove();
core.sys.posix.unistd.symlink((deleteme ~ "_broken_symlink\0").ptr, symfile.ptr);
{
//Issue 8298
DirEntry de = DirEntry(symfile);
assert(!de.isFile);
assert(!de.isDir);
assert(de.isSymlink);
assertThrown(de.size);
assertThrown(de.timeStatusChanged);
assertThrown(de.timeLastAccessed);
assertThrown(de.timeLastModified);
assertThrown(de.attributes);
assertThrown(de.statBuf);
assert(symfile.exists);
symfile.remove();
}
} }
if("/usr/include/assert.h".exists) if("/usr/include/assert.h".exists)