90 lines
1.9 KiB
C++
90 lines
1.9 KiB
C++
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
#include <pty.h>
|
|
#include <fcntl.h>
|
|
|
|
#include "Terminal.h"
|
|
#include "modules/ImguiModule/src/ImguiModule.h"
|
|
|
|
|
|
Terminal::Terminal(Archimedes::App* a, void* h) : Archimedes::Module(a, h) {
|
|
|
|
name = "Terminal";
|
|
|
|
ImguiModule* im = new ImguiModule(a, h);
|
|
deps[im->getName()] = im;
|
|
}
|
|
|
|
Terminal::~Terminal() {
|
|
|
|
}
|
|
|
|
void Terminal::onLoad() {
|
|
|
|
ImguiModule* im = (ImguiModule*) moduleInstances["ImguiModule"];
|
|
|
|
if(!im) {
|
|
std::cout << "No ImguiModule for Terminal!\n";
|
|
std::abort();
|
|
}
|
|
|
|
ImGui::SetCurrentContext(im->getContext());
|
|
|
|
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->stopModule(getName());
|
|
} 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();
|
|
}
|