Browse Source

Minor cleanup of process class and functions.

merge-requests/365/head
eidheim 10 years ago
parent
commit
c38e3dc7af
  1. 8
      src/CMakeLists.txt
  2. 4
      src/cmake.cc
  3. 2
      src/juci.cc
  4. 7
      src/process.cpp
  5. 7
      src/process.hpp
  6. 19
      src/process_unix.cpp
  7. 23
      src/process_win.cpp
  8. 4
      src/source_clang.cc
  9. 11
      src/terminal.cc
  10. 4
      src/terminal.h
  11. 14
      src/window.cc

8
src/CMakeLists.txt

@ -74,8 +74,8 @@ set(source_files juci.h
cmake.h
cmake.cc
dialogs.cc
process.h
process.cc
process.hpp
process.cpp
../libclangmm/src/CodeCompleteResults.cc
../libclangmm/src/CompilationDatabase.cc
@ -93,10 +93,10 @@ set(source_files juci.h
../libclangmm/src/Utility.cc)
if(MSYS)
list(APPEND source_files process_win.cc)
list(APPEND source_files process_win.cpp)
list(APPEND source_files dialogs_unix.cc) #dialogs_win.cc does not work any more because of missing SHCreateItemFromParsingName
else()
list(APPEND source_files process_unix.cc)
list(APPEND source_files process_unix.cpp)
list(APPEND source_files dialogs_unix.cc)
endif()

4
src/cmake.cc

@ -47,9 +47,9 @@ CMake::CMake(const boost::filesystem::path &path) {
bool CMake::create_compile_commands(const boost::filesystem::path &path) {
Dialog::Message message("Creating "+path.string()+"/compile_commands.json");
auto exit_code=Singleton::terminal->process(Singleton::config->terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path);
auto exit_status=Singleton::terminal->process(Singleton::config->terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path);
message.hide();
if(exit_code==EXIT_SUCCESS) {
if(exit_status==EXIT_SUCCESS) {
#ifdef _WIN32 //Temporary fix to MSYS2's libclang
auto compile_commands_path=path;
compile_commands_path+="/compile_commands.json";

2
src/juci.cc

@ -67,7 +67,7 @@ void Application::on_activate() {
it++;
}
std::thread another_juci_app([this, directory, files_in_directory](){
Singleton::terminal->async_print("Executing: juci "+directory.string()+files_in_directory);
Singleton::terminal->async_print("Executing: juci "+directory.string()+files_in_directory+"\n");
Singleton::terminal->process("juci "+directory.string()+files_in_directory, "", false);
});
another_juci_app.detach();

7
src/process.cc → src/process.cpp

@ -1,4 +1,4 @@
#include "process.h"
#include "process.hpp"
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
@ -14,10 +14,7 @@ Process::Process(const std::string &command, const std::string &path,
}
Process::~Process() {
if(stdout_thread.joinable())
stdout_thread.join();
if(stderr_thread.joinable())
stderr_thread.join();
close_all();
}
bool Process::write(const std::string &data) {

7
src/process.h → src/process.hpp

@ -14,7 +14,7 @@
///Create a new process given command and run path.
///Note: on Windows it seems impossible to specify which pipes to use.
///Thus, if read_stdout=nullptr, read_stderr=nullptr and open_stdin=false,
///Thus, if read_stdout==nullptr, read_stderr==nullptr and open_stdin==false,
///the stdout, stderr and stdin are sent to the parent process instead.
///Compile with -DMSYS_PROCESS_USE_SH to run command using "sh -c [command]" on Windows as well.
class Process {
@ -35,8 +35,8 @@ public:
///Get the process id of the started process.
id_type get_id() {return id;}
///Wait until process is finished, and return exit_code.
int get_exit_code();
///Wait until process is finished, and return exit status.
int get_exit_status();
///Write to stdin.
bool write(const char *bytes, size_t n);
///Write to stdin. Convenience function using write(const char *, size_t).
@ -60,6 +60,7 @@ private:
id_type open(const std::string &command, const std::string &path);
id_type id;
void async_read();
void close_all();
};
#endif // JUCI_PROCESS_H_

19
src/process_unix.cc → src/process_unix.cpp

@ -1,4 +1,4 @@
#include "process.h"
#include "process.hpp"
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
@ -100,18 +100,25 @@ void Process::async_read() {
}
}
int Process::get_exit_code() {
int Process::get_exit_status() {
if(id<=0)
return -1;
int exit_code;
waitpid(id, &exit_code, 0);
int exit_status;
waitpid(id, &exit_status, 0);
close_all();
return exit_status;
}
void Process::close_all() {
if(stdout_thread.joinable())
stdout_thread.join();
if(stderr_thread.joinable())
stderr_thread.join();
close_stdin();
if(stdin_fd)
close_stdin();
if(stdout_fd) {
close(*stdout_fd);
stdout_fd.reset();
@ -120,8 +127,6 @@ int Process::get_exit_code() {
close(*stderr_fd);
stderr_fd.reset();
}
return exit_code;
}
bool Process::write(const char *bytes, size_t n) {

23
src/process_win.cc → src/process_win.cpp

@ -1,4 +1,4 @@
#include "process.h"
#include "process.hpp"
#include <cstring>
#include "TlHelp32.h"
@ -7,7 +7,7 @@ using namespace std; //TODO: remove
//Based on the example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx.
//Note: on Windows it seems impossible to specify which pipes to use.
//Thus, if read_stdout=nullptr, read_stderr=nullptr and open_stdin=false, the stdout, stderr and stdin are sent to the parent process instead.
//Thus, if read_stdout==nullptr, read_stderr==nullptr and open_stdin==false, the stdout, stderr and stdin are sent to the parent process instead.
Process::id_type Process::open(const std::string &command, const std::string &path) {
if(open_stdin)
stdin_fd=std::unique_ptr<fd_type>(new fd_type);
@ -164,25 +164,32 @@ void Process::async_read() {
}
}
int Process::get_exit_code() {
int Process::get_exit_status() {
if(id==0)
return -1;
DWORD exit_code;
DWORD exit_status;
HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
if(process_handle) {
WaitForSingleObject(process_handle, INFINITE);
GetExitCodeProcess(process_handle, &exit_code);
GetExitCodeProcess(process_handle, &exit_status);
CloseHandle(process_handle);
}
else
exit_code=-1;
exit_status=-1;
close_all();
return static_cast<int>(exit_status);
}
void Process::close_all() {
if(stdout_thread.joinable())
stdout_thread.join();
if(stderr_thread.joinable())
stderr_thread.join();
close_stdin();
if(stdin_fd)
close_stdin();
if(stdout_fd) {
CloseHandle(*stdout_fd);
stdout_fd.reset();
@ -191,8 +198,6 @@ int Process::get_exit_code() {
CloseHandle(*stderr_fd);
stderr_fd.reset();
}
return static_cast<int>(exit_code);
}
bool Process::write(const char *bytes, size_t n) {

4
src/source_clang.cc

@ -988,8 +988,8 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream;
auto exit_code=Singleton::terminal->process(stdin_stream, stdout_stream, command);
if(exit_code==0) {
auto exit_status=Singleton::terminal->process(stdin_stream, stdout_stream, command);
if(exit_status==0) {
get_source_buffer()->begin_user_action();
auto iter=get_buffer()->get_insert()->get_iter();
auto cursor_line_nr=iter.get_line();

11
src/terminal.cc

@ -2,7 +2,6 @@
#include <iostream>
#include "logging.h"
#include "singletons.h"
#include "process.h"
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
@ -87,7 +86,7 @@ int Terminal::process(const std::string &command, const boost::filesystem::path
return -1;
}
return process->get_exit_code();
return process->get_exit_status();
}
int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path) {
@ -121,10 +120,10 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c
}
process.close_stdin();
return process.get_exit_code();
return process.get_exit_status();
}
void Terminal::async_process(const std::string &command, const boost::filesystem::path &path, std::function<void(int exit_code)> callback) {
void Terminal::async_process(const std::string &command, const boost::filesystem::path &path, std::function<void(int exit_status)> callback) {
std::thread async_execute_thread([this, command, path, callback](){
processes_mutex.lock();
stdin_buffer.clear();
@ -146,7 +145,7 @@ void Terminal::async_process(const std::string &command, const boost::filesystem
processes_mutex.unlock();
}
auto exit_code=process->get_exit_code();
auto exit_status=process->get_exit_status();
processes_mutex.lock();
for(auto it=processes.begin();it!=processes.end();it++) {
@ -159,7 +158,7 @@ void Terminal::async_process(const std::string &command, const boost::filesystem
processes_mutex.unlock();
if(callback)
callback(exit_code);
callback(exit_status);
});
async_execute_thread.detach();
}

4
src/terminal.h

@ -8,7 +8,7 @@
#include <thread>
#include <atomic>
#include <iostream>
#include "process.h"
#include "process.hpp"
class Terminal : public Gtk::TextView {
public:
@ -29,7 +29,7 @@ public:
Terminal();
int process(const std::string &command, const boost::filesystem::path &path="", bool use_pipes=true);
int process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path="");
void async_process(const std::string &command, const boost::filesystem::path &path="", std::function<void(int exit_code)> callback=nullptr);
void async_process(const std::string &command, const boost::filesystem::path &path="", std::function<void(int exit_status)> callback=nullptr);
void kill_last_async_process(bool force=false);
void kill_async_processes(bool force=false);

14
src/window.cc

@ -527,9 +527,9 @@ void Window::set_menu_actions() {
compiling=true;
Singleton::terminal->print("Compiling and running "+executable_path.string()+"\n");
auto project_path=cmake.project_path;
Singleton::terminal->async_process(Singleton::config->terminal.make_command, cmake.project_path, [this, executable_path, project_path](int exit_code){
Singleton::terminal->async_process(Singleton::config->terminal.make_command, cmake.project_path, [this, executable_path, project_path](int exit_status){
compiling=false;
if(exit_code==EXIT_SUCCESS) {
if(exit_status==EXIT_SUCCESS) {
auto executable_path_spaces_fixed=executable_path.string();
char last_char=0;
for(size_t c=0;c<executable_path_spaces_fixed.size();c++) {
@ -539,8 +539,8 @@ void Window::set_menu_actions() {
}
last_char=executable_path_spaces_fixed[c];
}
Singleton::terminal->async_process(executable_path_spaces_fixed, project_path, [this, executable_path](int exit_code){
Singleton::terminal->async_print(executable_path.string()+" returned: "+std::to_string(exit_code)+'\n');
Singleton::terminal->async_process(executable_path_spaces_fixed, project_path, [this, executable_path](int exit_status){
Singleton::terminal->async_print(executable_path.string()+" returned: "+std::to_string(exit_status)+'\n');
});
}
});
@ -566,7 +566,7 @@ void Window::set_menu_actions() {
if(cmake.project_path!="") {
compiling=true;
Singleton::terminal->print("Compiling project "+cmake.project_path.string()+"\n");
Singleton::terminal->async_process(Singleton::config->terminal.make_command, cmake.project_path, [this](int exit_code){
Singleton::terminal->async_process(Singleton::config->terminal.make_command, cmake.project_path, [this](int exit_status){
compiling=false;
});
}
@ -586,8 +586,8 @@ void Window::set_menu_actions() {
auto run_path=notebook.get_current_folder();
Singleton::terminal->async_print("Running: "+content+'\n');
Singleton::terminal->async_process(content, run_path, [this, content](int exit_code){
Singleton::terminal->async_print(content+" returned: "+std::to_string(exit_code)+'\n');
Singleton::terminal->async_process(content, run_path, [this, content](int exit_status){
Singleton::terminal->async_print(content+" returned: "+std::to_string(exit_status)+'\n');
});
}
entry_box.hide();

Loading…
Cancel
Save