From e7372d18a1a661d8c3dba9f51e1f17b5f94171a7 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Wed, 10 Jan 2024 11:17:08 +0100 Subject: New upstream version 3.3.0 --- OpenFilesScreen.c | 183 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 78 deletions(-) (limited to 'OpenFilesScreen.c') diff --git a/OpenFilesScreen.c b/OpenFilesScreen.c index 787e17b..d6d663c 100644 --- a/OpenFilesScreen.c +++ b/OpenFilesScreen.c @@ -12,9 +12,9 @@ in the source distribution for its full text. #include #include #include +#include #include #include -#include #include #include #include @@ -27,13 +27,17 @@ in the source distribution for its full text. #include "XUtils.h" +// cf. getIndexForType; must be larger than the maximum value returned. +#define LSOF_DATACOL_COUNT 8 + typedef struct OpenFiles_Data_ { - char* data[8]; + char* data[LSOF_DATACOL_COUNT]; } OpenFiles_Data; typedef struct OpenFiles_ProcessData_ { OpenFiles_Data data; int error; + int cols[LSOF_DATACOL_COUNT]; struct OpenFiles_FileData_* files; } OpenFiles_ProcessData; @@ -44,22 +48,22 @@ typedef struct 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; - case 'o': - return 7; + 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; + case 'o': + return 7; } /* should never reach here */ @@ -72,12 +76,12 @@ static const char* getDataForType(const OpenFiles_Data* data, char type) { } OpenFilesScreen* OpenFilesScreen_new(const Process* process) { - OpenFilesScreen* this = xMalloc(sizeof(OpenFilesScreen)); + OpenFilesScreen* this = xCalloc(1, sizeof(OpenFilesScreen)); Object_setClass(this, Class(OpenFilesScreen)); if (Process_isThread(process)) { - this->pid = process->tgid; + this->pid = Process_getThreadGroup(process); } else { - this->pid = process->pid; + this->pid = Process_getPid(process); } return (OpenFilesScreen*) InfoScreen_init(&this->super, process, NULL, LINES - 2, " FD TYPE MODE DEVICE SIZE OFFSET NODE NAME"); } @@ -92,6 +96,9 @@ static void OpenFilesScreen_draw(InfoScreen* this) { static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) { OpenFiles_ProcessData* pdata = xCalloc(1, sizeof(OpenFiles_ProcessData)); + pdata->cols[getIndexForType('s')] = 8; + pdata->cols[getIndexForType('o')] = 8; + pdata->cols[getIndexForType('i')] = 8; int fdpair[2] = {0, 0}; if (pipe(fdpair) == -1) { @@ -122,7 +129,7 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) { xSnprintf(buffer, sizeof(buffer), "%d", pid); // Use of NULL in variadic functions must have a pointer cast. // The NULL constant is not required by standard to have a pointer type. - execlp("lsof", "lsof", "-P", "-o", "-p", buffer, "-F", (char *)NULL); + execlp("lsof", "lsof", "-P", "-o", "-p", buffer, "-F", (char*)NULL); exit(127); } close(fdpair[1]); @@ -144,52 +151,60 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) { unsigned char cmd = line[0]; switch (cmd) { - case 'f': /* file descriptor */ - { - OpenFiles_FileData* nextFile = xCalloc(1, sizeof(OpenFiles_FileData)); - if (fdata == NULL) { - pdata->files = nextFile; - } else { - fdata->next = nextFile; - } - 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_and_xStrdup(&item->data[index], line + 1); - break; - } - case 'o': /* file's offset */ - { - size_t index = getIndexForType(cmd); - if (String_startsWith(line + 1, "0t")) { - free_and_xStrdup(&item->data[index], line + 3); - } else { + case 'f': /* file descriptor */ + { + OpenFiles_FileData* nextFile = xCalloc(1, sizeof(OpenFiles_FileData)); + if (fdata == NULL) { + pdata->files = nextFile; + } else { + fdata->next = nextFile; + } + 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_and_xStrdup(&item->data[index], line + 1); + size_t dlen = strlen(item->data[index]); + if (dlen > (size_t)pdata->cols[index]) { + pdata->cols[index] = (int)CLAMP(dlen, 0, INT16_MAX); + } + break; } - 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 '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; + case 'o': /* file's offset */ + { + size_t index = getIndexForType(cmd); + if (String_startsWith(line + 1, "0t")) { + free_and_xStrdup(&item->data[index], line + 3); + } else { + free_and_xStrdup(&item->data[index], line + 1); + } + size_t dlen = strlen(item->data[index]); + if (dlen > (size_t)pdata->cols[index]) { + pdata->cols[index] = (int)CLAMP(dlen, 0, INT16_MAX); + } + 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 '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; } if (cmd == 's') @@ -226,7 +241,7 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) { struct stat st; if (stat(filename, &st) == 0) { char fileSizeBuf[21]; /* 20 (long long) + 1 (NULL) */ - xSnprintf(fileSizeBuf, sizeof(fileSizeBuf), "%"PRIu64, st.st_size); /* st.st_size is long long on macOS, long on linux */ + xSnprintf(fileSizeBuf, sizeof(fileSizeBuf), "%"PRIu64, (uint64_t)st.st_size); /* st.st_size is long long on macOS, long on linux */ free_and_xStrdup(&item->data[fileSizeIndex], fileSizeBuf); } } @@ -239,32 +254,44 @@ static void OpenFiles_Data_clear(OpenFiles_Data* data) { free(data->data[i]); } -static void OpenFilesScreen_scan(InfoScreen* this) { - Panel* panel = this->display; +static void OpenFilesScreen_scan(InfoScreen* super) { + Panel* panel = super->display; int idx = Panel_getSelectedIndex(panel); Panel_prune(panel); - OpenFiles_ProcessData* pdata = OpenFilesScreen_getProcessData(((OpenFilesScreen*)this)->pid); + OpenFiles_ProcessData* pdata = OpenFilesScreen_getProcessData(((OpenFilesScreen*)super)->pid); if (pdata->error == 127) { - InfoScreen_addLine(this, "Could not execute 'lsof'. Please make sure it is available in your $PATH."); + InfoScreen_addLine(super, "Could not execute 'lsof'. Please make sure it is available in your $PATH."); } else if (pdata->error == 1) { - InfoScreen_addLine(this, "Failed listing open files."); + InfoScreen_addLine(super, "Failed listing open files."); } else { + char hdrbuf[128] = {0}; + snprintf(hdrbuf, sizeof(hdrbuf), "%5.5s %-7.7s %-4.4s %6.6s %*s %*s %*s %s", + "FD", "TYPE", "MODE", "DEVICE", + pdata->cols[getIndexForType('s')], "SIZE", + pdata->cols[getIndexForType('o')], "OFFSET", + pdata->cols[getIndexForType('i')], "NODE", + "NAME" + ); + Panel_setHeader(panel, hdrbuf); + OpenFiles_FileData* fdata = pdata->files; while (fdata) { OpenFiles_Data* data = &fdata->data; - size_t lenN = strlen(getDataForType(data, 'n')); - size_t sizeEntry = 5 + 7 + 4 + 10 + 10 + 10 + 10 + lenN + 8 /*spaces*/ + 1 /*null*/; - char entry[sizeEntry]; - xSnprintf(entry, sizeof(entry), "%5.5s %-7.7s %-4.4s %-10.10s %10.10s %10.10s %10.10s %s", + char* entry = NULL; + xAsprintf(&entry, "%5.5s %-7.7s %-4.4s %6.6s %*s %*s %*s %s", getDataForType(data, 'f'), getDataForType(data, 't'), getDataForType(data, 'a'), getDataForType(data, 'D'), + pdata->cols[getIndexForType('s')], getDataForType(data, 's'), + pdata->cols[getIndexForType('o')], getDataForType(data, 'o'), + pdata->cols[getIndexForType('i')], getDataForType(data, 'i'), getDataForType(data, 'n')); - InfoScreen_addLine(this, entry); + InfoScreen_addLine(super, entry); + free(entry); OpenFiles_Data_clear(data); OpenFiles_FileData* old = fdata; fdata = fdata->next; @@ -273,7 +300,7 @@ static void OpenFilesScreen_scan(InfoScreen* this) { OpenFiles_Data_clear(&pdata->data); } free(pdata); - Vector_insertionSort(this->lines); + Vector_insertionSort(super->lines); Vector_insertionSort(panel->items); Panel_setSelected(panel, idx); } -- cgit v1.2.3