summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenny Baumann <BenBE@geshi.org>2020-11-11 22:15:35 +0100
committerBenny Baumann <BenBE@geshi.org>2020-11-14 15:51:26 +0100
commit18763051a2c5a5d3a39bfabc284b3d72b1f6fc9b (patch)
tree6674c47d7b011aca855ea72a0b94c7567bc28294
parent2d6da2e52066067e4c82a2e16f73438319e1db81 (diff)
Split platform dependent parts for file locks screen
-rw-r--r--Action.c11
-rw-r--r--Makefile.am4
-rw-r--r--ProcessLocksScreen.c114
-rw-r--r--ProcessLocksScreen.h (renamed from linux/ProcessLocksScreen.h)19
-rw-r--r--darwin/Platform.c12
-rw-r--r--darwin/Platform.h15
-rw-r--r--dragonflybsd/Platform.c11
-rw-r--r--dragonflybsd/Platform.h8
-rw-r--r--freebsd/Platform.c11
-rw-r--r--freebsd/Platform.h8
-rw-r--r--linux/Platform.c119
-rw-r--r--linux/Platform.h6
-rw-r--r--linux/ProcessLocksScreen.c244
-rw-r--r--openbsd/Platform.c11
-rw-r--r--openbsd/Platform.h8
-rw-r--r--solaris/Platform.c11
-rw-r--r--solaris/Platform.h17
-rw-r--r--unsupported/Platform.c11
-rw-r--r--unsupported/Platform.h5
19 files changed, 382 insertions, 263 deletions
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 <dirent.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#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, "<END OF FILE>",
+ data->data[3] ? data->data[3] : "<N/A>"
+ );
+ } 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] : "<N/A>"
+ );
+ }
+
+ 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/ProcessLocksScreen.h
index ec940fba..5da53adc 100644
--- a/linux/ProcessLocksScreen.h
+++ b/ProcessLocksScreen.h
@@ -17,6 +17,25 @@ typedef struct ProcessLocksScreen_ {
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);
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 <stdbool.h>
+#include <sys/types.h>
+
#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 <stdbool.h>
+#include <sys/types.h>
+
#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 <stdbool.h>
+#include <sys/types.h>
+
#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 <assert.h>
#include <ctype.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
#include <math.h>
#include <stdio.h>
#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 <dirent.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#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, "<END OF FILE>",
- data->data[3] ? data->data[3] : "<N/A>"
- );
- } 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] : "<N/A>"
- );
- }
-
- 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/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 <stdbool.h>
+#include <sys/types.h>
+
#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 <libproc.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <sys/mkdev.h>
+#include <sys/proc.h>
+#include <sys/types.h>
+
#include "Action.h"
#include "BatteryMeter.h"
#include "DiskIOMeter.h"
+#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
-#include <signal.h>
-#include <sys/mkdev.h>
-#include <sys/proc.h>
-#include <libproc.h>
+
#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,

© 2014-2024 Faster IT GmbH | imprint | privacy policy