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__