aboutsummaryrefslogtreecommitdiffstats
path: root/Process.c
diff options
context:
space:
mode:
authorDaniel Lange <DLange@git.local>2016-04-11 13:01:07 +0200
committerDaniel Lange <DLange@git.local>2016-04-11 13:01:07 +0200
commitff9409b1737627857eb47f64f536a3f66b6a09a4 (patch)
tree61b631ba551e68a4f656b8b76ff7bd0d9955fc64 /Process.c
parentf75ab6d2c11e8a8e18191b087564aedebbeb96c5 (diff)
downloaddebian_htop-ff9409b1737627857eb47f64f536a3f66b6a09a4.tar.gz
debian_htop-ff9409b1737627857eb47f64f536a3f66b6a09a4.tar.bz2
debian_htop-ff9409b1737627857eb47f64f536a3f66b6a09a4.zip
Imported Upstream version 2.0.0upstream/2.0.0
Diffstat (limited to 'Process.c')
-rw-r--r--Process.c812
1 files changed, 260 insertions, 552 deletions
diff --git a/Process.c b/Process.c
index 4efd854..07ecba1 100644
--- a/Process.c
+++ b/Process.c
@@ -1,16 +1,17 @@
/*
htop - Process.c
-(C) 2004-2011 Hisham H. Muhammad
+(C) 2004-2015 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Process.h"
+#include "Settings.h"
-#include "ProcessList.h"
#include "CRT.h"
-#include "String.h"
+#include "StringUtils.h"
#include "RichString.h"
+#include "Platform.h"
#include <stdio.h>
#include <sys/time.h>
@@ -23,16 +24,16 @@ in the source distribution for its full text.
#include <string.h>
#include <stdbool.h>
#include <pwd.h>
-#include <sched.h>
#include <time.h>
#include <assert.h>
-#include <sys/syscall.h>
+#include <math.h>
-#ifdef HAVE_LIBHWLOC
-#include <hwloc/linux.h>
+#ifdef __ANDROID__
+#define SYS_ioprio_get __NR_ioprio_get
+#define SYS_ioprio_set __NR_ioprio_set
#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) )
@@ -41,137 +42,87 @@ 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
-#define PROCESS_FLAG_IOPRIO 2
-#define PROCESS_FLAG_OPENVZ 4
-#define PROCESS_FLAG_VSERVER 8
-#define PROCESS_FLAG_CGROUP 16
-
-#ifndef Process_isKernelThread
-#define Process_isKernelThread(_process) (_process->pgrp == 0)
-#endif
-#ifndef Process_isUserlandThread
-#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
-#endif
-
-#ifndef Process_isThread
-#define Process_isThread(_process) (Process_isUserlandThread(_process) || Process_isKernelThread(_process))
-#endif
+#include <sys/types.h>
-typedef enum ProcessField_ {
- PID = 1, COMM, STATE, PPID, PGRP, SESSION, TTY_NR, TPGID, FLAGS, MINFLT, CMINFLT, MAJFLT, CMAJFLT, UTIME,
- STIME, CUTIME, CSTIME, PRIORITY, NICE, ITREALVALUE, STARTTIME, VSIZE, RSS, RLIM, STARTCODE, ENDCODE,
- STARTSTACK, KSTKESP, KSTKEIP, SIGNAL, BLOCKED, SSIGIGNORE, SIGCATCH, WCHAN, NSWAP, CNSWAP, EXIT_SIGNAL,
- PROCESSOR, M_SIZE, M_RESIDENT, M_SHARE, M_TRS, M_DRS, M_LRS, M_DT, ST_UID, PERCENT_CPU, PERCENT_MEM,
- USER, TIME, NLWP, TGID,
- #ifdef HAVE_OPENVZ
- CTID, VPID,
- #endif
- #ifdef HAVE_VSERVER
- VXID,
- #endif
- #ifdef HAVE_TASKSTATS
- RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
- #endif
- #ifdef HAVE_CGROUP
- CGROUP,
- #endif
- #ifdef HAVE_OOM
- OOM,
- #endif
- IO_PRIORITY,
- LAST_PROCESSFIELD
+#define PROCESS_FLAG_IO 0x0001
+
+typedef enum ProcessFields {
+ PID = 1,
+ COMM = 2,
+ STATE = 3,
+ PPID = 4,
+ PGRP = 5,
+ SESSION = 6,
+ TTY_NR = 7,
+ TPGID = 8,
+ MINFLT = 10,
+ MAJFLT = 12,
+ PRIORITY = 18,
+ NICE = 19,
+ STARTTIME = 21,
+ PROCESSOR = 38,
+ M_SIZE = 39,
+ M_RESIDENT = 40,
+ ST_UID = 46,
+ PERCENT_CPU = 47,
+ PERCENT_MEM = 48,
+ USER = 49,
+ TIME = 50,
+ NLWP = 51,
+ TGID = 52,
} ProcessField;
-struct ProcessList_;
+typedef struct ProcessPidColumn_ {
+ int id;
+ char* label;
+} ProcessPidColumn;
typedef struct Process_ {
Object super;
- struct ProcessList_ *pl;
+ struct Settings_* settings;
+ unsigned long long int time;
pid_t pid;
+ pid_t ppid;
+ pid_t tgid;
char* comm;
+ int commLen;
int indent;
+
+ int basenameOffset;
+ bool updated;
+
char state;
bool tag;
bool showChildren;
bool show;
- pid_t ppid;
unsigned int pgrp;
unsigned int session;
unsigned int tty_nr;
- pid_t tgid;
int tpgid;
+ uid_t st_uid;
unsigned long int flags;
+ int processor;
- uid_t st_uid;
float percent_cpu;
float percent_mem;
char* user;
- unsigned long long int utime;
- unsigned long long int stime;
- unsigned long long int cutime;
- unsigned long long int cstime;
long int priority;
long int nice;
long int nlwp;
- IOPriority ioPriority;
char starttime_show[8];
time_t starttime_ctime;
- #ifdef HAVE_TASKSTATS
- unsigned long long io_rchar;
- unsigned long long io_wchar;
- unsigned long long io_syscr;
- unsigned long long io_syscw;
- unsigned long long io_read_bytes;
- unsigned long long io_write_bytes;
- unsigned long long io_cancelled_write_bytes;
- double io_rate_read_bps;
- unsigned long long io_rate_read_time;
- double io_rate_write_bps;
- unsigned long long io_rate_write_time;
- #endif
-
- int processor;
long m_size;
long m_resident;
- long m_share;
- long m_trs;
- long m_drs;
- long m_lrs;
- long m_dt;
-
- #ifdef HAVE_OPENVZ
- unsigned int ctid;
- unsigned int vpid;
- #endif
- #ifdef HAVE_VSERVER
- unsigned int vxid;
- #endif
-
- #ifdef HAVE_CGROUP
- char* cgroup;
- #endif
- #ifdef HAVE_OOM
- unsigned int oom;
- #endif
int exit_signal;
- int basenameOffset;
- bool updated;
unsigned long int minflt;
- unsigned long int cminflt;
unsigned long int majflt;
- unsigned long int cmajflt;
#ifdef DEBUG
long int itrealvalue;
unsigned long int vsize;
@@ -193,131 +144,35 @@ typedef struct Process_ {
} Process;
-}*/
+typedef struct ProcessFieldData_ {
+ const char* name;
+ const char* title;
+ const char* description;
+ int flags;
+} ProcessFieldData;
-const char *Process_fieldNames[] = {
- "", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION",
- "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT",
- "UTIME", "STIME", "CUTIME", "CSTIME", "PRIORITY", "NICE", "ITREALVALUE",
- "STARTTIME", "VSIZE", "RSS", "RLIM", "STARTCODE", "ENDCODE", "STARTSTACK",
- "KSTKESP", "KSTKEIP", "SIGNAL", "BLOCKED", "SIGIGNORE", "SIGCATCH", "WCHAN",
- "NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE",
- "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM",
- "USER", "TIME", "NLWP", "TGID",
-#ifdef HAVE_OPENVZ
- "CTID", "VPID",
-#endif
-#ifdef HAVE_VSERVER
- "VXID",
-#endif
-#ifdef HAVE_TASKSTATS
- "RCHAR", "WCHAR", "SYSCR", "SYSCW", "RBYTES", "WBYTES", "CNCLWB",
- "IO_READ_RATE", "IO_WRITE_RATE", "IO_RATE",
-#endif
-#ifdef HAVE_CGROUP
- "CGROUP",
-#endif
-#ifdef HAVE_OOM
- "OOM",
-#endif
- "IO_PRIORITY",
-"*** report bug! ***"
-};
+// Implemented in platform-specific code:
+void Process_writeField(Process* this, RichString* str, ProcessField field);
+long Process_compare(const void* v1, const void* v2);
+void Process_delete(Object* cast);
+bool Process_isThread(Process* this);
+extern ProcessFieldData Process_fields[];
+extern ProcessPidColumn Process_pidColumns[];
+extern char Process_pidFormat[20];
-const int Process_fieldFlags[] = {
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
-#ifdef HAVE_OPENVZ
- PROCESS_FLAG_OPENVZ, PROCESS_FLAG_OPENVZ,
-#endif
-#ifdef HAVE_VSERVER
- PROCESS_FLAG_VSERVER,
-#endif
-#ifdef HAVE_TASKSTATS
- PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO,
- PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO,
-#endif
-#ifdef HAVE_CGROUP
- PROCESS_FLAG_CGROUP,
-#endif
-#ifdef HAVE_OOM
- 0,
-#endif
- PROCESS_FLAG_IOPRIO
-};
+typedef Process*(*Process_New)(struct Settings_*);
+typedef void (*Process_WriteField)(Process*, RichString*, ProcessField);
-const char *Process_fieldTitles[] = {
- "", " PID ", "Command ", "S ", " PPID ", " PGRP ", " SESN ",
- " TTY ", " TPGID ", "- ", " MINFLT ", " CMINFLT ", " MAJFLT ", " CMAJFLT ",
- " UTIME+ ", " STIME+ ", " CUTIME+ ", " CSTIME+ ", "PRI ", " NI ", "- ",
- "START ", "- ", "- ", "- ", "- ", "- ", "- ",
- "- ", "- ", "- ", "- ", "- ", "- ", "- ",
- "- ", "- ", "- ", "CPU ", " VIRT ", " RES ", " SHR ",
- " CODE ", " DATA ", " LIB ", " DIRTY ", " UID ", "CPU% ", "MEM% ",
- "USER ", " TIME+ ", "NLWP ", " TGID ",
-#ifdef HAVE_OPENVZ
- " CTID ", " VPID ",
-#endif
-#ifdef HAVE_VSERVER
- " VXID ",
-#endif
-#ifdef HAVE_TASKSTATS
- " RD_CHAR ", " WR_CHAR ", " RD_SYSC ", " WR_SYSC ", " IO_RBYTES ", " IO_WBYTES ", " IO_CANCEL ",
- " IORR ", " IOWR ", " IORW ",
-#endif
-#ifdef HAVE_CGROUP
- " CGROUP ",
-#endif
-#ifdef HAVE_OOM
- " OOM ",
-#endif
- "IO ",
-"*** report bug! ***"
-};
+typedef struct ProcessClass_ {
+ const ObjectClass super;
+ const Process_WriteField writeField;
+} ProcessClass;
-static int Process_getuid = -1;
+#define As_Process(this_) ((ProcessClass*)((this_)->super.klass))
-static char* Process_pidFormat = "%7u ";
-static char* Process_tpgidFormat = "%7u ";
-
-void Process_getMaxPid() {
- FILE* file = fopen(PROCDIR "/sys/kernel/pid_max", "r");
- if (!file) return;
- int maxPid = 4194303;
- fscanf(file, "%32d", &maxPid);
- fclose(file);
- if (maxPid > 99999) {
- Process_fieldTitles[PID] = " PID ";
- Process_fieldTitles[PPID] = " PPID ";
- Process_fieldTitles[TPGID] = " TPGID ";
- Process_fieldTitles[TGID] = " TGID ";
- Process_fieldTitles[PGRP] = " PGRP ";
- Process_fieldTitles[SESSION] = " SESN ";
- #ifdef HAVE_OOM
- Process_fieldTitles[OOM] = " OOM ";
- #endif
- Process_pidFormat = "%7u ";
- Process_tpgidFormat = "%7d ";
- } else {
- Process_fieldTitles[PID] = " PID ";
- Process_fieldTitles[PPID] = " PPID ";
- Process_fieldTitles[TPGID] = "TPGID ";
- Process_fieldTitles[TGID] = " TGID ";
- Process_fieldTitles[PGRP] = " PGRP ";
- Process_fieldTitles[SESSION] = " SESN ";
- #ifdef HAVE_OOM
- Process_fieldTitles[OOM] = " OOM ";
- #endif
- Process_pidFormat = "%5u ";
- Process_tpgidFormat = "%5d ";
- }
-}
+}*/
+
+static int Process_getuid = -1;
#define ONE_K 1024L
#define ONE_M (ONE_K * ONE_K)
@@ -327,7 +182,24 @@ void Process_getMaxPid() {
#define ONE_DECIMAL_M (ONE_DECIMAL_K * ONE_DECIMAL_K)
#define ONE_DECIMAL_G (ONE_DECIMAL_M * ONE_DECIMAL_K)
-static void Process_humanNumber(RichString* str, unsigned long number, bool coloring) {
+char Process_pidFormat[20] = "%7d ";
+
+static char Process_titleBuffer[20][20];
+
+void Process_setupColumnWidths() {
+ int maxPid = Platform_getMaxPid();
+ if (maxPid == -1) return;
+ int digits = ceil(log10(maxPid));
+ assert(digits < 20);
+ for (int i = 0; Process_pidColumns[i].label; i++) {
+ assert(i < 20);
+ sprintf(Process_titleBuffer[i], "%*s ", digits, Process_pidColumns[i].label);
+ Process_fields[Process_pidColumns[i].id].title = Process_titleBuffer[i];
+ }
+ sprintf(Process_pidFormat, "%%%dd ", digits);
+}
+
+void Process_humanNumber(RichString* str, unsigned long number, bool coloring) {
char buffer[11];
int len;
@@ -338,7 +210,7 @@ static void Process_humanNumber(RichString* str, unsigned long number, bool colo
largeNumberColor = CRT_colors[PROCESS];
processMegabytesColor = CRT_colors[PROCESS];
}
-
+
if(number >= (10 * ONE_DECIMAL_M)) {
#ifdef __LP64__
if(number >= (100 * ONE_DECIMAL_G)) {
@@ -375,7 +247,7 @@ static void Process_humanNumber(RichString* str, unsigned long number, bool colo
RichString_appendn(str, processColor, buffer, len);
}
-static void Process_colorNumber(RichString* str, unsigned long long number, bool coloring) {
+void Process_colorNumber(RichString* str, unsigned long long number, bool coloring) {
char buffer[14];
int largeNumberColor = CRT_colors[LARGE_NUMBER];
@@ -402,19 +274,13 @@ static void Process_colorNumber(RichString* str, unsigned long long number, bool
}
}
-static double jiffy = 0.0;
-
-static void Process_printTime(RichString* str, unsigned long long t) {
- if(jiffy == 0.0) jiffy = sysconf(_SC_CLK_TCK);
- double jiffytime = 1.0 / jiffy;
+void Process_printTime(RichString* str, unsigned long long totalHundredths) {
+ unsigned long long totalSeconds = totalHundredths / 100;
- double realTime = t * jiffytime;
- unsigned long long iRealTime = (unsigned long long) realTime;
-
- unsigned long long hours = iRealTime / 3600;
- int minutes = (iRealTime / 60) % 60;
- int seconds = iRealTime % 60;
- int hundredths = (realTime - iRealTime) * 100;
+ unsigned long long hours = totalSeconds / 3600;
+ int minutes = (totalSeconds / 60) % 60;
+ int seconds = totalSeconds % 60;
+ int hundredths = totalHundredths - (totalSeconds * 100);
char buffer[11];
if (hours >= 100) {
snprintf(buffer, 10, "%7lluh ", hours);
@@ -432,79 +298,97 @@ static void Process_printTime(RichString* str, unsigned long long t) {
}
static inline void Process_writeCommand(Process* this, int attr, int baseattr, RichString* str) {
- int start = RichString_size(str);
- RichString_append(str, attr, this->comm);
- if (this->pl->highlightBaseName) {
- int finish = RichString_size(str) - 1;
- if (this->basenameOffset != -1)
- finish = (start + this->basenameOffset) - 1;
- int colon = RichString_findChar(str, ':', start);
- if (colon != -1 && colon < finish) {
- finish = colon;
- } else {
- for (int i = finish - start; i >= 0; i--) {
- if (this->comm[i] == '/') {
- start += i+1;
- break;
- }
+ int start = RichString_size(str), finish = 0;
+ char* comm = this->comm;
+
+ if (this->settings->highlightBaseName || !this->settings->showProgramPath) {
+ int i, basename = 0;
+ for (i = 0; i < this->basenameOffset; i++) {
+ if (comm[i] == '/') {
+ basename = i + 1;
+ } else if (comm[i] == ':') {
+ finish = i + 1;
+ break;
}
}
- RichString_setAttrn(str, baseattr, start, finish);
+ if (!finish) {
+ if (this->settings->showProgramPath)
+ start += basename;
+ else
+ comm += basename;
+ finish = this->basenameOffset - basename;
+ }
+ finish += start - 1;
}
+
+ RichString_append(str, attr, comm);
+
+ if (this->settings->highlightBaseName)
+ RichString_setAttrn(str, baseattr, start, finish);
}
-static inline void Process_outputRate(RichString* str, int attr, char* buffer, int n, double rate, int coloring) {
- rate = rate / 1024;
- if (rate < 0.01)
- snprintf(buffer, n, " 0 ");
- else if (rate <= 10)
- snprintf(buffer, n, "%5.2f ", rate);
- else if (rate <= 100)
- snprintf(buffer, n, "%5.1f ", rate);
- else {
- Process_humanNumber(str, rate, coloring);
- return;
+void Process_outputRate(RichString* str, char* buffer, int n, double rate, int coloring) {
+ int largeNumberColor = CRT_colors[LARGE_NUMBER];
+ int processMegabytesColor = CRT_colors[PROCESS_MEGABYTES];
+ int processColor = CRT_colors[PROCESS];
+ if (!coloring) {
+ largeNumberColor = CRT_colors[PROCESS];
+ processMegabytesColor = CRT_colors[PROCESS];
+ }
+ if (rate < ONE_K) {
+ int len = snprintf(buffer, n, "%7.2f B/s ", rate);
+ RichString_appendn(str, processColor, buffer, len);
+ } else if (rate < ONE_K * ONE_K) {
+ int len = snprintf(buffer, n, "%7.2f K/s ", rate / ONE_K);
+ RichString_appendn(str, processColor, buffer, len);
+ } else if (rate < ONE_K * ONE_K * ONE_K) {
+ int len = snprintf(buffer, n, "%7.2f M/s ", rate / ONE_K / ONE_K);
+ RichString_appendn(str, processMegabytesColor, buffer, len);
+ } else {
+ int len = snprintf(buffer, n, "%7.2f G/s ", rate / ONE_K / ONE_K / ONE_K);
+ RichString_appendn(str, largeNumberColor, buffer, len);
}
- RichString_append(str, attr, buffer);
}
-static void Process_writeField(Process* this, RichString* str, ProcessField field) {
+void Process_writeField(Process* this, RichString* str, ProcessField field) {
char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR];
int baseattr = CRT_colors[PROCESS_BASENAME];
int n = sizeof(buffer) - 1;
- bool coloring = this->pl->highlightMegabytes;
+ bool coloring = this->settings->highlightMegabytes;
switch (field) {
- case PID: snprintf(buffer, n, Process_pidFormat, this->pid); break;
- case PPID: snprintf(buffer, n, Process_pidFormat, this->ppid); break;
- case PGRP: snprintf(buffer, n, Process_pidFormat, this->pgrp); break;
- case SESSION: snprintf(buffer, n, Process_pidFormat, this->session); break;
- case TTY_NR: snprintf(buffer, n, "%5u ", this->tty_nr); break;
- case TGID: snprintf(buffer, n, Process_pidFormat, this->tgid); break;
- case TPGID: snprintf(buffer, n, Process_tpgidFormat, this->tpgid); break;
- case MINFLT: Process_colorNumber(str, this->minflt, coloring); return;
- case CMINFLT: Process_colorNumber(str, this->cminflt, coloring); return;
- case MAJFLT: Process_colorNumber(str, this->majflt, coloring); return;
- case CMAJFLT: Process_colorNumber(str, this->cmajflt, coloring); return;
- case PROCESSOR: snprintf(buffer, n, "%3d ", ProcessList_cpuId(this->pl, this->processor)); break;
- case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
+ case PERCENT_CPU: {
+ if (this->percent_cpu > 999.9) {
+ snprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu);
+ } else if (this->percent_cpu > 99.9) {
+ snprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu);
+ } else {
+ snprintf(buffer, n, "%4.1f ", this->percent_cpu);
+ }
+ break;
+ }
+ case PERCENT_MEM: {
+ if (this->percent_mem > 99.9) {
+ snprintf(buffer, n, "100. ");
+ } else {
+ snprintf(buffer, n, "%4.1f ", this->percent_mem);
+ }
+ break;
+ }
case COMM: {
- if (this->pl->highlightThreads && Process_isThread(this)) {
+ if (this->settings->highlightThreads && Process_isThread(this)) {
attr = CRT_colors[PROCESS_THREAD];
baseattr = CRT_colors[PROCESS_THREAD_BASENAME];
}
- if (!this->pl->treeView || this->indent == 0) {
+ if (!this->settings->treeView || this->indent == 0) {
Process_writeCommand(this, attr, baseattr, str);
return;
} else {
char* buf = buffer;
int maxIndent = 0;
- const char **treeStr = this->pl->treeStr;
bool lastItem = (this->indent < 0);
int indent = (this->indent < 0 ? -this->indent : this->indent);
- if (treeStr == NULL)
- treeStr = ProcessList_treeStrAscii;
for (int i = 0; i < 32; i++)
if (indent & (1 << i))
@@ -512,26 +396,34 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
for (int i = 0; i < maxIndent - 1; i++) {
int written;
if (indent & (1 << i))
- written = snprintf(buf, n, "%s ", treeStr[TREE_STR_VERT]);
+ written = snprintf(buf, n, "%s ", CRT_treeStr[TREE_STR_VERT]);
else
written = snprintf(buf, n, " ");
buf += written;
n -= written;
}
- const char* draw = treeStr[lastItem ? (this->pl->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
- snprintf(buf, n, "%s%s ", draw, this->showChildren ? treeStr[TREE_STR_SHUT] : treeStr[TREE_STR_OPEN] );
+ const char* draw = CRT_treeStr[lastItem ? (this->settings->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
+ snprintf(buf, n, "%s%s ", draw, this->showChildren ? CRT_treeStr[TREE_STR_SHUT] : CRT_treeStr[TREE_STR_OPEN] );
RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
Process_writeCommand(this, attr, baseattr, str);
return;
}
}
- case STATE: {
- snprintf(buffer, n, "%c ", this->state);
- attr = this->state == 'R'
- ? CRT_colors[PROCESS_R_STATE]
+ case MAJFLT: Process_colorNumber(str, this->majflt, coloring); return;
+ case MINFLT: Process_colorNumber(str, this->minflt, coloring); return;
+ case M_RESIDENT: Process_humanNumber(str, this->m_resident * PAGE_SIZE_KB, coloring); return;
+ case M_SIZE: Process_humanNumber(str, this->m_size * PAGE_SIZE_KB, coloring); return;
+ case NICE: {
+ snprintf(buffer, n, "%3ld ", this->nice);
+ attr = this->nice < 0 ? CRT_colors[PROCESS_HIGH_PRIORITY]
+ : this->nice > 0 ? CRT_colors[PROCESS_LOW_PRIORITY]
: attr;
break;
}
+ case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
+ case PGRP: snprintf(buffer, n, Process_pidFormat, this->pgrp); break;
+ case PID: snprintf(buffer, n, Process_pidFormat, this->pid); break;
+ case PPID: snprintf(buffer, n, Process_pidFormat, this->ppid); break;
case PRIORITY: {
if(this->priority == -100)
snprintf(buffer, n, " RT ");
@@ -539,21 +431,26 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
snprintf(buffer, n, "%3ld ", this->priority);
break;
}
- case NICE: {
- snprintf(buffer, n, "%3ld ", this->nice);
- attr = this->nice < 0 ? CRT_colors[PROCESS_HIGH_PRIORITY]
- : this->nice > 0 ? CRT_colors[PROCESS_LOW_PRIORITY]
- : attr;
+ case PROCESSOR: snprintf(buffer, n, "%3d ", Settings_cpuId(this->settings, this->processor)); break;
+ case SESSION: snprintf(buffer, n, Process_pidFormat, this->session); break;
+ case STARTTIME: snprintf(buffer, n, "%s", this->starttime_show); break;
+ case STATE: {
+ snprintf(buffer, n, "%c ", this->state);
+ switch(this->state) {
+ case 'R':
+ attr = CRT_colors[PROCESS_R_STATE];
+ break;
+ case 'D':
+ attr = CRT_colors[PROCESS_D_STATE];
+ break;
+ }
break;
}
- case M_DRS: Process_humanNumber(str, this->m_drs * PAGE_SIZE_KB, coloring); return;
- case M_DT: Process_humanNumber(str, this->m_dt * PAGE_SIZE_KB, coloring); return;
- case M_LRS: Process_humanNumber(str, this->m_lrs * PAGE_SIZE_KB, coloring); return;
- case M_TRS: Process_humanNumber(str, this->m_trs * PAGE_SIZE_KB, coloring); return;
- case M_SIZE: Process_humanNumber(str, this->m_size * PAGE_SIZE_KB, coloring); return;
- case M_RESIDENT: Process_humanNumber(str, this->m_resident * PAGE_SIZE_KB, coloring); return;
- case M_SHARE: Process_humanNumber(str, this->m_share * PAGE_SIZE_KB, coloring); return;
case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break;
+ 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 USER: {
if (Process_getuid != (int) this->st_uid)
attr = CRT_colors[PROCESS_SHADOW];
@@ -568,128 +465,48 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
}
break;
}
- case UTIME: Process_printTime(str, this->utime); return;
- case STIME: Process_printTime(str, this->stime); return;
- case CUTIME: Process_printTime(str, this->cutime); return;
- case CSTIME: Process_printTime(str, this->cstime); return;
- case TIME: Process_printTime(str, this->utime + this->stime); return;
- case PERCENT_CPU: {
- if (this->percent_cpu > 999.9) {
- snprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu);
- } else if (this->percent_cpu > 99.9) {
- snprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu);
- } else {
- snprintf(buffer, n, "%4.1f ", this->percent_cpu);
- }
- break;
- }
- case PERCENT_MEM: {
- if (this->percent_mem > 99.9) {
- snprintf(buffer, n, "100. ");
- } else {
- snprintf(buffer, n, "%4.1f ", this->percent_mem);
- }
- break;
- }
- case STARTTIME: snprintf(buffer, n, "%s", this->starttime_show); break;
- #ifdef HAVE_OPENVZ
- case CTID: snprintf(buffer, n, "%5u ", this->ctid); break;
- case VPID: snprintf(buffer, n, "%5u ", this->vpid); break;
- #endif
- #ifdef HAVE_VSERVER
- case VXID: snprintf(buffer, n, "%5u ", this->vxid); break;
- #endif
- #ifdef HAVE_TASKSTATS
- case RCHAR: Process_colorNumber(str, this->io_rchar, coloring); return;
- case WCHAR: Process_colorNumber(str, this->io_wchar, coloring); return;
- case SYSCR: Process_colorNumber(str, this->io_syscr, coloring); return;
- case SYSCW: Process_colorNumber(str, this->io_syscw, coloring); return;
- case RBYTES: Process_colorNumber(str, this->io_read_bytes, coloring); return;
- case WBYTES: Process_colorNumber(str, this->io_write_bytes, coloring); return;
- case CNCLWB: Process_colorNumber(str, this->io_cancelled_write_bytes, coloring); return;
- case IO_READ_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_read_bps, coloring); return;
- case IO_WRITE_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_write_bps, coloring); return;
- case IO_RATE: Process_outputRate(str, attr, buffer, n, this->io_rate_read_bps + this->io_rate_write_bps, coloring); return;
- #endif
- #ifdef HAVE_CGROUP
- case CGROUP: snprintf(buffer, n, "%-10s ", this->cgroup); break;
- #endif
- #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, "- ");
}
RichString_append(str, attr, buffer);
}
-static void Process_display(Object* cast, RichString* out) {
+void Process_display(Object* cast, RichString* out) {
Process* this = (Process*) cast;
- ProcessField* fields = this->pl->fields;
+ ProcessField* fields = this->settings->fields;
RichString_prune(out);
for (int i = 0; fields[i]; i++)
- Process_writeField(this, out, fields[i]);
- if (this->pl->shadowOtherUsers && (int)this->st_uid != Process_getuid)
+ As_Process(this)->writeField(this, out, fields[i]);
+ if (this->settings->shadowOtherUsers && (int)this->st_uid != Process_getuid)
RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]);
if (this->tag == true)
RichString_setAttr(out, CRT_colors[PROCESS_TAG]);
assert(out->chlen > 0);
}
-void Process_delete(Object* cast) {
- Process* this = (Process*) cast;
+void Process_done(Process* this) {
assert (this != NULL);
- if (this->comm) free(this->comm);
-#ifdef HAVE_CGROUP
- if (this->cgroup) free(this->cgroup);
-#endif
- free(this);
+ free(this->comm);
}
-ObjectClass Process_class = {
- .extends = Class(Object),
- .display = Process_display,
- .delete = Process_delete,
- .compare = Process_compare
+ProcessClass Process_class = {
+ .super = {
+ .extends = Class(Object),
+ .display = Process_display,
+ .delete = Process_delete,
+ .compare = Process_compare
+ },
+ .writeField = Process_writeField,
};
-Process* Process_new(struct ProcessList_ *pl) {
- Process* this = calloc(1, sizeof(Process));
- Object_setClass(this, Class(Process));
- this->pid = 0;
- this->pl = pl;
+void Process_init(Process* this, struct Settings_* settings) {
+ this->settings = settings;
this->tag = false;
this->showChildren = true;
this->show = true;
this->updated = false;
- this->utime = 0;
- this->stime = 0;
- this->comm = NULL;
this->basenameOffset = -1;
- this->indent = 0;
-#ifdef HAVE_CGROUP
- this->cgroup = NULL;
-#endif
if (Process_getuid == -1) Process_getuid = getuid();
- return this;
}
void Process_toggleTag(Process* this) {
@@ -697,8 +514,11 @@ void Process_toggleTag(Process* this) {
}
bool Process_setPriority(Process* this, int priority) {
+ uid_t euid = geteuid();
+ seteuid(getuid());
int old_prio = getpriority(PRIO_PROCESS, this->pid);
int err = setpriority(PRIO_PROCESS, this->pid, priority);
+ seteuid(euid);
if (err == 0 && old_prio != getpriority(PRIO_PROCESS, this->pid)) {
this->nice = priority;
}
@@ -709,193 +529,81 @@ 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) {
- hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
- bool ok = (hwloc_linux_get_tid_cpubind(this->pl->topology, this->pid, cpuset) == 0);
- Affinity* affinity = NULL;
- if (ok) {
- affinity = Affinity_new();
- if (hwloc_bitmap_last(cpuset) == -1) {
- for (int i = 0; i < this->pl->cpuCount; i++) {
- Affinity_add(affinity, i);
- }
- } else {
- unsigned int id;
- hwloc_bitmap_foreach_begin(id, cpuset);
- Affinity_add(affinity, id);
- hwloc_bitmap_foreach_end();
- }
- }
- hwloc_bitmap_free(cpuset);
- return affinity;
-}
-
-bool Process_setAffinity(Process* this, Affinity* affinity) {
- hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
- for (int i = 0; i < affinity->used; i++) {
- hwloc_bitmap_set(cpuset, affinity->cpus[i]);
- }
- bool ok = (hwloc_linux_set_tid_cpubind(this->pl->topology, this->pid, cpuset) == 0);
- hwloc_bitmap_free(cpuset);
- return ok;
-}
-
-#elif HAVE_NATIVE_AFFINITY
-
-Affinity* Process_getAffinity(Process* this) {
- cpu_set_t cpuset;
- bool ok = (sched_getaffinity(this->pid, sizeof(cpu_set_t), &cpuset) == 0);
- if (!ok) return NULL;
- Affinity* affinity = Affinity_new();
- for (int i = 0; i < this->pl->cpuCount; i++) {
- if (CPU_ISSET(i, &cpuset))
- Affinity_add(affinity, i);
- }
- return affinity;
-}
-
-bool Process_setAffinity(Process* this, Affinity* affinity) {
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- for (int i = 0; i < affinity->used; i++) {
- CPU_SET(affinity->cpus[i], &cpuset);
- }
- bool ok = (sched_setaffinity(this->pid, sizeof(unsigned long), &cpuset) == 0);
- return ok;
-}
-
-#endif
-
void Process_sendSignal(Process* this, size_t sgn) {
+ uid_t euid = geteuid();
+ seteuid(getuid());
kill(this->pid, (int) sgn);
+ seteuid(euid);
}
-int Process_pidCompare(const void* v1, const void* v2) {
+long Process_pidCompare(const void* v1, const void* v2) {
Process* p1 = (Process*)v1;
Process* p2 = (Process*)v2;
return (p1->pid - p2->pid);
}
-int Process_compare(const void* v1, const void* v2) {
+long Process_compare(const void* v1, const void* v2) {
Process *p1, *p2;
- ProcessList *pl = ((Process*)v1)->pl;
- if (pl->direction == 1) {
+ Settings *settings = ((Process*)v1)->settings;
+ if (settings->direction == 1) {
p1 = (Process*)v1;
p2 = (Process*)v2;
} else {
p2 = (Process*)v1;
p1 = (Process*)v2;
}
- long long diff;
- switch (pl->sortKey) {
+ switch (settings->sortKey) {
+ case PERCENT_CPU:
+ return (p2->percent_cpu > p1->percent_cpu ? 1 : -1);
+ case PERCENT_MEM:
+ return (p2->m_resident - p1->m_resident);
+ case COMM:
+ return strcmp(p1->comm, p2->comm);
+ case MAJFLT:
+ return (p2->majflt - p1->majflt);
+ case MINFLT:
+ return (p2->minflt - p1->minflt);
+ case M_RESIDENT:
+ return (p2->m_resident - p1->m_resident);
+ case M_SIZE:
+ return (p2->m_size - p1->m_size);
+ case NICE:
+ return (p1->nice - p2->nice);
+ case NLWP:
+ return (p1->nlwp - p2->nlwp);
+ case PGRP:
+ return (p1->pgrp - p2->pgrp);
case PID:
return (p1->pid - p2->pid);
case PPID:
return (p1->ppid - p2->ppid);
- case USER:
- return strcmp(p1->user ? p1->user : "", p2->user ? p2->user : "");
case PRIORITY:
return (p1->priority - p2->priority);
case PROCESSOR:
return (p1->processor - p2->processor);
case SESSION:
return (p1->session - p2->session);
- case STATE:
- return (p1->state - p2->state);
- case NICE:
- return (p1->nice - p2->nice);
- case M_DRS:
- return (p2->m_drs - p1->m_drs);
- case M_DT:
- return (p2->m_dt - p1->m_dt);
- case M_LRS:
- return (p2->m_lrs - p1->m_lrs);
- case M_TRS:
- return (p2->m_trs - p1->m_trs);
- case M_SIZE:
- return (p2->m_size - p1->m_size);
- case M_RESIDENT:
- return (p2->m_resident - p1->m_resident);
- case M_SHARE:
- return (p2->m_share - p1->m_share);
- case PERCENT_CPU:
- return (p2->percent_cpu > p1->percent_cpu ? 1 : -1);
- case PERCENT_MEM:
- return (p2->m_resident - p1->m_resident);
- case UTIME:
- return (p2->utime - p1->utime);
- case STIME:
- return (p2->stime - p1->stime);
- case TIME:
- return ((p2->utime+p2->stime) - (p1->utime+p1->stime));
- case COMM:
- return strcmp(p1->comm, p2->comm);
- case NLWP:
- return (p1->nlwp - p2->nlwp);
case STARTTIME: {
if (p1->starttime_ctime == p2->starttime_ctime)
return (p1->pid - p2->pid);
else
return (p1->starttime_ctime - p2->starttime_ctime);
}
- #ifdef HAVE_OPENVZ
- case CTID:
- return (p1->ctid - p2->ctid);
- case VPID:
- return (p1->vpid - p2->vpid);
- #endif
- #ifdef HAVE_VSERVER
- case VXID:
- return (p1->vxid - p2->vxid);
- #endif
- #ifdef HAVE_TASKSTATS
- case RCHAR: diff = p2->io_rchar - p1->io_rchar; goto test_diff;
- case WCHAR: diff = p2->io_wchar - p1->io_wchar; goto test_diff;
- case SYSCR: diff = p2->io_syscr - p1->io_syscr; goto test_diff;
- case SYSCW: diff = p2->io_syscw - p1->io_syscw; goto test_diff;
- case RBYTES: diff = p2->io_read_bytes - p1->io_read_bytes; goto test_diff;
- case WBYTES: diff = p2->io_write_bytes - p1->io_write_bytes; goto test_diff;
- case CNCLWB: diff = p2->io_cancelled_write_bytes - p1->io_cancelled_write_bytes; goto test_diff;
- case IO_READ_RATE: diff = p2->io_rate_read_bps - p1->io_rate_read_bps; goto test_diff;
- case IO_WRITE_RATE: diff = p2->io_rate_write_bps - p1->io_rate_write_bps; goto test_diff;
- case IO_RATE: diff = (p2->io_rate_read_bps + p2->io_rate_write_bps) - (p1->io_rate_read_bps + p1->io_rate_write_bps); goto test_diff;
- #endif
- #ifdef HAVE_CGROUP
- case CGROUP:
- return strcmp(p1->cgroup ? p1->cgroup : "", p2->cgroup ? p2->cgroup : "");
- #endif
- #ifdef HAVE_OOM
- case OOM:
- return (p1->oom - p2->oom);
- #endif
- case IO_PRIORITY:
- return Process_effectiveIOPriority(p1) - Process_effectiveIOPriority(p2);
+ case STATE:
+ return (p1->state - p2->state);
+ case ST_UID:
+ return (p1->st_uid - p2->st_uid);
+ case TIME:
+ return ((p2->time) - (p1->time));
+ case TGID:
+ return (p1->tgid - p2->tgid);
+ case TPGID:
+ return (p1->tpgid - p2->tpgid);
+ case TTY_NR:
+ return (p1->tty_nr - p2->tty_nr);
+ case USER:
+ return strcmp(p1->user ? p1->user : "", p2->user ? p2->user : "");
default:
return (p1->pid - p2->pid);
}
- test_diff:
- return (diff > 0) ? 1 : (diff < 0 ? -1 : 0);
}

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