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:39:20 UTC

[34/50] mesos git commit: Windows: Implemented `os::ls()` without `dirent.hpp`.

Windows: Implemented `os::ls()` without `dirent.hpp`.

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


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

Branch: refs/heads/master
Commit: bb52f6c2cf1a13ad64645595f9cdb12aa305a7f0
Parents: 3ebe54d
Author: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Authored: Mon Jul 10 14:45:59 2017 -0700
Committer: Joseph Wu <jo...@apache.org>
Committed: Mon Jul 10 17:15:37 2017 -0700

----------------------------------------------------------------------
 3rdparty/stout/include/Makefile.am              |   3 +-
 .../include/stout/internal/windows/dirent.hpp   | 228 -------------------
 3rdparty/stout/include/stout/os/ls.hpp          |  56 +----
 3rdparty/stout/include/stout/os/posix/ls.hpp    |  67 ++++++
 3rdparty/stout/include/stout/os/windows/ls.hpp  |  71 ++++++
 5 files changed, 145 insertions(+), 280 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/bb52f6c2/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/Makefile.am b/3rdparty/stout/include/Makefile.am
index 4068f0e..80724f4 100644
--- a/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/stout/include/Makefile.am
@@ -40,7 +40,6 @@ nobase_include_HEADERS =			\
   stout/hashmap.hpp				\
   stout/hashset.hpp				\
   stout/internal/windows/attributes.hpp		\
-  stout/internal/windows/dirent.hpp		\
   stout/internal/windows/grp.hpp		\
   stout/internal/windows/longpath.hpp		\
   stout/internal/windows/pwd.hpp		\
@@ -130,6 +129,7 @@ nobase_include_HEADERS =			\
   stout/os/posix/getenv.hpp			\
   stout/os/posix/kill.hpp			\
   stout/os/posix/killtree.hpp			\
+  stout/os/posix/ls.hpp				\
   stout/os/posix/mkdir.hpp			\
   stout/os/posix/mkdtemp.hpp			\
   stout/os/posix/mktemp.hpp			\
@@ -167,6 +167,7 @@ nobase_include_HEADERS =			\
   stout/os/windows/getenv.hpp			\
   stout/os/windows/kill.hpp			\
   stout/os/windows/killtree.hpp			\
+  stout/os/windows/ls.hpp			\
   stout/os/windows/mkdir.hpp			\
   stout/os/windows/mktemp.hpp			\
   stout/os/windows/mkdtemp.hpp			\

