summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-03-13 13:39:18 +0000
committerMaxime Coste <frrrwww@gmail.com>2015-03-13 13:39:18 +0000
commit6b3201f0f1aa7e6bd59f766b29bccc2778555069 (patch)
treeebd4ab741e957e9d5a396f9a8097f8c48c1c417c
parentdbe27d3df21552de2003ca38a79c2a9f4406a829 (diff)
Change ShellManager to return both stdout and the return value in a pair
-rw-r--r--src/command_manager.cc4
-rw-r--r--src/commands.cc3
-rw-r--r--src/normal.cc20
-rw-r--r--src/shell_manager.cc40
-rw-r--r--src/shell_manager.hh14
5 files changed, 29 insertions, 52 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc
index 459fcc22..62018bc8 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -310,8 +310,8 @@ String eval_token(const Token& token, Context& context,
switch (token.type())
{
case Token::Type::ShellExpand:
- return ShellManager::instance().eval(content, context, shell_params,
- env_vars);
+ return ShellManager::instance().eval(content, context, {},
+ shell_params, env_vars).first;
case Token::Type::RegisterExpand:
return context.main_sel_register_value(content).str();
case Token::Type::OptionExpand:
diff --git a/src/commands.cc b/src/commands.cc
index dd6d9878..2ab31021 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -733,7 +733,8 @@ void define_command(const ParametersParser& parser, Context& context)
{ "token_to_complete", to_string(token_to_complete) },
{ "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) };
};
}
diff --git a/src/normal.cc b/src/normal.cc
index 4d16bad0..1d4d1cba 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -393,8 +393,8 @@ void pipe(Context& context, NormalParams)
bool insert_eol = str.back() != '\n';
if (insert_eol)
str += '\n';
- str = ShellManager::instance().pipe(str, real_cmd, context,
- {}, EnvVarMap{});
+ str = ShellManager::instance().eval(real_cmd, context, str,
+ {}, EnvVarMap{}).first;
if ((insert_eol or sel.max() == buffer.back_coord()) and
str.back() == '\n')
str = str.substr(0, str.length()-1).str();
@@ -406,9 +406,9 @@ void pipe(Context& context, NormalParams)
else
{
for (auto& sel : selections)
- ShellManager::instance().pipe(
- content(buffer, sel), real_cmd, context, {},
- EnvVarMap{});
+ ShellManager::instance().eval(real_cmd, context,
+ content(buffer, sel),
+ {}, EnvVarMap{}).first;
}
});
}
@@ -435,8 +435,8 @@ void insert_output(Context& context, NormalParams)
if (real_cmd.empty())
return;
- auto str = ShellManager::instance().eval(real_cmd, context, {},
- EnvVarMap{});
+ auto str = ShellManager::instance().eval(real_cmd, context, {}, {},
+ EnvVarMap{}).first;
ScopedEdition edition(context);
context.selections().insert(str, mode);
});
@@ -783,10 +783,8 @@ void keep_pipe(Context& context, NormalParams)
Vector<Selection> keep;
for (auto& sel : context.selections())
{
- int status = 0;
- shell_manager.pipe(content(buffer, sel), cmdline, context,
- {}, EnvVarMap{}, &status);
- if (status == 0)
+ if (shell_manager.eval(cmdline, context, content(buffer, sel),
+ {}, EnvVarMap{}).second == 0)
keep.push_back(sel);
}
if (keep.empty())
diff --git a/src/shell_manager.cc b/src/shell_manager.cc
index 0e5760ed..4dcb7eef 100644
--- a/src/shell_manager.cc
+++ b/src/shell_manager.cc
@@ -26,19 +26,9 @@ ShellManager::ShellManager()
setenv("PATH", new_path.c_str(), 1);
}
-String ShellManager::eval(StringView cmdline, const Context& context,
- 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)
+std::pair<String, int> ShellManager::eval(
+ StringView cmdline, const Context& context, StringView input,
+ ConstArrayView<String> params, const EnvVarMap& env_vars)
{
int write_pipe[2]; // child stdin
int read_pipe[2]; // child stdout
@@ -48,7 +38,6 @@ String ShellManager::pipe(StringView input,
::pipe(read_pipe);
::pipe(error_pipe);
- String output;
if (pid_t pid = fork())
{
close(write_pipe[0]);
@@ -58,7 +47,7 @@ String ShellManager::pipe(StringView input,
write(write_pipe[1], input.data(), (int)input.length());
close(write_pipe[1]);
- String error;
+ String stdout, stderr;
{
auto pipe_reader = [](String& output) {
return [&output](FDWatcher& watcher, EventMode) {
@@ -70,24 +59,19 @@ String ShellManager::pipe(StringView input,
};
};
- FDWatcher stdout_watcher{read_pipe[0], pipe_reader(output)};
- FDWatcher stderr_watcher{error_pipe[0], pipe_reader(error)};
+ FDWatcher stdout_watcher{read_pipe[0], pipe_reader(stdout)};
+ FDWatcher stderr_watcher{error_pipe[0], pipe_reader(stderr)};
while (not stdout_watcher.closed() or not stderr_watcher.closed())
EventManager::instance().handle_next_events(EventMode::Urgent);
}
- if (not error.empty())
- write_debug("shell stderr: <<<\n" + error + ">>>");
+ if (not stderr.empty())
+ write_debug("shell stderr: <<<\n" + stderr + ">>>");
- waitpid(pid, exit_status, 0);
- if (exit_status)
- {
- if (WIFEXITED(*exit_status))
- *exit_status = WEXITSTATUS(*exit_status);
- else
- *exit_status = -1;
- }
+ int status = 0;
+ waitpid(pid, &status, 0);
+ return { stdout, WIFEXITED(status) ? WEXITSTATUS(status) : - 1 };
}
else try
{
@@ -131,7 +115,7 @@ String ShellManager::pipe(StringView input,
exit(-1);
}
catch (...) { exit(-1); }
- return output;
+ return {};
}
void ShellManager::register_env_var(StringView regex,
diff --git a/src/shell_manager.hh b/src/shell_manager.hh
index 60b9b13f..fde507b6 100644
--- a/src/shell_manager.hh
+++ b/src/shell_manager.hh
@@ -20,16 +20,10 @@ class ShellManager : public Singleton<ShellManager>
public:
ShellManager();
- String eval(StringView cmdline, const Context& context,
- ConstArrayView<String> params,
- const EnvVarMap& env_vars,
- int* exit_status = nullptr);
-
- String pipe(StringView input,
- StringView cmdline, const Context& context,
- ConstArrayView<String> params,
- const EnvVarMap& env_vars,
- int* exit_status = nullptr);
+ std::pair<String, int> eval(StringView cmdline, const Context& context,
+ StringView input = {},
+ ConstArrayView<String> params = {},
+ const EnvVarMap& env_vars = EnvVarMap{});
void register_env_var(StringView regex, EnvVarRetriever retriever);
String get_val(StringView name, const Context& context) const;