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,
std::function<void(const char* bytes, size_t n)> read_stdout,
std::function<void(const char* bytes, size_t n)> 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();

9
src/process.h

@ -21,7 +21,7 @@ public:
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_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<void(const char* bytes, size_t n)> read_stdout;
std::function<void(const char* bytes, size_t n)> read_stderr;
std::thread stdout_thread, stderr_thread;
bool use_stdin;
bool open_stdin;
std::mutex stdin_mutex;
const size_t buffer_size;

20
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<file_descriptor_type>(new file_descriptor_type);
if(read_stdout)
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())
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);

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
//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<file_descriptor_type>(new file_descriptor_type);
if(read_stdout)
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())
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<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();
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) {

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) {
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();
}

Loading…
Cancel
Save