| @@ -0,0 +1,26 @@ | |||
| #include "./proc.hpp" | |||
| #include <dds/util.hpp> | |||
| #include <algorithm> | |||
| #include <array> | |||
| #include <cctype> | |||
| using namespace dds; | |||
| bool dds::needs_quoting(std::string_view s) { | |||
| std::string_view okay_chars = "@%-+=:,./|_"; | |||
| const bool all_okay = std::all_of(s.begin(), s.end(), [&](char c) { | |||
| return std::isalnum(c) || (okay_chars.find(c) != okay_chars.npos); | |||
| }); | |||
| return !all_okay; | |||
| } | |||
| std::string dds::quote_argument(std::string_view s) { | |||
| if (!needs_quoting(s)) { | |||
| return std::string(s); | |||
| } | |||
| auto new_s = replace(s, "\\", "\\\\"); | |||
| new_s = replace(s, "\"", "\\\""); | |||
| return "\"" + new_s + "\""; | |||
| } | |||
| @@ -3,9 +3,26 @@ | |||
| #include <string> | |||
| #include <vector> | |||
| #include <string_view> | |||
| namespace dds { | |||
| bool needs_quoting(std::string_view); | |||
| std::string quote_argument(std::string_view); | |||
| template <typename Container> | |||
| std::string quote_command(const Container& c) { | |||
| std::string acc; | |||
| for (const auto& arg : c) { | |||
| acc += quote_argument(arg) + " "; | |||
| } | |||
| if (!acc.empty()) { | |||
| acc.pop_back(); | |||
| } | |||
| return acc; | |||
| } | |||
| struct proc_result { | |||
| int signal = 0; | |||
| int retc = 0; | |||
| @@ -20,18 +20,10 @@ namespace { | |||
| throw std::system_error(std::error_code(::GetLastError(), std::system_category()), what); | |||
| } | |||
| std::string concat_args(const std::vector<std::string>& cmd) { | |||
| std::stringstream strm; | |||
| for (const auto& arg : cmd) { | |||
| strm << arg << ' '; | |||
| } | |||
| return strm.str(); | |||
| } | |||
| } // namespace | |||
| proc_result dds::run_proc(const std::vector<std::string>& cmd) { | |||
| auto cmd_str = concat_args(cmd); | |||
| const auto cmd_str = quote_command(cmd); | |||
| ::SECURITY_ATTRIBUTES security = {}; | |||
| security.bInheritHandle = TRUE; | |||