#include #include #include #include #include "Terminal.h" #include "modules/ImguiModule/ImguiModule.h" Terminal::Terminal(Archimedes::App* a, void* h) : Archimedes::Module(a, h) { name = "Terminal"; ImguiModule* im = new ImguiModule(a, h); deps[*im] = im; } Terminal::~Terminal() { if(app) { ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; } im->releaseContext(ImGui::GetCurrentContext()); } } void Terminal::onLoad() { ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; } if(!im) { std::cout << "No ImguiModule for Terminal!\n"; std::abort(); } ImGui::SetCurrentContext(im->aquireContext()); child_pid = forkpty(&master, nullptr, nullptr, nullptr); if(!child_pid) { char* const* args = nullptr; execvp("bash", args); } //fcntl(master, F_SETFL, fcntl(master, F_GETFL, 0) | O_NONBLOCK); /* if (master >= 0) (void)write(master, "ls\n", 3); */ } void Terminal::run() { static fd_set fds; static int rc; static char opArr[150]; static std::string input, output; static timeval to; to = { 0, 0 }; FD_ZERO(&fds); FD_SET(master, &fds); rc = select(master + 1, &fds, NULL, NULL, &to); switch(rc) { case -1: std::cerr << "Error " << errno << " on select()\n"; exit(1); default: if(FD_ISSET(master, &fds)) { rc = read(master, opArr, 150); if(rc < 0) { //error on read app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); } else { if(input == "clear") output = ""; output += opArr; } } } ImGui::Begin("Terminal Module"); ImGui::TextWrapped("%s", output.c_str()); ImGui::InputText("input", &input); if(ImGui::Button("send")) { (void)write(master, (input + "\n").c_str(), input.length() + 1); } ImGui::End(); }