mirror of https://github.com/xzeldon/htop.git
Interpret TTY_NR column on Linux,
translate dev_t to major:minor on other platforms. Closes #316.
This commit is contained in:
parent
8a147dd5b4
commit
8af4d9f453
|
@ -102,7 +102,6 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) {
|
||||||
fdata = nextFile;
|
fdata = nextFile;
|
||||||
item = &(fdata->data);
|
item = &(fdata->data);
|
||||||
}
|
}
|
||||||
assert(cmd >= 0 && cmd <= 0xff);
|
|
||||||
item->data[cmd] = xStrdup(line + 1);
|
item->data[cmd] = xStrdup(line + 1);
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ in the source distribution for its full text.
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.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 TIME: Process_printTime(str, this->time); return;
|
||||||
case TGID: snprintf(buffer, n, Process_pidFormat, this->tgid); break;
|
case TGID: snprintf(buffer, n, Process_pidFormat, this->tgid); break;
|
||||||
case TPGID: snprintf(buffer, n, Process_pidFormat, this->tpgid); 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: {
|
case USER: {
|
||||||
if (Process_getuid != (int) this->st_uid)
|
if (Process_getuid != (int) this->st_uid)
|
||||||
attr = CRT_colors[PROCESS_SHADOW];
|
attr = CRT_colors[PROCESS_SHADOW];
|
||||||
|
|
|
@ -79,7 +79,7 @@ ProcessFieldData Process_fields[] = {
|
||||||
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
|
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
|
||||||
[PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group 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, },
|
[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, },
|
[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, },
|
[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, },
|
[MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, },
|
||||||
|
|
|
@ -62,7 +62,7 @@ ProcessFieldData Process_fields[] = {
|
||||||
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
|
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
|
||||||
[PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group 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, },
|
[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, },
|
[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, },
|
[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, },
|
[MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, },
|
||||||
|
|
|
@ -124,6 +124,7 @@ typedef struct LinuxProcess_ {
|
||||||
char* cgroup;
|
char* cgroup;
|
||||||
#endif
|
#endif
|
||||||
unsigned int oom;
|
unsigned int oom;
|
||||||
|
char* ttyDevice;
|
||||||
} LinuxProcess;
|
} LinuxProcess;
|
||||||
|
|
||||||
#ifndef Process_isKernelThread
|
#ifndef Process_isKernelThread
|
||||||
|
@ -144,7 +145,7 @@ ProcessFieldData Process_fields[] = {
|
||||||
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
|
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
|
||||||
[PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group 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, },
|
[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, },
|
[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, },
|
[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, },
|
[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
|
#ifdef HAVE_CGROUP
|
||||||
free(this->cgroup);
|
free(this->cgroup);
|
||||||
#endif
|
#endif
|
||||||
|
free(this->ttyDevice);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,6 +294,15 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
|
||||||
int attr = CRT_colors[DEFAULT_COLOR];
|
int attr = CRT_colors[DEFAULT_COLOR];
|
||||||
int n = sizeof(buffer) - 1;
|
int n = sizeof(buffer) - 1;
|
||||||
switch ((int)field) {
|
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 CMINFLT: Process_colorNumber(str, lp->cminflt, coloring); return;
|
||||||
case CMAJFLT: Process_colorNumber(str, lp->cmajflt, 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;
|
case M_DRS: Process_humanNumber(str, lp->m_drs * PAGE_SIZE_KB, coloring); return;
|
||||||
|
|
|
@ -116,6 +116,7 @@ typedef struct LinuxProcess_ {
|
||||||
char* cgroup;
|
char* cgroup;
|
||||||
#endif
|
#endif
|
||||||
unsigned int oom;
|
unsigned int oom;
|
||||||
|
char* ttyDevice;
|
||||||
} LinuxProcess;
|
} LinuxProcess;
|
||||||
|
|
||||||
#ifndef Process_isKernelThread
|
#ifndef Process_isKernelThread
|
||||||
|
|
|
@ -59,11 +59,19 @@ typedef struct CPUData_ {
|
||||||
unsigned long long int guestPeriod;
|
unsigned long long int guestPeriod;
|
||||||
} CPUData;
|
} CPUData;
|
||||||
|
|
||||||
|
typedef struct TtyDriver_ {
|
||||||
|
char* path;
|
||||||
|
unsigned int major;
|
||||||
|
unsigned int minorFrom;
|
||||||
|
unsigned int minorTo;
|
||||||
|
} TtyDriver;
|
||||||
|
|
||||||
typedef struct LinuxProcessList_ {
|
typedef struct LinuxProcessList_ {
|
||||||
ProcessList super;
|
ProcessList super;
|
||||||
|
|
||||||
CPUData* cpus;
|
CPUData* cpus;
|
||||||
|
TtyDriver* ttyDrivers;
|
||||||
|
|
||||||
} LinuxProcessList;
|
} LinuxProcessList;
|
||||||
|
|
||||||
#ifndef PROCDIR
|
#ifndef PROCDIR
|
||||||
|
@ -78,6 +86,10 @@ typedef struct LinuxProcessList_ {
|
||||||
#define PROCMEMINFOFILE PROCDIR "/meminfo"
|
#define PROCMEMINFOFILE PROCDIR "/meminfo"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PROCTTYDRIVERSFILE
|
||||||
|
#define PROCTTYDRIVERSFILE PROCDIR "/tty/drivers"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PROC_LINE_LENGTH
|
#ifndef PROC_LINE_LENGTH
|
||||||
#define PROC_LINE_LENGTH 512
|
#define PROC_LINE_LENGTH 512
|
||||||
#endif
|
#endif
|
||||||
|
@ -87,11 +99,105 @@ typedef struct LinuxProcessList_ {
|
||||||
#ifndef CLAMP
|
#ifndef CLAMP
|
||||||
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
|
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
|
||||||
#endif
|
#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) {
|
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId) {
|
||||||
LinuxProcessList* this = xCalloc(1, sizeof(LinuxProcessList));
|
LinuxProcessList* this = xCalloc(1, sizeof(LinuxProcessList));
|
||||||
ProcessList* pl = &(this->super);
|
ProcessList* pl = &(this->super);
|
||||||
ProcessList_init(pl, Class(LinuxProcess), usersTable, pidWhiteList, userId);
|
ProcessList_init(pl, Class(LinuxProcess), usersTable, pidWhiteList, userId);
|
||||||
|
|
||||||
|
LinuxProcessList_initTtyDrivers(this);
|
||||||
|
|
||||||
// Update CPU count:
|
// Update CPU count:
|
||||||
FILE* file = fopen(PROCSTATFILE, "r");
|
FILE* file = fopen(PROCSTATFILE, "r");
|
||||||
|
@ -122,25 +228,15 @@ void ProcessList_delete(ProcessList* pl) {
|
||||||
LinuxProcessList* this = (LinuxProcessList*) pl;
|
LinuxProcessList* this = (LinuxProcessList*) pl;
|
||||||
ProcessList_done(pl);
|
ProcessList_done(pl);
|
||||||
free(this->cpus);
|
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);
|
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 double jiffy = 0.0;
|
||||||
|
|
||||||
static inline unsigned long long LinuxProcess_adjustTime(unsigned long long t) {
|
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->processor = strtol(location, &location, 10);
|
||||||
|
|
||||||
process->time = lp->utime + lp->stime;
|
process->time = lp->utime + lp->stime;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,6 +590,48 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirna
|
||||||
return true;
|
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) {
|
static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char* dirname, Process* parent, double period, struct timeval tv) {
|
||||||
ProcessList* pl = (ProcessList*) this;
|
ProcessList* pl = (ProcessList*) this;
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
|
@ -556,8 +694,13 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
|
||||||
char command[MAX_NAME+1];
|
char command[MAX_NAME+1];
|
||||||
unsigned long long int lasttimes = (lp->utime + lp->stime);
|
unsigned long long int lasttimes = (lp->utime + lp->stime);
|
||||||
int commLen = 0;
|
int commLen = 0;
|
||||||
|
unsigned int tty_nr = proc->tty_nr;
|
||||||
if (! LinuxProcessList_readStatFile(proc, dirname, name, command, &commLen))
|
if (! LinuxProcessList_readStatFile(proc, dirname, name, command, &commLen))
|
||||||
goto errorReadingProcess;
|
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)
|
if (settings->flags & PROCESS_FLAG_LINUX_IOPRIO)
|
||||||
LinuxProcess_updateIOPriority(lp);
|
LinuxProcess_updateIOPriority(lp);
|
||||||
float percent_cpu = (lp->utime + lp->stime - lasttimes) / period * 100.0;
|
float percent_cpu = (lp->utime + lp->stime - lasttimes) / period * 100.0;
|
||||||
|
|
|
@ -40,11 +40,19 @@ typedef struct CPUData_ {
|
||||||
unsigned long long int guestPeriod;
|
unsigned long long int guestPeriod;
|
||||||
} CPUData;
|
} CPUData;
|
||||||
|
|
||||||
|
typedef struct TtyDriver_ {
|
||||||
|
char* path;
|
||||||
|
unsigned int major;
|
||||||
|
unsigned int minorFrom;
|
||||||
|
unsigned int minorTo;
|
||||||
|
} TtyDriver;
|
||||||
|
|
||||||
typedef struct LinuxProcessList_ {
|
typedef struct LinuxProcessList_ {
|
||||||
ProcessList super;
|
ProcessList super;
|
||||||
|
|
||||||
CPUData* cpus;
|
CPUData* cpus;
|
||||||
|
TtyDriver* ttyDrivers;
|
||||||
|
|
||||||
} LinuxProcessList;
|
} LinuxProcessList;
|
||||||
|
|
||||||
#ifndef PROCDIR
|
#ifndef PROCDIR
|
||||||
|
@ -59,6 +67,10 @@ typedef struct LinuxProcessList_ {
|
||||||
#define PROCMEMINFOFILE PROCDIR "/meminfo"
|
#define PROCMEMINFOFILE PROCDIR "/meminfo"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PROCTTYDRIVERSFILE
|
||||||
|
#define PROCTTYDRIVERSFILE PROCDIR "/tty/drivers"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PROC_LINE_LENGTH
|
#ifndef PROC_LINE_LENGTH
|
||||||
#define PROC_LINE_LENGTH 512
|
#define PROC_LINE_LENGTH 512
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,7 +79,7 @@ typedef struct LinuxProcessList_ {
|
||||||
#ifndef CLAMP
|
#ifndef CLAMP
|
||||||
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
|
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId);
|
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId);
|
||||||
|
|
||||||
void ProcessList_delete(ProcessList* pl);
|
void ProcessList_delete(ProcessList* pl);
|
||||||
|
|
|
@ -85,7 +85,7 @@ ProcessFieldData Process_fields[] = {
|
||||||
.flags = 0, },
|
.flags = 0, },
|
||||||
[TTY_NR] = {
|
[TTY_NR] = {
|
||||||
.name = "TTY_NR",
|
.name = "TTY_NR",
|
||||||
.title = " TTY ",
|
.title = " TTY ",
|
||||||
.description = "Controlling terminal",
|
.description = "Controlling terminal",
|
||||||
.flags = 0, },
|
.flags = 0, },
|
||||||
[TPGID] = {
|
[TPGID] = {
|
||||||
|
|
|
@ -39,7 +39,7 @@ ProcessFieldData Process_fields[] = {
|
||||||
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
|
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
|
||||||
[PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group 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, },
|
[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, },
|
[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, },
|
[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, },
|
[MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, },
|
||||||
|
|
Loading…
Reference in New Issue