Change ShellManager to return both stdout and the return value in a pair

This commit is contained in:
Maxime Coste 2015-03-13 13:39:18 +00:00
parent dbe27d3df2
commit 6b3201f0f1
5 changed files with 29 additions and 52 deletions

View File

@ -310,8 +310,8 @@ String eval_token(const Token& token, Context& context,
switch (token.type()) switch (token.type())
{ {
case Token::Type::ShellExpand: case Token::Type::ShellExpand:
return ShellManager::instance().eval(content, context, shell_params, return ShellManager::instance().eval(content, context, {},
env_vars); shell_params, env_vars).first;
case Token::Type::RegisterExpand: case Token::Type::RegisterExpand:
return context.main_sel_register_value(content).str(); return context.main_sel_register_value(content).str();
case Token::Type::OptionExpand: case Token::Type::OptionExpand:

View File

@ -733,7 +733,8 @@ void define_command(const ParametersParser& parser, Context& context)
{ "token_to_complete", to_string(token_to_complete) }, { "token_to_complete", to_string(token_to_complete) },
{ "pos_in_token", to_string(pos_in_token) } { "pos_in_token", to_string(pos_in_token) }
}; };
String output = ShellManager::instance().eval(shell_cmd, context, params, vars); String output = ShellManager::instance().eval(shell_cmd, context,
{}, params, vars).first;
return Completions{ 0_byte, pos_in_token, split(output, '\n', 0) }; return Completions{ 0_byte, pos_in_token, split(output, '\n', 0) };
}; };
} }

View File

@ -393,8 +393,8 @@ void pipe(Context& context, NormalParams)
bool insert_eol = str.back() != '\n'; bool insert_eol = str.back() != '\n';
if (insert_eol) if (insert_eol)
str += '\n'; str += '\n';
str = ShellManager::instance().pipe(str, real_cmd, context, str = ShellManager::instance().eval(real_cmd, context, str,
{}, EnvVarMap{}); {}, EnvVarMap{}).first;
if ((insert_eol or sel.max() == buffer.back_coord()) and if ((insert_eol or sel.max() == buffer.back_coord()) and
str.back() == '\n') str.back() == '\n')
str = str.substr(0, str.length()-1).str(); str = str.substr(0, str.length()-1).str();
@ -406,9 +406,9 @@ void pipe(Context& context, NormalParams)
else else
{ {
for (auto& sel : selections) for (auto& sel : selections)
ShellManager::instance().pipe( ShellManager::instance().eval(real_cmd, context,
content(buffer, sel), real_cmd, context, {}, content(buffer, sel),
EnvVarMap{}); {}, EnvVarMap{}).first;
} }
}); });
} }
@ -435,8 +435,8 @@ void insert_output(Context& context, NormalParams)
if (real_cmd.empty()) if (real_cmd.empty())
return; return;
auto str = ShellManager::instance().eval(real_cmd, context, {}, auto str = ShellManager::instance().eval(real_cmd, context, {}, {},
EnvVarMap{}); EnvVarMap{}).first;
ScopedEdition edition(context); ScopedEdition edition(context);
context.selections().insert(str, mode); context.selections().insert(str, mode);
}); });
@ -783,10 +783,8 @@ void keep_pipe(Context& context, NormalParams)
Vector<Selection> keep; Vector<Selection> keep;
for (auto& sel : context.selections()) for (auto& sel : context.selections())
{ {
int status = 0; if (shell_manager.eval(cmdline, context, content(buffer, sel),
shell_manager.pipe(content(buffer, sel), cmdline, context, {}, EnvVarMap{}).second == 0)
{}, EnvVarMap{}, &status);
if (status == 0)
keep.push_back(sel); keep.push_back(sel);
} }
if (keep.empty()) if (keep.empty())

View File

