summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHisham <hisham@gobolinux.org>2016-10-01 03:09:04 -0300
committerHisham <hisham@gobolinux.org>2016-10-01 03:09:04 -0300
commit8af4d9f453ffa2209e486418811f7652822951c6 (patch)
tree432b6b39b0f9f7c746224370ccf438eea3495ac6
parent8a147dd5b4bc35feebb14a3a55ee44186ce3cea4 (diff)
Interpret TTY_NR column on Linux,
translate dev_t to major:minor on other platforms. Closes #316.
-rw-r--r--OpenFilesScreen.c1
-rw-r--r--Process.c3
-rw-r--r--darwin/Platform.c2
-rw-r--r--freebsd/FreeBSDProcess.c2
-rw-r--r--linux/LinuxProcess.c13
-rw-r--r--linux/LinuxProcess.h1
-rw-r--r--linux/LinuxProcessList.c183
-rw-r--r--linux/LinuxProcessList.h18
-rw-r--r--openbsd/OpenBSDProcess.c2
-rw-r--r--unsupported/Platform.c2
10 files changed, 197 insertions, 30 deletions
diff --git a/OpenFilesScreen.c b/OpenFilesScreen.c
index 80079d04..75190fe1 100644
--- a/OpenFilesScreen.c
+++ b/OpenFilesScreen.c
@@ -102,7 +102,6 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) {
fdata = nextFile;
item = &(fdata->data);
}
- assert(cmd >= 0 && cmd <= 0xff);
item->data[cmd] = xStrdup(line + 1);
free(line);
}
diff --git a/Process.c b/Process.c
index 6a904e2c..a1ffcf0e 100644
--- a/Process.c
+++ b/Process.c
@@ -18,6 +18,7 @@ in the source distribution for its full text.
#include <sys/resource.h>
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
@@ -454,7 +455,7 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
case TIME: Process_printTime(str, this->time); return;
case TGID: snprintf(buffer, n, Process_pidFormat, this->tgid); break;
case TPGID: snprintf(buffer, n, Process_pidFormat, this->tpgid); break;
- case TTY_NR: snprintf(buffer, n, "%5u ", this->tty_nr); break;
+ case TTY_NR: snprintf(buffer, n, "%3u:%3u ", major(this->tty_nr), minor(this->tty_nr)); break;
case USER: {
if (Process_getuid != (int) this->st_uid)
attr = CRT_colors[PROCESS_SHADOW];
diff --git a/darwin/Platform.c b/darwin/Platform.c
index e6a435c0..29934899 100644
--- a/darwin/Platform.c
+++ b/darwin/Platform.c
@@ -79,7 +79,7 @@ ProcessFieldData Process_fields[] = {
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
[PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group ID", .flags = 0, },
[SESSION] = { .name = "SESSION", .title = " SESN ", .description = "Process's session ID", .flags = 0, },
- [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, },
+ [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, },
[TPGID] = { .name = "TPGID", .title = " TPGID ", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, },
[MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, },
[MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, },
diff --git a/freebsd/FreeBSDProcess.c b/freebsd/FreeBSDProcess.c
index b0d2c37c..22e00043 100644
--- a/freebsd/FreeBSDProcess.c
+++ b/freebsd/FreeBSDProcess.c
@@ -62,7 +62,7 @@ ProcessFieldData Process_fields[] = {
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
[PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group ID", .flags = 0, },
[SESSION] = { .name = "SESSION", .title = " SESN ", .description = "Process's session ID", .flags = 0, },
- [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, },
+ [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, },
[TPGID] = { .name = "TPGID", .title = " TPGID ", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, },
[MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, },
[MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, },
diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c
index 43b5e38f..d0e9acd2 100644
--- a/linux/LinuxProcess.c
+++ b/linux/LinuxProcess.c
@@ -124,6 +124,7 @@ typedef struct LinuxProcess_ {
char* cgroup;
#endif
unsigned int oom;
+ char* ttyDevice;
} LinuxProcess;
#ifndef Process_isKernelThread
@@ -144,7 +145,7 @@ ProcessFieldData Process_fields[] = {
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
[PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group ID", .flags = 0, },
[SESSION] = { .name = "SESSION", .title = " SESN ", .description = "Process's session ID", .flags = 0, },
- [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, },
+ [TTY_NR] = { .name = "TTY_NR", .title = "TTY ", .description = "Controlling terminal", .flags = 0, },
[TPGID] = { .name = "TPGID", .title = " TPGID ", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, },
[FLAGS] = { .name = "FLAGS", .title = NULL, .description = NULL, .flags = 0, },
[MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, },
@@ -254,6 +255,7 @@ void Process_delete(Object* cast) {
#ifdef HAVE_CGROUP
free(this->cgroup);
#endif
+ free(this->ttyDevice);
free(this);
}
@@ -292,6 +294,15 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
int attr = CRT_colors[DEFAULT_COLOR];
int n = sizeof(buffer) - 1;
switch ((int)field) {
+ case TTY_NR: {
+ if (lp->ttyDevice) {
+ snprintf(buffer, n, "%-9s", lp->ttyDevice + 5 /* skip "/dev/" */);
+ } else {
+ attr = CRT_colors[PROCESS_SHADOW];
+ snprintf(buffer, n, "? ");
+ }
+ break;
+ }
case CMINFLT: Process_colorNumber(str, lp->cminflt, coloring); return;
case CMAJFLT: Process_colorNumber(str, lp->cmajflt, coloring); return;
case M_DRS: Process_humanNumber(str, lp->m_drs * PAGE_SIZE_KB, coloring); return;
diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h
index f2d81aa3..b42808e1 100644
--- a/linux/LinuxProcess.h
+++ b/linux/LinuxProcess.h
@@ -116,6 +116,7 @@ typedef struct LinuxProcess_ {
char* cgroup;
#endif
unsigned int oom;
+ char* ttyDevice;
} LinuxProcess;
#ifndef Process_isKernelThread
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 20e3d58c..280191c8 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -59,11 +59,19 @@ typedef struct CPUData_ {
unsigned long long int guestPeriod;
} CPUData;
+typedef struct TtyDriver_ {
+ char* path;
+ unsigned int major;
+ unsigned int minorFrom;
+ unsigned int minorTo;
+} TtyDriver;
+
typedef struct LinuxProcessList_ {
ProcessList super;
-
+
CPUData* cpus;
-
+ TtyDriver* ttyDrivers;
+
} LinuxProcessList;
#ifndef PROCDIR
@@ -78,6 +86,10 @@ typedef struct LinuxProcessList_ {
#define PROCMEMINFOFILE PROCDIR "/meminfo"
#endif
+#ifndef PROCTTYDRIVERSFILE
+#define PROCTTYDRIVERSFILE PROCDIR "/tty/drivers"
+#endif
+
#ifndef PROC_LINE_LENGTH
#define PROC_LINE_LENGTH 512
#endif
@@ -87,11 +99,105 @@ typedef struct LinuxProcessList_ {
#ifndef CLAMP
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
#endif
-
+
+static ssize_t xread(int fd, void *buf, size_t count) {
+ // Read some bytes. Retry on EINTR and when we don't get as many bytes as we requested.
+ size_t alreadyRead = 0;
+ for(;;) {
+ ssize_t res = read(fd, buf, count);
+ if (res == -1 && errno == EINTR) continue;
+ if (res > 0) {
+ buf = ((char*)buf)+res;
+ count -= res;
+ alreadyRead += res;
+ }
+ if (res == -1) return -1;
+ if (count == 0 || res == 0) return alreadyRead;
+ }
+}
+
+static int sortTtyDrivers(const void* va, const void* vb) {
+ TtyDriver* a = (TtyDriver*) va;
+ TtyDriver* b = (TtyDriver*) vb;
+ return (a->major == b->major) ? (a->minorFrom - b->minorFrom) : (a->major - b->major);
+}
+
+static void LinuxProcessList_initTtyDrivers(LinuxProcessList* this) {
+ TtyDriver* ttyDrivers;
+ int fd = open(PROCTTYDRIVERSFILE, O_RDONLY);
+ if (fd == -1)
+ return;
+ char* buf = NULL;
+ int bufSize = MAX_READ;
+ int bufLen = 0;
+ for(;;) {
+ buf = realloc(buf, bufSize);
+ int size = xread(fd, buf + bufLen, MAX_READ);
+ if (size <= 0) {
+ buf[bufLen] = '\0';
+ close(fd);
+ break;
+ }
+ bufLen += size;
+ bufSize += MAX_READ;
+ }
+ if (bufLen == 0) {
+ free(buf);
+ return;
+ }
+ int numDrivers = 0;
+ int allocd = 10;
+ ttyDrivers = malloc(sizeof(TtyDriver) * allocd);
+ char* at = buf;
+ while (*at != '\0') {
+ at = strchr(at, ' '); // skip first token
+ while (*at == ' ') at++; // skip spaces
+ char* token = at; // mark beginning of path
+ at = strchr(at, ' '); // find end of path
+ *at = '\0'; at++; // clear and skip
+ ttyDrivers[numDrivers].path = strdup(token); // save
+ while (*at == ' ') at++; // skip spaces
+ token = at; // mark beginning of major
+ at = strchr(at, ' '); // find end of major
+ *at = '\0'; at++; // clear and skip
+ ttyDrivers[numDrivers].major = atoi(token); // save
+ while (*at == ' ') at++; // skip spaces
+ token = at; // mark beginning of minorFrom
+ while (*at >= '0' && *at <= '9') at++; //find end of minorFrom
+ if (*at == '-') { // if has range
+ *at = '\0'; at++; // clear and skip
+ ttyDrivers[numDrivers].minorFrom = atoi(token); // save
+ token = at; // mark beginning of minorTo
+ at = strchr(at, ' '); // find end of minorTo
+ *at = '\0'; at++; // clear and skip
+ ttyDrivers[numDrivers].minorTo = atoi(token); // save
+ } else { // no range
+ *at = '\0'; at++; // clear and skip
+ ttyDrivers[numDrivers].minorFrom = atoi(token); // save
+ ttyDrivers[numDrivers].minorTo = atoi(token); // save
+ }
+ at = strchr(at, '\n'); // go to end of line
+ at++; // skip
+ numDrivers++;
+ if (numDrivers == allocd) {
+ allocd += 10;
+ ttyDrivers = realloc(ttyDrivers, sizeof(TtyDriver) * allocd);
+ }
+ }
+ free(buf);
+ numDrivers++;
+ ttyDrivers = realloc(ttyDrivers, sizeof(TtyDriver) * numDrivers);
+ ttyDrivers[numDrivers - 1].path = NULL;
+ qsort(ttyDrivers, numDrivers - 1, sizeof(TtyDriver), sortTtyDrivers);
+ this->ttyDrivers = ttyDrivers;
+}
+
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId) {
LinuxProcessList* this = xCalloc(1, sizeof(LinuxProcessList));
ProcessList* pl = &(this->super);
ProcessList_init(pl, Class(LinuxProcess), usersTable, pidWhiteList, userId);
+
+ LinuxProcessList_initTtyDrivers(this);
// Update CPU count:
FILE* file = fopen(PROCSTATFILE, "r");
@@ -122,25 +228,15 @@ void ProcessList_delete(ProcessList* pl) {
LinuxProcessList* this = (LinuxProcessList*) pl;
ProcessList_done(pl);
free(this->cpus);
+ if (this->ttyDrivers) {
+ for(int i = 0; this->ttyDrivers[i].path; i++) {
+ free(this->ttyDrivers[i].path);
+ }
+ free(this->ttyDrivers);
+ }
free(this);
}
-static ssize_t xread(int fd, void *buf, size_t count) {
- // Read some bytes. Retry on EINTR and when we don't get as many bytes as we requested.
- size_t alreadyRead = 0;
- for(;;) {
- ssize_t res = read(fd, buf, count);
- if (res == -1 && errno == EINTR) continue;
- if (res > 0) {
- buf = ((char*)buf)+res;
- count -= res;
- alreadyRead += res;
- }
- if (res == -1) return -1;
- if (count == 0 || res == 0) return alreadyRead;
- }
-}
-
static double jiffy = 0.0;
static inline unsigned long long LinuxProcess_adjustTime(unsigned long long t) {
@@ -221,7 +317,7 @@ static bool LinuxProcessList_readStatFile(Process *process, const char* dirname,
process->processor = strtol(location, &location, 10);
process->time = lp->utime + lp->stime;
-
+
return true;
}
@@ -494,6 +590,48 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirna
return true;
}
+static char* LinuxProcessList_updateTtyDevice(TtyDriver* ttyDrivers, unsigned int tty_nr) {
+ unsigned int maj = major(tty_nr);
+ unsigned int min = minor(tty_nr);
+
+ int i = -1;
+ for (;;) {
+ i++;
+ if ((!ttyDrivers[i].path) || maj < ttyDrivers[i].major) {
+ break;
+ }
+ if (maj > ttyDrivers[i].major) {
+ continue;
+ }
+ if (min < ttyDrivers[i].minorFrom) {
+ break;
+ }
+ if (min > ttyDrivers[i].minorTo) {
+ continue;
+ }
+ unsigned int idx = min - ttyDrivers[i].minorFrom;
+ struct stat sstat;
+ char* fullPath;
+ for(;;) {
+ asprintf(&fullPath, "%s/%d", ttyDrivers[i].path, idx);
+ int err = stat(fullPath, &sstat);
+ if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) return fullPath;
+ free(fullPath);
+ asprintf(&fullPath, "%s%d", ttyDrivers[i].path, idx);
+ err = stat(fullPath, &sstat);
+ if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) return fullPath;
+ free(fullPath);
+ if (idx == min) break;
+ idx = min;
+ }
+ int err = stat(ttyDrivers[i].path, &sstat);
+ if (err == 0 && tty_nr == sstat.st_rdev) return strdup(ttyDrivers[i].path);
+ }
+ char* out;
+ asprintf(&out, "/dev/%u:%u", maj, min);
+ return out;
+}
+
static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char* dirname, Process* parent, double period, struct timeval tv) {
ProcessList* pl = (ProcessList*) this;
DIR* dir;
@@ -556,8 +694,13 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
char command[MAX_NAME+1];
unsigned long long int lasttimes = (lp->utime + lp->stime);
int commLen = 0;
+ unsigned int tty_nr = proc->tty_nr;
if (! LinuxProcessList_readStatFile(proc, dirname, name, command, &commLen))
goto errorReadingProcess;
+ if (tty_nr != proc->tty_nr && this->ttyDrivers) {
+ free(lp->ttyDevice);
+ lp->ttyDevice = LinuxProcessList_updateTtyDevice(this->ttyDrivers, proc->tty_nr);
+ }
if (settings->flags & PROCESS_FLAG_LINUX_IOPRIO)
LinuxProcess_updateIOPriority(lp);
float percent_cpu = (lp->utime + lp->stime - lasttimes) / period * 100.0;
diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h
index 97725812..ce39f805 100644
--- a/linux/LinuxProcessList.h
+++ b/linux/LinuxProcessList.h
@@ -40,11 +40,19 @@ typedef struct CPUData_ {
unsigned long long int guestPeriod;
} CPUData;
+typedef struct TtyDriver_ {
+ char* path;
+ unsigned int major;
+ unsigned int minorFrom;
+ unsigned int minorTo;
+} TtyDriver;
+
typedef struct LinuxProcessList_ {
ProcessList super;
-
+
CPUData* cpus;
-
+ TtyDriver* ttyDrivers;
+
} LinuxProcessList;
#ifndef PROCDIR
@@ -59,6 +67,10 @@ typedef struct LinuxProcessList_ {
#define PROCMEMINFOFILE PROCDIR "/meminfo"
#endif
+#ifndef PROCTTYDRIVERSFILE
+#define PROCTTYDRIVERSFILE PROCDIR "/tty/drivers"
+#endif
+
#ifndef PROC_LINE_LENGTH
#define PROC_LINE_LENGTH 512
#endif
@@ -67,7 +79,7 @@ typedef struct LinuxProcessList_ {
#ifndef CLAMP
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
#endif
-
+
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId);
void ProcessList_delete(ProcessList* pl);
diff --git a/openbsd/OpenBSDProcess.c b/openbsd/OpenBSDProcess.c
index 71c84e8c..70f9653b 100644
--- a/openbsd/OpenBSDProcess.c
+++ b/openbsd/OpenBSDProcess.c
@@ -85,7 +85,7 @@ ProcessFieldData Process_fields[] = {
.flags = 0, },
[TTY_NR] = {
.name = "TTY_NR",
- .title = " TTY ",
+ .title = " TTY ",
.description = "Controlling terminal",
.flags = 0, },
[TPGID] = {
diff --git a/unsupported/Platform.c b/unsupported/Platform.c
index 30726859..0df3ef9f 100644
--- a/unsupported/Platform.c
+++ b/unsupported/Platform.c
@@ -39,7 +39,7 @@ ProcessFieldData Process_fields[] = {
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
[PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group ID", .flags = 0, },
[SESSION] = { .name = "SESSION", .title = " SESN ", .description = "Process's session ID", .flags = 0, },
- [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, },
+ [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, },
[TPGID] = { .name = "TPGID", .title = " TPGID ", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, },
[MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, },
[MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, },

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