From d81cb34c82e5e700310372fb31a6331784c1ef71 Mon Sep 17 00:00:00 2001 From: JJ Date: Sun, 14 Feb 2021 13:53:42 +1100 Subject: [PATCH] Terminal: PTY master and rendering separate threads, close when LSh does --- Applications/Terminal/main.cpp | 66 ++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index cda942d0..4f057162 100755 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -87,7 +88,10 @@ const int escBufMax = 256; char escBuf[escBufMax]; -char charactersPerLine; +char charactersPerLine; // Characters displayed per line + +int masterPTYFd; // PTY file desc +pid_t lsh; // LSh Process PID void Scroll(){ if(curPos.y >= rowCount){ @@ -500,7 +504,31 @@ void PrintChar(char ch){ } } -extern "C" +[[noreturn]] void* PTYThread(void*){ + std::vector fds; + fds.push_back({.fd = masterPTYFd, .events = POLLIN, .revents = 0}); + + char buf[512]; + + while(waitpid(lsh, nullptr, WNOHANG) <= 0){ + poll(fds.data(), fds.size(), 500000); // Wake up every 500ms to check if LSh has exited + + while(int len = read(masterPTYFd, buf, 512)){ + for(int i = 0; i < len; i++){ + PrintChar(buf[i]); + } + + paint = true; + } + + if(paint){ + Lemon::InterruptThread(0); + } + } + + exit(0); // LSh must have exited +} + int main(int argc, char** argv){ terminalFont = Lemon::Graphics::LoadFont("/initrd/sourcecodepro.ttf", "termmonospace"); if(!terminalFont){ @@ -518,19 +546,19 @@ int main(int argc, char** argv){ buffer.push_back(std::vector()); } - - int masterPTYFd; syscall(SYS_GRANT_PTY, (uintptr_t)&masterPTYFd, 0, 0, 0, 0); - setenv("TERM", "xterm-256color", 1); // the Lemon OS terminal is (fairly) xterm compatible (256 colour, etc.) char* const _argv[] = {const_cast("/system/bin/lsh.lef")}; - lemon_spawn(_argv[0], 1, _argv, 1); + lsh = lemon_spawn(_argv[0], 1, _argv, 1); + + if(lsh < 0){ + perror("Error running lsh"); + return 1; + } window->OnPaint = OnPaint; - char* _buf = (char*)malloc(512); - winsize wSz = { .ws_row = static_cast(rowCount), .ws_col = static_cast(columnCount), @@ -540,11 +568,12 @@ int main(int argc, char** argv){ ioctl(masterPTYFd, TIOCSWINSZ, &wSz); - std::vector fds; - fds.push_back({.fd = masterPTYFd, .events = POLLIN, .revents = 0}); + pthread_t ptyThread; + if(pthread_create(&ptyThread, nullptr, PTYThread, nullptr)){ + perror("Error creating PTY thread"); + return 2; + } - //auto& wMHandler = window->GetHandler(); - //fds.insert(fds.begin(), wMHandler.GetFileDescriptors().begin(), wMHandler.GetFileDescriptors().end()); for(;;){ Lemon::LemonEvent ev; while(window->PollEvent(ev)){ @@ -594,22 +623,15 @@ int main(int argc, char** argv){ } } - while(int len = read(masterPTYFd, _buf, 512)){ - for(int i = 0; i < len; i++){ - PrintChar(_buf[i]); - } - - paint = true; - } - - if(paint){ + if(paint || paintAll){ window->Paint(); paint = false; paintAll = false; } - poll(fds.data(), fds.size(), 20000); + window->WaitEvent(); } + return 0; }