ShellManager: do not open child stdin if there is no data to write to it

Fixes #383
This commit is contained in:
Maxime Coste 2016-04-12 13:41:21 +01:00
parent 82a3f10a82
commit d1b693270e

View File

@ -29,8 +29,10 @@ namespace
struct Pipe struct Pipe
{ {
Pipe() { Pipe(bool create = true)
if (::pipe(m_fd) < 0) : m_fd{-1, -1}
{
if (create and ::pipe(m_fd) < 0)
throw runtime_error(format("unable to create pipe (fds: {}/{}; errno: {})", m_fd[0], m_fd[1], ::strerror(errno))); throw runtime_error(format("unable to create pipe (fds: {}/{}; errno: {})", m_fd[0], m_fd[1], ::strerror(errno)));
} }
~Pipe() { close_read_fd(); close_write_fd(); } ~Pipe() { close_read_fd(); close_write_fd(); }
@ -126,13 +128,16 @@ std::pair<String, int> ShellManager::eval(
auto spawn_time = profile ? Clock::now() : TimePoint{}; auto spawn_time = profile ? Clock::now() : TimePoint{};
Pipe child_stdin, child_stdout, child_stderr; Pipe child_stdin{not input.empty()}, child_stdout, child_stderr;
pid_t pid = spawn_shell(cmdline, shell_context.params, kak_env, pid_t pid = spawn_shell(cmdline, shell_context.params, kak_env,
[&child_stdin, &child_stdout, &child_stderr] { [&child_stdin, &child_stdout, &child_stderr] {
auto move = [](int oldfd, int newfd) { dup2(oldfd, newfd); close(oldfd); }; auto move = [](int oldfd, int newfd) { dup2(oldfd, newfd); close(oldfd); };
close(child_stdin.write_fd()); if (child_stdin.read_fd() != -1)
move(child_stdin.read_fd(), 0); {
close(child_stdin.write_fd());
move(child_stdin.read_fd(), 0);
}
close(child_stdout.read_fd()); close(child_stdout.read_fd());
move(child_stdout.write_fd(), 1); move(child_stdout.write_fd(), 1);