Browse Source

Fixed some issues with the new terminal/process source

merge-requests/365/head
eidheim 10 years ago
parent
commit
d7a48e30fe
  1. 4
      src/process.cc
  2. 9
      src/process.h
  3. 20
      src/process_unix.cc
  4. 20
      src/process_win.cc
  5. 10
      src/terminal.cc

4
src/process.cc

@ -6,8 +6,8 @@ using namespace std; //TODO: remove
Process::Process(const std::string &command, const std::string &path, Process::Process(const std::string &command, const std::string &path,
std::function<void(const char* bytes, size_t n)> read_stdout, std::function<void(const char* bytes, size_t n)> read_stdout,
std::function<void(const char* bytes, size_t n)> read_stderr, std::function<void(const char* bytes, size_t n)> read_stderr,
bool use_stdin, size_t buffer_size): bool open_stdin, size_t buffer_size):
read_stdout(read_stdout), read_stderr(read_stderr), use_stdin(use_stdin), buffer_size(buffer_size) { read_stdout(read_stdout), read_stderr(read_stderr), open_stdin(open_stdin), buffer_size(buffer_size) {
id=open(command, path); id=open(command, path);
if(id!=0) if(id!=0)
async_read(); async_read();

9
src/process.h

@ -21,7 +21,7 @@ public:
Process(const std::string &command, const std::string &path=std::string(), Process(const std::string &command, const std::string &path=std::string(),
std::function<void(const char *bytes, size_t n)> read_stdout=nullptr, std::function<void(const char *bytes, size_t n)> read_stdout=nullptr,
std::function<void(const char *bytes, size_t n)> read_stderr=nullptr, std::function<void(const char *bytes, size_t n)> read_stderr=nullptr,
bool use_stdin=false, bool open_stdin=false,
size_t buffer_size=131072); size_t buffer_size=131072);
~Process(); ~Process();
@ -29,7 +29,10 @@ public:
process_id_type get_id() {return id;} process_id_type get_id() {return id;}
///Wait until process is finished, and return exit_code. ///Wait until process is finished, and return exit_code.
int get_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. ///Kill a given process id.
static void kill(process_id_type id, bool force=false); static void kill(process_id_type id, bool force=false);
@ -38,7 +41,7 @@ private:
std::function<void(const char* bytes, size_t n)> read_stdout; std::function<void(const char* bytes, size_t n)> read_stdout;
std::function<void(const char* bytes, size_t n)> read_stderr; std::function<void(const char* bytes, size_t n)> read_stderr;
std::thread stdout_thread, stderr_thread; std::thread stdout_thread, stderr_thread;
bool use_stdin; bool open_stdin;
std::mutex stdin_mutex; std::mutex stdin_mutex;
const size_t buffer_size; const size_t buffer_size;

20
src/process_unix.cc

@ -7,7 +7,7 @@
using namespace std; //TODO: remove using namespace std; //TODO: remove
process_id_type Process::open(const std::string &command, const std::string &path) { process_id_type Process::open(const std::string &command, const std::string &path) {
if(use_stdin) if(open_stdin)
stdin_fd=std::unique_ptr<file_descriptor_type>(new file_descriptor_type); stdin_fd=std::unique_ptr<file_descriptor_type>(new file_descriptor_type);
if(read_stdout) if(read_stdout)
stdout_fd=std::unique_ptr<file_descriptor_type>(new file_descriptor_type); stdout_fd=std::unique_ptr<file_descriptor_type>(new file_descriptor_type);
@ -109,12 +109,7 @@ int Process::get_exit_code() {
if(stderr_thread.joinable()) if(stderr_thread.joinable())
stderr_thread.join(); stderr_thread.join();
stdin_mutex.lock(); close_stdin();
if(stdin_fd) {
close(*stdin_fd);
stdin_fd.reset();
}
stdin_mutex.unlock();
if(stdout_fd) { if(stdout_fd) {
close(*stdout_fd); close(*stdout_fd);
stdout_fd.reset(); stdout_fd.reset();
@ -127,7 +122,7 @@ int Process::get_exit_code() {
return 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(); stdin_mutex.lock();
if(stdin_fd) { if(stdin_fd) {
if(::write(*stdin_fd, bytes, n)>=0) { if(::write(*stdin_fd, bytes, n)>=0) {
@ -143,6 +138,15 @@ bool Process::write(const char *bytes, size_t n) {
return false; 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) { void Process::kill(process_id_type id, bool force) {
if(force) if(force)
::kill(-id, SIGTERM); ::kill(-id, SIGTERM);

20
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 //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 //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) { process_id_type Process::open(const std::string &command, const std::string &path) {
if(use_stdin) if(open_stdin)
stdin_fd=std::unique_ptr<file_descriptor_type>(new file_descriptor_type); stdin_fd=std::unique_ptr<file_descriptor_type>(new file_descriptor_type);
if(read_stdout) if(read_stdout)
stdout_fd=std::unique_ptr<file_descriptor_type>(new file_descriptor_type); stdout_fd=std::unique_ptr<file_descriptor_type>(new file_descriptor_type);
@ -184,12 +184,7 @@ int Process::get_exit_code() {
if(stderr_thread.joinable()) if(stderr_thread.joinable())
stderr_thread.join(); stderr_thread.join();
stdin_mutex.lock(); close_stdin();
if(stdin_fd) {
CloseHandle(*stdin_fd);
stdin_fd.reset();
}
stdin_mutex.unlock();
if(stdout_fd) { if(stdout_fd) {
CloseHandle(*stdout_fd); CloseHandle(*stdout_fd);
stdout_fd.reset(); stdout_fd.reset();
@ -202,7 +197,7 @@ int Process::get_exit_code() {
return static_cast<int>(exit_code); return static_cast<int>(exit_code);
} }
bool Process::write(const char *bytes, size_t n) { bool Process::write_stdin(const char *bytes, size_t n) {
stdin_mutex.lock(); stdin_mutex.lock();
if(stdin_fd) { if(stdin_fd) {
DWORD written; DWORD written;
@ -220,6 +215,15 @@ bool Process::write(const char *bytes, size_t n) {
return false; 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) { void Process::kill(process_id_type id, bool force) {
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(snapshot) { if(snapshot) {

10
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) { 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) { 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; Glib::ustring::iterator iter;
while(!umessage.validate(iter)) { while(!umessage.validate(iter)) {
auto next_char_iter=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); stdout_stream.write(umessage.data(), n);
}, [this](const char* bytes, size_t n) { }, [this](const char* bytes, size_t n) {
async_print(std::string(bytes, n), true); async_print(std::string(bytes, n), true);
}); }, true);
if(process.get_id()<=0) { if(process.get_id()<=0) {
async_print("Error: Failed to run command: " + command + "\n", true); 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(); auto read_n=stdin_stream.gcount();
if(read_n==0) if(read_n==0)
break; break;
if(!process.write(buffer, read_n)) if(!process.write_stdin(buffer, read_n)) {
break; break;
} }
}
process.close_stdin();
return process.get_exit_code(); return process.get_exit_code();
} }
@ -263,7 +265,7 @@ bool Terminal::on_key_press_event(GdkEventKey *event) {
} }
else if(event->keyval==GDK_KEY_Return) { else if(event->keyval==GDK_KEY_Return) {
stdin_buffer+='\n'; 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)); get_buffer()->insert_at_cursor(stdin_buffer.substr(stdin_buffer.size()-1));
stdin_buffer.clear(); stdin_buffer.clear();
} }

Loading…
Cancel
Save