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;
return stat(toStringz(name), &statbuf) == 0;
return lstat(toStringz(name), &statbuf) == 0;
}
}
@ -2065,14 +2065,14 @@ else version(Posix)
@property bool isDir()
{
_ensureStatDone();
_ensureStatOrLStatDone();
return (_statBuf.st_mode & S_IFMT) == S_IFDIR;
}
@property bool isFile()
{
_ensureStatDone();
_ensureStatOrLStatDone();
return (_statBuf.st_mode & S_IFMT) == S_IFREG;
}
@ -2148,6 +2148,31 @@ else version(Posix)
_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
expensive and not always needed.
@ -2228,6 +2253,26 @@ unittest
assert(de.isDir);
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)