mirror of https://github.com/xzeldon/htop.git
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).
This commit is contained in:
parent
79ad39c718
commit
f8b9ced93f
|
@ -24,30 +24,63 @@ in the source distribution for its full text.
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
|
||||||
const InfoScreenClass OpenFilesScreen_class = {
|
typedef struct OpenFiles_Data_ {
|
||||||
.super = {
|
char* data[7];
|
||||||
.extends = Class(Object),
|
} OpenFiles_Data;
|
||||||
.delete = OpenFilesScreen_delete
|
|
||||||
},
|
|
||||||
.scan = OpenFilesScreen_scan,
|
|
||||||
.draw = OpenFilesScreen_draw
|
|
||||||
};
|
|
||||||
|
|
||||||
OpenFilesScreen* OpenFilesScreen_new(Process* process) {
|
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(const Process* process) {
|
||||||
OpenFilesScreen* this = xMalloc(sizeof(OpenFilesScreen));
|
OpenFilesScreen* this = xMalloc(sizeof(OpenFilesScreen));
|
||||||
Object_setClass(this, Class(OpenFilesScreen));
|
Object_setClass(this, Class(OpenFilesScreen));
|
||||||
if (Process_isThread(process))
|
if (Process_isThread(process))
|
||||||
this->pid = process->tgid;
|
this->pid = process->tgid;
|
||||||
else
|
else
|
||||||
this->pid = process->pid;
|
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) {
|
void OpenFilesScreen_delete(Object* this) {
|
||||||
free(InfoScreen_done((InfoScreen*)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);
|
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];
|
unsigned char cmd = line[0];
|
||||||
if (cmd == 'f') {
|
switch (cmd) {
|
||||||
|
case 'f': /* file descriptor */
|
||||||
|
{
|
||||||
OpenFiles_FileData* nextFile = xCalloc(1, sizeof(OpenFiles_FileData));
|
OpenFiles_FileData* nextFile = xCalloc(1, sizeof(OpenFiles_FileData));
|
||||||
if (fdata == NULL) {
|
if (fdata == NULL) {
|
||||||
pdata->files = nextFile;
|
pdata->files = nextFile;
|
||||||
|
@ -108,8 +143,35 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) {
|
||||||
}
|
}
|
||||||
fdata = nextFile;
|
fdata = nextFile;
|
||||||
item = &(fdata->data);
|
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);
|
free(line);
|
||||||
}
|
}
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
|
@ -128,13 +190,12 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) {
|
||||||
return pdata;
|
return pdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void OpenFiles_Data_clear(OpenFiles_Data* data) {
|
static void OpenFiles_Data_clear(OpenFiles_Data* data) {
|
||||||
for (int i = 0; i < 255; i++)
|
for (size_t i = 0; i < ARRAYSIZE(data->data); i++)
|
||||||
if (data->data[i])
|
|
||||||
free(data->data[i]);
|
free(data->data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenFilesScreen_scan(InfoScreen* this) {
|
static void OpenFilesScreen_scan(InfoScreen* this) {
|
||||||
Panel* panel = this->display;
|
Panel* panel = this->display;
|
||||||
int idx = Panel_getSelectedIndex(panel);
|
int idx = Panel_getSelectedIndex(panel);
|
||||||
Panel_prune(panel);
|
Panel_prune(panel);
|
||||||
|
@ -146,19 +207,20 @@ void OpenFilesScreen_scan(InfoScreen* this) {
|
||||||
} else {
|
} else {
|
||||||
OpenFiles_FileData* fdata = pdata->files;
|
OpenFiles_FileData* fdata = pdata->files;
|
||||||
while (fdata) {
|
while (fdata) {
|
||||||
char** data = fdata->data.data;
|
OpenFiles_Data* data = &fdata->data;
|
||||||
int lenN = data['n'] ? strlen(data['n']) : 0;
|
size_t lenN = strlen(getDataForType(data, 'n'));
|
||||||
int sizeEntry = 5 + 7 + 10 + 10 + 10 + lenN + 5 /*spaces*/ + 1 /*null*/;
|
size_t sizeEntry = 5 + 7 + 4 + 10 + 10 + 10 + lenN + 7 /*spaces*/ + 1 /*null*/;
|
||||||
char entry[sizeEntry];
|
char entry[sizeEntry];
|
||||||
xSnprintf(entry, sizeEntry, "%5.5s %7.7s %10.10s %10.10s %10.10s %s",
|
xSnprintf(entry, sizeof(entry), "%5.5s %-7.7s %-4.4s %-10.10s %10.10s %10.10s %s",
|
||||||
data['f'] ? data['f'] : "",
|
getDataForType(data, 'f'),
|
||||||
data['t'] ? data['t'] : "",
|
getDataForType(data, 't'),
|
||||||
data['D'] ? data['D'] : "",
|
getDataForType(data, 'a'),
|
||||||
data['s'] ? data['s'] : "",
|
getDataForType(data, 'D'),
|
||||||
data['i'] ? data['i'] : "",
|
getDataForType(data, 's'),
|
||||||
data['n'] ? data['n'] : "");
|
getDataForType(data, 'i'),
|
||||||
|
getDataForType(data, 'n'));
|
||||||
InfoScreen_addLine(this, entry);
|
InfoScreen_addLine(this, entry);
|
||||||
OpenFiles_Data_clear(&fdata->data);
|
OpenFiles_Data_clear(data);
|
||||||
OpenFiles_FileData* old = fdata;
|
OpenFiles_FileData* old = fdata;
|
||||||
fdata = fdata->next;
|
fdata = fdata->next;
|
||||||
free(old);
|
free(old);
|
||||||
|
@ -170,3 +232,12 @@ void OpenFilesScreen_scan(InfoScreen* this) {
|
||||||
Vector_insertionSort(panel->items);
|
Vector_insertionSort(panel->items);
|
||||||
Panel_setSelected(panel, idx);
|
Panel_setSelected(panel, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const InfoScreenClass OpenFilesScreen_class = {
|
||||||
|
.super = {
|
||||||
|
.extends = Class(Object),
|
||||||
|
.delete = OpenFilesScreen_delete
|
||||||
|
},
|
||||||
|
.scan = OpenFilesScreen_scan,
|
||||||
|
.draw = OpenFilesScreen_draw
|
||||||
|
};
|
||||||
|
|
|
@ -9,21 +9,6 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
#include "InfoScreen.h"
|
#include "InfoScreen.h"
|
||||||
|
|
||||||
typedef struct OpenFiles_Data_ {
|
|
||||||
char* data[256];
|
|
||||||
} 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;
|
|
||||||
|
|
||||||
typedef struct OpenFilesScreen_ {
|
typedef struct OpenFilesScreen_ {
|
||||||
InfoScreen super;
|
InfoScreen super;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
@ -31,12 +16,8 @@ typedef struct OpenFilesScreen_ {
|
||||||
|
|
||||||
extern const InfoScreenClass OpenFilesScreen_class;
|
extern const InfoScreenClass OpenFilesScreen_class;
|
||||||
|
|
||||||
OpenFilesScreen* OpenFilesScreen_new(Process* process);
|
OpenFilesScreen* OpenFilesScreen_new(const Process* process);
|
||||||
|
|
||||||
void OpenFilesScreen_delete(Object* this);
|
void OpenFilesScreen_delete(Object* this);
|
||||||
|
|
||||||
void OpenFilesScreen_draw(InfoScreen* this);
|
|
||||||
|
|
||||||
void OpenFilesScreen_scan(InfoScreen* this);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue