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;