/*
htop - LinuxProcessList.c
(C) 2014 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "LinuxProcessList.h"
#include "LinuxProcess.h"
#include "CRT.h"
#include "StringUtils.h"
#include <errno.h>
#include <sys/time.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <stdbool.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <sys/types.h>
#include <fcntl.h>
/*{
#include "ProcessList.h"
typedef struct CPUData_ {
unsigned long long int totalTime;
unsigned long long int userTime;
unsigned long long int systemTime;
unsigned long long int systemAllTime;
unsigned long long int idleAllTime;
unsigned long long int idleTime;
unsigned long long int niceTime;
unsigned long long int ioWaitTime;
unsigned long long int irqTime;
unsigned long long int softIrqTime;
unsigned long long int stealTime;
unsigned long long int guestTime;
unsigned long long int totalPeriod;
unsigned long long int userPeriod;
unsigned long long int systemPeriod;
unsigned long long int systemAllPeriod;
unsigned long long int idleAllPeriod;
unsigned long long int idlePeriod;
unsigned long long int nicePeriod;
unsigned long long int ioWaitPeriod;
unsigned long long int irqPeriod;
unsigned long long int softIrqPeriod;
unsigned long long int stealPeriod;
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
#define PROCDIR "/proc"
#endif
#ifndef PROCSTATFILE
#define PROCSTATFILE PROCDIR "/stat"
#endif
#ifndef PROCMEMINFOFILE
#define PROCMEMINFOFILE PROCDIR "/meminfo"
#endif
#ifndef PROCTTYDRIVERSFILE
#define PROCTTYDRIVERSFILE PROCDIR "/tty/drivers"
#endif
#ifndef PROC_LINE_LENGTH
#define PROC_LINE_LENGTH 512
#endif
}*/
#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;