mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
Merge pull request #1142 from MikeWey/Issue8298
Fix Issue #8298, Don't throw exceptions on broken symlinks.
This commit is contained in:
commit
1d7912c679
1 changed files with 48 additions and 3 deletions
51
std/file.d
51
std/file.d
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue