This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit ca719052531904d5b04d3958e8185d88cc927fdb
Author: Benjamin Mahler <bmah...@apache.org>
AuthorDate: Wed Apr 1 19:52:37 2020 -0400

    Moved documentation into os/shell.hpp interface.
    
    The os/shell.hpp wrapper provides a single place to read the interface
    and documentation for both POSIX and Windows, this makes it easier
    for us to document the interface and OS differences that a caller
    needs to know about in one place.
    
    Review: https://reviews.apache.org/r/72304
---
 3rdparty/stout/include/stout/os/posix/shell.hpp   | 36 +------------
 3rdparty/stout/include/stout/os/shell.hpp         | 66 ++++++++++++++++++++++-
 3rdparty/stout/include/stout/os/windows/shell.hpp | 24 +--------
 3 files changed, 67 insertions(+), 59 deletions(-)

diff --git a/3rdparty/stout/include/stout/os/posix/shell.hpp 
b/3rdparty/stout/include/stout/os/posix/shell.hpp
index 96dd280..9b47201 100644
--- a/3rdparty/stout/include/stout/os/posix/shell.hpp
+++ b/3rdparty/stout/include/stout/os/posix/shell.hpp
@@ -44,29 +44,7 @@ constexpr const char* arg1 = "-c";
 
 } // namespace Shell {
 
-/**
- * Runs a shell command with optional arguments.
- *
- * This assumes that a successful execution will result in the exit code
- * for the command to be `EXIT_SUCCESS`; in this case, the contents
- * of the `Try` will be the contents of `stdout`.
- *
- * If the exit code is non-zero or the process was signaled, we will
- * return an appropriate error message; but *not* `stderr`.
- *
- * If the caller needs to examine the contents of `stderr` it should
- * be redirected to `stdout` (using, e.g., "2>&1 || true" in the command
- * string).  The `|| true` is required to obtain a success exit
- * code in case of errors, and still obtain `stderr`, as piped to
- * `stdout`.
- *
- * @param fmt the formatting string that contains the command to execute
- *   in the underlying shell.
- * @param t optional arguments for `fmt`.
- *
- * @return the output from running the specified command with the shell; or
- *   an error message if the command's exit code is non-zero.
- */
+
 template <typename... T>
 Try<std::string> shell(const std::string& fmt, const T&... t)
 {
@@ -116,18 +94,6 @@ Try<std::string> shell(const std::string& fmt, const T&... 
t)
 }
 
 
-// Executes a command by calling "/bin/sh -c <command>", and returns
-// after the command has been completed. Returns the exit code on success
-// and `None` on error (e.g., fork/exec/waitpid failed). This function
-// is async signal safe. We return an `Option<int>` instead of a `Try<int>`,
-// because although `Try` does not dynamically allocate, `Error` uses
-// `std::string`, which is not async signal safe.
-//
-// Note: Be cautious about shell injection
-// (https://en.wikipedia.org/wiki/Code_injection#Shell_injection)
-// when using this method and use proper validation and sanitization
-// on the `command`. For this reason in general `os::spawn` is
-// preferred if a shell is not required.
 inline Option<int> system(const std::string& command)
 {
   pid_t pid = ::fork();
diff --git a/3rdparty/stout/include/stout/os/shell.hpp 
b/3rdparty/stout/include/stout/os/shell.hpp
index 33cc8a6..2c378b7 100644
--- a/3rdparty/stout/include/stout/os/shell.hpp
+++ b/3rdparty/stout/include/stout/os/shell.hpp
@@ -13,7 +13,6 @@
 #ifndef __STOUT_OS_SHELL_HPP__
 #define __STOUT_OS_SHELL_HPP__
 
-
 // For readability, we minimize the number of #ifdef blocks in the code by
 // splitting platform specific system calls into separate directories.
 #ifdef __WINDOWS__
@@ -22,5 +21,70 @@
 #include <stout/os/posix/shell.hpp>
 #endif // __WINDOWS__
 
+namespace os {
+
+// Executes a shell command (formatted in an sprintf manner) in a subprocess.
+//
+// Blocks until the subprocess terminates and returns the stdout
+// (but not stderr!) from running the specified command with the
+// shell; or an error message if the command's exit code is non-zero
+// or the process exited from a signal.
+//
+// POSIX: Performs a `popen(command.c_str(), "r")` and reads the
+// output until EOF or reading fails. Note that this is not an
+// async signal safe function.
+//
+// Windows: Forks and executes a "cmd /c <command>" subprocess.
+// TODO(bmahler): Rather than passing the command string to cmd /c,
+// this function is incorrectly quoting / escaping it as if it's
+// executing a program compatible with `CommandLineToArgvW`. cmd.exe
+// Does not use `CommandLineToArgvW` and has its own parsing, which
+// means we should not be adding extra quoting and the caller should
+// make sure that the command is correctly escaped. See MESOS-10093.
+//
+// Note: Be cautious about shell injection
+// (https://en.wikipedia.org/wiki/Code_injection#Shell_injection)
+// when using this method and use proper validation and sanitization
+// on the `command`. For this reason in general directly executing the
+// program using `os::spawn` is preferred if a shell is not required.
+//
+// TODO(bmahler): Embedding string formatting leads to a confusing
+// interface, why don't we let callers decide how they want to format
+// the command string?
+template <typename... T>
+Try<std::string> shell(const std::string& fmt, const T&... t);
+
+
+// Executes a shell command in a subprocess.
+//
+// Blocks until the subprocess terminates and returns the exit code of
+// the subprocess, or `None` if an error occurred (e.g., fork / exec /
+// waitpid or the Windows equivalents failed).
+//
+// POSIX: Performs a `fork()` / `execlp("sh", "-c", command, (char*)0)`
+// in an async signal safe manner. Note that this is not a pure wrapper
+// of the POSIX `system` call because the POSIX implementation ignores
+// SIGINT/SIGQUIT and blocks SIGCHLD while waiting for the child to
+// complete (which is not async-signal-safe).
+//
+// Windows: Forks and executes a "cmd /c <command>" subprocess.
+// TODO(bmahler): Rather than passing the command string to cmd /c,
+// this function is incorrectly quoting / escaping it as if it's
+// executing a program compatible with `CommandLineToArgvW`. cmd.exe
+// Does not use `CommandLineToArgvW` and has its own parsing, which
+// means we should not be adding extra quoting and the caller should
+// make sure that the command is correctly escaped. See MESOS-10093.
+//
+// Note: Be cautious about shell injection
+// (https://en.wikipedia.org/wiki/Code_injection#Shell_injection)
+// when using this method and use proper validation and sanitization
+// on the `command`. For this reason in general directly executing the
+// program using `os::spawn` is preferred if a shell is not required.
+//
+// Note that the return type is `Option<int>` rather than `Try<int>`
+// because `Error` uses an std::string which is not async signal safe.
+inline Option<int> system(const std::string& command);
+
+} // namespace os {
 
 #endif // __STOUT_OS_SHELL_HPP__
diff --git a/3rdparty/stout/include/stout/os/windows/shell.hpp 
b/3rdparty/stout/include/stout/os/windows/shell.hpp
index 3238fe1..587f061 100644
--- a/3rdparty/stout/include/stout/os/windows/shell.hpp
+++ b/3rdparty/stout/include/stout/os/windows/shell.hpp
@@ -52,20 +52,7 @@ constexpr const char* arg1 = "/c";
 
 } // namespace Shell {
 
-// Runs a shell command (with `cmd.exe`) with optional arguments.
-//
-// This assumes that a successful execution will result in the exit
-// code for the command to be `0`; in this case, the contents of the
-// `Try` will be the contents of `stdout`.
-//
-// If the exit code is non-zero, we will return an appropriate error
-// message; but *not* `stderr`.
-//
-// If the caller needs to examine the contents of `stderr` it should
-// be redirected to `stdout` (using, e.g., `2>&1 || exit /b 0` in the
-// command string). The `|| exit /b 0` is required to obtain a success
-// exit code in case of errors, and still obtain `stderr`, as piped to
-// `stdout`.
+
 template <typename... T>
 Try<std::string> shell(const std::string& fmt, const T&... t)
 {
@@ -176,15 +163,6 @@ Try<std::string> shell(const std::string& fmt, const T&... 
t)
 }
 
 
-// Executes a command by calling "cmd /c <command>", and returns
-// after the command has been completed. Returns the process exit
-// code on success and `None` on error.
-//
-// Note: Be cautious about shell injection
-// (https://en.wikipedia.org/wiki/Code_injection#Shell_injection)
-// when using this method and use proper validation and sanitization
-// on the `command`. For this reason in general `os::spawn` is
-// preferred if a shell is not required.
 inline Option<int> system(const std::string& command)
 {
   return os::spawn(Shell::name, {Shell::arg0, Shell::arg1, command});

Reply via email to