summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-06-08 22:42:51 +0100
committerMaxime Coste <frrrwww@gmail.com>2015-06-08 22:42:51 +0100
commit409d804ee85074eed8bd94f616bc23284bdf5eb9 (patch)
treeac725706d8155d1141be6fb366aa1840bb2f9beb
parent6cb7e20d54984494d98589213119a9e2accb0317 (diff)
Do not close stderr/stdout before program finish
Programs like grep called in '$' command will fail due to SIGPIPE for example. So we need to keep the pipe open.
-rw-r--r--src/command_manager.cc2
-rw-r--r--src/commands.cc2
-rw-r--r--src/event_manager.cc7
-rw-r--r--src/normal.cc4
-rw-r--r--src/shell_manager.cc16
-rw-r--r--src/shell_manager.hh4
6 files changed, 18 insertions, 17 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc
index e57ab196..9ac3a8d4 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -271,7 +271,7 @@ String expand_token(const Token& token, const Context& context,
{
case Token::Type::ShellExpand:
return ShellManager::instance().eval(content, context, {},
- ShellManager::Flags::ReadOutput,
+ ShellManager::Flags::WaitForStdout,
shell_params, env_vars).first;
case Token::Type::RegisterExpand:
return context.main_sel_register_value(content).str();
diff --git a/src/commands.cc b/src/commands.cc
index 6d6a55fc..e73b61ec 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -787,7 +787,7 @@ void define_command(const ParametersParser& parser, Context& context)
{ "pos_in_token", to_string(pos_in_token) }
};
String output = ShellManager::instance().eval(shell_cmd, context, {},
- ShellManager::Flags::ReadOutput,
+ ShellManager::Flags::WaitForStdout,
params, vars).first;
return Completions{ 0_byte, pos_in_token, split(output, '\n', 0) };
};
diff --git a/src/event_manager.cc b/src/event_manager.cc
index 21cd6331..0b345fc2 100644
--- a/src/event_manager.cc
+++ b/src/event_manager.cc
@@ -25,8 +25,11 @@ void FDWatcher::run(EventMode mode)
void FDWatcher::close_fd()
{
- close(m_fd);
- m_fd = -1;
+ if (m_fd != -1)
+ {
+ close(m_fd);
+ m_fd = -1;
+ }
}
Timer::Timer(TimePoint date, Callback callback, EventMode mode)
diff --git a/src/normal.cc b/src/normal.cc
index 75fb2b20..8cd44a7b 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -396,7 +396,7 @@ void pipe(Context& context, NormalParams)
str += '\n';
str = ShellManager::instance().eval(
real_cmd, context, str,
- ShellManager::Flags::ReadOutput,
+ ShellManager::Flags::WaitForStdout,
{}, EnvVarMap{}).first;
if ((insert_eol or sel.max() == buffer.back_coord()) and
@@ -441,7 +441,7 @@ void insert_output(Context& context, NormalParams)
return;
auto str = ShellManager::instance().eval(real_cmd, context, {},
- ShellManager::Flags::ReadOutput,
+ ShellManager::Flags::WaitForStdout,
{}, EnvVarMap{}).first;
ScopedEdition edition(context);
context.selections().insert(str, mode);
diff --git a/src/shell_manager.cc b/src/shell_manager.cc
index ff483d89..3a64eef2 100644
--- a/src/shell_manager.cc
+++ b/src/shell_manager.cc
@@ -60,20 +60,18 @@ 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)};
- 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)
+ while (not terminated or
+ ((flags & Flags::WaitForStdout) and
+ (not stdout_watcher.closed() or
+ not stderr_watcher.closed())))
{
EventManager::instance().handle_next_events(EventMode::Urgent);
if (not terminated)
terminated = waitpid(pid, &status, WNOHANG);
}
+
+ stdout_watcher.close_fd();
+ stderr_watcher.close_fd();
}
if (not child_stderr.empty())
diff --git a/src/shell_manager.hh b/src/shell_manager.hh
index 36c74a3a..586cf59b 100644
--- a/src/shell_manager.hh
+++ b/src/shell_manager.hh
@@ -24,12 +24,12 @@ public:
enum class Flags
{
None = 0,
- ReadOutput = 1
+ WaitForStdout = 1
};
std::pair<String, int> eval(StringView cmdline, const Context& context,
StringView input = {},
- Flags flags = Flags::ReadOutput,
+ Flags flags = Flags::WaitForStdout,
ConstArrayView<String> params = {},
const EnvVarMap& env_vars = EnvVarMap{});