Change ShellManager to return both stdout and the return value in a pair
This commit is contained in:
parent
dbe27d3df2
commit
6b3201f0f1
|
@ -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:
|
||||||
|
|
|
@ -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) };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user