From ee82b3a9303f4b36cc1165e073dcfe7133ec413c Mon Sep 17 00:00:00 2001 From: Ahmed Elsayed Date: Wed, 25 Dec 2019 11:59:02 +0100 Subject: [PATCH] Add options to display parents and children processes of filtered processes --- DisplayOptionsPanel.c | 2 ++ ProcessList.c | 29 ++++++++++++++++++++++++++++- Settings.c | 10 ++++++++++ Settings.h | 2 ++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c index 0ff54e331..6353c539e 100644 --- a/DisplayOptionsPanel.c +++ b/DisplayOptionsPanel.c @@ -84,6 +84,8 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* Panel_setHeader(super, "Display options"); Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Tree view"), &(settings->treeView))); + Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Show parent processes during filter"), &(settings->showParentsInFilter))); + Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Show children processes during filter"), &(settings->showChildrenInFilter))); Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Shadow other users' processes"), &(settings->shadowOtherUsers))); Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Hide kernel threads"), &(settings->hideKernelThreads))); Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Hide userland process threads"), &(settings->hideUserlandThreads))); diff --git a/ProcessList.c b/ProcessList.c index 7482b0377..346286af4 100644 --- a/ProcessList.c +++ b/ProcessList.c @@ -293,6 +293,16 @@ void ProcessList_expandTree(ProcessList* this) { } } +static void ProcessList_filterChildern(ProcessList *this, pid_t pid, Hashtable *processFilter) { + for (int i = Vector_size(this->processes) - 1; i >= 0; i--) { + Process *p = (Process*) (Vector_get(this->processes, i)); + if (p->pid != pid && Process_isChildOf(p, pid)) { + Hashtable_put(processFilter, p->pid, (void*) 1); + ProcessList_filterChildern(this, p->pid, processFilter); + } + } +} + void ProcessList_rebuildPanel(ProcessList* this) { const char* incFilter = this->incFilter; @@ -303,13 +313,29 @@ void ProcessList_rebuildPanel(ProcessList* this) { Panel_prune(this->panel); int size = ProcessList_size(this); int idx = 0; + Hashtable* filteredProcesses = Hashtable_new(size, false); + for (int i = 0; i < size; i++) { + Process* p = ProcessList_get(this, i); + pid_t ppid = Process_getParentPid(p); + + if (incFilter && !(String_contains_i(p->comm, incFilter))) + continue; + + if (this->settings->showChildrenInFilter) + ProcessList_filterChildern(this, p->pid, filteredProcesses); + do { + Hashtable_put(filteredProcesses, p->pid, (void*) 1); + ppid = Process_getParentPid(p); + p = Hashtable_get(this->processTable, ppid); + } while (this->settings->showParentsInFilter && p && p->pid != p->ppid); + } for (int i = 0; i < size; i++) { bool hidden = false; Process* p = ProcessList_get(this, i); if ( (!p->show) || (this->userId != (uid_t) -1 && (p->st_uid != this->userId)) - || (incFilter && !(String_contains_i(p->comm, incFilter))) + || (incFilter && !Hashtable_get(filteredProcesses, p->pid)) || (this->pidWhiteList && !Hashtable_get(this->pidWhiteList, p->tgid)) ) hidden = true; @@ -322,6 +348,7 @@ void ProcessList_rebuildPanel(ProcessList* this) { idx++; } } + Hashtable_delete(filteredProcesses); } Process* ProcessList_getProcess(ProcessList* this, pid_t pid, bool* preExisting, Process_New constructor) { diff --git a/Settings.c b/Settings.c index db2fa0668..73ad4a109 100644 --- a/Settings.c +++ b/Settings.c @@ -46,6 +46,8 @@ typedef struct Settings_ { bool countCPUsFromZero; bool detailedCPUTime; bool treeView; + bool showParentsInFilter; + bool showChildrenInFilter; bool showProgramPath; bool hideThreads; bool shadowOtherUsers; @@ -196,6 +198,10 @@ static bool Settings_read(Settings* this, const char* fileName) { this->direction = atoi(option[1]); } else if (String_eq(option[0], "tree_view")) { this->treeView = atoi(option[1]); + } else if (String_eq(option[0], "show_parents_in_filter")) { + this->showParentsInFilter = atoi(option[1]); + } else if (String_eq(option[0], "show_children_in_filter")) { + this->showChildrenInFilter = atoi(option[1]); } else if (String_eq(option[0], "hide_threads")) { this->hideThreads = atoi(option[1]); } else if (String_eq(option[0], "hide_kernel_threads")) { @@ -309,6 +315,8 @@ bool Settings_write(Settings* this) { fprintf(fd, "highlight_megabytes=%d\n", (int) this->highlightMegabytes); fprintf(fd, "highlight_threads=%d\n", (int) this->highlightThreads); fprintf(fd, "tree_view=%d\n", (int) this->treeView); + fprintf(fd, "show_parents_in_filter=%d\n", (int) this->showParentsInFilter); + fprintf(fd, "show_children_in_filter=%d\n", (int) this->showChildrenInFilter); fprintf(fd, "header_margin=%d\n", (int) this->headerMargin); fprintf(fd, "detailed_cpu_time=%d\n", (int) this->detailedCPUTime); fprintf(fd, "cpu_count_from_zero=%d\n", (int) this->countCPUsFromZero); @@ -336,6 +344,8 @@ Settings* Settings_new(int cpuCount) { this->hideKernelThreads = false; this->hideUserlandThreads = false; this->treeView = false; + this->showParentsInFilter = false; + this->showChildrenInFilter = false; this->highlightBaseName = false; this->highlightMegabytes = false; this->detailedCPUTime = false; diff --git a/Settings.h b/Settings.h index d9dc0683c..fec068d75 100644 --- a/Settings.h +++ b/Settings.h @@ -37,6 +37,8 @@ typedef struct Settings_ { bool countCPUsFromZero; bool detailedCPUTime; bool treeView; + bool showParentsInFilter; + bool showChildrenInFilter; bool showProgramPath; bool hideThreads; bool shadowOtherUsers;