From 466d4da0c6e7255a38b8de3c3b9dc0373805cc41 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Tue, 12 Jan 2016 06:00:58 -0200 Subject: refactor *Screen classes, add InfoScreen superclass --- TraceScreen.c | 254 ++++++++++++++++++++++------------------------------------ 1 file changed, 98 insertions(+), 156 deletions(-) (limited to 'TraceScreen.c') diff --git a/TraceScreen.c b/TraceScreen.c index 3a62eb63..0752a13c 100644 --- a/TraceScreen.c +++ b/TraceScreen.c @@ -8,6 +8,7 @@ in the source distribution for its full text. #include "TraceScreen.h" #include "CRT.h" +#include "InfoScreen.h" #include "ProcessList.h" #include "ListItem.h" #include "IncSet.h" @@ -26,13 +27,17 @@ in the source distribution for its full text. #include /*{ -#include "Process.h" -#include "Panel.h" +#include "InfoScreen.h" typedef struct TraceScreen_ { - Process* process; - Panel* display; + InfoScreen super; bool tracing; + int fdpair[2]; + int child; + FILE* strace; + int fd_strace; + bool contLine; + bool follow; } TraceScreen; }*/ @@ -43,188 +48,125 @@ static const char* TraceScreenKeys[] = {"F3", "F4", "F8", "F9", "Esc"}; static int TraceScreenEvents[] = {KEY_F(3), KEY_F(4), KEY_F(8), KEY_F(9), 27}; +InfoScreenClass TraceScreen_class = { + .super = { + .extends = Class(Object), + .delete = TraceScreen_delete + }, + .draw = TraceScreen_draw, + .onErr = TraceScreen_updateTrace, + .onKey = TraceScreen_onKey, +}; + TraceScreen* TraceScreen_new(Process* process) { TraceScreen* this = malloc(sizeof(TraceScreen)); - this->process = process; - FunctionBar* fuBar = FunctionBar_new(TraceScreenFunctions, TraceScreenKeys, TraceScreenEvents); - this->display = Panel_new(0, 1, COLS, LINES-2, false, Class(ListItem), fuBar); + Object_setClass(this, Class(TraceScreen)); this->tracing = true; - return this; + this->contLine = false; + this->follow = false; + FunctionBar* fuBar = FunctionBar_new(TraceScreenFunctions, TraceScreenKeys, TraceScreenEvents); + CRT_disableDelay(); + return (TraceScreen*) InfoScreen_init(&this->super, process, fuBar, LINES-2, ""); } -void TraceScreen_delete(TraceScreen* this) { - Panel_delete((Object*)this->display); - free(this); +void TraceScreen_delete(Object* cast) { + TraceScreen* this = (TraceScreen*) cast; + if (this->child > 0) { + kill(this->child, SIGTERM); + waitpid(this->child, NULL, 0); + fclose(this->strace); + } + CRT_enableDelay(); + free(InfoScreen_done((InfoScreen*)cast)); } -static void TraceScreen_draw(TraceScreen* this, IncSet* inc) { +void TraceScreen_draw(InfoScreen* this) { attrset(CRT_colors[PANEL_HEADER_FOCUS]); mvhline(0, 0, ' ', COLS); mvprintw(0, 0, "Trace of process %d - %s", this->process->pid, this->process->comm); attrset(CRT_colors[DEFAULT_COLOR]); - IncSet_drawBar(inc); -} - -static inline void addLine(const char* line, Vector* lines, Panel* panel, const char* incFilter) { - Vector_add(lines, (Object*) ListItem_new(line, 0)); - if (!incFilter || String_contains_i(line, incFilter)) - Panel_add(panel, (Object*)Vector_get(lines, Vector_size(lines)-1)); + IncSet_drawBar(this->inc); } -static inline void appendLine(const char* line, Vector* lines, Panel* panel, const char* incFilter) { - ListItem* last = (ListItem*)Vector_get(lines, Vector_size(lines)-1); - ListItem_append(last, line); - if (incFilter && Panel_get(panel, Panel_size(panel)-1) != (Object*)last && String_contains_i(line, incFilter)) - Panel_add(panel, (Object*)last); -} - -void TraceScreen_run(TraceScreen* this) { +bool TraceScreen_forkTracer(TraceScreen* this) { char buffer[1001]; - int fdpair[2]; - int err = pipe(fdpair); - if (err == -1) return; - int child = fork(); - if (child == -1) return; - if (child == 0) { + int err = pipe(this->fdpair); + if (err == -1) return false; + this->child = fork(); + if (this->child == -1) return false; + if (this->child == 0) { seteuid(getuid()); - dup2(fdpair[1], STDERR_FILENO); - int ok = fcntl(fdpair[1], F_SETFL, O_NONBLOCK); + dup2(this->fdpair[1], STDERR_FILENO); + int ok = fcntl(this->fdpair[1], F_SETFL, O_NONBLOCK); if (ok != -1) { - sprintf(buffer, "%d", this->process->pid); + sprintf(buffer, "%d", this->super.process->pid); execlp("strace", "strace", "-p", buffer, NULL); } const char* message = "Could not execute 'strace'. Please make sure it is available in your $PATH."; - ssize_t written = write(fdpair[1], message, strlen(message)); + ssize_t written = write(this->fdpair[1], message, strlen(message)); (void) written; exit(1); } - fcntl(fdpair[0], F_SETFL, O_NONBLOCK); - FILE* strace = fdopen(fdpair[0], "r"); - Panel* panel = this->display; - int fd_strace = fileno(strace); - CRT_disableDelay(); - bool contLine = false; - bool follow = false; - bool looping = true; - - FunctionBar* bar = panel->defaultBar; - IncSet* inc = IncSet_new(bar); - - Vector* lines = Vector_new(panel->items->type, true, DEFAULT_SIZE); - - TraceScreen_draw(this, inc); - - while (looping) { - - Panel_draw(panel, true); - const char* incFilter = IncSet_filter(inc); - - if (inc->active) - move(LINES-1, CRT_cursorX); - int ch = getch(); - - if (ch == ERR) { - fd_set fds; - FD_ZERO(&fds); -// FD_SET(STDIN_FILENO, &fds); - FD_SET(fd_strace, &fds); - struct timeval tv; - tv.tv_sec = 0; tv.tv_usec = 500; - int ready = select(fd_strace+1, &fds, NULL, NULL, &tv); - int nread = 0; - if (ready > 0 && FD_ISSET(fd_strace, &fds)) - nread = fread(buffer, 1, 1000, strace); - if (nread && this->tracing) { - char* line = buffer; - buffer[nread] = '\0'; - for (int i = 0; i < nread; i++) { - if (buffer[i] == '\n') { - buffer[i] = '\0'; - if (contLine) { - appendLine(line, lines, panel, incFilter); - contLine = false; - } else { - addLine(line, lines, panel, incFilter); - } - line = buffer+i+1; - } - } - if (line < buffer+nread) { - addLine(line, lines, panel, incFilter); - buffer[nread] = '\0'; - contLine = true; + fcntl(this->fdpair[0], F_SETFL, O_NONBLOCK); + this->strace = fdopen(this->fdpair[0], "r"); + this->fd_strace = fileno(this->strace); + return true; +} + +void TraceScreen_updateTrace(InfoScreen* super) { + TraceScreen* this = (TraceScreen*) super; + char buffer[1001]; + fd_set fds; + FD_ZERO(&fds); +// FD_SET(STDIN_FILENO, &fds); + FD_SET(this->fd_strace, &fds); + struct timeval tv; + tv.tv_sec = 0; tv.tv_usec = 500; + int ready = select(this->fd_strace+1, &fds, NULL, NULL, &tv); + int nread = 0; + if (ready > 0 && FD_ISSET(this->fd_strace, &fds)) + nread = fread(buffer, 1, 1000, this->strace); + if (nread && this->tracing) { + char* line = buffer; + buffer[nread] = '\0'; + for (int i = 0; i < nread; i++) { + if (buffer[i] == '\n') { + buffer[i] = '\0'; + if (this->contLine) { + InfoScreen_appendLine(&this->super, line); + this->contLine = false; + } else { + InfoScreen_addLine(&this->super, line); } - if (follow) - Panel_setSelected(panel, Panel_size(panel)-1); + line = buffer+i+1; } } - - if (ch == KEY_MOUSE) { - MEVENT mevent; - int ok = getmouse(&mevent); - if (ok == OK) - if (mevent.y >= panel->y && mevent.y < LINES - 1) { - Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV); - follow = false; - ch = 0; - } if (mevent.y == LINES - 1) - ch = IncSet_synthesizeEvent(inc, mevent.x); - } - - if (inc->active) { - IncSet_handleKey(inc, ch, panel, IncSet_getListItemValue, lines); - continue; + if (line < buffer+nread) { + InfoScreen_addLine(&this->super, line); + buffer[nread] = '\0'; + this->contLine = true; } - - switch(ch) { - case ERR: - continue; - case KEY_HOME: - Panel_setSelected(panel, 0); - break; - case KEY_END: - Panel_setSelected(panel, Panel_size(panel)-1); - break; - case KEY_F(3): - case '/': - IncSet_activate(inc, INC_SEARCH, panel); - break; - case KEY_F(4): - case '\\': - IncSet_activate(inc, INC_FILTER, panel); - break; + if (this->follow) + Panel_setSelected(this->super.display, Panel_size(this->super.display)-1); + } +} + +bool TraceScreen_onKey(InfoScreen* super, int ch) { + TraceScreen* this = (TraceScreen*) super; + switch(ch) { case 'f': case KEY_F(8): - follow = !follow; - if (follow) - Panel_setSelected(panel, Panel_size(panel)-1); - break; + this->follow = !(this->follow); + if (this->follow) + Panel_setSelected(super->display, Panel_size(super->display)-1); + return true; case 't': case KEY_F(9): this->tracing = !this->tracing; - FunctionBar_setLabel(bar, KEY_F(9), this->tracing?"Stop Tracing ":"Resume Tracing "); - TraceScreen_draw(this, inc); - break; - case 'q': - case 27: - case KEY_F(10): - looping = false; - break; - case KEY_RESIZE: - Panel_resize(panel, COLS, LINES-2); - TraceScreen_draw(this, inc); - break; - default: - follow = false; - Panel_onKey(panel, ch); - } + FunctionBar_setLabel(super->display->defaultBar, KEY_F(9), this->tracing?"Stop Tracing ":"Resume Tracing "); + InfoScreen_draw(this); + return true; } - - IncSet_delete(inc); - Vector_delete(lines); - - kill(child, SIGTERM); - waitpid(child, NULL, 0); - fclose(strace); - CRT_enableDelay(); + this->follow = false; + return false; } -- cgit v1.2.3