File indexing completed on 2025-01-18 09:50:11
0001
0002
0003
0004
0005 #ifndef BOOST_PROCESS_V2_IMPL_SHELL_IPP
0006 #define BOOST_PROCESS_V2_IMPL_SHELL_IPP
0007
0008 #include <boost/process/v2/detail/config.hpp>
0009 #include <boost/process/v2/detail/last_error.hpp>
0010 #include <boost/process/v2/detail/throw_error.hpp>
0011 #include <boost/process/v2/detail/config.hpp>
0012 #include <boost/process/v2/error.hpp>
0013 #include <boost/process/v2/shell.hpp>
0014
0015 #if defined(BOOST_PROCESS_V2_WINDOWS)
0016 #include <shellapi.h>
0017 #else
0018 #include <wordexp.h>
0019 #endif
0020
0021 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0022
0023 #if defined(BOOST_PROCESS_V2_WINDOWS)
0024 BOOST_PROCESS_V2_DECL const error_category& get_shell_category()
0025 {
0026 return system_category();
0027 }
0028 #else
0029
0030 struct shell_category_t final : public error_category
0031 {
0032 shell_category_t() : error_category(0xDAF1u) {}
0033
0034 const char* name() const noexcept
0035 {
0036 return "process.v2.utf8";
0037 }
0038 std::string message(int value) const
0039 {
0040 switch (value)
0041 {
0042 case WRDE_BADCHAR:
0043 return "Illegal occurrence of newline or one of |, &, ;, <, >, (, ), {, }.";
0044 case WRDE_BADVAL:
0045 return "An undefined shell variable was referenced, and the WRDE_UNDEF flag told us to consider this an error.";
0046 case WRDE_CMDSUB:
0047 return "Command substitution occurred, and the WRDE_NOCMD flag told us to consider this an error.";
0048 case WRDE_NOSPACE:
0049 return "Out of memory.";
0050 case WRDE_SYNTAX:
0051 return "Shell syntax error, such as unbalanced parentheses or unmatched quotes.";
0052 default:
0053 return "process.v2.wordexp error";
0054 }
0055 }
0056 };
0057
0058 BOOST_PROCESS_V2_DECL const error_category& get_shell_category()
0059 {
0060 static shell_category_t instance;
0061 return instance;
0062 }
0063
0064 #endif
0065
0066 #if defined (BOOST_PROCESS_V2_WINDOWS)
0067
0068 void shell::parse_()
0069 {
0070 argv_ = ::CommandLineToArgvW(input_.c_str(), &argc_);
0071 if (argv_ == nullptr)
0072 {
0073 error_code ec;
0074 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
0075 throw system_error(ec, "shell::parse");
0076 }
0077 }
0078
0079 shell::~shell()
0080 {
0081 if (argv_ != nullptr)
0082 LocalFree(argv_);
0083 }
0084
0085 auto shell::args() const-> args_type
0086 {
0087 return input_.c_str();
0088 }
0089
0090 #else
0091
0092 void shell::parse_()
0093 {
0094 wordexp_t we{};
0095 auto cd = wordexp(input_.c_str(), &we, WRDE_NOCMD);
0096
0097 if (cd != 0)
0098 detail::throw_error(error_code(cd, get_shell_category()), "shell::parse");
0099 else
0100 {
0101 argc_ = static_cast<int>(we.we_wordc);
0102 argv_ = we.we_wordv;
0103 }
0104
0105 free_argv_ = +[](int argc, char ** argv)
0106 {
0107 wordexp_t we{
0108 .we_wordc = static_cast<std::size_t>(argc),
0109 .we_wordv = argv,
0110 .we_offs = 0
0111 };
0112 wordfree(&we);
0113 };
0114 }
0115
0116 shell::~shell()
0117 {
0118 if (argv_ != nullptr && free_argv_ != nullptr)
0119 free_argv_(argc_, argv_);
0120 }
0121
0122 auto shell::args() const -> args_type
0123 {
0124 if (argc() == 0)
0125 {
0126 static const char * helper = nullptr;
0127 return &helper;
0128 }
0129 else
0130 return const_cast<const char**>(argv());
0131 }
0132
0133 #endif
0134
0135 BOOST_PROCESS_V2_END_NAMESPACE
0136
0137 #endif