From 18763051a2c5a5d3a39bfabc284b3d72b1f6fc9b Mon Sep 17 00:00:00 2001 From: Benny Baumann Date: Wed, 11 Nov 2020 22:15:35 +0100 Subject: Split platform dependent parts for file locks screen --- Action.c | 11 +- Makefile.am | 4 +- ProcessLocksScreen.c | 114 +++++++++++++++++++++ ProcessLocksScreen.h | 45 +++++++++ darwin/Platform.c | 12 +++ darwin/Platform.h | 15 ++- dragonflybsd/Platform.c | 11 ++ dragonflybsd/Platform.h | 8 ++ freebsd/Platform.c | 11 ++ freebsd/Platform.h | 8 ++ linux/Platform.c | 119 ++++++++++++++++++++++ linux/Platform.h | 6 ++ linux/ProcessLocksScreen.c | 244 --------------------------------------------- linux/ProcessLocksScreen.h | 26 ----- openbsd/Platform.c | 11 ++ openbsd/Platform.h | 8 ++ solaris/Platform.c | 11 ++ solaris/Platform.h | 17 +++- unsupported/Platform.c | 11 ++ unsupported/Platform.h | 5 + 20 files changed, 408 insertions(+), 289 deletions(-) create mode 100644 ProcessLocksScreen.c create mode 100644 ProcessLocksScreen.h delete mode 100644 linux/ProcessLocksScreen.c delete mode 100644 linux/ProcessLocksScreen.h diff --git a/Action.c b/Action.c index aa9614a5..ee5b9af8 100644 --- a/Action.c +++ b/Action.c @@ -27,6 +27,7 @@ in the source distribution for its full text. #include "MainPanel.h" #include "OpenFilesScreen.h" #include "Process.h" +#include "ProcessLocksScreen.h" #include "ProvideCurses.h" #include "ScreenManager.h" #include "SignalsPanel.h" @@ -34,10 +35,6 @@ in the source distribution for its full text. #include "Vector.h" #include "XUtils.h" -#ifdef HTOP_LINUX -#include "linux/ProcessLocksScreen.h" -#endif - Object* Action_pickFromVector(State* st, Panel* list, int x, bool followProcess) { Panel* panel = st->panel; @@ -375,7 +372,6 @@ static Htop_Reaction actionLsof(State* st) { return HTOP_REFRESH | HTOP_REDRAW_BAR; } -#ifdef HTOP_LINUX static Htop_Reaction actionShowLocks(State* st) { Process* p = (Process*) Panel_getSelected(st->panel); if (!p) return HTOP_OK; @@ -386,7 +382,6 @@ static Htop_Reaction actionShowLocks(State* st) { CRT_enableDelay(); return HTOP_REFRESH | HTOP_REDRAW_BAR; } -#endif static Htop_Reaction actionStrace(State* st) { Process* p = (Process*) Panel_getSelected(st->panel); @@ -452,9 +447,7 @@ static const struct { const char* key; const char* info; } helpRight[] = { { .key = " e: ", .info = "show process environment" }, { .key = " i: ", .info = "set IO priority" }, { .key = " l: ", .info = "list open files with lsof" }, -#ifdef HTOP_LINUX { .key = " x: ", .info = "list file locks of process" }, -#endif { .key = " s: ", .info = "trace syscalls with strace" }, { .key = " w: ", .info = "wrap process command in multiple lines" }, { .key = " F2 C S: ", .info = "setup" }, @@ -640,9 +633,7 @@ void Action_setBindings(Htop_Action* keys) { keys['S'] = actionSetup; keys['C'] = actionSetup; keys[KEY_F(2)] = actionSetup; -#ifdef HTOP_LINUX keys['x'] = actionShowLocks; -#endif keys['l'] = actionLsof; keys['s'] = actionStrace; keys[' '] = actionTag; diff --git a/Makefile.am b/Makefile.am index c9193a86..9a3067ff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,6 +53,7 @@ myhtopsources = \ Panel.c \ Process.c \ ProcessList.c \ + ProcessLocksScreen.c \ RichString.c \ ScreenManager.c \ Settings.c \ @@ -105,6 +106,7 @@ myhtopheaders = \ Panel.h \ Process.h \ ProcessList.h \ + ProcessLocksScreen.h \ ProvideCurses.h \ RichString.h \ ScreenManager.h \ @@ -129,7 +131,6 @@ linux_platform_headers = \ linux/LinuxProcessList.h \ linux/Platform.h \ linux/PressureStallMeter.h \ - linux/ProcessLocksScreen.h \ linux/SELinuxMeter.h \ linux/ZramMeter.h \ linux/ZramStats.h \ @@ -146,7 +147,6 @@ myhtopplatsources = \ linux/LinuxProcessList.c \ linux/Platform.c \ linux/PressureStallMeter.c \ - linux/ProcessLocksScreen.c \ linux/SELinuxMeter.c \ linux/ZramMeter.c \ zfs/ZfsArcMeter.c \ diff --git a/ProcessLocksScreen.c b/ProcessLocksScreen.c new file mode 100644 index 00000000..480afccb --- /dev/null +++ b/ProcessLocksScreen.c @@ -0,0 +1,114 @@ +/* +htop - ProcessLocksScreen.c +(C) 2020 htop dev team +Released under the GNU GPLv2, see the COPYING file +in the source distribution for its full text. +*/ + +#include "config.h" // IWYU pragma: keep + +#include "ProcessLocksScreen.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CRT.h" +#include "Compat.h" +#include "FunctionBar.h" +#include "IncSet.h" +#include "Platform.h" +#include "ProcessList.h" +#include "XUtils.h" + + +ProcessLocksScreen* ProcessLocksScreen_new(const Process* process) { + ProcessLocksScreen* this = xMalloc(sizeof(ProcessLocksScreen)); + Object_setClass(this, Class(ProcessLocksScreen)); + if (Process_isThread(process)) + this->pid = process->tgid; + else + this->pid = process->pid; + return (ProcessLocksScreen*) InfoScreen_init(&this->super, process, NULL, LINES-3, " ID TYPE EXCLUSION READ/WRITE DEVICE:INODE START END FILENAME"); +} + +void ProcessLocksScreen_delete(Object* this) { + free(InfoScreen_done((InfoScreen*)this)); +} + +static void ProcessLocksScreen_draw(InfoScreen* this) { + InfoScreen_drawTitled(this, "Snapshot of file locks of process %d - %s", ((ProcessLocksScreen*)this)->pid, this->process->comm); +} + +static inline void FileLocks_Data_clear(FileLocks_Data* data) { + for (size_t i = 0; i < ARRAYSIZE(data->data); i++) + free(data->data[i]); +} + +static void ProcessLocksScreen_scan(InfoScreen* this) { + Panel* panel = this->display; + int idx = Panel_getSelectedIndex(panel); + Panel_prune(panel); + FileLocks_ProcessData* pdata = Platform_getProcessLocks(((ProcessLocksScreen*)this)->pid); + if (!pdata) { + InfoScreen_addLine(this, "This feature is not supported on your platform."); + } else if (pdata->error) { + InfoScreen_addLine(this, "Could not determine file locks."); + } else { + FileLocks_LockData* ldata = pdata->locks; + if (!ldata) { + InfoScreen_addLine(this, "No locks have been found for the selected process."); + } + while (ldata) { + FileLocks_Data* data = &ldata->data; + + char entry[512]; + if (ULLONG_MAX == data->end) { + xSnprintf(entry, sizeof(entry), "%10d %-10s %-10s %-10s %02x:%02x:%020"PRIu64" %20"PRIu64" %20s %s", + data->id, + data->data[0], data->data[1], data->data[2], + data->dev[0], data->dev[1], data->inode, + data->start, "", + data->data[3] ? data->data[3] : "" + ); + } else { + xSnprintf(entry, sizeof(entry), "%10d %-10s %-10s %-10s %02x:%02x:%020"PRIu64" %20"PRIu64" %20"PRIu64" %s", + data->id, + data->data[0], data->data[1], data->data[2], + data->dev[0], data->dev[1], data->inode, + data->start, data->end, + data->data[3] ? data->data[3] : "" + ); + } + + InfoScreen_addLine(this, entry); + FileLocks_Data_clear(&ldata->data); + + FileLocks_LockData* old = ldata; + ldata = ldata->next; + free(old); + } + } + free(pdata); + Vector_insertionSort(this->lines); + Vector_insertionSort(panel->items); + Panel_setSelected(panel, idx); +} + +const InfoScreenClass ProcessLocksScreen_class = { + .super = { + .extends = Class(Object), + .delete = ProcessLocksScreen_delete + }, + .scan = ProcessLocksScreen_scan, + .draw = ProcessLocksScreen_draw +}; diff --git a/ProcessLocksScreen.h b/ProcessLocksScreen.h new file mode 100644 index 00000000..5da53adc --- /dev/null +++ b/ProcessLocksScreen.h @@ -0,0 +1,45 @@ +#ifndef HEADER_ProcessLocksScreen +#define HEADER_ProcessLocksScreen +/* +htop - ProcessLocksScreen.h +(C) 2020 htop dev team +Released under the GNU GPLv2, see the COPYING file +in the source distribution for its full text. +*/ + +#include "InfoScreen.h" + +#include + + +typedef struct ProcessLocksScreen_ { + InfoScreen super; + pid_t pid; +} ProcessLocksScreen; + +typedef struct FileLocks_Data_ { + char* data[4]; + int id; + unsigned int dev[2]; + uint64_t inode; + uint64_t start; + uint64_t end; +} FileLocks_Data; + +typedef struct FileLocks_LockData_ { + FileLocks_Data data; + struct FileLocks_LockData_* next; +} FileLocks_LockData; + +typedef struct FileLocks_ProcessData_ { + bool error; + struct FileLocks_LockData_* locks; +} FileLocks_ProcessData; + +extern const InfoScreenClass ProcessLocksScreen_class; + +ProcessLocksScreen* ProcessLocksScreen_new(const Process* process); + +void ProcessLocksScreen_delete(Object* this); + +#endif diff --git a/darwin/Platform.c b/darwin/Platform.c index b1f9283d..1f9120cb 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -17,6 +17,7 @@ in the source distribution for its full text. #include "DateMeter.h" #include "DateTimeMeter.h" #include "HostnameMeter.h" +#include "ProcessLocksScreen.h" #include "UptimeMeter.h" #include "zfs/ZfsArcMeter.h" #include "zfs/ZfsCompressedArcMeter.h" @@ -311,6 +312,17 @@ char* Platform_getProcessEnv(pid_t pid) { return env; } +char* Platform_getInodeFilename(pid_t pid, ino_t inode) { + (void)pid; + (void)inode; + return NULL; +} + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { + (void)pid; + return NULL; +} + bool Platform_getDiskIO(DiskIOData* data) { // TODO (void)data; diff --git a/darwin/Platform.h b/darwin/Platform.h index 471b38a9..2eb34372 100644 --- a/darwin/Platform.h +++ b/darwin/Platform.h @@ -8,12 +8,17 @@ Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ +#include +#include + #include "Action.h" -#include "SignalsPanel.h" -#include "CPUMeter.h" -#include "DiskIOMeter.h" #include "BatteryMeter.h" +#include "CPUMeter.h" #include "DarwinProcess.h" +#include "DiskIOMeter.h" +#include "ProcessLocksScreen.h" +#include "SignalsPanel.h" + extern ProcessField Platform_defaultFields[]; @@ -49,6 +54,10 @@ void Platform_setZfsCompressedArcValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); +char* Platform_getInodeFilename(pid_t pid, ino_t inode); + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); + bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, diff --git a/dragonflybsd/Platform.c b/dragonflybsd/Platform.c index 5b81c610..d0cda8c2 100644 --- a/dragonflybsd/Platform.c +++ b/dragonflybsd/Platform.c @@ -206,6 +206,17 @@ char* Platform_getProcessEnv(pid_t pid) { return NULL; } +char* Platform_getInodeFilename(pid_t pid, ino_t inode) { + (void)pid; + (void)inode; + return NULL; +} + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { + (void)pid; + return NULL; +} + bool Platform_getDiskIO(DiskIOData* data) { // TODO (void)data; diff --git a/dragonflybsd/Platform.h b/dragonflybsd/Platform.h index 6c884719..41fe44cd 100644 --- a/dragonflybsd/Platform.h +++ b/dragonflybsd/Platform.h @@ -8,9 +8,13 @@ Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ +#include +#include + #include "Action.h" #include "BatteryMeter.h" #include "DiskIOMeter.h" +#include "ProcessLocksScreen.h" #include "SignalsPanel.h" extern ProcessFieldData Process_fields[]; @@ -41,6 +45,10 @@ void Platform_setSwapValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); +char* Platform_getInodeFilename(pid_t pid, ino_t inode); + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); + bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, diff --git a/freebsd/Platform.c b/freebsd/Platform.c index bdd49bf6..a49cfd25 100644 --- a/freebsd/Platform.c +++ b/freebsd/Platform.c @@ -243,6 +243,17 @@ char* Platform_getProcessEnv(pid_t pid) { return env; } +char* Platform_getInodeFilename(pid_t pid, ino_t inode) { + (void)pid; + (void)inode; + return NULL; +} + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { + (void)pid; + return NULL; +} + bool Platform_getDiskIO(DiskIOData* data) { if (devstat_checkversion(NULL) < 0) diff --git a/freebsd/Platform.h b/freebsd/Platform.h index 894b3e25..2cdd068d 100644 --- a/freebsd/Platform.h +++ b/freebsd/Platform.h @@ -7,9 +7,13 @@ Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ +#include +#include + #include "Action.h" #include "BatteryMeter.h" #include "DiskIOMeter.h" +#include "ProcessLocksScreen.h" #include "SignalsPanel.h" extern ProcessFieldData Process_fields[]; @@ -44,6 +48,10 @@ void Platform_setZfsCompressedArcValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); +char* Platform_getInodeFilename(pid_t pid, ino_t inode); + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); + bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, diff --git a/linux/Platform.c b/linux/Platform.c index f7a768c9..7e51bf61 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -11,11 +11,16 @@ in the source distribution for its full text. #include #include +#include +#include +#include +#include #include #include #include "BatteryMeter.h" #include "ClockMeter.h" +#include "Compat.h" #include "CPUMeter.h" #include "DateMeter.h" #include "DateTimeMeter.h" @@ -304,6 +309,120 @@ char* Platform_getProcessEnv(pid_t pid) { return env; } +/* + * Return the absolute path of a file given its pid&inode number + * + * Based on implementation of lslocks from util-linux: + * https://sources.debian.org/src/util-linux/2.36-3/misc-utils/lslocks.c/#L162 + */ +char* Platform_getInodeFilename(pid_t pid, ino_t inode) { + struct stat sb; + struct dirent *de; + DIR *dirp; + size_t len; + int fd; + + char path[PATH_MAX]; + char sym[PATH_MAX]; + char* ret = NULL; + + memset(path, 0, sizeof(path)); + memset(sym, 0, sizeof(sym)); + + xSnprintf(path, sizeof(path), "%s/%d/fd/", PROCDIR, pid); + if (strlen(path) >= (sizeof(path) - 2)) + return NULL; + + if (!(dirp = opendir(path))) + return NULL; + + if ((fd = dirfd(dirp)) < 0 ) + goto out; + + while ((de = readdir(dirp))) { + if (String_eq(de->d_name, ".") || String_eq(de->d_name, "..")) + continue; + + /* care only for numerical descriptors */ + if (!strtoull(de->d_name, (char **) NULL, 10)) + continue; + + if (!Compat_fstatat(fd, path, de->d_name, &sb, 0) && inode != sb.st_ino) + continue; + + if ((len = Compat_readlinkat(fd, path, de->d_name, sym, sizeof(sym) - 1)) < 1) + goto out; + + sym[len] = '\0'; + + ret = xStrdup(sym); + break; + } + +out: + closedir(dirp); + return ret; +} + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { + FileLocks_ProcessData* pdata = xCalloc(1, sizeof(FileLocks_ProcessData)); + + FILE* f = fopen(PROCDIR "/locks", "r"); + if (!f) { + pdata->error = true; + return pdata; + } + + char buffer[1024]; + FileLocks_LockData** data_ref = &pdata->locks; + while(fgets(buffer, sizeof(buffer), f)) { + if (!strchr(buffer, '\n')) + continue; + + int lock_id; + char lock_type[16]; + char lock_excl[16]; + char lock_rw[16]; + pid_t lock_pid; + unsigned int lock_dev[2]; + uint64_t lock_inode; + char lock_start[25]; + char lock_end[25]; + + if (10 != sscanf(buffer, "%d: %15s %15s %15s %d %x:%x:%"PRIu64" %24s %24s", + &lock_id, lock_type, lock_excl, lock_rw, &lock_pid, + &lock_dev[0], &lock_dev[1], &lock_inode, + lock_start, lock_end)) + continue; + + if (pid != lock_pid) + continue; + + FileLocks_LockData* ldata = xCalloc(1, sizeof(FileLocks_LockData)); + FileLocks_Data* data = &ldata->data; + data->id = lock_id; + data->data[0] = xStrdup(lock_type); + data->data[1] = xStrdup(lock_excl); + data->data[2] = xStrdup(lock_rw); + data->data[3] = Platform_getInodeFilename(lock_pid, lock_inode); + data->dev[0] = lock_dev[0]; + data->dev[1] = lock_dev[1]; + data->inode = lock_inode; + data->start = strtoull(lock_start, NULL, 10); + if (!String_eq(lock_end, "EOF")) { + data->end = strtoull(lock_end, NULL, 10); + } else { + data->end = ULLONG_MAX; + } + + *data_ref = ldata; + data_ref = &ldata->next; + } + + fclose(f); + return pdata; +} + void Platform_getPressureStall(const char *file, bool some, double* ten, double* sixty, double* threehundred) { *ten = *sixty = *threehundred = 0; char procname[128+1]; diff --git a/linux/Platform.h b/linux/Platform.h index b61a4db8..5a661a04 100644 --- a/linux/Platform.h +++ b/linux/Platform.h @@ -14,6 +14,7 @@ in the source distribution for its full text. #include "DiskIOMeter.h" #include "Meter.h" #include "Process.h" +#include "ProcessLocksScreen.h" #include "SignalsPanel.h" extern ProcessField Platform_defaultFields[]; @@ -45,8 +46,13 @@ void Platform_setZramValues(Meter* this); void Platform_setZfsArcValues(Meter* this); void Platform_setZfsCompressedArcValues(Meter* this); + char* Platform_getProcessEnv(pid_t pid); +char* Platform_getInodeFilename(pid_t pid, ino_t inode); + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); + void Platform_getPressureStall(const char *file, bool some, double* ten, double* sixty, double* threehundred); bool Platform_getDiskIO(DiskIOData* data); diff --git a/linux/ProcessLocksScreen.c b/linux/ProcessLocksScreen.c deleted file mode 100644 index c93d2845..00000000 --- a/linux/ProcessLocksScreen.c +++ /dev/null @@ -1,244 +0,0 @@ -/* -htop - ProcessLocksScreen.c -(C) 2020 htop dev team -Released under the GNU GPLv2, see the COPYING file -in the source distribution for its full text. -*/ - -#include "config.h" // IWYU pragma: keep - -#include "ProcessLocksScreen.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CRT.h" -#include "Compat.h" -#include "FunctionBar.h" -#include "IncSet.h" -#include "ProcessList.h" -#include "XUtils.h" - - -typedef struct FileLocks_Data_ { - char* data[4]; - int id; - unsigned int dev[2]; - uint64_t inode; - uint64_t start; - uint64_t end; -} FileLocks_Data; - -typedef struct FileLocks_ProcessData_ { - bool error; - struct FileLocks_LockData_* locks; -} FileLocks_ProcessData; - -typedef struct FileLocks_LockData_ { - FileLocks_Data data; - struct FileLocks_LockData_* next; -} FileLocks_LockData; - -ProcessLocksScreen* ProcessLocksScreen_new(const Process* process) { - ProcessLocksScreen* this = xMalloc(sizeof(ProcessLocksScreen)); - Object_setClass(this, Class(ProcessLocksScreen)); - if (Process_isThread(process)) - this->pid = process->tgid; - else - this->pid = process->pid; - return (ProcessLocksScreen*) InfoScreen_init(&this->super, process, NULL, LINES-3, " ID TYPE EXCLUSION READ/WRITE DEVICE:INODE START END FILENAME"); -} - -void ProcessLocksScreen_delete(Object* this) { - free(InfoScreen_done((InfoScreen*)this)); -} - -static void ProcessLocksScreen_draw(InfoScreen* this) { - InfoScreen_drawTitled(this, "Snapshot of file locks of process %d - %s", ((ProcessLocksScreen*)this)->pid, this->process->comm); -} - -/* - * Return the absolute path of a file given its pid&inode number - * - * Based on implementation of lslocks from util-linux: - * https://sources.debian.org/src/util-linux/2.36-3/misc-utils/lslocks.c/#L162 - */ -static char *ProcessLocksScreen_getInodeFilename(pid_t pid, ino_t inode) { - struct stat sb; - struct dirent *de; - DIR *dirp; - size_t len; - int fd; - - char path[PATH_MAX]; - char sym[PATH_MAX]; - char* ret = NULL; - - memset(path, 0, sizeof(path)); - memset(sym, 0, sizeof(sym)); - - xSnprintf(path, sizeof(path), "%s/%d/fd/", PROCDIR, pid); - if (strlen(path) >= (sizeof(path) - 2)) - return NULL; - - if (!(dirp = opendir(path))) - return NULL; - - if ((fd = dirfd(dirp)) < 0 ) - goto out; - - while ((de = readdir(dirp))) { - if (String_eq(de->d_name, ".") || String_eq(de->d_name, "..")) - continue; - - /* care only for numerical descriptors */ - if (!strtoull(de->d_name, (char **) NULL, 10)) - continue; - - if (!Compat_fstatat(fd, path, de->d_name, &sb, 0) && inode != sb.st_ino) - continue; - - if ((len = Compat_readlinkat(fd, path, de->d_name, sym, sizeof(sym) - 1)) < 1) - goto out; - - sym[len] = '\0'; - - ret = xStrdup(sym); - break; - } - -out: - closedir(dirp); - return ret; -} - -static FileLocks_ProcessData* ProcessLocksScreen_getProcessData(pid_t pid) { - FileLocks_ProcessData* pdata = xCalloc(1, sizeof(FileLocks_ProcessData)); - - FILE* f = fopen(PROCDIR "/locks", "r"); - if (!f) { - pdata->error = true; - return pdata; - } - - char buffer[1024]; - FileLocks_LockData** data_ref = &pdata->locks; - while(fgets(buffer, sizeof(buffer), f)) { - if (!strchr(buffer, '\n')) - continue; - - int lock_id; - char lock_type[16]; - char lock_excl[16]; - char lock_rw[16]; - pid_t lock_pid; - unsigned int lock_dev[2]; - uint64_t lock_inode; - char lock_start[25]; - char lock_end[25]; - - if (10 != sscanf(buffer, "%d: %15s %15s %15s %d %x:%x:%"PRIu64" %24s %24s", - &lock_id, lock_type, lock_excl, lock_rw, &lock_pid, - &lock_dev[0], &lock_dev[1], &lock_inode, - lock_start, lock_end)) - continue; - - if (pid != lock_pid) - continue; - - FileLocks_LockData* ldata = xCalloc(1, sizeof(FileLocks_LockData)); - FileLocks_Data* data = &ldata->data; - data->id = lock_id; - data->data[0] = xStrdup(lock_type); - data->data[1] = xStrdup(lock_excl); - data->data[2] = xStrdup(lock_rw); - data->data[3] = ProcessLocksScreen_getInodeFilename(lock_pid, lock_inode); - data->dev[0] = lock_dev[0]; - data->dev[1] = lock_dev[1]; - data->inode = lock_inode; - data->start = strtoull(lock_start, NULL, 10); - if (!String_eq(lock_end, "EOF")) { - data->end = strtoull(lock_end, NULL, 10); - } else { - data->end = ULLONG_MAX; - } - - *data_ref = ldata; - data_ref = &ldata->next; - } - - fclose(f); - return pdata; -} - -static inline void FileLocks_Data_clear(FileLocks_Data* data) { - for (size_t i = 0; i < ARRAYSIZE(data->data); i++) - free(data->data[i]); -} - -static void ProcessLocksScreen_scan(InfoScreen* this) { - Panel* panel = this->display; - int idx = Panel_getSelectedIndex(panel); - Panel_prune(panel); - FileLocks_ProcessData* pdata = ProcessLocksScreen_getProcessData(((ProcessLocksScreen*)this)->pid); - if (pdata->error) { - InfoScreen_addLine(this, "Could not read file locks."); - } else { - FileLocks_LockData* ldata = pdata->locks; - if (!ldata) { - InfoScreen_addLine(this, "No locks have been found for the selected process."); - } - while (ldata) { - FileLocks_Data* data = &ldata->data; - - char entry[512]; - if (ULLONG_MAX == data->end) { - xSnprintf(entry, sizeof(entry), "%10d %-10s %-10s %-10s %02x:%02x:%020"PRIu64" %20"PRIu64" %20s %s", - data->id, - data->data[0], data->data[1], data->data[2], - data->dev[0], data->dev[1], data->inode, - data->start, "", - data->data[3] ? data->data[3] : "" - ); - } else { - xSnprintf(entry, sizeof(entry), "%10d %-10s %-10s %-10s %02x:%02x:%020"PRIu64" %20"PRIu64" %20"PRIu64" %s", - data->id, - data->data[0], data->data[1], data->data[2], - data->dev[0], data->dev[1], data->inode, - data->start, data->end, - data->data[3] ? data->data[3] : "" - ); - } - - InfoScreen_addLine(this, entry); - FileLocks_Data_clear(&ldata->data); - - FileLocks_LockData* old = ldata; - ldata = ldata->next; - free(old); - } - } - free(pdata); - Vector_insertionSort(this->lines); - Vector_insertionSort(panel->items); - Panel_setSelected(panel, idx); -} - -const InfoScreenClass ProcessLocksScreen_class = { - .super = { - .extends = Class(Object), - .delete = ProcessLocksScreen_delete - }, - .scan = ProcessLocksScreen_scan, - .draw = ProcessLocksScreen_draw -}; diff --git a/linux/ProcessLocksScreen.h b/linux/ProcessLocksScreen.h deleted file mode 100644 index ec940fba..00000000 --- a/linux/ProcessLocksScreen.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef HEADER_ProcessLocksScreen -#define HEADER_ProcessLocksScreen -/* -htop - ProcessLocksScreen.h -(C) 2020 htop dev team -Released under the GNU GPLv2, see the COPYING file -in the source distribution for its full text. -*/ - -#include "InfoScreen.h" - -#include - - -typedef struct ProcessLocksScreen_ { - InfoScreen super; - pid_t pid; -} ProcessLocksScreen; - -extern const InfoScreenClass ProcessLocksScreen_class; - -ProcessLocksScreen* ProcessLocksScreen_new(const Process* process); - -void ProcessLocksScreen_delete(Object* this); - -#endif diff --git a/openbsd/Platform.c b/openbsd/Platform.c index df6bc0cc..a24d6a2d 100644 --- a/openbsd/Platform.c +++ b/openbsd/Platform.c @@ -288,6 +288,17 @@ char* Platform_getProcessEnv(pid_t pid) { return env; } +char* Platform_getInodeFilename(pid_t pid, ino_t inode) { + (void)pid; + (void)inode; + return NULL; +} + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { + (void)pid; + return NULL; +} + bool Platform_getDiskIO(DiskIOData* data) { // TODO (void)data; diff --git a/openbsd/Platform.h b/openbsd/Platform.h index 8cb5bdf3..c7f4e4d7 100644 --- a/openbsd/Platform.h +++ b/openbsd/Platform.h @@ -8,9 +8,13 @@ Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ +#include +#include + #include "Action.h" #include "BatteryMeter.h" #include "DiskIOMeter.h" +#include "ProcessLocksScreen.h" #include "SignalsPanel.h" extern ProcessFieldData Process_fields[]; @@ -42,6 +46,10 @@ void Platform_setSwapValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); +char* Platform_getInodeFilename(pid_t pid, ino_t inode); + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); + bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, diff --git a/solaris/Platform.c b/solaris/Platform.c index 87247969..8e08c025 100644 --- a/solaris/Platform.c +++ b/solaris/Platform.c @@ -264,6 +264,17 @@ char* Platform_getProcessEnv(pid_t pid) { return envBuilder.env; } +char* Platform_getInodeFilename(pid_t pid, ino_t inode) { + (void)pid; + (void)inode; + return NULL; +} + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { + (void)pid; + return NULL; +} + bool Platform_getDiskIO(DiskIOData* data) { // TODO (void)data; diff --git a/solaris/Platform.h b/solaris/Platform.h index 8718dbfe..5db271ce 100644 --- a/solaris/Platform.h +++ b/solaris/Platform.h @@ -9,14 +9,19 @@ Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ +#include +#include +#include +#include +#include +#include + #include "Action.h" #include "BatteryMeter.h" #include "DiskIOMeter.h" +#include "ProcessLocksScreen.h" #include "SignalsPanel.h" -#include -#include -#include -#include + #define kill(pid, signal) kill(pid / 1024, signal) @@ -64,6 +69,10 @@ void Platform_setZfsCompressedArcValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); +char* Platform_getInodeFilename(pid_t pid, ino_t inode); + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); + bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, diff --git a/unsupported/Platform.c b/unsupported/Platform.c index 3f8cefa6..4208b73c 100644 --- a/unsupported/Platform.c +++ b/unsupported/Platform.c @@ -141,6 +141,17 @@ char* Platform_getProcessEnv(pid_t pid) { return NULL; } +char* Platform_getInodeFilename(pid_t pid, ino_t inode) { + (void)pid; + (void)inode; + return NULL; +} + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { + (void)pid; + return NULL; +} + bool Platform_getDiskIO(DiskIOData* data) { (void)data; return false; diff --git a/unsupported/Platform.h b/unsupported/Platform.h index 902b6a9b..8ca201c1 100644 --- a/unsupported/Platform.h +++ b/unsupported/Platform.h @@ -11,6 +11,7 @@ in the source distribution for its full text. #include "Action.h" #include "BatteryMeter.h" #include "DiskIOMeter.h" +#include "ProcessLocksScreen.h" #include "SignalsPanel.h" #include "UnsupportedProcess.h" @@ -48,6 +49,10 @@ bool Process_isThread(const Process* this); char* Platform_getProcessEnv(pid_t pid); +char* Platform_getInodeFilename(pid_t pid, ino_t inode); + +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); + bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, -- cgit v1.2.3