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) {

Reply via email to