From d7a48e30fe5aa58728c4a67f583bcfd9ab9a73d4 Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 4 Dec 2015 16:06:16 +0100 Subject: [PATCH] Fixed some issues with the new terminal/process source --- src/process.cc | 4 ++-- src/process.h | 9 ++++++--- src/process_unix.cc | 20 ++++++++++++-------- src/process_win.cc | 20 ++++++++++++-------- src/terminal.cc | 10 ++++++---- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/process.cc b/src/process.cc index 2391ab3..72a4906 100644 --- a/src/process.cc +++ b/src/process.cc @@ -6,8 +6,8 @@ using namespace std; //TODO: remove Process::Process(const std::string &command, const std::string &path, std::function read_stdout, std::function read_stderr, - bool use_stdin, size_t buffer_size): - read_stdout(read_stdout), read_stderr(read_stderr), use_stdin(use_stdin), buffer_size(buffer_size) { + bool open_stdin, size_t buffer_size): + read_stdout(read_stdout), read_stderr(read_stderr), open_stdin(open_stdin), buffer_size(buffer_size) { id=open(command, path); if(id!=0) async_read(); diff --git a/src/process.h b/src/process.h index 66019b1..79d0e68 100644 --- a/src/process.h +++ b/src/process.h @@ -21,7 +21,7 @@ public: Process(const std::string &command, const std::string &path=std::string(), std::function read_stdout=nullptr, std::function read_stderr=nullptr, - bool use_stdin=false, + bool open_stdin=false, size_t buffer_size=131072); ~Process(); @@ -29,7 +29,10 @@ public: process_id_type get_id() {return id;} ///Wait until process is finished, and return exit_code. int get_exit_code(); - bool write(const char *bytes, size_t n); + ///Write to stdin. + bool write_stdin(const char *bytes, size_t n); + ///Close stdin. If the process takes parameters from stdin, use this to notify that all parameters have been sent. + void close_stdin(); ///Kill a given process id. static void kill(process_id_type id, bool force=false); @@ -38,7 +41,7 @@ private: std::function read_stdout; std::function read_stderr; std::thread stdout_thread, stderr_thread; - bool use_stdin; + bool open_stdin; std::mutex stdin_mutex; const size_t buffer_size; diff --git a/src/process_unix.cc b/src/process_unix.cc index 74bbe30..f7e1fb5 100644 --- a/src/process_unix.cc +++ b/src/process_unix.cc @@ -7,7 +7,7 @@ using namespace std; //TODO: remove process_id_type Process::open(const std::string &command, const std::string &path) { - if(use_stdin) + if(open_stdin) stdin_fd=std::unique_ptr(new file_descriptor_type); if(read_stdout) stdout_fd=std::unique_ptr(new file_descriptor_type); @@ -109,12 +109,7 @@ int Process::get_exit_code() { if(stderr_thread.joinable()) stderr_thread.join(); - stdin_mutex.lock(); - if(stdin_fd) { - close(*stdin_fd); - stdin_fd.reset(); - } - stdin_mutex.unlock(); + close_stdin(); if(stdout_fd) { close(*stdout_fd); stdout_fd.reset(); @@ -127,7 +122,7 @@ int Process::get_exit_code() { return exit_code; } -bool Process::write(const char *bytes, size_t n) { +bool Process::write_stdin(const char *bytes, size_t n) { stdin_mutex.lock(); if(stdin_fd) { if(::write(*stdin_fd, bytes, n)>=0) { @@ -143,6 +138,15 @@ bool Process::write(const char *bytes, size_t n) { return false; } +void Process::close_stdin() { + stdin_mutex.lock(); + if(stdin_fd) { + close(*stdin_fd); + stdin_fd.reset(); + } + stdin_mutex.unlock(); +} + void Process::kill(process_id_type id, bool force) { if(force) ::kill(-id, SIGTERM); diff --git a/src/process_win.cc b/src/process_win.cc index a4cc727..6487adf 100644 --- a/src/process_win.cc +++ b/src/process_win.cc @@ -9,7 +9,7 @@ using namespace std; //TODO: remove //Note: on Windows it seems impossible to specify which pipes to use //Thus, if stdin_h, stdout_h and stderr all are NULL, the out,err,in is sent to the parent process instead process_id_type Process::open(const std::string &command, const std::string &path) { - if(use_stdin) + if(open_stdin) stdin_fd=std::unique_ptr(new file_descriptor_type); if(read_stdout) stdout_fd=std::unique_ptr(new file_descriptor_type); @@ -184,12 +184,7 @@ int Process::get_exit_code() { if(stderr_thread.joinable()) stderr_thread.join(); - stdin_mutex.lock(); - if(stdin_fd) { - CloseHandle(*stdin_fd); - stdin_fd.reset(); - } - stdin_mutex.unlock(); + close_stdin(); if(stdout_fd) { CloseHandle(*stdout_fd); stdout_fd.reset(); @@ -202,7 +197,7 @@ int Process::get_exit_code() { return static_cast(exit_code); } -bool Process::write(const char *bytes, size_t n) { +bool Process::write_stdin(const char *bytes, size_t n) { stdin_mutex.lock(); if(stdin_fd) { DWORD written; @@ -220,6 +215,15 @@ bool Process::write(const char *bytes, size_t n) { return false; } +void Process::close_stdin() { + stdin_mutex.lock(); + if(stdin_fd) { + CloseHandle(*stdin_fd); + stdin_fd.reset(); + } + stdin_mutex.unlock(); +} + void Process::kill(process_id_type id, bool force) { HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(snapshot) { diff --git a/src/terminal.cc b/src/terminal.cc index a8cc032..b271279 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -92,7 +92,7 @@ int Terminal::process(const std::string &command, const boost::filesystem::path int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path) { Process process(command, path.string(), [this, &stdout_stream](const char* bytes, size_t n) { - Glib::ustring umessage(bytes, n); + Glib::ustring umessage(std::string(bytes, n)); Glib::ustring::iterator iter; while(!umessage.validate(iter)) { auto next_char_iter=iter; @@ -102,7 +102,7 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c stdout_stream.write(umessage.data(), n); }, [this](const char* bytes, size_t n) { async_print(std::string(bytes, n), true); - }); + }, true); if(process.get_id()<=0) { async_print("Error: Failed to run command: " + command + "\n", true); @@ -115,9 +115,11 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c auto read_n=stdin_stream.gcount(); if(read_n==0) break; - if(!process.write(buffer, read_n)) + if(!process.write_stdin(buffer, read_n)) { break; + } } + process.close_stdin(); return process.get_exit_code(); } @@ -263,7 +265,7 @@ bool Terminal::on_key_press_event(GdkEventKey *event) { } else if(event->keyval==GDK_KEY_Return) { stdin_buffer+='\n'; - processes.back()->write(stdin_buffer.c_str(), stdin_buffer.size()); + processes.back()->write_stdin(stdin_buffer.c_str(), stdin_buffer.size()); get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size()-1)); stdin_buffer.clear(); }