summaryrefslogtreecommitdiff
path: root/src/shell_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2021-03-04 20:59:15 +1100
committerMaxime Coste <mawww@kakoune.org>2021-03-04 20:59:15 +1100
commitf6c8ebc4d04a97ef8934356b10f16866a6267b51 (patch)
tree8f5b828c21a603db81a656a8994b4e992dd5f1a0 /src/shell_manager.cc
parentda80a8cf6ae3f2993d86c2c328b099078e037c96 (diff)
Refactor pipe reader/writer
Diffstat (limited to 'src/shell_manager.cc')
-rw-r--r--src/shell_manager.cc97
1 files changed, 46 insertions, 51 deletions
diff --git a/src/shell_manager.cc b/src/shell_manager.cc
index 93a9f3fe..c39afadd 100644
--- a/src/shell_manager.cc
+++ b/src/shell_manager.cc
@@ -165,6 +165,49 @@ Vector<String> generate_env(StringView cmdline, const Context& context, const Sh
return env;
}
+FDWatcher make_pipe_reader(Pipe& pipe, String& contents)
+{
+ return {pipe.read_fd(), FdEvents::Read,
+ [&contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) {
+ char buffer[1024];
+ while (fd_readable(pipe.read_fd()))
+ {
+ size_t size = ::read(pipe.read_fd(), buffer, sizeof(buffer));
+ if (size <= 0)
+ {
+ pipe.close_read_fd();
+ watcher.disable();
+ return;
+ }
+ contents += StringView{buffer, buffer+size};
+ }
+ }};
+}
+
+FDWatcher make_pipe_writer(Pipe& pipe, StringView contents)
+{
+ int flags = fcntl(pipe.write_fd(), F_GETFL, 0);
+ fcntl(pipe.write_fd(), F_SETFL, flags | O_NONBLOCK);
+ return {pipe.write_fd(), FdEvents::Write,
+ [contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) mutable {
+ while (fd_writable(pipe.write_fd()))
+ {
+ ssize_t size = ::write(pipe.write_fd(), contents.begin(),
+ (size_t)contents.length());
+ if (size > 0)
+ contents = contents.substr(ByteCount{(int)size});
+ if (size == -1 and (errno == EAGAIN or errno == EWOULDBLOCK))
+ return;
+ if (size < 0 or contents.empty())
+ {
+ pipe.close_write_fd();
+ watcher.disable();
+ return;
+ }
+ }
+ }};
+}
+
}
std::pair<String, int> ShellManager::eval(
@@ -213,58 +256,10 @@ std::pair<String, int> ShellManager::eval(
auto wait_time = Clock::now();
- struct PipeReader : FDWatcher
- {
- PipeReader(Pipe& pipe, String& contents)
- : FDWatcher(pipe.read_fd(), FdEvents::Read,
- [&contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) {
- char buffer[1024];
- while (fd_readable(pipe.read_fd()))
- {
- size_t size = ::read(pipe.read_fd(), buffer, 1024);
- if (size <= 0)
- {
- pipe.close_read_fd();
- watcher.disable();
- return;
- }
- contents += StringView{buffer, buffer+size};
- }
- })
- {}
- };
-
- struct PipeWriter : FDWatcher
- {
- PipeWriter(Pipe& pipe, StringView contents)
- : FDWatcher(pipe.write_fd(), FdEvents::Write,
- [contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) mutable {
- while (fd_writable(pipe.write_fd()))
- {
- ssize_t size = ::write(pipe.write_fd(), contents.begin(),
- (size_t)contents.length());
- if (size > 0)
- contents = contents.substr(ByteCount{(int)size});
- if (size == -1 and (errno == EAGAIN or errno == EWOULDBLOCK))
- return;
- if (size < 0 or contents.empty())
- {
- pipe.close_write_fd();
- watcher.disable();
- return;
- }
- }
- })
- {
- int flags = fcntl(pipe.write_fd(), F_GETFL, 0);
- fcntl(pipe.write_fd(), F_SETFL, flags | O_NONBLOCK);
- }
- };
-
String stdout_contents, stderr_contents;
- PipeReader stdout_reader{child_stdout, stdout_contents};
- PipeReader stderr_reader{child_stderr, stderr_contents};
- PipeWriter stdin_writer{child_stdin, input};
+ auto stdout_reader = make_pipe_reader(child_stdout, stdout_contents);
+ auto stderr_reader = make_pipe_reader(child_stderr, stderr_contents);
+ auto stdin_writer = make_pipe_writer(child_stdin, input);
// block SIGCHLD to make sure we wont receive it before
// our call to pselect, that will end up blocking indefinitly.