http://git-wip-us.apache.org/repos/asf/mesos/blob/bb52f6c2/3rdparty/stout/include/stout/internal/windows/dirent.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/internal/windows/dirent.hpp b/3rdparty/stout/include/stout/internal/windows/dirent.hpp
deleted file mode 100644
index 7dbdb10..0000000
--- a/3rdparty/stout/include/stout/internal/windows/dirent.hpp
+++ /dev/null
@@ -1,228 +0,0 @@
-// 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_INTERNAL_WINDOWS_DIRENT_HPP__
-#define __STOUT_INTERNAL_WINDOWS_DIRENT_HPP__
-
-#include <assert.h>
-#include <malloc.h>
-
-#include <stout/windows.hpp>
-
-
-// Abbreviated version of the POSIX `dirent` struct. cf. specification[1].
-//
-// [1] http://www.gnu.org/software/libc/manual/html_node/Directory-Entries.html
-struct dirent
-{
-  char d_name[MAX_PATH];
-  unsigned short d_namlen;
-};
-
-
-// `DIR` is normally an opaque struct in the standard, we expose the
-// implementation here because this header is intended for internal use only.
-struct DIR
-{
-  struct dirent curr;
-  char *d_name;
-  WIN32_FIND_DATA fd;
-  HANDLE handle;
-};
-
-
-// Avoid the C++-style name-mangling linkage, and use C-style instead to give
-// the appearance that this code is part of the real C standard library.
-extern "C" {
-namespace internal {
-
-void free_dir(DIR* directory);
-
-bool open_dir_stream(DIR* directory);
-
-bool reentrant_advance_dir_stream(DIR* directory);
-
-} // namespace internal {
-
-
-// Windows implementation of POSIX standard `opendir`. cf. specification[1].
-//
-// [1] http://www.gnu.org/software/libc/manual/html_node/Opening-a-Directory.html#Opening-a-Directory
-inline DIR* opendir(const char* path)
-{
-  if (path == nullptr) {
-    errno = ENOTDIR;
-    return nullptr;
-  }
-
-  const size_t path_size = strlen(path);
-
-  if (path_size == 0 || path_size >= MAX_PATH) {
-    errno = ENOENT;
-    return nullptr;
-  }
-
-  const char windows_folder_separator = '\\';
-  const char windows_drive_separator = ':';
-  const char wildcard[] = "*";
-  const char dir_separator_and_wildcard[] = "\\*";
-
-  // Allocate space for directory. Be sure to leave room at the end of
-  // `directory->d_name` for a directory separator and a wildcard.
-  DIR* directory = (DIR*) malloc(sizeof(DIR));
-
-  if (directory == nullptr) {
-    errno = ENOMEM;
-    return nullptr;
-  }
-
-  directory->d_name =
-    (char*) malloc(path_size + strlen(dir_separator_and_wildcard) + 1);
-
-  if (directory->d_name == nullptr) {
-    errno = ENOMEM;
-    free(directory);
-    return nullptr;
-  }
-
-  // Copy path over and append the appropriate postfix.
-  strcpy(directory->d_name, path);
-
-  const size_t last_char_in_name =
-    directory->d_name[strlen(directory->d_name) - 1];
-
-  if (last_char_in_name != windows_folder_separator &&
-      last_char_in_name != windows_drive_separator) {
-    strcat(directory->d_name, dir_separator_and_wildcard);
-  } else {
-    strcat(directory->d_name, wildcard);
-  }
-
-  if (!internal::open_dir_stream(directory)) {
-    internal::free_dir(directory);
-    return nullptr;
-  }
-
-  return directory;
-}
-
-
-// Implementation of the standard POSIX function. See documentation[1].
-//
-// On success: returns a pointer to the next directory entry, or `nullptr` if
-// we've reached the end of the stream.
-//
-// On failure: returns `nullptr` and sets `errno`.
-//
-// NOTE: as with most POSIX implementations of this function, you must reset
-// `errno` before calling `readdir`.
-//
-// [1] http://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html#Reading_002fClosing-Directory
-inline struct dirent* readdir(DIR* directory)
-{
-  if (directory == nullptr) {
-    errno = EBADF;
-    return nullptr;
-  }
-
-  if (!internal::reentrant_advance_dir_stream(directory)) {
-    return nullptr;
-  }
-
-  return &directory->curr;
-}
-
-
-// Implementation of the standard POSIX function. See documentation[1].
-//
-// On success, return 0; on failure, return -1 and set `errno` appropriately.
-//
-// [1] http://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html#Reading_002fClosing-Directory
-inline int closedir(DIR* directory)
-{
-  if (directory == nullptr) {
-    errno = EBADF;
-    return -1;
-  }
-
-  BOOL search_closed = false;
-
-  if (directory->handle != INVALID_HANDLE_VALUE) {
-    search_closed = FindClose(directory->handle);
-  }
-
-  internal::free_dir(directory);
-
-  return search_closed ? 0 : -1;
-}
-
-namespace internal {
-
-inline void free_dir(DIR* directory)
-{
-  if (directory != nullptr) {
-    free(directory->d_name);
-  }
-
-  free(directory);
-}
-
-
-inline bool open_dir_stream(DIR* directory)
-{
-  assert(directory != nullptr);
-
-  directory->handle = FindFirstFile(directory->d_name, &directory->fd);
-
-  if (directory->handle == INVALID_HANDLE_VALUE) {
-    errno = ENOENT;
-    return false;
-  }
-
-  // NOTE: `d_name` can be a statically-sized array of `MAX_PATH` size because
-  // `cFileName` is. See[1]. This simplifies this copy operation because we
-  // don't have to `malloc`.
-  //
-  // [1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa365740(v=vs.85).aspx
-  strcpy(directory->curr.d_name, directory->fd.cFileName);
-  directory->curr.d_namlen =
-    static_cast<unsigned short>(strlen(directory->curr.d_name));
-
-  return true;
-}
-
-
-inline bool reentrant_advance_dir_stream(DIR* directory)
-{
-  assert(directory != nullptr);
-
-  if (!FindNextFile(directory->handle, &directory->fd)) {
-    return false;
-  }
-
-  // NOTE: `d_name` can be a statically-sized array of `MAX_PATH` size because
-  // `cFileName` is. See[1]. This simplifies this copy operation because we
-  // don't have to `malloc`.
-  //
-  // [1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa365740(v=vs.85).aspx
-  strcpy(directory->curr.d_name, directory->fd.cFileName);
-  directory->curr.d_namlen =
-    static_cast<unsigned short>(strlen(directory->curr.d_name));
-
-  return true;
-}
-
-} // namespace internal {
-} // extern "C" {
-
-
-#endif // __STOUT_INTERNAL_WINDOWS_DIRENT_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/bb52f6c2/3rdparty/stout/include/stout/os/ls.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/ls.hpp b/3rdparty/stout/include/stout/os/ls.hpp
index 25e2bec..03e04e2 100644
--- a/3rdparty/stout/include/stout/os/ls.hpp
+++ b/3rdparty/stout/include/stout/os/ls.hpp
@@ -13,60 +13,14 @@
 #ifndef __STOUT_OS_LS_HPP__
 #define __STOUT_OS_LS_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/internal/windows/dirent.hpp>
+#include <stout/os/windows/ls.hpp>
 #else