@ -26,19 +26,9 @@ ShellManager::ShellManager()
setenv("PATH", new_path.c_str(), 1); setenv("PATH", new_path.c_str(), 1);
} }
String ShellManager::eval(StringView cmdline, const Context& context, std::pair<String, int> ShellManager::eval(
ConstArrayView<String> params, StringView cmdline, const Context& context, StringView input,
const EnvVarMap& env_vars, ConstArrayView<String> params, const EnvVarMap& env_vars)
int* exit_status)
{
return pipe("", cmdline, context, params, env_vars, exit_status);
}
String ShellManager::pipe(StringView input,
StringView cmdline, const Context& context,
ConstArrayView<String> params,
const EnvVarMap& env_vars,
int* exit_status)
{ {
int write_pipe[2]; // child stdin int write_pipe[2]; // child stdin
int read_pipe[2]; // child stdout int read_pipe[2]; // child stdout
@ -48,7 +38,6 @@ String ShellManager::pipe(StringView input,
::pipe(read_pipe); ::pipe(read_pipe);
::pipe(error_pipe); ::pipe(error_pipe);
String output;
if (pid_t pid = fork()) if (pid_t pid = fork())
{ {
close(write_pipe[0]); close(write_pipe[0]);
@ -58,7 +47,7 @@ String ShellManager::pipe(StringView input,
write(write_pipe[1], input.data(), (int)input.length()); write(write_pipe[1], input.data(), (int)input.length());
close(write_pipe[1]); close(write_pipe[1]);
String error; String stdout, stderr;
{ {
auto pipe_reader = [](String& output) { auto pipe_reader = [](String& output) {
return [&output](FDWatcher& watcher, EventMode) { return [&output](FDWatcher& watcher, EventMode) {
@ -70,24 +59,19 @@ String ShellManager::pipe(StringView input,
}; };
}; };
FDWatcher stdout_watcher{read_pipe[0], pipe_reader(output)}; FDWatcher stdout_watcher{read_pipe[0], pipe_reader(stdout)};
FDWatcher stderr_watcher{error_pipe[0], pipe_reader(error)}; FDWatcher stderr_watcher{error_pipe[0], pipe_reader(stderr)};
while (not stdout_watcher.closed() or not stderr_watcher.closed()) while (not stdout_watcher.closed() or not stderr_watcher.closed())
EventManager::instance().handle_next_events(EventMode::Urgent); EventManager::instance().handle_next_events(EventMode::Urgent);
} }
if (not error.empty()) if (not stderr.empty())
write_debug("shell stderr: <<<\n" + error + ">>>"); write_debug("shell stderr: <<<\n" + stderr + ">>>");
waitpid(pid, exit_status, 0); int status = 0;
if (exit_status) waitpid(pid, &status, 0);
{ return { stdout, WIFEXITED(status) ? WEXITSTATUS(status) : - 1 };
if (WIFEXITED(*exit_status))
*exit_status = WEXITSTATUS(*exit_status);
else
*exit_status = -1;
}
} }
else try else try
{ {
@ -131,7 +115,7 @@ String ShellManager::pipe(StringView input,
exit(-1); exit(-1);
} }
catch (...) { exit(-1); } catch (...) { exit(-1); }
return output; return {};
} }
void ShellManager::register_env_var(StringView regex, void ShellManager::register_env_var(StringView regex,

View File

@ -20,16 +20,10 @@ class ShellManager : public Singleton<ShellManager>
public: public:
ShellManager(); ShellManager();
String eval(StringView cmdline, const Context& context, std::pair<String, int> eval(StringView cmdline, const Context& context,
ConstArrayView<String> params, StringView input = {},
const EnvVarMap& env_vars, ConstArrayView<String> params = {},
int* exit_status = nullptr); const EnvVarMap& env_vars = EnvVarMap{});
String pipe(StringView input,
StringView cmdline, const Context& context,
ConstArrayView<String> params,
const EnvVarMap& env_vars,
int* exit_status = nullptr);
void register_env_var(StringView regex, EnvVarRetriever retriever); void register_env_var(StringView regex, EnvVarRetriever retriever);
String get_val(StringView name, const Context& context) const; String get_val(StringView name, const Context& context) const;