You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jo...@apache.org on 2017/07/11 01:38:51 UTC

[05/50] mesos git commit: Windows: Updated `os::mkdir()` to support long paths.

Windows: Updated `os::mkdir()` to support long paths.

This commit fixes some long path problems on Windows by replacing the
use of the deprecated POSIX function `mkdir` with the explicit Unicode
function `CreateDirectoryW` on Windows. Paths are resolved to be be
absolute and then prepended with `\\?\`, which forces long path support
without requiring a registry or group policy setting.

Because `CreateDirectory` will fail with "permission denied" on paths
such as `C:\`, `os::exists` is used to check if the path exists before
attempting to create it.

Review: https://reviews.apache.org/r/60302/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ed653a0f
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ed653a0f
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ed653a0f

Branch: refs/heads/master
Commit: ed653a0fafb2233644cdf753abddfc743cba61e7
Parents: 6f02733
Author: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Authored: Wed Jul 5 13:15:38 2017 -0700
Committer: Joseph Wu <jo...@apache.org>
Committed: Mon Jul 10 17:15:32 2017 -0700

----------------------------------------------------------------------
 3rdparty/stout/include/Makefile.am              |  2 +
 3rdparty/stout/include/stout/os/mkdir.hpp       | 53 ++-------------
 3rdparty/stout/include/stout/os/posix/mkdir.hpp | 63 +++++++++++++++++
 .../stout/include/stout/os/windows/mkdir.hpp    | 71 ++++++++++++++++++++
 3rdparty/stout/include/stout/windows.hpp        |  7 --
 5 files changed, 141 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/ed653a0f/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/Makefile.am b/3rdparty/stout/include/Makefile.am
index 9087ff1..f05e968 100644
--- a/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/stout/include/Makefile.am
@@ -128,6 +128,7 @@ nobase_include_HEADERS =			\
   stout/os/posix/getenv.hpp			\
   stout/os/posix/kill.hpp			\
   stout/os/posix/killtree.hpp			\
+  stout/os/posix/mkdir.hpp			\
   stout/os/posix/mkdtemp.hpp			\
   stout/os/posix/pagesize.hpp			\
   stout/os/posix/pipe.hpp			\
@@ -161,6 +162,7 @@ nobase_include_HEADERS =			\
   stout/os/windows/getenv.hpp			\
   stout/os/windows/kill.hpp			\
   stout/os/windows/killtree.hpp			\
+  stout/os/windows/mkdir.hpp			\
   stout/os/windows/mkdtemp.hpp			\
   stout/os/windows/pagesize.hpp			\
   stout/os/windows/pipe.hpp			\

http://git-wip-us.apache.org/repos/asf/mesos/blob/ed653a0f/3rdparty/stout/include/stout/os/mkdir.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/mkdir.hpp b/3rdparty/stout/include/stout/os/mkdir.hpp
index b384391..b877d7d 100644
--- a/3rdparty/stout/include/stout/os/mkdir.hpp
+++ b/3rdparty/stout/include/stout/os/mkdir.hpp
@@ -13,57 +13,14 @@
 #ifndef __STOUT_OS_MKDIR_HPP__
 #define __STOUT_OS_MKDIR_HPP__
 
-#ifndef __WINDOWS__
-#include <sys/stat.h>
-#endif // __WINDOWS__
-
-#include <string>
-#include <vector>
-
-#include <stout/error.hpp>
-#include <stout/nothing.hpp>
-#include <stout/strings.hpp>
-#include <stout/try.hpp>
-
-#include <stout/os/constants.hpp>
 
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specific system calls into separate directories.
 #ifdef __WINDOWS__
-#include <stout/windows.hpp> // To be certain we're using the right `mkdir`.
+#include <stout/os/windows/mkdir.hpp>
+#else
+#include <stout/os/posix/mkdir.hpp>
 #endif // __WINDOWS__
 
 
-namespace os {
-
-inline Try<Nothing> mkdir(const std::string& directory, bool recursive = true)
-{
-  if (!recursive) {
-    if (::mkdir(directory.c_str(), 0755) < 0) {
-      return ErrnoError();
-    }
-  } else {
-    std::vector<std::string> tokens =
-      strings::tokenize(directory, stringify(os::PATH_SEPARATOR));
-
-    std::string path;
-
-    // We got an absolute path, so keep the leading slash.
-    if (directory.find_first_of(stringify(os::PATH_SEPARATOR)) == 0) {
-      path = os::PATH_SEPARATOR;
-    }
-
-    foreach (const std::string& token, tokens) {
-      path += token;
-      if (::mkdir(path.c_str(), 0755) < 0 && errno != EEXIST) {
-        return ErrnoError();
-      }
-
-      path += os::PATH_SEPARATOR;
-    }
-  }
-
-  return Nothing();
-}
-
-} // namespace os {
-
 #endif // __STOUT_OS_MKDIR_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/ed653a0f/3rdparty/stout/include/stout/os/posix/mkdir.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/posix/mkdir.hpp b/3rdparty/stout/include/stout/os/posix/mkdir.hpp
new file mode 100644
index 0000000..418db9a
--- /dev/null
+++ b/3rdparty/stout/include/stout/os/posix/mkdir.hpp
@@ -0,0 +1,63 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __STOUT_OS_POSIX_MKDIR_HPP__
+#define __STOUT_OS_POSIX_MKDIR_HPP__
+
+#include <sys/stat.h>
+
+#include <string>
+#include <vector>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+
+#include <stout/os/constants.hpp>
+
+
+namespace os {
+
+inline Try<Nothing> mkdir(const std::string& directory, bool recursive = true)
+{
+  if (!recursive) {
+    if (::mkdir(directory.c_str(), 0755) < 0) {
+      return ErrnoError();
+    }
+  } else {
+    std::vector<std::string> tokens =
+      strings::tokenize(directory, stringify(os::PATH_SEPARATOR));
+
+    std::string path;
+
+    // We got an absolute path, so keep the leading slash.
+    if (directory.find_first_of(stringify(os::PATH_SEPARATOR)) == 0) {
+      path = os::PATH_SEPARATOR;
+    }
+
+    foreach (const std::string& token, tokens) {
+      path += token;
+      if (::mkdir(path.c_str(), 0755) < 0 && errno != EEXIST) {
+        return ErrnoError();
+      }
+
+      path += os::PATH_SEPARATOR;
+    }
+  }
+
+  return Nothing();
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_MKDIR_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/ed653a0f/3rdparty/stout/include/stout/os/windows/mkdir.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/windows/mkdir.hpp b/3rdparty/stout/include/stout/os/windows/mkdir.hpp
new file mode 100644
index 0000000..8d8d80b
--- /dev/null
+++ b/3rdparty/stout/include/stout/os/windows/mkdir.hpp
@@ -0,0 +1,71 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __STOUT_OS_WINDOWS_MKDIR_HPP__
+#define __STOUT_OS_WINDOWS_MKDIR_HPP__
+
+#include <string>
+#include <vector>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+#include <stout/windows.hpp>
+
+#include <stout/os/exists.hpp>
+#include <stout/os/constants.hpp>
+
+#include <stout/internal/windows/longpath.hpp>
+
+
+namespace os {
+
+inline Try<Nothing> mkdir(const std::string& directory, bool recursive = true)
+{
+  if (!recursive) {
+    // NOTE: We check for existence because parts of certain directories
+    // like `C:\` will return an error if passed to `CreateDirectory`,
+    // even though the drive may already exist.
+    if (os::exists(directory)) {
+      return Nothing();
+    }
+
+    std::wstring longpath = ::internal::windows::longpath(directory);
+    if (::CreateDirectoryW(longpath.data(), nullptr) == 0) {
+      return WindowsError("Failed to create directory: " + directory);
+    }
+  } else {
+    // Remove the long path prefix, if it already exists, otherwise the
+    // tokenizer includes the long path prefix (`\\?\`) as the first part
+    // of the path.
+    std::vector<std::string> tokens = strings::tokenize(
+        strings::remove(directory, os::LONGPATH_PREFIX, strings::Mode::PREFIX),
+        stringify(os::PATH_SEPARATOR));
+
+    std::string path;
+
+    foreach (const std::string& token, tokens) {
+      path += token + os::PATH_SEPARATOR;
+      Try<Nothing> result = mkdir(path, false);
+      if (result.isError()) {
+        return result;
+      }
+    }
+  }
+
+  return Nothing();
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_MKDIR_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/ed653a0f/3rdparty/stout/include/stout/windows.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/windows.hpp b/3rdparty/stout/include/stout/windows.hpp
index 0cd22d5..6aa0d53 100644
--- a/3rdparty/stout/include/stout/windows.hpp
+++ b/3rdparty/stout/include/stout/windows.hpp
@@ -359,13 +359,6 @@ inline char* getcwd(char* path, size_t maxlen)
 }
 
 
-inline auto mkdir(const char* path, mode_t mode) ->
-decltype(_mkdir(path))
-{
-  return _mkdir(path);
-}
-
-
 inline auto mktemp(char* path) ->
 decltype(_mktemp(path))
 {