summaryrefslogtreecommitdiff
path: root/src/shell_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-06-08 13:34:08 +0100
committerMaxime Coste <frrrwww@gmail.com>2015-06-08 13:45:20 +0100
commit942fc224af403de0a73511a4e6a5dfe4bfa53b91 (patch)
tree43b9482e2e150c6513f4f230bed667e97fd04a91 /src/shell_manager.cc
parent7acf3da3ca6b012d603e4cf7360abb4a3235daca (diff)
Specify if ShellManager should read output or not using a flag
Some program (xclip), will fork a daemon keeping stdout/stderr open, so waiting for them to be closed make kakoune hang. Commands discarding stdout can then just not wait on it.
Diffstat (limited to 'src/shell_manager.cc')
-rw-r--r--src/shell_manager.cc20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/shell_manager.cc b/src/shell_manager.cc
index ce926ecb..ff483d89 100644
--- a/src/shell_manager.cc
+++ b/src/shell_manager.cc
@@ -24,7 +24,7 @@ ShellManager::ShellManager()
std::pair<String, int> ShellManager::eval(
StringView cmdline, const Context& context, StringView input,
- ConstArrayView<String> params, const EnvVarMap& env_vars)
+ Flags flags, ConstArrayView<String> params, const EnvVarMap& env_vars)
{
int write_pipe[2]; // child stdin
int read_pipe[2]; // child stdout
@@ -44,6 +44,8 @@ std::pair<String, int> ShellManager::eval(
close(write_pipe[1]);
String child_stdout, child_stderr;
+ int status = 0;
+ bool terminated = false;
{
auto pipe_reader = [](String& output) {
return [&output](FDWatcher& watcher, EventMode) {
@@ -58,15 +60,25 @@ std::pair<String, int> ShellManager::eval(
FDWatcher stdout_watcher{read_pipe[0], pipe_reader(child_stdout)};
FDWatcher stderr_watcher{error_pipe[0], pipe_reader(child_stderr)};
- while (not stdout_watcher.closed() or not stderr_watcher.closed())
+ if (not (flags & Flags::ReadOutput))
+ {
+ stdout_watcher.close_fd();
+ stderr_watcher.close_fd();
+ }
+
+ while (not stdout_watcher.closed() or
+ not stderr_watcher.closed() or
+ not terminated)
+ {
EventManager::instance().handle_next_events(EventMode::Urgent);
+ if (not terminated)
+ terminated = waitpid(pid, &status, WNOHANG);
+ }
}
if (not child_stderr.empty())
write_to_debug_buffer(format("shell stderr: <<<\n{}>>>", child_stderr));
- int status = 0;
- waitpid(pid, &status, 0);
return { child_stdout, WIFEXITED(status) ? WEXITSTATUS(status) : - 1 };
}
else try