Repository: mesos Updated Branches: refs/heads/master 10d7988ee -> 1de39e676
Windows: Fixed return of bad types in stat.hpp. Commit 5f159cdcb introduced `return Error(...)` logic to functions which return `bool`, not `Try<bool>`, which broke the Windows build. Furthermore, in the instances of `isdir` and `isfile`, erroring when asked to not follow a symlink is not correct. The semantics of symlinks provide clear answers to `isdir` and `isfile` when the target is a link, and is not being followed (it is neither a regular file nor a directory). We explicitly match the POSIX semantics for `isfile` where `S_IFREG` returns `false` for symbolic links. For the functions `mode` and `dev`, which return types wrapped by `Try`, we should only error if asked not to follow symlinks, and the target is actually a symlink. If it is not a symlink to begin with, we should not prematurely error. If it is a symlink, we should error because there is no equivalent of `lstat` on Windows to obtain `st_mode` or `st_dev` of a symlink itself. Review: https://reviews.apache.org/r/57926/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/1de39e67 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/1de39e67 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/1de39e67 Branch: refs/heads/master Commit: 1de39e676a0dc5f78eeff303cb0eba5467168b9f Parents: 10d7988 Author: Andrew Schwartzmeyer <[email protected]> Authored: Fri Mar 24 21:07:30 2017 -0700 Committer: Joseph Wu <[email protected]> Committed: Fri Mar 24 21:07:30 2017 -0700 ---------------------------------------------------------------------- .../stout/include/stout/os/windows/stat.hpp | 25 +++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/1de39e67/3rdparty/stout/include/stout/os/windows/stat.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/stout/include/stout/os/windows/stat.hpp b/3rdparty/stout/include/stout/os/windows/stat.hpp index 8587341..b2ff436 100644 --- a/3rdparty/stout/include/stout/os/windows/stat.hpp +++ b/3rdparty/stout/include/stout/os/windows/stat.hpp @@ -31,14 +31,19 @@ namespace os { namespace stat { +// Forward declaration. +inline bool islink(const std::string& path); + inline bool isdir( const std::string& path, const FollowSymlink follow = FOLLOW_SYMLINK) { struct _stat s; - if (follow == DO_NOT_FOLLOW_SYMLINK) { - return Error("Non-following stat not supported for '" + path + "'"); + // A symlink itself is not a directory. + // If it's not a link, we ignore `follow`. + if (follow == DO_NOT_FOLLOW_SYMLINK && islink(path)) { + return false; } if (::_stat(path.c_str(), &s) < 0) { @@ -55,8 +60,12 @@ inline bool isfile( { struct _stat s; - if (follow == DO_NOT_FOLLOW_SYMLINK) { - return Error("Non-following stat not supported for '" + path + "'"); + // A symlink itself is a file, but not a regular file. + // On POSIX, this check is done with `S_IFREG`, which + // returns false for symbolic links. + // If it's not a link, we ignore `follow`. + if (follow == DO_NOT_FOLLOW_SYMLINK && islink(path)) { + return false; } if (::_stat(path.c_str(), &s) < 0) { @@ -150,8 +159,8 @@ inline Try<mode_t> mode( { struct _stat s; - if (follow == DO_NOT_FOLLOW_SYMLINK) { - return Error("Non-following stat not supported for '" + path + "'"); + if (follow == DO_NOT_FOLLOW_SYMLINK && islink(path)) { + return Error("lstat not supported for symlink '" + path + "'"); } if (::_stat(path.c_str(), &s) < 0) { @@ -168,8 +177,8 @@ inline Try<dev_t> dev( { struct _stat s; - if (follow == DO_NOT_FOLLOW_SYMLINK) { - return Error("Non-following stat not supported for '" + path + "'"); + if (follow == DO_NOT_FOLLOW_SYMLINK && islink(path)) { + return Error("lstat not supported for symlink '" + path + "'"); } if (::_stat(path.c_str(), &s) < 0) {
