diff options
author | Christian Göttsche <cgzones@googlemail.com> | 2020-10-07 19:02:23 +0200 |
---|---|---|
committer | cgzones <cgzones@googlemail.com> | 2020-10-10 11:26:43 +0200 |
commit | f8b9ced93f258f1b4b6071f08a54c6f0f9233b49 (patch) | |
tree | 56ccf65109e8f2c41ee9d4de840fc453cf085c5d /OpenFilesScreen.c | |
parent | 79ad39c718bfb2973d610c2d039a5024354e602f (diff) |
OpenFilesScreen update
- Remove local types and function from header file
- Reduce OpenFiles_Data to neccessary size
- Print file access mode (r/w/u)
- Fix memory leak on consecutive items without an intermediate file item:
==15257==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 120 byte(s) in 12 object(s) allocated from:
#0 0x48c864 in strdup (htop/htop+0x48c864)
#1 0x542f68 in xStrdup htop/XAlloc.c:71:17
#2 0x50e225 in OpenFilesScreen_getProcessData htop/OpenFilesScreen.c:112:25
#3 0x50cd17 in OpenFilesScreen_scan htop/OpenFilesScreen.c:141:35
#4 0x4fd3eb in InfoScreen_run htop/InfoScreen.c:81:35
#5 0x4d58bb in actionLsof htop/Action.c:361:4
#6 0x501766 in MainPanel_eventHandler htop/MainPanel.c:80:19
#7 0x5289fa in ScreenManager_run htop/ScreenManager.c:227:19
#8 0x4f748e in main htop/htop.c:300:4
#9 0x7ff73e0d8cc9 in __libc_start_main csu/../csu/libc-start.c:308:16
SUMMARY: AddressSanitizer: 120 byte(s) leaked in 12 allocation(s).
Diffstat (limited to 'OpenFilesScreen.c')
-rw-r--r-- | OpenFilesScreen.c | 129 |
1 files changed, 100 insertions, 29 deletions
diff --git a/OpenFilesScreen.c b/OpenFilesScreen.c index 7c0acebe..1973cc45 100644 --- a/OpenFilesScreen.c +++ b/OpenFilesScreen.c @@ -24,30 +24,63 @@ in the source distribution for its full text. #include <sys/wait.h> -const InfoScreenClass OpenFilesScreen_class = { - .super = { - .extends = Class(Object), - .delete = OpenFilesScreen_delete - }, - .scan = OpenFilesScreen_scan, - .draw = OpenFilesScreen_draw -}; +typedef struct OpenFiles_Data_ { + char* data[7]; +} OpenFiles_Data; + +typedef struct OpenFiles_ProcessData_ { + OpenFiles_Data data; + int error; + struct OpenFiles_FileData_* files; +} OpenFiles_ProcessData; + +typedef struct OpenFiles_FileData_ { + OpenFiles_Data data; + struct OpenFiles_FileData_* next; +} OpenFiles_FileData; + +static size_t getIndexForType(char type) { + switch (type) { + case 'f': + return 0; + case 'a': + return 1; + case 'D': + return 2; + case 'i': + return 3; + case 'n': + return 4; + case 's': + return 5; + case 't': + return 6; + } + + /* should never reach here */ + abort(); +} + +static const char* getDataForType(const OpenFiles_Data* data, char type) { + size_t index = getIndexForType(type); + return data->data[index] ? data->data[index] : ""; +} -OpenFilesScreen* OpenFilesScreen_new(Process* process) { +OpenFilesScreen* OpenFilesScreen_new(const Process* process) { OpenFilesScreen* this = xMalloc(sizeof(OpenFilesScreen)); Object_setClass(this, Class(OpenFilesScreen)); if (Process_isThread(process)) this->pid = process->tgid; else this->pid = process->pid; - return (OpenFilesScreen*) InfoScreen_init(&this->super, process, NULL, LINES-3, " FD TYPE DEVICE SIZE NODE NAME"); + return (OpenFilesScreen*) InfoScreen_init(&this->super, process, NULL, LINES-3, " FD TYPE MODE DEVICE SIZE NODE NAME"); } void OpenFilesScreen_delete(Object* this) { free(InfoScreen_done((InfoScreen*)this)); } -void OpenFilesScreen_draw(InfoScreen* this) { +static void OpenFilesScreen_draw(InfoScreen* this) { InfoScreen_drawTitled(this, "Snapshot of files open in process %d - %s", ((OpenFilesScreen*)this)->pid, this->process->comm); } @@ -99,7 +132,9 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) { } unsigned char cmd = line[0]; - if (cmd == 'f') { + switch (cmd) { + case 'f': /* file descriptor */ + { OpenFiles_FileData* nextFile = xCalloc(1, sizeof(OpenFiles_FileData)); if (fdata == NULL) { pdata->files = nextFile; @@ -108,8 +143,35 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) { } fdata = nextFile; item = &(fdata->data); + } /* FALLTHRU */ + case 'a': /* file access mode */ + case 'D': /* file's major/minor device number */ + case 'i': /* file's inode number */ + case 'n': /* file name, comment, Internet address */ + case 's': /* file's size */ + case 't': /* file's type */ + { + size_t index = getIndexForType(cmd); + free(item->data[index]); + item->data[index] = xStrdup(line + 1); + break; + } + case 'c': /* process command name */ + case 'd': /* file's device character code */ + case 'g': /* process group ID */ + case 'G': /* file flags */ + case 'k': /* link count */ + case 'l': /* file's lock status */ + case 'L': /* process login name */ + case 'o': /* file's offset */ + case 'p': /* process ID */ + case 'P': /* protocol name */ + case 'R': /* parent process ID */ + case 'T': /* TCP/TPI information, identified by prefixes */ + case 'u': /* process user ID */ + /* ignore */ + break; } - item->data[cmd] = xStrdup(line + 1); free(line); } fclose(fd); @@ -128,13 +190,12 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) { return pdata; } -static inline void OpenFiles_Data_clear(OpenFiles_Data* data) { - for (int i = 0; i < 255; i++) - if (data->data[i]) - free(data->data[i]); +static void OpenFiles_Data_clear(OpenFiles_Data* data) { + for (size_t i = 0; i < ARRAYSIZE(data->data); i++) + free(data->data[i]); } -void OpenFilesScreen_scan(InfoScreen* this) { +static void OpenFilesScreen_scan(InfoScreen* this) { Panel* panel = this->display; int idx = Panel_getSelectedIndex(panel); Panel_prune(panel); @@ -146,19 +207,20 @@ void OpenFilesScreen_scan(InfoScreen* this) { } else { OpenFiles_FileData* fdata = pdata->files; while (fdata) { - char** data = fdata->data.data; - int lenN = data['n'] ? strlen(data['n']) : 0; - int sizeEntry = 5 + 7 + 10 + 10 + 10 + lenN + 5 /*spaces*/ + 1 /*null*/; + OpenFiles_Data* data = &fdata->data; + size_t lenN = strlen(getDataForType(data, 'n')); + size_t sizeEntry = 5 + 7 + 4 + 10 + 10 + 10 + lenN + 7 /*spaces*/ + 1 /*null*/; char entry[sizeEntry]; - xSnprintf(entry, sizeEntry, "%5.5s %7.7s %10.10s %10.10s %10.10s %s", - data['f'] ? data['f'] : "", - data['t'] ? data['t'] : "", - data['D'] ? data['D'] : "", - data['s'] ? data['s'] : "", - data['i'] ? data['i'] : "", - data['n'] ? data['n'] : ""); + xSnprintf(entry, sizeof(entry), "%5.5s %-7.7s %-4.4s %-10.10s %10.10s %10.10s %s", + getDataForType(data, 'f'), + getDataForType(data, 't'), + getDataForType(data, 'a'), + getDataForType(data, 'D'), + getDataForType(data, 's'), + getDataForType(data, 'i'), + getDataForType(data, 'n')); InfoScreen_addLine(this, entry); - OpenFiles_Data_clear(&fdata->data); + OpenFiles_Data_clear(data); OpenFiles_FileData* old = fdata; fdata = fdata->next; free(old); @@ -170,3 +232,12 @@ void OpenFilesScreen_scan(InfoScreen* this) { Vector_insertionSort(panel->items); Panel_setSelected(panel, idx); } + +const InfoScreenClass OpenFilesScreen_class = { + .super = { + .extends = Class(Object), + .delete = OpenFilesScreen_delete + }, + .scan = OpenFilesScreen_scan, + .draw = OpenFilesScreen_draw +}; |