You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by an...@apache.org on 2018/01/16 21:35:02 UTC
[2/3] mesos git commit: Ported `os::which` to Windows.
Ported `os::which` to Windows.
Because `os::which` still lived in `posix/os.hpp`, it was refactored
into its own `os/which.hpp` (which the respective `os/posix/which.hpp`
and `os/windows/which.hpp`. Consumers of this will need additionally
include the new header, instead of just `os.hpp`.
The differences in implementation from POSIX to Windows are:
* Split the `PATH` on `;` not `:`.
* Also loop over `PATHEXT` because executables on Windows end with one
of a set of extensions.
* Removed the permissions check because it is not applicable on
Windows (instead, an executable ends with an extension in `PATHEXT`,
see above).
Review: https://reviews.apache.org/r/65144
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c8594dcc
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c8594dcc
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c8594dcc
Branch: refs/heads/master
Commit: c8594dcc31b75d67c5f72488479cf7c7baac98e1
Parents: de508d9
Author: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Authored: Fri Jan 12 15:14:43 2018 -0800
Committer: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Committed: Tue Jan 16 11:53:43 2018 -0800
----------------------------------------------------------------------
3rdparty/stout/include/Makefile.am | 3 +
3rdparty/stout/include/stout/os/posix/which.hpp | 72 ++++++++++++++++
3rdparty/stout/include/stout/os/which.hpp | 24 ++++++
.../stout/include/stout/os/windows/which.hpp | 90 ++++++++++++++++++++
3rdparty/stout/include/stout/posix/os.hpp | 39 ---------
3rdparty/stout/tests/os_tests.cpp | 6 +-
6 files changed, 191 insertions(+), 43 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/c8594dcc/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/Makefile.am b/3rdparty/stout/include/Makefile.am
index e5f1104..742bfc4 100644
--- a/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/stout/include/Makefile.am
@@ -115,6 +115,7 @@ nobase_include_HEADERS = \
stout/os/touch.hpp \
stout/os/utime.hpp \
stout/os/wait.hpp \
+ stout/os/which.hpp \
stout/os/write.hpp \
stout/os/xattr.hpp \
stout/os/posix/bootid.hpp \
@@ -152,6 +153,7 @@ nobase_include_HEADERS = \
stout/os/posix/stat.hpp \
stout/os/posix/su.hpp \
stout/os/posix/temp.hpp \
+ stout/os/posix/which.hpp \
stout/os/posix/write.hpp \
stout/os/posix/xattr.hpp \
stout/os/raw/argv.hpp \
@@ -191,6 +193,7 @@ nobase_include_HEADERS = \
stout/os/windows/stat.hpp \
stout/os/windows/su.hpp \
stout/os/windows/temp.hpp \
+ stout/os/windows/which.hpp \
stout/os/windows/write.hpp \
stout/os/windows/xattr.hpp \
stout/path.hpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/c8594dcc/3rdparty/stout/include/stout/os/posix/which.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/posix/which.hpp b/3rdparty/stout/include/stout/os/posix/which.hpp
new file mode 100644
index 0000000..96586dd
--- /dev/null
+++ b/3rdparty/stout/include/stout/os/posix/which.hpp
@@ -0,0 +1,72 @@
+// 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_WHICH_HPP__
+#define __STOUT_OS_POSIX_WHICH_HPP__
+
+#include <string>
+#include <vector>
+
+#include <stout/none.hpp>
+#include <stout/option.hpp>
+#include <stout/os.hpp>
+#include <stout/path.hpp>
+#include <stout/strings.hpp>
+
+#include <stout/os/exists.hpp>
+#include <stout/os/permissions.hpp>
+
+
+namespace os {
+
+inline Option<std::string> which(
+ const std::string& command,
+ const Option<std::string>& _path = None())
+{
+ Option<std::string> path = _path;
+
+ if (path.isNone()) {
+ path = getenv("PATH");
+
+ if (path.isNone()) {
+ return None();
+ }
+ }
+
+ std::vector<std::string> tokens = strings::tokenize(path.get(), ":");
+ foreach (const std::string& token, tokens) {
+ const std::string commandPath = path::join(token, command);
+ if (!os::exists(commandPath)) {
+ continue;
+ }
+
+ Try<os::Permissions> permissions = os::permissions(commandPath);
+ if (permissions.isError()) {
+ continue;
+ }
+
+ if (!permissions.get().owner.x &&
+ !permissions.get().group.x &&
+ !permissions.get().others.x) {
+ continue;
+ }
+
+ return commandPath;
+ }
+
+ return None();
+}
+
+} // namespace os {
+
+
+#endif // __STOUT_OS_POSIX_WHICH_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/c8594dcc/3rdparty/stout/include/stout/os/which.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/which.hpp b/3rdparty/stout/include/stout/os/which.hpp
new file mode 100644
index 0000000..af0a7e8
--- /dev/null
+++ b/3rdparty/stout/include/stout/os/which.hpp
@@ -0,0 +1,24 @@
+// 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_WHICH_HPP__
+#define __STOUT_OS_WHICH_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/os/windows/which.hpp>
+#else
+#include <stout/os/posix/which.hpp>
+#endif // __WINDOWS__
+
+#endif // __STOUT_OS_WHICH_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/c8594dcc/3rdparty/stout/include/stout/os/windows/which.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/windows/which.hpp b/3rdparty/stout/include/stout/os/windows/which.hpp
new file mode 100644
index 0000000..fc541cc
--- /dev/null
+++ b/3rdparty/stout/include/stout/os/windows/which.hpp
@@ -0,0 +1,90 @@
+// 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_WHICH_HPP__
+#define __STOUT_OS_WINDOWS_WHICH_HPP__
+
+#include <string>
+#include <vector>
+
+#include <stout/none.hpp>
+#include <stout/option.hpp>
+#include <stout/os.hpp>
+#include <stout/path.hpp>
+#include <stout/strings.hpp>
+
+#include <stout/os/exists.hpp>
+
+
+namespace os {
+
+// This behaves "like the user expects" of POSIX `which`, but on Windows. That
+// is, if a path is not specified, we search through the `PATH` environment
+// variable, but explicitly do not search the current working directory (which
+// `CreateProcess` and Windows' `where` would do).
+//
+// Because the executable permission does not work on Windows, the closest
+// equivalent is to check the path extension against those listed in `PATHEXT`.
+// However, we first search for exactly the file name the user specified with
+// `command`, regardless of extension, because it could be an executable. If an
+// exact match is not found, we continue the search with the environment's
+// "executable" extensions.
+inline Option<std::string> which(
+ const std::string& command,
+ const Option<std::string>& _path = None())
+{
+ Option<std::string> path = _path;
+
+ if (path.isNone()) {
+ path = os::getenv("PATH");
+
+ if (path.isNone()) {
+ return None();
+ }
+ }
+
+ Option<std::string> pathext = os::getenv("PATHEXT");
+
+ if (pathext.isNone()) {
+ pathext = ".COM;.EXE;.BAT;.CMD";
+ }
+
+ std::vector<std::string> tokens = strings::tokenize(path.get(), ";");
+ std::vector<std::string> exts = strings::tokenize(pathext.get(), ";");
+
+ // NOTE: This handles the edge case of `command` already having an extension,
+ // e.g. `docker.exe`. By starting with the case of "", we don't have to
+ // special case the loops below.
+ exts.insert(exts.begin(), "");
+
+ // Nested loops, but fairly finite. This is how `where` works on Windows
+ // (which is the equivalent of `which`). The loops are nested such that we
+ // first search through `PATH` for `command`, then through `PATH` for
+ // `command.COM` and so on.
+ foreach (const std::string& ext, exts) {
+ foreach (const std::string& token, tokens) {
+ const std::string commandPath = path::join(token, command + ext);
+ if (!os::exists(commandPath)) {
+ continue;
+ }
+
+ return commandPath;
+ }
+ }
+
+ return None();
+}
+
+} // namespace os {
+
+
+#endif // __STOUT_OS_WINDOWS_WHICH_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/c8594dcc/3rdparty/stout/include/stout/posix/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/posix/os.hpp b/3rdparty/stout/include/stout/posix/os.hpp
index 7427bd7..3c52a49 100644
--- a/3rdparty/stout/include/stout/posix/os.hpp
+++ b/3rdparty/stout/include/stout/posix/os.hpp
@@ -403,45 +403,6 @@ inline Try<Version> release()
}
-inline Option<std::string> which(
- const std::string& command,
- const Option<std::string>& _path = None())
-{
- Option<std::string> path = _path;
-
- if (path.isNone()) {
- path = getenv("PATH");
-
- if (path.isNone()) {
- return None();
- }
- }
-
- std::vector<std::string> tokens = strings::tokenize(path.get(), ":");
- foreach (const std::string& token, tokens) {
- const std::string commandPath = path::join(token, command);
- if (!os::exists(commandPath)) {
- continue;
- }
-
- Try<os::Permissions> permissions = os::permissions(commandPath);
- if (permissions.isError()) {
- continue;
- }
-
- if (!permissions.get().owner.x &&
- !permissions.get().group.x &&
- !permissions.get().others.x) {
- continue;
- }
-
- return commandPath;
- }
-
- return None();
-}
-
-
inline Try<std::string> var()
{
return "/var";
http://git-wip-us.apache.org/repos/asf/mesos/blob/c8594dcc/3rdparty/stout/tests/os_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/tests/os_tests.cpp b/3rdparty/stout/tests/os_tests.cpp
index de41077..11f1720 100644
--- a/3rdparty/stout/tests/os_tests.cpp
+++ b/3rdparty/stout/tests/os_tests.cpp
@@ -50,6 +50,7 @@
#include <stout/os/killtree.hpp>
#include <stout/os/realpath.hpp>
#include <stout/os/stat.hpp>
+#include <stout/os/which.hpp>
#include <stout/os/write.hpp>
#if defined(__APPLE__) || defined(__FreeBSD__)
@@ -1035,15 +1036,12 @@ TEST_F(OsTest, SYMLINK_Realpath)
}
-// NOTE: Disabled on Windows because `which` doesn't exist.
-#ifndef __WINDOWS__
TEST_F(OsTest, Which)
{
// TODO(jieyu): Test PATH search ordering and file execution bit.
- Option<string> which = os::which("ls");
+ Option<string> which = os::which("ping");
ASSERT_SOME(which);
which = os::which("bar");
EXPECT_NONE(which);
}
-#endif // __WINDOWS__