summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2014-11-24 18:55:03 -0200
committerHisham Muhammad <hisham@gobolinux.org>2014-11-24 18:55:03 -0200
commiteb229d9aefa622d3ae25fc7c92b9f66590216d8b (patch)
tree641cf56a8e78fcc7f3f4c4f6b4e1762bfda3d0fb
parent1eda099d06837651a0e6fac4585e80f83363d4ef (diff)
Changes for supporting separate platform subdirectories.
-rw-r--r--Action.c59
-rw-r--r--Action.h42
-rw-r--r--CRT.c27
-rw-r--r--CRT.h5
-rw-r--r--Makefile.am36
-rw-r--r--Process.c48
-rw-r--r--Process.h21
-rw-r--r--ProcessList.c684
-rw-r--r--ProcessList.h45
-rw-r--r--RichString.c2
-rw-r--r--configure.ac36
-rw-r--r--htop.c99
-rw-r--r--htop.h25
13 files changed, 210 insertions, 919 deletions
diff --git a/Action.c b/Action.c
new file mode 100644
index 00000000..23f0c840
--- /dev/null
+++ b/Action.c
@@ -0,0 +1,59 @@
+/*
+htop - Action.c
+(C) 2014 Hisham H. Muhammad
+Released under the GNU GPL, see the COPYING file
+in the source distribution for its full text.
+*/
+
+#include "Process.h"
+#include "Panel.h"
+#include "Action.h"
+
+/*{
+
+#include "IncSet.h"
+#include "Settings.h"
+#include "UsersTable.h"
+
+typedef enum {
+ HTOP_OK = 0x00,
+ HTOP_REFRESH = 0x01,
+ HTOP_RECALCULATE = 0x03, // implies HTOP_REFRESH
+ HTOP_SAVE_SETTINGS = 0x04,
+ HTOP_KEEP_FOLLOWING = 0x08,
+ HTOP_QUIT = 0x10,
+ HTOP_REDRAW_BAR = 0x20,
+ HTOP_UPDATE_PANELHDR = 0x41, // implies HTOP_REFRESH
+} Htop_Reaction;
+
+typedef Htop_Reaction (*Htop_Action)();
+
+typedef struct State_ {
+ IncSet* inc;
+ Settings* settings;
+ UsersTable* ut;
+} State;
+
+typedef bool(*Action_ForeachProcessFn)(Process*, size_t);
+
+}*/
+
+bool Action_foreachProcess(Panel* panel, Action_ForeachProcessFn fn, int arg, bool* wasAnyTagged) {
+ bool ok = true;
+ bool anyTagged = false;
+ for (int i = 0; i < Panel_size(panel); i++) {
+ Process* p = (Process*) Panel_get(panel, i);
+ if (p->tag) {
+ ok = fn(p, arg) && ok;
+ anyTagged = true;
+ }
+ }
+ if (!anyTagged) {
+ Process* p = (Process*) Panel_getSelected(panel);
+ if (p) ok = fn(p, arg) && ok;
+ }
+ if (wasAnyTagged)
+ *wasAnyTagged = anyTagged;
+ return ok;
+}
+
diff --git a/Action.h b/Action.h
new file mode 100644
index 00000000..5a2ce1ce
--- /dev/null
+++ b/Action.h
@@ -0,0 +1,42 @@
+/* Do not edit this file. It was automatically generated. */
+
+#ifndef HEADER_Action
+#define HEADER_Action
+/*
+htop - Action.h
+(C) 2014 Hisham H. Muhammad
+Released under the GNU GPL, see the COPYING file
+in the source distribution for its full text.
+*/
+
+
+#include "IncSet.h"
+#include "Settings.h"
+#include "UsersTable.h"
+
+typedef enum {
+ HTOP_OK = 0x00,
+ HTOP_REFRESH = 0x01,
+ HTOP_RECALCULATE = 0x03, // implies HTOP_REFRESH
+ HTOP_SAVE_SETTINGS = 0x04,
+ HTOP_KEEP_FOLLOWING = 0x08,
+ HTOP_QUIT = 0x10,
+ HTOP_REDRAW_BAR = 0x20,
+ HTOP_UPDATE_PANELHDR = 0x41, // implies HTOP_REFRESH
+} Htop_Reaction;
+
+typedef Htop_Reaction (*Htop_Action)();
+
+typedef struct State_ {
+ IncSet* inc;
+ Settings* settings;
+ UsersTable* ut;
+} State;
+
+typedef bool(*Action_ForeachProcessFn)(Process*, size_t);
+
+
+bool Action_foreachProcess(Panel* panel, Action_ForeachProcessFn fn, int arg, bool* wasAnyTagged);
+
+
+#endif
diff --git a/CRT.c b/CRT.c
index 14a30d0f..c06c3caf 100644
--- a/CRT.c
+++ b/CRT.c
@@ -7,7 +7,6 @@ in the source distribution for its full text.
#include "CRT.h"
-#include "config.h"
#include "String.h"
#include "RichString.h"
@@ -16,9 +15,6 @@ in the source distribution for its full text.
#include <signal.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>
-#endif
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
@@ -112,6 +108,8 @@ typedef enum ColorElements_ {
void CRT_fatalError(const char* note) __attribute__ ((noreturn));
+void CRT_handleSIGSEGV(int sgn);
+
}*/
// TODO: centralize these in Settings.
@@ -134,27 +132,6 @@ char* CRT_termType;
void *backtraceArray[128];
-static void CRT_handleSIGSEGV(int sgn) {
- (void) sgn;
- CRT_done();
- #if __linux
- fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at http://hisham.hm/htop\n");
- #ifdef HAVE_EXECINFO_H
- size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *));
- fprintf(stderr, "\n Please include in your report the following backtrace: \n");
- backtrace_symbols_fd(backtraceArray, size, 2);
- fprintf(stderr, "\nAdditionally, in order to make the above backtrace useful,");
- fprintf(stderr, "\nplease also run the following command to generate a disassembly of your binary:");
- fprintf(stderr, "\n\n objdump -d `which htop` > ~/htop.objdump");
- fprintf(stderr, "\n\nand then attach the file ~/htop.objdump to your bug report.");
- fprintf(stderr, "\n\nThank you for helping to improve htop!\n\n");
- #endif
- #else
- fprintf(stderr, "\n\nhtop " VERSION " aborting. Unsupported platform.\n");
- #endif
- abort();
-}
-
static void CRT_handleSIGTERM(int sgn) {
(void) sgn;
CRT_done();
diff --git a/CRT.h b/CRT.h
index 260d0874..b77a83a7 100644
--- a/CRT.h
+++ b/CRT.h
@@ -9,9 +9,6 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
-#ifdef HAVE_EXECINFO_H
-#endif
-
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
#define COLORSCHEME_DEFAULT 0
@@ -103,6 +100,8 @@ typedef enum ColorElements_ {
void CRT_fatalError(const char* note) __attribute__ ((noreturn));
+void CRT_handleSIGSEGV(int sgn);
+
// TODO: centralize these in Settings.
diff --git a/Makefile.am b/Makefile.am
index 820e2e54..9eb31a79 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,9 @@
ACLOCAL_AMFLAGS = -I m4
+AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS = htop
+
dist_man_MANS = htop.1
EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png scripts/MakeHeader.py \
install-sh autogen.sh missing
@@ -10,7 +12,7 @@ applications_DATA = htop.desktop
pixmapdir = $(datadir)/pixmaps
pixmap_DATA = htop.png
-htop_CFLAGS = -pedantic -Wall -Wextra -std=c99 -rdynamic -D_XOPEN_SOURCE_EXTENDED -DSYSCONFDIR=\"$(sysconfdir)\"
+htop_CFLAGS = -pedantic -Wall -Wextra -std=c99 -rdynamic -D_XOPEN_SOURCE_EXTENDED -DSYSCONFDIR=\"$(sysconfdir)\" -I"$(my_htop_platform)"
AM_CPPFLAGS = -DNDEBUG
myhtopsources = AvailableMetersPanel.c CategoriesPanel.c CheckItem.c \
@@ -18,23 +20,42 @@ ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c \
DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c \
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.c \
BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c \
-IOPriorityPanel.c SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \
+SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \
UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c \
-HostnameMeter.c OpenFilesScreen.c Affinity.c IOPriority.c IncSet.c
+HostnameMeter.c OpenFilesScreen.c Affinity.c IncSet.c Action.c
myhtopheaders = AvailableColumnsPanel.h AvailableMetersPanel.h \
CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h \
-IOPriorityPanel.h CPUMeter.h CRT.h DisplayOptionsPanel.h FunctionBar.h \
+CPUMeter.h CRT.h DisplayOptionsPanel.h FunctionBar.h \
Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.h \
BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h \
ScreenManager.h Settings.h SignalsPanel.h String.h SwapMeter.h TasksMeter.h \
TraceScreen.h UptimeMeter.h UsersTable.h Vector.h Process.h AffinityPanel.h \
-HostnameMeter.h OpenFilesScreen.h Affinity.h IOPriority.h IncSet.h
+HostnameMeter.h OpenFilesScreen.h Affinity.h IncSet.h Action.h
+
+if HTOP_LINUX
+myhtopplatsources = linux/Platform.c linux/IOPriorityPanel.c linux/IOPriority.c \
+linux/LinuxProcessList.c linux/LinuxCRT.c
+
+myhtopplatheaders = linux/Platform.h linux/IOPriorityPanel.h linux/IOPriority.h \
+linux/LinuxProcessList.h linux/LinuxCRT.h
+endif
+
+if HTOP_UNSUPPORTED
+myhtopplatsources = unsupported/Platform.c unsupported/UnsupportedProcessList.c \
+unsupported/UnsupportedCRT.c
+
+myhtopplatheaders = unsupported/Platform.h unsupported/UnsupportedProcessList.h \
+unsupported/UnsupportedCRT.h
+endif
SUFFIXES = .h
-BUILT_SOURCES = $(myhtopheaders)
-htop_SOURCES = $(myhtopheaders) $(myhtopsources) config.h
+BUILT_SOURCES = $(myhtopheaders) $(myhtopplatheaders)
+htop_SOURCES = $(myhtopheaders) $(myhtopplatheaders) $(myhtopsources) $(myhtopplatsources) config.h
+
+target:
+ echo $(htop_SOURCES)
profile:
$(MAKE) all CFLAGS="-pg" AM_CPPFLAGS="-pg -O2 -DNDEBUG"
@@ -47,3 +68,4 @@ debug:
cppcheck:
cppcheck -q -v . --enable=all -DHAVE_CGROUP -DHAVE_OPENVZ -DHAVE_TASKSTATS
+
diff --git a/Process.c b/Process.c
index 5501b3e9..dd08521b 100644
--- a/Process.c
+++ b/Process.c
@@ -1,6 +1,6 @@
/*
htop - Process.c
-(C) 2004-2011 Hisham H. Muhammad
+(C) 2004-2014 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
@@ -32,7 +32,7 @@ in the source distribution for its full text.
#include <hwloc/linux.h>
#endif
-// This works only with glibc 2.1+. On earlier versions
+// On Linux, this works only with glibc 2.1+. On earlier versions
// the behavior is similar to have a hardcoded page size.
#ifndef PAGE_SIZE
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
@@ -42,7 +42,7 @@ in the source distribution for its full text.
/*{
#include "Object.h"
#include "Affinity.h"
-#include "IOPriority.h"
+
#include <sys/types.h>
#define PROCESS_FLAG_IO 1
@@ -122,7 +122,6 @@ typedef struct Process_ {
long int priority;
long int nice;
long int nlwp;
- IOPriority ioPriority;
char starttime_show[8];
time_t starttime_ctime;
@@ -628,24 +627,6 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
#ifdef HAVE_OOM
case OOM: snprintf(buffer, n, Process_pidFormat, this->oom); break;
#endif
- case IO_PRIORITY: {
- int klass = IOPriority_class(this->ioPriority);
- if (klass == IOPRIO_CLASS_NONE) {
- // see note [1] above
- snprintf(buffer, n, "B%1d ", (int) (this->nice + 20) / 5);
- } else if (klass == IOPRIO_CLASS_BE) {
- snprintf(buffer, n, "B%1d ", IOPriority_data(this->ioPriority));
- } else if (klass == IOPRIO_CLASS_RT) {
- attr = CRT_colors[PROCESS_HIGH_PRIORITY];
- snprintf(buffer, n, "R%1d ", IOPriority_data(this->ioPriority));
- } else if (this->ioPriority == IOPriority_Idle) {
- attr = CRT_colors[PROCESS_LOW_PRIORITY];
- snprintf(buffer, n, "id ");
- } else {
- snprintf(buffer, n, "?? ");
- }
- break;
- }
default:
snprintf(buffer, n, "- ");
}
@@ -720,27 +701,6 @@ bool Process_changePriorityBy(Process* this, size_t delta) {
return Process_setPriority(this, this->nice + delta);
}
-IOPriority Process_updateIOPriority(Process* this) {
- IOPriority ioprio = syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, this->pid);
- this->ioPriority = ioprio;
- return ioprio;
-}
-
-bool Process_setIOPriority(Process* this, IOPriority ioprio) {
- syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, this->pid, ioprio);
- return (Process_updateIOPriority(this) == ioprio);
-}
-
-/*
-[1] Note that before kernel 2.6.26 a process that has not asked for
-an io priority formally uses "none" as scheduling class, but the
-io scheduler will treat such processes as if it were in the best
-effort class. The priority within the best effort class will be
-dynamically derived from the cpu nice level of the process:
-io_priority = (cpu_nice + 20) / 5. -- From ionice(1) man page
-*/
-#define Process_effectiveIOPriority(p_) (IOPriority_class(p_->ioPriority) == IOPRIO_CLASS_NONE ? IOPriority_tuple(IOPRIO_CLASS_BE, (p_->nice + 20) / 5) : p_->ioPriority)
-
#ifdef HAVE_LIBHWLOC
Affinity* Process_getAffinity(Process* this) {
@@ -902,8 +862,6 @@ long Process_compare(const void* v1, const void* v2) {
case OOM:
return (p1->oom - p2->oom);
#endif
- case IO_PRIORITY:
- return Process_effectiveIOPriority(p1) - Process_effectiveIOPriority(p2);
default:
return (p1->pid - p2->pid);
}
diff --git a/Process.h b/Process.h
index 87196eee..c4ef808d 100644
--- a/Process.h
+++ b/Process.h
@@ -4,7 +4,7 @@
#define HEADER_Process
/*
htop - Process.h
-(C) 2004-2011 Hisham H. Muhammad
+(C) 2004-2014 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
@@ -12,7 +12,7 @@ in the source distribution for its full text.
#ifdef HAVE_LIBHWLOC
#endif
-// This works only with glibc 2.1+. On earlier versions
+// On Linux, this works only with glibc 2.1+. On earlier versions
// the behavior is similar to have a hardcoded page size.
#ifndef PAGE_SIZE
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
@@ -21,7 +21,7 @@ in the source distribution for its full text.
#include "Object.h"
#include "Affinity.h"
-#include "IOPriority.h"
+
#include <sys/types.h>
#define PROCESS_FLAG_IO 1
@@ -101,7 +101,6 @@ typedef struct Process_ {
long int priority;
long int nice;
long int nlwp;
- IOPriority ioPriority;
char starttime_show[8];
time_t starttime_ctime;
@@ -202,20 +201,6 @@ bool Process_setPriority(Process* this, int priority);
bool Process_changePriorityBy(Process* this, size_t delta);
-IOPriority Process_updateIOPriority(Process* this);
-
-bool Process_setIOPriority(Process* this, IOPriority ioprio);
-
-/*
-[1] Note that before kernel 2.6.26 a process that has not asked for
-an io priority formally uses "none" as scheduling class, but the
-io scheduler will treat such processes as if it were in the best
-effort class. The priority within the best effort class will be
-dynamically derived from the cpu nice level of the process:
-extern io_priority;
-*/
-#define Process_effectiveIOPriority(p_) (IOPriority_class(p_->ioPriority) == IOPRIO_CLASS_NONE ? IOPriority_tuple(IOPRIO_CLASS_BE, (p_->nice + 20) / 5) : p_->ioPriority)
-
#ifdef HAVE_LIBHWLOC
Affinity* Process_getAffinity(Process* this);
diff --git a/ProcessList.c b/ProcessList.c
index 7841e0a3..16a52a59 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -35,18 +35,6 @@ in the source distribution for its full text.
#include "Panel.h"
#include "Process.h"
-#ifndef PROCDIR
-#define PROCDIR "/proc"
-#endif
-
-#ifndef PROCSTATFILE
-#define PROCSTATFILE PROCDIR "/stat"
-#endif
-
-#ifndef PROCMEMINFOFILE
-#define PROCMEMINFOFILE PROCDIR "/meminfo"
-#endif
-
#ifndef MAX_NAME
#define MAX_NAME 128
#endif
@@ -155,6 +143,9 @@ typedef struct ProcessList_ {
} ProcessList;
+ProcessList* ProcessList_new(UsersTable* ut, Hashtable* pidWhiteList);
+void ProcessList_scan(ProcessList* pl);
+
}*/
static ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
@@ -179,45 +170,18 @@ const char *ProcessList_treeStrUtf8[TREE_STR_COUNT] = {
"\xe2\x94\x80", // TREE_STR_SHUT ─
};
-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;
- }
-}
-
-ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) {
- ProcessList* this;
- this = calloc(1, sizeof(ProcessList));
+ProcessList* ProcessList_init(ProcessList* this, UsersTable* usersTable, Hashtable* pidWhiteList) {
this->processes = Vector_new(Class(Process), true, DEFAULT_SIZE);
this->processTable = Hashtable_new(140, false);
this->usersTable = usersTable;
this->pidWhiteList = pidWhiteList;
- /* tree-view auxiliary buffers */
+ // tree-view auxiliary buffers
this->processes2 = Vector_new(Class(Process), true, DEFAULT_SIZE);
- FILE* file = fopen(PROCSTATFILE, "r");
- if (file == NULL) {
- CRT_fatalError("Cannot open " PROCSTATFILE);
- }
- char buffer[256];
- int cpus = -1;
- do {
- cpus++;
- fgets(buffer, 255, file);
- } while (String_startsWith(buffer, "cpu"));
- fclose(file);
- this->cpuCount = MAX(cpus - 1, 1);
+ // set later by platform-specific code
+ this->cpuCount = 0;
+ this->cpus = NULL;
#ifdef HAVE_LIBHWLOC
this->topologyOk = false;
@@ -229,12 +193,6 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) {
this->topologyOk = true;
}
#endif
- this->cpus = calloc(cpus, sizeof(CPUData));
-
- for (int i = 0; i < cpus; i++) {
- this->cpus[i].totalTime = 1;
- this->cpus[i].totalPeriod = 1;
- }
this->fields = calloc(LAST_PROCESSFIELD+1, sizeof(ProcessField));
// TODO: turn 'fields' into a Vector,
@@ -245,10 +203,6 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) {
this->flags |= Process_fieldFlags[defaultHeaders[i]];
}
- #ifdef HAVE_OPENVZ
- this->flags |= PROCESS_FLAG_OPENVZ;
- #endif
-
this->sortKey = PERCENT_CPU;
this->direction = 1;
this->hideThreads = false;
@@ -304,7 +258,7 @@ void ProcessList_printHeader(ProcessList* this, RichString* header) {
}
}
-static void ProcessList_add(ProcessList* this, Process* p) {
+void ProcessList_add(ProcessList* this, Process* p) {
assert(Vector_indexOf(this->processes, p, Process_pidCompare) == -1);
assert(Hashtable_get(this->processTable, p->pid) == NULL);
@@ -316,7 +270,7 @@ static void ProcessList_add(ProcessList* this, Process* p) {
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
}
-static void ProcessList_remove(ProcessList* this, Process* p) {
+void ProcessList_remove(ProcessList* this, Process* p) {
assert(Vector_indexOf(this->processes, p, Process_pidCompare) != -1);
assert(Hashtable_get(this->processTable, p->pid) != NULL);
Process* pp = Hashtable_remove(this->processTable, p->pid);
@@ -385,6 +339,7 @@ void ProcessList_sort(ProcessList* this) {
// Take PID 1 as root and add to the new listing
int vsize = Vector_size(this->processes);
Process* init = (Process*) (Vector_take(this->processes, 0));
+ if (!init) return;
// This assertion crashes on hardened kernels.
// I wonder how well tree view works on those systems.
// assert(init->pid == 1);
@@ -408,622 +363,6 @@ void ProcessList_sort(ProcessList* this) {
}
}
-static bool ProcessList_readStatFile(Process *process, const char* dirname, const char* name, char* command) {
- char filename[MAX_NAME+1];
- snprintf(filename, MAX_NAME, "%s/%s/stat", dirname, name);
- int fd = open(filename, O_RDONLY);
- if (fd == -1)
- return false;
-
- static char buf[MAX_READ+1];
-
- int size = xread(fd, buf, MAX_READ);
- close(fd);
- if (size <= 0) return false;
- buf[size] = '\0';
-
- assert(process->pid == atoi(buf));
- char *location = strchr(buf, ' ');
- if (!location) return false;
-
- location += 2;
- char *end = strrchr(location, ')');
- if (!end) return false;
-
- int commsize = end - location;
- memcpy(command, location, commsize);
- command[commsize] = '\0';
- location = end + 2;
-
- process->state = location[0];
- location += 2;
- process->ppid = strtol(location, &location, 10);
- location += 1;
- process->pgrp = strtoul(location, &location, 10);
- location += 1;
- process->session = strtoul(location, &location, 10);
- location += 1;
- process->tty_nr = strtoul(location, &location, 10);
- location += 1;
- process->tpgid = strtol(location, &location, 10);
- location += 1;
- process->flags = strtoul(location, &location, 10);
- location += 1;
- process->minflt = strtoull(location, &location, 10);
- location += 1;
- process->cminflt = strtoull(location, &location, 10);
- location += 1;
- process->majflt = strtoull(location, &location, 10);
- location += 1;
- process->cmajflt = strtoull(location, &location, 10);
- location += 1;
- process->utime = strtoull(location, &location, 10);
- location += 1;
- process->stime = strtoull(location, &location, 10);
- location += 1;
- process->cutime = strtoull(location, &location, 10);
- location += 1;
- process->cstime = strtoull(location, &location, 10);
- location += 1;
- process->priority = strtol(location, &location, 10);
- location += 1;
- process->nice = strtol(location, &location, 10);
- location += 1;
- process->nlwp = strtol(location, &location, 10);
- location += 1;
- for (int i=0; i<17; i++) location = strchr(location, ' ')+1;
- process->exit_signal = strtol(location, &location, 10);
- location += 1;
- assert(location != NULL);
- process->processor = strtol(location, &location, 10);
- assert(location == NULL);
-
- return true;
-}
-
-static bool ProcessList_statProcessDir(Process* process, const char* dirname, char* name, time_t curTime) {
- char filename[MAX_NAME+1];
- filename[MAX_NAME] = '\0';
-
- snprintf(filename, MAX_NAME, "%s/%s", dirname, name);
- struct stat sstat;
- int statok = stat(filename, &sstat);
- if (statok == -1)
- return false;
- process->st_uid = sstat.st_uid;
-
- struct tm date;
- time_t ctime = sstat.st_ctime;
- process->starttime_ctime = ctime;
- (void) localtime_r((time_t*) &ctime, &date);
- strftime(process->starttime_show, 7, ((ctime > curTime - 86400) ? "%R " : "%b%d "), &date);
-
- return true;
-}
-
-#ifdef HAVE_TASKSTATS
-
-static void ProcessList_readIoFile(Process* process, const char* dirname, char* name, unsigned long long now) {
- char filename[MAX_NAME+1];
- filename[MAX_NAME] = '\0';
-
- snprintf(filename, MAX_NAME, "%s/%s/io", dirname, name);
- int fd = open(filename, O_RDONLY);
- if (fd == -1)
- return;
-
- char buffer[1024];
- ssize_t buflen = xread(fd, buffer, 1023);
- close(fd);
- if (buflen < 1) return;
- buffer[buflen] = '\0';
- unsigned long long last_read = process->io_read_bytes;
- unsigned long long last_write = process->io_write_bytes;
- char *buf = buffer;
- char *line = NULL;
- while ((line = strsep(&buf, "\n")) != NULL) {
- switch (line[0]) {
- case 'r':
- if (line[1] == 'c' && strncmp(line+2, "har: ", 5) == 0)
- process->io_rchar = strtoull(line+7, NULL, 10);
- else if (strncmp(line+1, "ead_bytes: ", 11) == 0) {
- process->io_read_bytes = strtoull(line+12, NULL, 10);
- process->io_rate_read_bps =
- ((double)(process->io_read_bytes - last_read))/(((double)(now - process->io_rate_read_time))/1000);
- process->io_rate_read_time = now;
- }
- break;
- case 'w':
- if (line[1] == 'c' && strncmp(line+2, "har: ", 5) == 0)
- process->io_wchar = strtoull(line+7, NULL, 10);
- else if (strncmp(line+1, "rite_bytes: ", 12) == 0) {
- process->io_write_bytes = strtoull(line+13, NULL, 10);
- process->io_rate_write_bps =
- ((double)(process->io_write_bytes - last_write))/(((double)(now - process->io_rate_write_time))/1000);
- process->io_rate_write_time = now;
- }
- break;
- case 's':
- if (line[5] == 'r' && strncmp(line+1, "yscr: ", 6) == 0)
- process->io_syscr = strtoull(line+7, NULL, 10);
- else if (strncmp(line+1, "yscw: ", 6) == 0)
- sscanf(line, "syscw: %32llu", &process->io_syscw);
- process->io_syscw = strtoull(line+7, NULL, 10);
- break;
- case 'c':
- if (strncmp(line+1, "ancelled_write_bytes: ", 22) == 0)
- process->io_cancelled_write_bytes = strtoull(line+23, NULL, 10);
- }
- }
-}
-
-#endif
-
-static bool ProcessList_readStatmFile(Process* process, const char* dirname, const char* name) {
- char filename[MAX_NAME+1];
- snprintf(filename, MAX_NAME, "%s/%s/statm", dirname, name);
- int fd = open(filename, O_RDONLY);
- if (fd == -1)
- return false;
- char buf[256];
- ssize_t rres = xread(fd, buf, 255);
- close(fd);
- if (rres < 1) return false;
-
- char *p = buf;
- errno = 0;
- process->m_size = strtol(p, &p, 10); if (*p == ' ') p++;
- process->m_resident = strtol(p, &p, 10); if (*p == ' ') p++;
- process->m_share = strtol(p, &p, 10); if (*p == ' ') p++;
- process->m_trs = strtol(p, &p, 10); if (*p == ' ') p++;
- process->m_lrs = strtol(p, &p, 10); if (*p == ' ') p++;
- process->m_drs = strtol(p, &p, 10); if (*p == ' ') p++;
- process->m_dt = strtol(p, &p, 10);
- return (errno == 0);
-}
-
-#ifdef HAVE_OPENVZ
-
-static void ProcessList_readOpenVZData(ProcessList* this, Process* process, const char* dirname, const char* name) {
- if ( (!(this->flags & PROCESS_FLAG_OPENVZ)) || (access("/proc/vz", R_OK) != 0)) {
- process->vpid = process->pid;
- process->ctid = 0;
- this->flags |= ~PROCESS_FLAG_OPENVZ;
- return;
- }
- char filename[MAX_NAME+1];
- snprintf(filename, MAX_NAME, "%s/%s/stat", dirname, name);
- FILE* file = fopen(filename, "r");
- if (!file)
- return;
- fscanf(file,
- "%*32u %*32s %*1c %*32u %*32u %*32u %*32u %*32u %*32u %*32u "
- "%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u "
- "%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u "
- "%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u "
- "%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u "
- "%*32u %*32u %*32u %*32u %*32u %*32u %*32u "
- "%*32u %*32u %32u %32u",
- &process->vpid, &process->ctid);
- fclose(file);
-}
-
-#endif
-
-#ifdef HAVE_CGROUP
-
-static void ProcessList_readCGroupFile(Process* process, const char* dirname, const char* name) {
- char filename[MAX_NAME+1];
- snprintf(filename, MAX_NAME, "%s/%s/cgroup", dirname, name);
- FILE* file = fopen(filename, "r");
- if (!file) {
- process->cgroup = strdup("");
- return;
- }
- char buffer[256];
- char *ok = fgets(buffer, 255, file);
- if (ok) {
- char* trimmed = String_trim(buffer);
- int nFields;
- char** fields = String_split(trimmed, ':', &nFields);
- free(trimmed);
- if (nFields >= 3) {
- process->cgroup = strndup(fields[2] + 1, 10);
- } else {
- process->cgroup = strdup("");
- }
- String_freeArray(fields);
- }
- fclose(file);
-}
-
-#endif
-
-#ifdef HAVE_VSERVER
-
-static void ProcessList_readVServerData(Process* process, const char* dirname, const char* name) {
- char filename[MAX_NAME+1];
- snprintf(filename, MAX_NAME, "%s/%s/status", dirname, name);
- FILE* file = fopen(filename, "r");
- if (!file)
- return;
- char buffer[256];
- process->vxid = 0;
- while (fgets(buffer, 255, file)) {
- if (String_startsWith(buffer, "VxID:")) {
- int vxid;
- int ok = sscanf(buffer, "VxID:\t%32d", &vxid);
- if (ok >= 1) {
- process->vxid = vxid;
- }
- }
- #if defined HAVE_ANCIENT_VSERVER
- else if (String_startsWith(buffer, "s_context:")) {
- int vxid;
- int ok = sscanf(buffer, "s_context:\t%32d", &vxid);
- if (ok >= 1) {
- process->vxid = vxid;
- }
- }
- #endif
- }
- fclose(file);
-}
-
-#endif
-
-#ifdef HAVE_OOM
-
-static void ProcessList_readOomData(Process* process, const char* dirname, const char* name) {
- char filename[MAX_NAME+1];
- snprintf(filename, MAX_NAME, "%s/%s/oom_score", dirname, name);
- FILE* file = fopen(filename, "r");
- if (!file)
- return;
- char buffer[256];
- if (fgets(buffer, 255, file)) {
- unsigned int oom;
- int ok = sscanf(buffer, "%32u", &oom);
- if (ok >= 1) {
- process->oom = oom;
- }
- }
- fclose(file);
-}
-
-#endif
-
-static bool ProcessList_readCmdlineFile(Process* process, const char* dirname, const char* name) {
- if (Process_isKernelThread(process))
- return true;
-
- char filename[MAX_NAME+1];
- snprintf(filename, MAX_NAME, "%s/%s/cmdline", dirname, name);
- int fd = open(filename, O_RDONLY);
- if (fd == -1)
- return false;
-
- char command[4096+1]; // max cmdline length on Linux
- int amtRead = xread(fd, command, sizeof(command) - 1);
- close(fd);
- int tokenEnd = 0;
- if (amtRead > 0) {
- for (int i = 0; i < amtRead; i++)
- if (command[i] == '\0' || command[i] == '\n') {
- if (tokenEnd == 0) {
- tokenEnd = i;
- }
- command[i] = ' ';
- }
- }
- if (tokenEnd == 0) {
- tokenEnd = amtRead;
- }
- command[amtRead] = '\0';
- free(process->comm);
- process->comm = strdup(command);
- process->basenameOffset = tokenEnd;
-
- return true;
-}
-
-
-static bool ProcessList_processEntries(ProcessList* this, const char* dirname, Process* parent, double period, struct timeval tv) {
- DIR* dir;
- struct dirent* entry;
-
- time_t curTime = tv.tv_sec;
- #ifdef HAVE_TASKSTATS
- unsigned long long now = tv.tv_sec*1000LL+tv.tv_usec/1000LL;
- #endif
-
- dir = opendir(dirname);
- if (!dir) return false;
- int cpus = this->cpuCount;
- bool hideKernelThreads = this->hideKernelThreads;
- bool hideUserlandThreads = this->hideUserlandThreads;
- while ((entry = readdir(dir)) != NULL) {
- char* name = entry->d_name;
-
- // The RedHat kernel hides threads with a dot.
- // I believe this is non-standard.
- if ((!this->hideThreads) && name[0] == '.') {
- name++;
- }
-
- // Just skip all non-number directories.
- if (name[0] < '0' || name[0] > '9') {
- continue;
- }
-
- // filename is a number: process directory
- int pid = atoi(name);
-
- if (parent && pid == parent->pid)
- continue;
-
- if (pid <= 0)
- continue;
-
- Process* process = NULL;
- Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid);
-
- if (existingProcess) {
- assert(Vector_indexOf(this->processes, existingProcess, Process_pidCompare) != -1);
- process = existingProcess;
- assert(process->pid == pid);
- } else {
- process = Process_new(this);
- assert(process->comm == NULL);
- process->pid = pid;
- process->tgid = parent ? parent->pid : pid;
- }
-
- char subdirname[MAX_NAME+1];
- snprintf(subdirname, MAX_NAME, "%s/%s/task", dirname, name);
- ProcessList_processEntries(this, subdirname, process, period, tv);
-
- #ifdef HAVE_TASKSTATS
- if (this->flags & PROCESS_FLAG_IO)
- ProcessList_readIoFile(process, dirname, name, now);
- #endif
-
- if (! ProcessList_readStatmFile(process, dirname, name))
- goto errorReadingProcess;
-
- process->show = ! ((hideKernelThreads && Process_isKernelThread(process)) || (hideUserlandThreads && Process_isUserlandThread(process)));
-
- char command[MAX_NAME+1];
- unsigned long long int lasttimes = (process->utime + process->stime);
- if (! ProcessList_readStatFile(process, dirname, name, command))
- goto errorReadingProcess;
- if (this->flags & PROCESS_FLAG_IOPRIO)
- Process_updateIOPriority(process);
- float percent_cpu = (process->utime + process->stime - lasttimes) / period * 100.0;
- process->percent_cpu = MAX(MIN(percent_cpu, cpus*100.0), 0.0);
- if (isnan(process->percent_cpu)) process->percent_cpu = 0.0;
- process->percent_mem = (process->m_resident * PAGE_SIZE_KB) / (double)(this->totalMem) * 100.0;
-
- if(!existingProcess) {
-
- if (! ProcessList_statProcessDir(process, dirname, name, curTime))
- goto errorReadingProcess;
-
- process->user = UsersTable_getRef(this->usersTable, process->st_uid);
-
- #ifdef HAVE_OPENVZ
- ProcessList_readOpenVZData(this, process, dirname, name);
- #endif
-
- #ifdef HAVE_VSERVER
- if (this->flags & PROCESS_FLAG_VSERVER)
- ProcessList_readVServerData(process, dirname, name);
- #endif
-
- if (! ProcessList_readCmdlineFile(process, dirname, name))
- goto errorReadingProcess;
-
- ProcessList_add(this, process);
- } else {
- if (this->updateProcessNames) {
- if (! ProcessList_readCmdlineFile(process, dirname, name))
- goto errorReadingProcess;
- }
- }
-
- #ifdef HAVE_CGROUP
- if (this->flags & PROCESS_FLAG_CGROUP)
- ProcessList_readCGroupFile(process, dirname, name);
- #endif
-
- #ifdef HAVE_OOM
- ProcessList_readOomData(process, dirname, name);
- #endif
-
- if (process->state == 'Z') {
- free(process->comm);
- process->basenameOffset = -1;
- process->comm = strdup(command);
- } else if (Process_isThread(process)) {
- if (this->showThreadNames || Process_isKernelThread(process) || process->state == 'Z') {
- free(process->comm);
- process->basenameOffset = -1;
- process->comm = strdup(command);
- } else if (this->showingThreadNames) {
- if (! ProcessList_readCmdlineFile(process, dirname, name))
- goto errorReadingProcess;
- }
- if (Process_isKernelThread(process)) {
- this->kernelThreads++;
- } else {
- this->userlandThreads++;
- }
- }
-
- this->totalTasks++;
- if (process->state == 'R')
- this->runningTasks++;
- process->updated = true;
-
- continue;
-
- // Exception handler.
- errorReadingProcess: {
- if (process->comm) {
- free(process->comm);
- process->basenameOffset = -1;
- process->comm = NULL;
- }
- if (existingProcess)
- ProcessList_remove(this, process);
- else
- Process_delete((Object*)process);
- }
- }
- closedir(dir);
- return true;
-}
-
-void ProcessList_scan(ProcessList* this) {
- unsigned long long int usertime, nicetime, systemtime, idletime;
- unsigned long long int swapFree = 0;
-
- FILE* file = fopen(PROCMEMINFOFILE, "r");
- if (file == NULL) {
- CRT_fatalError("Cannot open " PROCMEMINFOFILE);
- }
- int cpus = this->cpuCount;
- assert(cpus > 0);
- {
- char buffer[128];
- while (fgets(buffer, 128, file)) {
-
- switch (buffer[0]) {
- case 'M':
- if (String_startsWith(buffer, "MemTotal:"))
- sscanf(buffer, "MemTotal: %32llu kB", &this->totalMem);
- else if (String_startsWith(buffer, "MemFree:"))
- sscanf(buffer, "MemFree: %32llu kB", &this->freeMem);
- else if (String_startsWith(buffer, "MemShared:"))
- sscanf(buffer, "MemShared: %32llu kB", &this->sharedMem);
- break;
- case 'B':
- if (String_startsWith(buffer, "Buffers:"))
- sscanf(buffer, "Buffers: %32llu kB", &this->buffersMem);
- break;
- case 'C':
- if (String_startsWith(buffer, "Cached:"))
- sscanf(buffer, "Cached: %32llu kB", &this->cachedMem);
- break;
- case 'S':
- if (String_startsWith(buffer, "SwapTotal:"))
- sscanf(buffer, "SwapTotal: %32llu kB", &this->totalSwap);
- if (String_startsWith(buffer, "SwapFree:"))
- sscanf(buffer, "SwapFree: %32llu kB", &swapFree);
- break;
- }
- }
- }
-
- this->usedMem = this->totalMem - this->freeMem;
- this->usedSwap = this->totalSwap - swapFree;
- fclose(file);
-
- file = fopen(PROCSTATFILE, "r");
- if (file == NULL) {
- CRT_fatalError("Cannot open " PROCSTATFILE);
- }
- for (int i = 0; i <= cpus; i++) {
- char buffer[256];
- int cpuid;
- unsigned long long int ioWait, irq, softIrq, steal, guest, guestnice;
- unsigned long long int systemalltime, idlealltime, totaltime, virtalltime;
- ioWait = irq = softIrq = steal = guest = guestnice = 0;
- // Dependending on your kernel version,
- // 5, 7, 8 or 9 of these fields will be set.
- // The rest will remain at zero.
- fgets(buffer, 255, file);
- if (i == 0)
- sscanf(buffer, "cpu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
- else {
- sscanf(buffer, "cpu%4d %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
- assert(cpuid == i - 1);
- }
- // Guest time is already accounted in usertime
- usertime = usertime - guest;
- nicetime = nicetime - guestnice;
- // Fields existing on kernels >= 2.6
- // (and RHEL's patched kernel 2.4...)
- idlealltime = idletime + ioWait;
- systemalltime = systemtime + irq + softIrq;
- virtalltime = guest + guestnice;
- totaltime = usertime + nicetime + systemalltime + idlealltime + steal + virtalltime;
- CPUData* cpuData = &(this->cpus[i]);
- assert (usertime >= cpuData->userTime);
- assert (nicetime >= cpuData->niceTime);
- assert (systemtime >= cpuData->systemTime);
- assert (idletime >= cpuData->idleTime);
- assert (totaltime >= cpuData->totalTime);
- assert (systemalltime >= cpuData->systemAllTime);
- assert (idlealltime >= cpuData->idleAllTime);
- assert (ioWait >= cpuData->ioWaitTime);
- assert (irq >= cpuData->irqTime);
- assert (softIrq >= cpuData->softIrqTime);
- assert (steal >= cpuData->stealTime);
- assert (virtalltime >= cpuData->guestTime);
- cpuData->userPeriod = usertime - cpuData->userTime;
- cpuData->nicePeriod = nicetime - cpuData->niceTime;
- cpuData->systemPeriod = systemtime - cpuData->systemTime;
- cpuData->systemAllPeriod = systemalltime - cpuData->systemAllTime;
- cpuData->idleAllPeriod = idlealltime - cpuData->idleAllTime;
- cpuData->idlePeriod = idletime - cpuData->idleTime;
- cpuData->ioWaitPeriod = ioWait - cpuData->ioWaitTime;
- cpuData->irqPeriod = irq - cpuData->irqTime;
- cpuData->softIrqPeriod = softIrq - cpuData->softIrqTime;
- cpuData->stealPeriod = steal - cpuData->stealTime;
- cpuData->guestPeriod = virtalltime - cpuData->guestTime;
- cpuData->totalPeriod = totaltime - cpuData->totalTime;
- cpuData->userTime = usertime;
- cpuData->niceTime = nicetime;
- cpuData->systemTime = systemtime;
- cpuData->systemAllTime = systemalltime;
- cpuData->idleAllTime = idlealltime;
- cpuData->idleTime = idletime;
- cpuData->ioWaitTime = ioWait;
- cpuData->irqTime = irq;
- cpuData->softIrqTime = softIrq;
- cpuData->stealTime = steal;
- cpuData->guestTime = virtalltime;
- cpuData->totalTime = totaltime;
- }
- double period = (double)this->cpus[0].totalPeriod / cpus; fclose(file);
-
- // mark all process as "dirty"
- for (int i = 0; i < Vector_size(this->processes); i++) {
- Process* p = (Process*) Vector_get(this->processes, i);
- p->updated = false;
- }
-
- this->totalTasks = 0;
- this->userlandThreads = 0;
- this->kernelThreads = 0;
- this->runningTasks = 0;
-
- struct timeval tv;
- gettimeofday(&tv, NULL);
- ProcessList_processEntries(this, PROCDIR, NULL, period, tv);
-
- this->showingThreadNames = this->showThreadNames;
-
- for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
- Process* p = (Process*) Vector_get(this->processes, i);
- if (p->updated == false)
- ProcessList_remove(this, p);
- else
- p->updated = false;
- }
-
-}
ProcessField ProcessList_keyAt(ProcessList* this, int at) {
int x = 0;
@@ -1083,3 +422,4 @@ void ProcessList_rebuildPanel(ProcessList* this, bool flags, int following, cons
}
}
}
+
diff --git a/ProcessList.h b/ProcessList.h
index fce7d03f..2bd5788a 100644
--- a/ProcessList.h
+++ b/ProcessList.h
@@ -15,18 +15,6 @@ in the source distribution for its full text.
#include "Panel.h"
#include "Process.h"
-#ifndef PROCDIR
-#define PROCDIR "/proc"
-#endif
-
-#ifndef PROCSTATFILE
-#define PROCSTATFILE PROCDIR "/stat"
-#endif
-
-#ifndef PROCMEMINFOFILE
-#define PROCMEMINFOFILE PROCDIR "/meminfo"
-#endif
-
#ifndef MAX_NAME
#define MAX_NAME 128
#endif
@@ -135,12 +123,15 @@ typedef struct ProcessList_ {
} ProcessList;
+ProcessList* ProcessList_new(UsersTable* ut, Hashtable* pidWhiteList);
+void ProcessList_scan(ProcessList* pl);
+
extern const char *ProcessList_treeStrAscii[TREE_STR_COUNT];
extern const char *ProcessList_treeStrUtf8[TREE_STR_COUNT];
-ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList);
+ProcessList* ProcessList_init(ProcessList* this, UsersTable* usersTable, Hashtable* pidWhiteList);
void ProcessList_delete(ProcessList* this);
@@ -150,39 +141,21 @@ void ProcessList_invertSortOrder(ProcessList* this);
void ProcessList_printHeader(ProcessList* this, RichString* header);
+void ProcessList_add(ProcessList* this, Process* p);
+
+void ProcessList_remove(ProcessList* this, Process* p);
+
Process* ProcessList_get(ProcessList* this, int idx);
int ProcessList_size(ProcessList* this);
void ProcessList_sort(ProcessList* this);
-#ifdef HAVE_TASKSTATS
-
-#endif
-
-#ifdef HAVE_OPENVZ
-
-#endif
-
-#ifdef HAVE_CGROUP
-
-#endif
-
-#ifdef HAVE_VSERVER
-
-#endif
-
-#ifdef HAVE_OOM
-
-#endif
-
-
-void ProcessList_scan(ProcessList* this);
-
ProcessField ProcessList_keyAt(ProcessList* this, int at);
void ProcessList_expandTree(ProcessList* this);
void ProcessList_rebuildPanel(ProcessList* this, bool flags, int following, const char* incFilter);
+
#endif
diff --git a/RichString.c b/RichString.c
index fb2f2578..51914b08 100644
--- a/RichString.c
+++ b/RichString.c
@@ -174,4 +174,4 @@ void RichString_appendn(RichString* this, int attrs, const char* data, int len)
void RichString_write(RichString* this, int attrs, const char* data) {
RichString_writeFrom(this, attrs, data, 0, strlen(data));
-} \ No newline at end of file
+}
diff --git a/configure.ac b/configure.ac
index 63d34842..45279181 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,6 +22,19 @@ AC_DISABLE_SHARED
AC_ENABLE_STATIC
AC_PROG_LIBTOOL
+# Checks for platform.
+# ----------------------------------------------------------------------
+case "$target" in
+*linux*)
+ my_htop_platform=linux
+ ;;
+*)
+ my_htop_platform=unsupported
+ ;;
+esac
+AM_CONDITIONAL([HTOP_LINUX], [test "$my_htop_platform" = linux])
+AM_CONDITIONAL([HTOP_UNSUPPORTED], [test "$my_htop_platform" = unsupported])
+
# Checks for libraries.
# ----------------------------------------------------------------------
AC_CHECK_LIB([m], [ceil], [], [missing_libraries="$missing_libraries libm"])
@@ -60,17 +73,25 @@ CFLAGS="$save_cflags"
# Checks for features and flags.
# ----------------------------------------------------------------------
PROCDIR=/proc
+
+AC_ARG_ENABLE(proc, [AC_HELP_STRING([--enable-proc], [use Linux-compatible proc filesystem])], enable_proc="yes", enable_proc="no")
+if test "x$enable_proc" = xyes; then
+ AC_DEFINE(HAVE_PROC, 1, [Define if using a Linux-compatible proc filesystem.])
+fi
+
AC_ARG_WITH(proc, [ --with-proc=DIR Location of a Linux-compatible proc filesystem (default=/proc).],
- if test -n "$withval"; then
- AC_DEFINE_UNQUOTED(PROCDIR, "$withval", [Path of proc filesystem])
- PROCDIR="$withval"
- fi,
- AC_DEFINE(PROCDIR, "/proc", [Path of proc filesystem]))
+if test -n "$withval"; then
+ AC_DEFINE_UNQUOTED(PROCDIR, "$withval", [Path of proc filesystem])
+ PROCDIR="$withval"
+fi,
+AC_DEFINE(PROCDIR, "/proc", [Path of proc filesystem]))
if test "x$cross_compiling" = xno; then
-AC_CHECK_FILE($PROCDIR/stat,,AC_MSG_ERROR(Cannot find /proc/stat. Make sure you have a Linux-compatible /proc filesystem mounted. See the file README for help.))
-AC_CHECK_FILE($PROCDIR/meminfo,,AC_MSG_ERROR(Cannot find /proc/meminfo. Make sure you have a Linux-compatible /proc filesystem mounted. See the file README for help.))
+ if test "x$enable_proc" = xyes; then
+ AC_CHECK_FILE($PROCDIR/stat,,AC_MSG_ERROR(Cannot find $PROCDIR/stat. Make sure you have a Linux-compatible /proc filesystem mounted. See the file README for help.))
+ AC_CHECK_FILE($PROCDIR/meminfo,,AC_MSG_ERROR(Cannot find $PROCDIR/meminfo. Make sure you have a Linux-compatible /proc filesystem mounted. See the file README for help.))
+ fi
fi
AC_ARG_ENABLE(openvz, [AC_HELP_STRING([--enable-openvz], [enable OpenVZ support])], ,enable_openvz="no")
@@ -161,5 +182,6 @@ fi
# We're done, let's go!
# ----------------------------------------------------------------------
+AC_SUBST(my_htop_platform)
AC_CONFIG_FILES([Makefile htop.1])
AC_OUTPUT
diff --git a/htop.c b/htop.c
index 01393e61..e4b4ddf2 100644
--- a/htop.c
+++ b/htop.c
@@ -22,8 +22,9 @@ in the source distribution for its full text.
#include "TraceScreen.h"
#include "OpenFilesScreen.h"
#include "AffinityPanel.h"
-#include "IOPriorityPanel.h"
+#include "Platform.h"
#include "IncSet.h"
+#include "Action.h"
#include "htop.h"
#include <unistd.h>
@@ -43,31 +44,6 @@ in the source distribution for its full text.
#define COPYRIGHT "(C) 2004-2014 Hisham Muhammad"
-/*{
-
-typedef enum {
- HTOP_OK = 0x00,
- HTOP_REFRESH = 0x01,
- HTOP_RECALCULATE = 0x03, // implies HTOP_REFRESH
- HTOP_SAVE_SETTINGS = 0x04,
- HTOP_KEEP_FOLLOWING = 0x08,
- HTOP_QUIT = 0x10,
- HTOP_REDRAW_BAR = 0x20,
- HTOP_UPDATE_PANELHDR = 0x41, // implies HTOP_REFRESH
-} Htop_Reaction;
-
-typedef Htop_Reaction (*Htop_Action)();
-
-typedef struct State_ {
- IncSet* inc;
- Settings* settings;
- UsersTable* ut;
-} State;
-
-typedef bool(*ForeachProcessFn)(Process*, size_t);
-
-}*/
-
static void printVersionFlag() {
fputs("htop " VERSION " - " COPYRIGHT "\n"
"Released under the GNU GPL.\n\n",
@@ -211,28 +187,9 @@ static void Setup_run(Settings* settings, const Header* header) {
ScreenManager_delete(scr);
}
-static bool foreachProcess(Panel* panel, ForeachProcessFn fn, int arg, bool* wasAnyTagged) {
- bool ok = true;
- bool anyTagged = false;
- for (int i = 0; i < Panel_size(panel); i++) {
- Process* p = (Process*) Panel_get(panel, i);
- if (p->tag) {
- ok = fn(p, arg) && ok;
- anyTagged = true;
- }
- }
- if (!anyTagged) {
- Process* p = (Process*) Panel_getSelected(panel);
- if (p) ok = fn(p, arg) && ok;
- }
- if (wasAnyTagged)
- *wasAnyTagged = anyTagged;
- return ok;
-}
-
static bool changePriority(Panel* panel, int delta) {
bool anyTagged;
- bool ok = foreachProcess(panel, (ForeachProcessFn) Process_changePriorityBy, delta, &anyTagged);
+ bool ok = Action_foreachProcess(panel, (Action_ForeachProcessFn) Process_changePriorityBy, delta, &anyTagged);
if (!ok)
beep();
return anyTagged;
@@ -429,24 +386,6 @@ static Htop_Reaction actionInvertSortOrder(Panel* panel, ProcessList* pl) {
return HTOP_REFRESH | HTOP_SAVE_SETTINGS;
}
-static Htop_Reaction actionSetIOPriority(Panel* panel, ProcessList* pl, Header* header) {
- (void) panel, (void) pl;
- Process* p = (Process*) Panel_getSelected(panel);
- if (!p) return HTOP_OK;
- IOPriority ioprio = p->ioPriority;
- Panel* ioprioPanel = IOPriorityPanel_new(ioprio);
- const char* fuFunctions[] = {"Set ", "Cancel ", NULL};
- void* set = pickFromVector(panel, ioprioPanel, 21, fuFunctions, header);
- if (set) {
- IOPriority ioprio = IOPriorityPanel_getIOPriority(ioprioPanel);
- bool ok = foreachProcess(panel, (ForeachProcessFn) Process_setIOPriority, (size_t) ioprio, NULL);
- if (!ok)
- beep();
- }
- Panel_delete((Object*)ioprioPanel);
- return HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR;
-}
-
static Htop_Reaction actionSetSortColumn(Panel* panel, ProcessList* pl, Header* header) {
return sortBy(panel, pl, header);
}
@@ -479,11 +418,14 @@ static Htop_Reaction actionSetAffinity(Panel* panel, ProcessList* pl, Header* he
void* set = pickFromVector(panel, affinityPanel, 15, fuFunctions, header);
if (set) {
Affinity* affinity = AffinityPanel_getAffinity(affinityPanel);
- bool ok = foreachProcess(panel, (ForeachProcessFn) Process_setAffinity, (size_t) affinity, NULL);
+ bool ok = Action_foreachProcess(panel, (Action_ForeachProcessFn) Process_setAffinity, (size_t) affinity, NULL);
if (!ok) beep();
Affinity_delete(affinity);
}
Panel_delete((Object*)affinityPanel);
+#else
+ (void) panel;
+ (void) header;
#endif
return HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR;
}
@@ -498,7 +440,7 @@ static Htop_Reaction actionKill(Panel* panel, ProcessList* pl, Header* header) {
Panel_setHeader(panel, "Sending...");
Panel_draw(panel, true);
refresh();
- foreachProcess(panel, (ForeachProcessFn) Process_sendSignal, (size_t) sgn->key, NULL);
+ Action_foreachProcess(panel, (Action_ForeachProcessFn) Process_sendSignal, (size_t) sgn->key, NULL);
napms(500);
}
}
@@ -596,7 +538,7 @@ static Htop_Reaction actionTagAllChildren(Panel* panel) {
return HTOP_OK;
}
-void setBindings(Htop_Action* keys) {
+static void setBindings(Htop_Action* keys) {
keys[KEY_RESIZE] = actionResize;
keys['M'] = actionSortByMemory;
keys['T'] = actionSortByTime;
@@ -615,7 +557,6 @@ void setBindings(Htop_Action* keys) {
keys['['] = actionLowerPriority;
keys[KEY_F(8)] = actionLowerPriority;
keys['I'] = actionInvertSortOrder;
- keys['i'] = actionSetIOPriority;
keys[KEY_F(6)] = actionExpandCollapseOrSortColumn;
keys[KEY_F(18)] = actionExpandCollapseOrSortColumn;
keys['<'] = actionSetSortColumn;
@@ -761,17 +702,7 @@ int main(int argc, char** argv) {
fprintf(stderr, "Error: could not read procfs (compiled to look in %s).\n", PROCDIR);
exit(1);
}
-
- bool quit = false;
- int sortTimeout = 0;
- int resetSortTimeout = 5;
- bool doRefresh = true;
- bool forceRecalculate = false;
- Settings* settings;
- ProcessList* pl = NULL;
- UsersTable* ut = UsersTable_new();
-
#ifdef HAVE_LIBNCURSESW
char *locale = setlocale(LC_ALL, NULL);
if (locale == NULL || locale[0] == '\0')
@@ -786,13 +717,14 @@ int main(int argc, char** argv) {
CRT_utf8 = false;
#endif
- pl = ProcessList_new(ut, pidWhiteList);
+ UsersTable* ut = UsersTable_new();
+ ProcessList* pl = ProcessList_new(ut, pidWhiteList);
pl->userOnly = userOnly;
pl->userId = userId;
Process_getMaxPid();
Header* header = Header_new(pl);
- settings = Settings_new(pl, header, pl->cpuCount);
+ Settings* settings = Settings_new(pl, header, pl->cpuCount);
int headerHeight = Header_calculateHeight(header);
// FIXME: move delay code to settings
@@ -839,12 +771,19 @@ int main(int argc, char** argv) {
Htop_Action keys[KEY_MAX] = { NULL };
setBindings(keys);
+ Platform_setBindings(keys);
State state = {
.inc = inc,
.settings = settings,
.ut = ut,
};
+
+ bool quit = false;
+ int sortTimeout = 0;
+ int resetSortTimeout = 5;
+ bool doRefresh = true;
+ bool forceRecalculate = false;
while (!quit) {
gettimeofday(&tv, NULL);
diff --git a/htop.h b/htop.h
index a1369431..77f6e2e8 100644
--- a/htop.h
+++ b/htop.h
@@ -13,33 +13,8 @@ in the source distribution for its full text.
#define COPYRIGHT "(C) 2004-2014 Hisham Muhammad"
-
-typedef enum {
- HTOP_OK = 0x00,
- HTOP_REFRESH = 0x01,
- HTOP_RECALCULATE = 0x03, // implies HTOP_REFRESH
- HTOP_SAVE_SETTINGS = 0x04,
- HTOP_KEEP_FOLLOWING = 0x08,
- HTOP_QUIT = 0x10,
- HTOP_REDRAW_BAR = 0x20,
- HTOP_UPDATE_PANELHDR = 0x41, // implies HTOP_REFRESH
-} Htop_Reaction;
-
-typedef Htop_Reaction (*Htop_Action)();
-
-typedef struct State_ {
- IncSet* inc;
- Settings* settings;
- UsersTable* ut;
-} State;
-
-typedef bool(*ForeachProcessFn)(Process*, size_t);
-
-
// ----------------------------------------
-void setBindings(Htop_Action* keys);
-
// ----------------------------------------
int main(int argc, char** argv);

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