-#include <dirent.h>
+#include <stout/os/posix/ls.hpp>
 #endif // __WINDOWS__
 
-#include <errno.h>
-#include <stdlib.h>
-
-#include <list>
-#include <string>
-
-#include <stout/error.hpp>
-#include <stout/try.hpp>
-
-
-namespace os {
-
-inline Try<std::list<std::string>> ls(const std::string& directory)
-{
-  DIR* dir = opendir(directory.c_str());
-
-  if (dir == nullptr) {
-    return ErrnoError("Failed to opendir '" + directory + "'");
-  }
-
-  std::list<std::string> result;
-  struct dirent* entry;
-
-  // Zero `errno` before starting to call `readdir`. This is necessary
-  // to allow us to determine when `readdir` returns an error.
-  errno = 0;
-
-  while ((entry = readdir(dir)) != nullptr) {
-    if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
-      continue;
-    }
-    result.push_back(entry->d_name);
-  }
-
-  if (errno != 0) {
-    // Preserve `readdir` error.
-    Error error = ErrnoError("Failed to read directory");
-    closedir(dir);
-    return error;
-  }
-
-  if (closedir(dir) == -1) {
-    return ErrnoError("Failed to close directory");
-  }
-
-  return result;
-}
-
-} // namespace os {
 
 #endif // __STOUT_OS_LS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/bb52f6c2/3rdparty/stout/include/stout/os/posix/ls.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/posix/ls.hpp b/3rdparty/stout/include/stout/os/posix/ls.hpp
new file mode 100644
index 0000000..6fa1067
--- /dev/null
+++ b/3rdparty/stout/include/stout/os/posix/ls.hpp
@@ -0,0 +1,67 @@
+// 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_LS_HPP__
+#define __STOUT_OS_POSIX_LS_HPP__
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <list>
+#include <string>
+
+#include <stout/error.hpp>
+#include <stout/try.hpp>
+
+
+namespace os {
+
+inline Try<std::list<std::string>> ls(const std::string& directory)
+{
+  DIR* dir = opendir(directory.c_str());
+
+  if (dir == nullptr) {
+    return ErrnoError("Failed to opendir '" + directory + "'");
+  }
+
+  std::list<std::string> result;
+  struct dirent* entry;
+
+  // Zero `errno` before starting to call `readdir`. This is necessary
+  // to allow us to determine when `readdir` returns an error.
+  errno = 0;
+
+  while ((entry = readdir(dir)) != nullptr) {
+    if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+      continue;
+    }
+    result.push_back(entry->d_name);
+  }
+
+  if (errno != 0) {
+    // Preserve `readdir` error.
+    Error error = ErrnoError("Failed to read directory");
+    closedir(dir);
+    return error;
+  }
+
+  if (closedir(dir) == -1) {
+    return ErrnoError("Failed to close directory");
+  }
+
+  return result;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_LS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/bb52f6c2/3rdparty/stout/include/stout/os/windows/ls.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/windows/ls.hpp b/3rdparty/stout/include/stout/os/windows/ls.hpp
new file mode 100644
index 0000000..98fad02
--- /dev/null
+++ b/3rdparty/stout/include/stout/os/windows/ls.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_LS_HPP__
+#define __STOUT_OS_LWINDOWS_S_HPP__
+
+#include <list>
+#include <string>
+
+#include <stout/error.hpp>
+#include <stout/try.hpp>
+
+#include <stout/internal/windows/longpath.hpp>
+
+
+namespace os {
+
+inline Try<std::list<std::string>> ls(const std::string& directory)
+{
+  // Ensure the path ends with a backslash.
+  std::string path = directory;
+  if (!strings::endsWith(path, "\\")) {
+    path += "\\";
+  }
+
+  // Get first file matching pattern `X:\path\to\wherever\*`.
+  WIN32_FIND_DATAW found;
+  const std::wstring search_pattern =
+    ::internal::windows::longpath(path) + L"*";
+
+  const SharedHandle search_handle(
+      ::FindFirstFileW(search_pattern.data(), &found),
+      ::FindClose);
+
+  if (search_handle.get() == INVALID_HANDLE_VALUE) {
+    return WindowsError("Failed to search '" + directory + "'");
+  }
+
+  std::list<std::string> result;
+
+  do {
+    // NOTE: do-while is appropriate here because folder is guaranteed to have
+    // at least a file called `.` (and probably also one called `..`).
+    const std::wstring current_file(found.cFileName);
+
+    const bool is_current_directory = current_file.compare(L".") == 0;
+    const bool is_parent_directory = current_file.compare(L"..") == 0;
+
+    // Ignore the `.` and `..` files in the directory.
+    if (is_current_directory || is_parent_directory) {
+      continue;
+    }
+
+    result.push_back(stringify(current_file));
+  } while (::FindNextFileW(search_handle.get(), &found));
+
+  return result;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_LS_HPP__