1 Commits
0.8.2 ... 0.6.4

Author SHA1 Message Date
0384613450 Tag release 0.6.4 in revision history 2006-10-06 23:07:46 +00:00
103 changed files with 1448 additions and 5803 deletions

View File

@ -1,49 +0,0 @@
#include "AffinityPanel.h"
#include "Panel.h"
#include "CheckItem.h"
#include "debug.h"
#include <assert.h>
static HandlerResult AffinityPanel_eventHandler(Panel* this, int ch) {
HandlerResult result = IGNORED;
CheckItem* selected = (CheckItem*) Panel_getSelected(this);
switch(ch) {
case KEY_MOUSE:
case ' ':
CheckItem_set(selected, ! (CheckItem_get(selected)) );
result = HANDLED;
break;
case 0x0a:
case 0x0d:
case KEY_ENTER:
result = BREAK_LOOP;
break;
}
return result;
}
Panel* AffinityPanel_new(int processorCount, unsigned long mask) {
Panel* this = Panel_new(1, 1, 1, 1, CHECKITEM_CLASS, true, ListItem_compare);
this->eventHandler = AffinityPanel_eventHandler;
Panel_setHeader(this, "Use CPUs:");
for (int i = 0; i < processorCount; i++) {
char number[10];
snprintf(number, 9, "%d", i+1);
Panel_add(this, (Object*) CheckItem_new(String_copy(number), NULL, mask & (1 << i)));
}
return this;
}
unsigned long AffinityPanel_getAffinity(Panel* this) {
int size = Panel_size(this);
unsigned long mask = 0;
for (int i = 0; i < size; i++) {
if (CheckItem_get((CheckItem*)Panel_get(this, i)))
mask = mask | (1 << i);
}
return mask;
}

View File

@ -1,17 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_AffinityPanel
#define HEADER_AffinityPanel
#include "Panel.h"
#include "CheckItem.h"
#include "debug.h"
#include <assert.h>
Panel* AffinityPanel_new(int processorCount, unsigned long mask);
unsigned long AffinityPanel_getAffinity(Panel* this);
#endif

View File

@ -22,34 +22,6 @@ typedef struct AvailableColumnsPanel_ {
}*/ }*/
static void AvailableColumnsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
AvailableColumnsPanel* this = (AvailableColumnsPanel*) object;
Panel_done(super);
free(this);
}
static HandlerResult AvailableColumnsPanel_eventHandler(Panel* super, int ch) {
AvailableColumnsPanel* this = (AvailableColumnsPanel*) super;
char* text = ((ListItem*) Panel_getSelected(super))->value;
HandlerResult result = IGNORED;
switch(ch) {
case 13:
case KEY_ENTER:
case KEY_F(5):
{
int at = Panel_getSelectedIndex(this->columns);
Panel_insert(this->columns, at, (Object*) ListItem_new(text, 0));
Panel_setSelected(this->columns, at+1);
ColumnsPanel_update(this->columns);
result = HANDLED;
break;
}
}
return result;
}
AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr) { AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr) {
AvailableColumnsPanel* this = (AvailableColumnsPanel*) malloc(sizeof(AvailableColumnsPanel)); AvailableColumnsPanel* this = (AvailableColumnsPanel*) malloc(sizeof(AvailableColumnsPanel));
Panel* super = (Panel*) this; Panel* super = (Panel*) this;
@ -69,3 +41,32 @@ AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* colu
this->columns = columns; this->columns = columns;
return this; return this;
} }
void AvailableColumnsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
AvailableColumnsPanel* this = (AvailableColumnsPanel*) object;
Panel_done(super);
free(this);
}
HandlerResult AvailableColumnsPanel_eventHandler(Panel* super, int ch) {
AvailableColumnsPanel* this = (AvailableColumnsPanel*) super;
char* text = ((ListItem*) Panel_getSelected(super))->value;
HandlerResult result = IGNORED;
switch(ch) {
case 13:
case KEY_ENTER:
case KEY_F(5):
{
int at = Panel_getSelectedIndex(this->columns) + 1;
if (at == Panel_getSize(this->columns))
at--;
Panel_insert(this->columns, at, (Object*) ListItem_new(text, 0));
ColumnsPanel_update(this->columns);
result = HANDLED;
break;
}
}
return result;
}

View File

@ -25,4 +25,8 @@ typedef struct AvailableColumnsPanel_ {
AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr); AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr);
void AvailableColumnsPanel_delete(Object* object);
HandlerResult AvailableColumnsPanel_eventHandler(Panel* super, int ch);
#endif #endif

View File

@ -23,7 +23,41 @@ typedef struct AvailableMetersPanel_ {
}*/ }*/
static void AvailableMetersPanel_delete(Object* object) { AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr) {
AvailableMetersPanel* this = (AvailableMetersPanel*) malloc(sizeof(AvailableMetersPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = AvailableMetersPanel_delete;
this->settings = settings;
this->leftPanel = leftMeters;
this->rightPanel = rightMeters;
this->scr = scr;
super->eventHandler = AvailableMetersPanel_EventHandler;
Panel_setHeader(super, "Available meters");
for (int i = 1; Meter_types[i]; i++) {
MeterType* type = Meter_types[i];
if (type != &CPUMeter) {
Panel_add(super, (Object*) ListItem_new(type->uiName, i << 16));
}
}
MeterType* type = &CPUMeter;
int processors = settings->pl->processorCount;
if (processors > 1) {
Panel_add(super, (Object*) ListItem_new("CPU average", 0));
for (int i = 1; i <= processors; i++) {
char buffer[50];
sprintf(buffer, "%s %d", type->uiName, i);
Panel_add(super, (Object*) ListItem_new(buffer, i));
}
} else {
Panel_add(super, (Object*) ListItem_new("CPU", 1));
}
return this;
}
void AvailableMetersPanel_delete(Object* object) {
Panel* super = (Panel*) object; Panel* super = (Panel*) object;
AvailableMetersPanel* this = (AvailableMetersPanel*) object; AvailableMetersPanel* this = (AvailableMetersPanel*) object;
Panel_done(super); Panel_done(super);
@ -35,7 +69,7 @@ static inline void AvailableMetersPanel_addHeader(Header* header, Panel* panel,
Panel_add(panel, (Object*) Meter_toListItem(meter)); Panel_add(panel, (Object*) Meter_toListItem(meter));
} }
static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) { HandlerResult AvailableMetersPanel_EventHandler(Panel* super, int ch) {
AvailableMetersPanel* this = (AvailableMetersPanel*) super; AvailableMetersPanel* this = (AvailableMetersPanel*) super;
Header* header = this->settings->header; Header* header = this->settings->header;
@ -70,37 +104,3 @@ static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) {
} }
return result; return result;
} }
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr) {
AvailableMetersPanel* this = (AvailableMetersPanel*) malloc(sizeof(AvailableMetersPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = AvailableMetersPanel_delete;
this->settings = settings;
this->leftPanel = leftMeters;
this->rightPanel = rightMeters;
this->scr = scr;
super->eventHandler = AvailableMetersPanel_eventHandler;
Panel_setHeader(super, "Available meters");
for (int i = 1; Meter_types[i]; i++) {
MeterType* type = Meter_types[i];
if (type != &CPUMeter) {
Panel_add(super, (Object*) ListItem_new(type->uiName, i << 16));
}
}
MeterType* type = &CPUMeter;
int processors = settings->pl->processorCount;
if (processors > 1) {
Panel_add(super, (Object*) ListItem_new("CPU average", 0));
for (int i = 1; i <= processors; i++) {
char buffer[50];
sprintf(buffer, "%s %d", type->uiName, i);
Panel_add(super, (Object*) ListItem_new(buffer, i));
}
} else {
Panel_add(super, (Object*) ListItem_new("CPU", 1));
}
return this;
}

View File

@ -26,4 +26,8 @@ typedef struct AvailableMetersPanel_ {
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr); AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr);
void AvailableMetersPanel_delete(Object* object);
HandlerResult AvailableMetersPanel_EventHandler(Panel* super, int ch);
#endif #endif

View File

@ -1,331 +0,0 @@
/*
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
This "Meter" written by Ian P. Hands (iphands@gmail.com, ihands@redhat.com).
*/
#include "BatteryMeter.h"
#include "Meter.h"
#include "ProcessList.h"
#include "CRT.h"
#include "String.h"
#include "debug.h"
/*{
typedef enum ACPresence_ {
AC_ABSENT,
AC_PRESENT,
AC_ERROR
} ACPresence;
}*/
int BatteryMeter_attributes[] = {
BATTERY
};
static unsigned long int parseUevent(FILE * file, char *key) {
char line[100];
unsigned long int dValue = 0;
while (fgets(line, sizeof line, file)) {
if (strncmp(line, key, strlen(key)) == 0) {
char *value;
value = strtok(line, "=");
value = strtok(NULL, "=");
dValue = atoi(value);
break;
}
}
return dValue;
}
static unsigned long int parseBatInfo(const char *fileName, const unsigned short int lineNum, const unsigned short int wordNum) {
const DIR *batteryDir;
const struct dirent *dirEntries;
const char batteryPath[] = PROCDIR "/acpi/battery/";
batteryDir = opendir(batteryPath);
if (batteryDir == NULL) {
return 0;
}
char *entryName;
typedef struct listLbl {
char *content;
struct listLbl *next;
} list;
list *myList = NULL;
list *newEntry;
/*
Some of this is based off of code found in kismet (they claim it came from gkrellm).
Written for multi battery use...
*/
for (dirEntries = readdir((DIR *) batteryDir); dirEntries; dirEntries = readdir((DIR *) batteryDir)) {
entryName = (char *) dirEntries->d_name;
if (strncmp(entryName, "BAT", 3))
continue;
newEntry = calloc(1, sizeof(list));
newEntry->next = myList;
newEntry->content = entryName;
myList = newEntry;
}
unsigned long int total = 0;
for (newEntry = myList; newEntry; newEntry = newEntry->next) {
const char infoPath[30];
const FILE *file;
char line[50];
snprintf((char *) infoPath, sizeof infoPath, "%s%s/%s", batteryPath, newEntry->content, fileName);
if ((file = fopen(infoPath, "r")) == NULL) {
return 0;
}
for (unsigned short int i = 0; i < lineNum; i++) {
fgets(line, sizeof line, (FILE *) file);
}
fclose((FILE *) file);
const char *foundNumTmp = String_getToken(line, wordNum);
const unsigned long int foundNum = atoi(foundNumTmp);
free((char *) foundNumTmp);
total += foundNum;
}
free(myList);
free(newEntry);
closedir((DIR *) batteryDir);
return total;
}
static ACPresence chkIsOnline() {
FILE *file = NULL;
ACPresence isOn = AC_ERROR;
if (access(PROCDIR "/acpi/ac_adapter", F_OK) == 0) {
const struct dirent *dirEntries;
char *power_supplyPath = PROCDIR "/acpi/ac_adapter";
DIR *power_supplyDir = opendir(power_supplyPath);
char *entryName;
if (!power_supplyDir) {
closedir(power_supplyDir);
return AC_ERROR;
}
for (dirEntries = readdir((DIR *) power_supplyDir); dirEntries; dirEntries = readdir((DIR *) power_supplyDir)) {
entryName = (char *) dirEntries->d_name;
if (strncmp(entryName, "A", 1)) {
continue;
}
char statePath[50];
snprintf((char *) statePath, sizeof statePath, "%s/%s/state", power_supplyPath, entryName);
file = fopen(statePath, "r");
if (!file) {
isOn = AC_ERROR;
continue;
}
char line[100];
fgets(line, sizeof line, file);
line[sizeof(line) - 1] = '\0';
if (file) {
fclose(file);
file = NULL;
}
const char *isOnline = String_getToken(line, 2);
if (strcmp(isOnline, "on-line") == 0) {
free((char *) isOnline);
isOn = AC_PRESENT;
// If any AC adapter is being used then stop
break;
} else {
isOn = AC_ABSENT;
}
free((char *) isOnline);
}
if (power_supplyDir)
closedir(power_supplyDir);
} else {
char *power_supplyPath = "/sys/class/power_supply";
if (access("/sys/class/power_supply", F_OK) == 0) {
const struct dirent *dirEntries;
DIR *power_supplyDir = opendir(power_supplyPath);
char *entryName;
if (!power_supplyDir) {
return AC_ERROR;
}
for (dirEntries = readdir((DIR *) power_supplyDir); dirEntries; dirEntries = readdir((DIR *) power_supplyDir)) {
entryName = (char *) dirEntries->d_name;
if (strncmp(entryName, "A", 1)) {
continue;
}
char onlinePath[50];
snprintf((char *) onlinePath, sizeof onlinePath, "%s/%s/online", power_supplyPath, entryName);
file = fopen(onlinePath, "r");
if (!file) {
isOn = AC_ERROR;
continue;
}
isOn = (fgetc(file) - '0');
if (file) {
fclose(file);
file = NULL;
}
if (isOn == AC_PRESENT) {
// If any AC adapter is being used then stop
break;
} else {
continue;
}
}
if (power_supplyDir)
closedir(power_supplyDir);
}
}
// Just in case :-)
if (file)
fclose(file);
return isOn;
}
static double getProcBatData() {
const unsigned long int totalFull = parseBatInfo("info", 3, 4);
if (totalFull == 0)
return 0;
const unsigned long int totalRemain = parseBatInfo("state", 5, 3);
if (totalRemain == 0)
return 0;
double percent = totalFull > 0 ? ((double) totalRemain * 100) / (double) totalFull : 0;
return percent;
}
static double getSysBatData() {
const struct dirent *dirEntries;
char *power_supplyPath = "/sys/class/power_supply/";
DIR *power_supplyDir = opendir(power_supplyPath);
if (!power_supplyDir) {
closedir(power_supplyDir);
return 0;
}
char *entryName;
unsigned long int totalFull = 0;
unsigned long int totalRemain = 0;
for (dirEntries = readdir((DIR *) power_supplyDir); dirEntries; dirEntries = readdir((DIR *) power_supplyDir)) {
entryName = (char *) dirEntries->d_name;
if (strncmp(entryName, "BAT", 3)) {
continue;
}
const char ueventPath[50];
snprintf((char *) ueventPath, sizeof ueventPath, "%s%s/uevent", power_supplyPath, entryName);
FILE *file;
if ((file = fopen(ueventPath, "r")) == NULL) {
closedir(power_supplyDir);
return 0;
}
totalFull += parseUevent(file, "POWER_SUPPLY_ENERGY_FULL=");
totalRemain += parseUevent(file, "POWER_SUPPLY_ENERGY_NOW=");
fclose(file);
}
const double percent = totalFull > 0 ? ((double) totalRemain * 100) / (double) totalFull : 0;
closedir(power_supplyDir);
return percent;
}
static void BatteryMeter_setValues(Meter * this, char *buffer, int len) {
double percent = getProcBatData();
if (percent == 0) {
percent = getSysBatData();
if (percent == 0) {
snprintf(buffer, len, "n/a");
return;
}
}
this->values[0] = percent;
char *onAcText, *onBatteryText, *unknownText;
unknownText = "%.1f%%";
if (this->mode == TEXT_METERMODE) {
onAcText = "%.1f%% (Running on A/C)";
onBatteryText = "%.1f%% (Running on battery)";
} else {
onAcText = "%.1f%%(A/C)";
onBatteryText = "%.1f%%(bat)";
}
ACPresence isOnLine = chkIsOnline();
if (isOnLine == AC_PRESENT) {
snprintf(buffer, len, onAcText, percent);
} else if (isOnLine == AC_ABSENT) {
snprintf(buffer, len, onBatteryText, percent);
} else {
snprintf(buffer, len, unknownText, percent);
}
return;
}
MeterType BatteryMeter = {
.setValues = BatteryMeter_setValues,
.display = NULL,
.mode = TEXT_METERMODE,
.items = 1,
.total = 100.0,
.attributes = BatteryMeter_attributes,
.name = "Battery",
.uiName = "Battery",
.caption = "Battery: "
};

View File

@ -19,125 +19,9 @@ in the source distribution for its full text.
#include <assert.h> #include <assert.h>
int CPUMeter_attributes[] = { int CPUMeter_attributes[] = {
CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IRQ, CPU_SOFTIRQ, CPU_IOWAIT CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IOWAIT, CPU_IRQ, CPU_SOFTIRQ
}; };
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
static void CPUMeter_init(Meter* this) {
int processor = this->param;
if (this->pl->processorCount > 1) {
char caption[10];
sprintf(caption, "%-3d", processor);
Meter_setCaption(this, caption);
}
if (this->param == 0)
Meter_setCaption(this, "Avg");
}
static void CPUMeter_setValues(Meter* this, char* buffer, int size) {
ProcessList* pl = this->pl;
int processor = this->param;
if (processor > this->pl->processorCount) {
snprintf(buffer, size, "absent");
return;
}
double total = (double) pl->totalPeriod[processor];
double cpu;
this->values[0] = pl->nicePeriod[processor] / total * 100.0;
this->values[1] = pl->userPeriod[processor] / total * 100.0;
if (pl->detailedCPUTime) {
this->values[2] = pl->systemPeriod[processor] / total * 100.0;
this->values[3] = pl->irqPeriod[processor] / total * 100.0;
this->values[4] = pl->softIrqPeriod[processor] / total * 100.0;
this->values[5] = pl->ioWaitPeriod[processor] / total * 100.0;
this->type->items = 6;
cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+
this->values[3]+this->values[4])));
} else {
this->values[2] = pl->systemAllPeriod[processor] / total * 100.0;
this->type->items = 3;
cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2])));
}
snprintf(buffer, size, "%5.1f%%", cpu );
}
static void CPUMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* this = (Meter*)cast;
RichString_init(out);
if (this->param > this->pl->processorCount) {
RichString_append(out, CRT_colors[METER_TEXT], "absent");
return;
}
sprintf(buffer, "%5.1f%% ", this->values[1]);
RichString_append(out, CRT_colors[METER_TEXT], ":");
RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
if (this->pl->detailedCPUTime) {
sprintf(buffer, "%5.1f%% ", this->values[2]);
RichString_append(out, CRT_colors[METER_TEXT], "sy:");
RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[0]);
RichString_append(out, CRT_colors[METER_TEXT], "ni:");
RichString_append(out, CRT_colors[CPU_NICE], buffer);
sprintf(buffer, "%5.1f%% ", this->values[3]);
RichString_append(out, CRT_colors[METER_TEXT], "hi:");
RichString_append(out, CRT_colors[CPU_IRQ], buffer);
sprintf(buffer, "%5.1f%% ", this->values[4]);
RichString_append(out, CRT_colors[METER_TEXT], "si:");
RichString_append(out, CRT_colors[CPU_SOFTIRQ], buffer);
sprintf(buffer, "%5.1f%% ", this->values[5]);
RichString_append(out, CRT_colors[METER_TEXT], "wa:");
RichString_append(out, CRT_colors[CPU_IOWAIT], buffer);
} else {
sprintf(buffer, "%5.1f%% ", this->values[2]);
RichString_append(out, CRT_colors[METER_TEXT], "sys:");
RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[0]);
RichString_append(out, CRT_colors[METER_TEXT], "low:");
RichString_append(out, CRT_colors[CPU_NICE], buffer);
}
}
static void AllCPUsMeter_init(Meter* this) {
int processors = this->pl->processorCount;
this->drawBuffer = malloc(sizeof(Meter*) * processors);
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++)
meters[i] = Meter_new(this->pl, i+1, &CPUMeter);
this->h = processors;
this->mode = BAR_METERMODE;
}
static void AllCPUsMeter_done(Meter* this) {
int processors = this->pl->processorCount;
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++)
Meter_delete((Object*)meters[i]);
}
static void AllCPUsMeter_setMode(Meter* this, int mode) {
this->mode = mode;
int processors = this->pl->processorCount;
int h = Meter_modes[this->mode]->h;
this->h = h * processors;
}
static void AllCPUsMeter_draw(Meter* this, int x, int y, int w) {
int processors = this->pl->processorCount;
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++) {
Meter_setMode(meters[i], this->mode);
meters[i]->draw(meters[i], x, y, w);
y += meters[i]->h;
}
}
MeterType CPUMeter = { MeterType CPUMeter = {
.setValues = CPUMeter_setValues, .setValues = CPUMeter_setValues,
.display = CPUMeter_display, .display = CPUMeter_display,
@ -164,3 +48,111 @@ MeterType AllCPUsMeter = {
.setMode = AllCPUsMeter_setMode, .setMode = AllCPUsMeter_setMode,
.done = AllCPUsMeter_done .done = AllCPUsMeter_done
}; };
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
void CPUMeter_init(Meter* this) {
int processor = this->param;
if (this->pl->processorCount > 1) {
char caption[10];
sprintf(caption, "%-3d", processor);
Meter_setCaption(this, caption);
}
if (this->param == 0)
Meter_setCaption(this, "Avg");
}
void CPUMeter_setValues(Meter* this, char* buffer, int size) {
ProcessList* pl = this->pl;
int processor = this->param;
double total = (double) pl->totalPeriod[processor];
double cpu;
this->values[0] = pl->nicePeriod[processor] / total * 100.0;
this->values[1] = pl->userPeriod[processor] / total * 100.0;
if (pl->expandSystemTime) {
this->values[2] = pl->systemPeriod[processor] / total * 100.0;
this->values[3] = pl->ioWaitPeriod[processor] / total * 100.0;
this->values[4] = pl->irqPeriod[processor] / total * 100.0;
this->values[5] = pl->softIrqPeriod[processor] / total * 100.0;
this->type->items = 6;
cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+
this->values[3]+this->values[4]+this->values[5])));
} else {
this->values[2] = pl->systemAllPeriod[processor] / total * 100.0;
this->type->items = 3;
cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2])));
}
snprintf(buffer, size, "%5.1f%%", cpu );
}
void CPUMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* this = (Meter*)cast;
RichString_init(out);
sprintf(buffer, "%5.1f%% ", this->values[1]);
RichString_append(out, CRT_colors[METER_TEXT], ":");
RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
if (this->pl->expandSystemTime) {
sprintf(buffer, "%5.1f%% ", this->values[2]);
RichString_append(out, CRT_colors[METER_TEXT], "sy:");
RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[0]);
RichString_append(out, CRT_colors[METER_TEXT], "ni:");
RichString_append(out, CRT_colors[CPU_NICE], buffer);
sprintf(buffer, "%5.1f%% ", this->values[3]);
RichString_append(out, CRT_colors[METER_TEXT], "wa:");
RichString_append(out, CRT_colors[CPU_IOWAIT], buffer);
sprintf(buffer, "%5.1f%% ", this->values[4]);
RichString_append(out, CRT_colors[METER_TEXT], "hi:");
RichString_append(out, CRT_colors[CPU_IRQ], buffer);
sprintf(buffer, "%5.1f%% ", this->values[4]);
RichString_append(out, CRT_colors[METER_TEXT], "si:");
RichString_append(out, CRT_colors[CPU_SOFTIRQ], buffer);
} else {
sprintf(buffer, "%5.1f%% ", this->values[2]);
RichString_append(out, CRT_colors[METER_TEXT], "sys:");
RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[0]);
RichString_append(out, CRT_colors[METER_TEXT], "low:");
RichString_append(out, CRT_colors[CPU_NICE], buffer);
}
}
void AllCPUsMeter_init(Meter* this) {
int processors = this->pl->processorCount;
this->drawBuffer = malloc(sizeof(Meter*) * processors);
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++)
meters[i] = Meter_new(this->pl, i+1, &CPUMeter);
this->h = processors;
this->mode = BAR_METERMODE;
}
void AllCPUsMeter_done(Meter* this) {
int processors = this->pl->processorCount;
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++)
Meter_delete((Object*)meters[i]);
}
void AllCPUsMeter_setMode(Meter* this, int mode) {
this->mode = mode;
int processors = this->pl->processorCount;
int h = Meter_modes[this->mode]->h;
this->h = h * processors;
}
void AllCPUsMeter_draw(Meter* this, int x, int y, int w) {
int processors = this->pl->processorCount;
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++) {
Meter_setMode(meters[i], this->mode);
meters[i]->draw(meters[i], x, y, w);
y += meters[i]->h;
}
}

View File

@ -23,6 +23,10 @@ in the source distribution for its full text.
extern int CPUMeter_attributes[]; extern int CPUMeter_attributes[];
extern MeterType CPUMeter;
extern MeterType AllCPUsMeter;
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
#endif #endif
@ -30,8 +34,18 @@ extern int CPUMeter_attributes[];
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
extern MeterType CPUMeter; void CPUMeter_init(Meter* this);
extern MeterType AllCPUsMeter; void CPUMeter_setValues(Meter* this, char* buffer, int size);
void CPUMeter_display(Object* cast, RichString* out);
void AllCPUsMeter_init(Meter* this);
void AllCPUsMeter_done(Meter* this);
void AllCPUsMeter_setMode(Meter* this, int mode);
void AllCPUsMeter_draw(Meter* this, int x, int y, int w);
#endif #endif

73
CRT.c
View File

@ -14,7 +14,6 @@ in the source distribution for its full text.
#include "String.h" #include "String.h"
#include "config.h"
#include "debug.h" #include "debug.h"
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j) #define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
@ -56,7 +55,6 @@ typedef enum ColorElements_ {
METER_VALUE, METER_VALUE,
LED_COLOR, LED_COLOR,
UPTIME, UPTIME,
BATTERY,
TASKS_TOTAL, TASKS_TOTAL,
TASKS_RUNNING, TASKS_RUNNING,
SWAP, SWAP,
@ -69,8 +67,6 @@ typedef enum ColorElements_ {
PROCESS_BASENAME, PROCESS_BASENAME,
PROCESS_HIGH_PRIORITY, PROCESS_HIGH_PRIORITY,
PROCESS_LOW_PRIORITY, PROCESS_LOW_PRIORITY,
PROCESS_THREAD,
PROCESS_THREAD_BASENAME,
BAR_BORDER, BAR_BORDER,
BAR_SHADOW, BAR_SHADOW,
GRAPH_1, GRAPH_1,
@ -100,7 +96,6 @@ typedef enum ColorElements_ {
CPU_IOWAIT, CPU_IOWAIT,
CPU_IRQ, CPU_IRQ,
CPU_SOFTIRQ, CPU_SOFTIRQ,
HOSTNAME,
LAST_COLORELEMENT LAST_COLORELEMENT
} ColorElements; } ColorElements;
@ -116,17 +111,6 @@ int CRT_colors[LAST_COLORELEMENT] = { 0 };
char* CRT_termType; char* CRT_termType;
static void CRT_handleSIGSEGV(int signal) {
CRT_done();
fprintf(stderr, "htop " VERSION " aborted. Please report bug at http://htop.sf.net\n");
exit(1);
}
static void CRT_handleSIGTERM(int signal) {
CRT_done();
exit(0);
}
// TODO: pass an instance of Settings instead. // TODO: pass an instance of Settings instead.
void CRT_init(int delay, int colorScheme) { void CRT_init(int delay, int colorScheme) {
@ -195,6 +179,17 @@ void CRT_enableDelay() {
halfdelay(CRT_delay); halfdelay(CRT_delay);
} }
void CRT_handleSIGSEGV(int signal) {
CRT_done();
fprintf(stderr, "Aborted. Please report bug at http://htop.sf.net");
exit(1);
}
void CRT_handleSIGTERM(int signal) {
CRT_done();
exit(0);
}
void CRT_setColors(int colorScheme) { void CRT_setColors(int colorScheme) {
CRT_colorScheme = colorScheme; CRT_colorScheme = colorScheme;
if (colorScheme == COLORSCHEME_BLACKNIGHT) { if (colorScheme == COLORSCHEME_BLACKNIGHT) {
@ -214,11 +209,10 @@ void CRT_setColors(int colorScheme) {
CRT_colors[FUNCTION_KEY] = A_NORMAL; CRT_colors[FUNCTION_KEY] = A_NORMAL;
CRT_colors[PANEL_HEADER_FOCUS] = A_REVERSE; CRT_colors[PANEL_HEADER_FOCUS] = A_REVERSE;
CRT_colors[PANEL_HEADER_UNFOCUS] = A_REVERSE; CRT_colors[PANEL_HEADER_UNFOCUS] = A_REVERSE;
CRT_colors[PANEL_HIGHLIGHT_FOCUS] = A_REVERSE; CRT_colors[PANEL_HIGHLIGHT_FOCUS] = A_REVERSE | A_BOLD;
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD; CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_REVERSE;
CRT_colors[FAILED_SEARCH] = A_REVERSE | A_BOLD; CRT_colors[FAILED_SEARCH] = A_REVERSE | A_BOLD;
CRT_colors[UPTIME] = A_BOLD; CRT_colors[UPTIME] = A_BOLD;
CRT_colors[BATTERY] = A_BOLD;
CRT_colors[LARGE_NUMBER] = A_BOLD; CRT_colors[LARGE_NUMBER] = A_BOLD;
CRT_colors[METER_TEXT] = A_NORMAL; CRT_colors[METER_TEXT] = A_NORMAL;
CRT_colors[METER_VALUE] = A_BOLD; CRT_colors[METER_VALUE] = A_BOLD;
@ -233,8 +227,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_R_STATE] = A_BOLD; CRT_colors[PROCESS_R_STATE] = A_BOLD;
CRT_colors[PROCESS_HIGH_PRIORITY] = A_BOLD; CRT_colors[PROCESS_HIGH_PRIORITY] = A_BOLD;
CRT_colors[PROCESS_LOW_PRIORITY] = A_DIM; CRT_colors[PROCESS_LOW_PRIORITY] = A_DIM;
CRT_colors[PROCESS_THREAD] = A_BOLD;
CRT_colors[PROCESS_THREAD_BASENAME] = A_REVERSE;
CRT_colors[BAR_BORDER] = A_BOLD; CRT_colors[BAR_BORDER] = A_BOLD;
CRT_colors[BAR_SHADOW] = A_DIM; CRT_colors[BAR_SHADOW] = A_DIM;
CRT_colors[SWAP] = A_BOLD; CRT_colors[SWAP] = A_BOLD;
@ -262,10 +254,9 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = A_BOLD; CRT_colors[CHECK_BOX] = A_BOLD;
CRT_colors[CHECK_MARK] = A_NORMAL; CRT_colors[CHECK_MARK] = A_NORMAL;
CRT_colors[CHECK_TEXT] = A_NORMAL; CRT_colors[CHECK_TEXT] = A_NORMAL;
CRT_colors[CPU_IOWAIT] = A_NORMAL; CRT_colors[CPU_IOWAIT] = A_BOLD;
CRT_colors[CPU_IRQ] = A_BOLD; CRT_colors[CPU_IRQ] = A_BOLD;
CRT_colors[CPU_SOFTIRQ] = A_BOLD; CRT_colors[CPU_SOFTIRQ] = A_BOLD;
CRT_colors[HOSTNAME] = A_BOLD;
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE) { } else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE) {
CRT_colors[RESET_COLOR] = ColorPair(Black,White); CRT_colors[RESET_COLOR] = ColorPair(Black,White);
CRT_colors[DEFAULT_COLOR] = ColorPair(Black,White); CRT_colors[DEFAULT_COLOR] = ColorPair(Black,White);
@ -277,7 +268,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,White); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,White);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = ColorPair(Yellow,White); CRT_colors[UPTIME] = ColorPair(Yellow,White);
CRT_colors[BATTERY] = ColorPair(Yellow,White);
CRT_colors[LARGE_NUMBER] = ColorPair(Red,White); CRT_colors[LARGE_NUMBER] = ColorPair(Red,White);
CRT_colors[METER_TEXT] = ColorPair(Blue,White); CRT_colors[METER_TEXT] = ColorPair(Blue,White);
CRT_colors[METER_VALUE] = ColorPair(Black,White); CRT_colors[METER_VALUE] = ColorPair(Black,White);
@ -287,13 +277,11 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_SHADOW] = A_BOLD | ColorPair(Black,White); CRT_colors[PROCESS_SHADOW] = A_BOLD | ColorPair(Black,White);
CRT_colors[PROCESS_TAG] = ColorPair(White,Blue); CRT_colors[PROCESS_TAG] = ColorPair(White,Blue);
CRT_colors[PROCESS_MEGABYTES] = ColorPair(Blue,White); CRT_colors[PROCESS_MEGABYTES] = ColorPair(Blue,White);
CRT_colors[PROCESS_BASENAME] = ColorPair(Blue,White); CRT_colors[PROCESS_BASENAME] = ColorPair(Green,White);
CRT_colors[PROCESS_TREE] = ColorPair(Green,White); CRT_colors[PROCESS_TREE] = ColorPair(Blue,White);
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,White); CRT_colors[PROCESS_R_STATE] = ColorPair(Green,White);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,White); CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,White);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,White); CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,White);
CRT_colors[PROCESS_THREAD] = ColorPair(Blue,White);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,White);
CRT_colors[BAR_BORDER] = ColorPair(Blue,White); CRT_colors[BAR_BORDER] = ColorPair(Blue,White);
CRT_colors[BAR_SHADOW] = ColorPair(Black,White); CRT_colors[BAR_SHADOW] = ColorPair(Black,White);
CRT_colors[SWAP] = ColorPair(Red,White); CRT_colors[SWAP] = ColorPair(Red,White);
@ -317,14 +305,13 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CPU_NICE] = ColorPair(Cyan,White); CRT_colors[CPU_NICE] = ColorPair(Cyan,White);
CRT_colors[CPU_NORMAL] = ColorPair(Green,White); CRT_colors[CPU_NORMAL] = ColorPair(Green,White);
CRT_colors[CPU_KERNEL] = ColorPair(Red,White); CRT_colors[CPU_KERNEL] = ColorPair(Red,White);
CRT_colors[CLOCK] = ColorPair(Black,White); CRT_colors[CLOCK] = ColorPair(White,White);
CRT_colors[CHECK_BOX] = ColorPair(Blue,White); CRT_colors[CHECK_BOX] = ColorPair(Blue,White);
CRT_colors[CHECK_MARK] = ColorPair(Black,White); CRT_colors[CHECK_MARK] = ColorPair(Black,White);
CRT_colors[CHECK_TEXT] = ColorPair(Black,White); CRT_colors[CHECK_TEXT] = ColorPair(Black,White);
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black); CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,White);
CRT_colors[CPU_IRQ] = ColorPair(Blue,White); CRT_colors[CPU_IRQ] = ColorPair(Blue,White);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,White); CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,White);
CRT_colors[HOSTNAME] = ColorPair(Black,White);
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE2) { } else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE2) {
CRT_colors[RESET_COLOR] = ColorPair(Black,Black); CRT_colors[RESET_COLOR] = ColorPair(Black,Black);
CRT_colors[DEFAULT_COLOR] = ColorPair(Black,Black); CRT_colors[DEFAULT_COLOR] = ColorPair(Black,Black);
@ -336,7 +323,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,Black); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,Black);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = ColorPair(Yellow,Black); CRT_colors[UPTIME] = ColorPair(Yellow,Black);
CRT_colors[BATTERY] = ColorPair(Yellow,Black);
CRT_colors[LARGE_NUMBER] = ColorPair(Red,Black); CRT_colors[LARGE_NUMBER] = ColorPair(Red,Black);
CRT_colors[METER_TEXT] = ColorPair(Blue,Black); CRT_colors[METER_TEXT] = ColorPair(Blue,Black);
CRT_colors[METER_VALUE] = ColorPair(Black,Black); CRT_colors[METER_VALUE] = ColorPair(Black,Black);
@ -351,8 +337,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black); CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black); CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black); CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_THREAD] = ColorPair(Blue,Black);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[BAR_BORDER] = ColorPair(Blue,Black); CRT_colors[BAR_BORDER] = ColorPair(Blue,Black);
CRT_colors[BAR_SHADOW] = ColorPair(Black,Black); CRT_colors[BAR_SHADOW] = ColorPair(Black,Black);
CRT_colors[SWAP] = ColorPair(Red,Black); CRT_colors[SWAP] = ColorPair(Red,Black);
@ -380,10 +364,9 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = ColorPair(Blue,Black); CRT_colors[CHECK_BOX] = ColorPair(Blue,Black);
CRT_colors[CHECK_MARK] = ColorPair(Black,Black); CRT_colors[CHECK_MARK] = ColorPair(Black,Black);
CRT_colors[CHECK_TEXT] = ColorPair(Black,Black); CRT_colors[CHECK_TEXT] = ColorPair(Black,Black);
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black); CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black); CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black); CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black);
CRT_colors[HOSTNAME] = ColorPair(White,Black);
} else if (CRT_colorScheme == COLORSCHEME_MIDNIGHT) { } else if (CRT_colorScheme == COLORSCHEME_MIDNIGHT) {
CRT_colors[RESET_COLOR] = ColorPair(White,Blue); CRT_colors[RESET_COLOR] = ColorPair(White,Blue);
CRT_colors[DEFAULT_COLOR] = ColorPair(White,Blue); CRT_colors[DEFAULT_COLOR] = ColorPair(White,Blue);
@ -395,7 +378,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD | ColorPair(Yellow,Blue); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = A_BOLD | ColorPair(Yellow,Blue); CRT_colors[UPTIME] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[BATTERY] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Blue); CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Blue);
CRT_colors[METER_TEXT] = ColorPair(Cyan,Blue); CRT_colors[METER_TEXT] = ColorPair(Cyan,Blue);
CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Blue); CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Blue);
@ -410,8 +392,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Blue); CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Blue);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Blue); CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Blue);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Blue); CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Blue);
CRT_colors[PROCESS_THREAD] = ColorPair(Green,Blue);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green,Blue);
CRT_colors[BAR_BORDER] = A_BOLD | ColorPair(Yellow,Blue); CRT_colors[BAR_BORDER] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[BAR_SHADOW] = ColorPair(Cyan,Blue); CRT_colors[BAR_SHADOW] = ColorPair(Cyan,Blue);
CRT_colors[SWAP] = ColorPair(Red,Blue); CRT_colors[SWAP] = ColorPair(Red,Blue);
@ -439,10 +419,9 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = ColorPair(Cyan,Blue); CRT_colors[CHECK_BOX] = ColorPair(Cyan,Blue);
CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(White,Blue); CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(White,Blue);
CRT_colors[CHECK_TEXT] = A_NORMAL | ColorPair(White,Blue); CRT_colors[CHECK_TEXT] = A_NORMAL | ColorPair(White,Blue);
CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Blue); CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Black,Blue); CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Black,Blue);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Black,Blue); CRT_colors[CPU_SOFTIRQ] = ColorPair(Black,Blue);
CRT_colors[HOSTNAME] = ColorPair(White,Blue);
} else if (CRT_colorScheme == COLORSCHEME_BLACKNIGHT) { } else if (CRT_colorScheme == COLORSCHEME_BLACKNIGHT) {
CRT_colors[RESET_COLOR] = ColorPair(Cyan,Black); CRT_colors[RESET_COLOR] = ColorPair(Cyan,Black);
CRT_colors[DEFAULT_COLOR] = ColorPair(Cyan,Black); CRT_colors[DEFAULT_COLOR] = ColorPair(Cyan,Black);
@ -454,7 +433,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = ColorPair(Green,Black); CRT_colors[UPTIME] = ColorPair(Green,Black);
CRT_colors[BATTERY] = ColorPair(Green,Black);
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black); CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black);
CRT_colors[METER_TEXT] = ColorPair(Cyan,Black); CRT_colors[METER_TEXT] = ColorPair(Cyan,Black);
CRT_colors[METER_VALUE] = ColorPair(Green,Black); CRT_colors[METER_VALUE] = ColorPair(Green,Black);
@ -466,8 +444,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_MEGABYTES] = A_BOLD | ColorPair(Green,Black); CRT_colors[PROCESS_MEGABYTES] = A_BOLD | ColorPair(Green,Black);
CRT_colors[PROCESS_BASENAME] = A_BOLD | ColorPair(Green,Black); CRT_colors[PROCESS_BASENAME] = A_BOLD | ColorPair(Green,Black);
CRT_colors[PROCESS_TREE] = ColorPair(Cyan,Black); CRT_colors[PROCESS_TREE] = ColorPair(Cyan,Black);
CRT_colors[PROCESS_THREAD] = ColorPair(Green,Black);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black); CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black); CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black); CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
@ -494,14 +470,13 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CPU_NICE] = ColorPair(Blue,Black); CRT_colors[CPU_NICE] = ColorPair(Blue,Black);
CRT_colors[CPU_NORMAL] = ColorPair(Green,Black); CRT_colors[CPU_NORMAL] = ColorPair(Green,Black);
CRT_colors[CPU_KERNEL] = ColorPair(Red,Black); CRT_colors[CPU_KERNEL] = ColorPair(Red,Black);
CRT_colors[CLOCK] = ColorPair(Green,Black); CRT_colors[CLOCK] = A_BOLD;
CRT_colors[CHECK_BOX] = ColorPair(Green,Black); CRT_colors[CHECK_BOX] = ColorPair(Green,Black);
CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(Green,Black); CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(Green,Black);
CRT_colors[CHECK_TEXT] = ColorPair(Cyan,Black); CRT_colors[CHECK_TEXT] = ColorPair(Cyan,Black);
CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black); CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black); CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black); CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black);
CRT_colors[HOSTNAME] = ColorPair(Green,Black);
} else { } else {
/* Default */ /* Default */
CRT_colors[RESET_COLOR] = ColorPair(White,Black); CRT_colors[RESET_COLOR] = ColorPair(White,Black);
@ -514,7 +489,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = A_BOLD | ColorPair(Cyan,Black); CRT_colors[UPTIME] = A_BOLD | ColorPair(Cyan,Black);
CRT_colors[BATTERY] = A_BOLD | ColorPair(Cyan,Black);
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black); CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black);
CRT_colors[METER_TEXT] = ColorPair(Cyan,Black); CRT_colors[METER_TEXT] = ColorPair(Cyan,Black);
CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Black); CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Black);
@ -529,8 +503,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black); CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black); CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black); CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_THREAD] = ColorPair(Green,Black);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green,Black);
CRT_colors[BAR_BORDER] = A_BOLD; CRT_colors[BAR_BORDER] = A_BOLD;
CRT_colors[BAR_SHADOW] = A_BOLD | ColorPair(Black,Black); CRT_colors[BAR_SHADOW] = A_BOLD | ColorPair(Black,Black);
CRT_colors[SWAP] = ColorPair(Red,Black); CRT_colors[SWAP] = ColorPair(Red,Black);
@ -558,9 +530,8 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = ColorPair(Cyan,Black); CRT_colors[CHECK_BOX] = ColorPair(Cyan,Black);
CRT_colors[CHECK_MARK] = A_BOLD; CRT_colors[CHECK_MARK] = A_BOLD;
CRT_colors[CHECK_TEXT] = A_NORMAL; CRT_colors[CHECK_TEXT] = A_NORMAL;
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black); CRT_colors[CPU_IOWAIT] = ColorPair(Cyan,Black);
CRT_colors[CPU_IRQ] = ColorPair(Yellow,Black); CRT_colors[CPU_IRQ] = ColorPair(Yellow,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Magenta,Black); CRT_colors[CPU_SOFTIRQ] = ColorPair(Magenta,Black);
CRT_colors[HOSTNAME] = A_BOLD;
} }
} }

9
CRT.h
View File

@ -17,7 +17,6 @@ in the source distribution for its full text.
#include "String.h" #include "String.h"
#include "config.h"
#include "debug.h" #include "debug.h"
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j) #define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
@ -58,7 +57,6 @@ typedef enum ColorElements_ {
METER_VALUE, METER_VALUE,
LED_COLOR, LED_COLOR,
UPTIME, UPTIME,
BATTERY,
TASKS_TOTAL, TASKS_TOTAL,
TASKS_RUNNING, TASKS_RUNNING,
SWAP, SWAP,
@ -71,8 +69,6 @@ typedef enum ColorElements_ {
PROCESS_BASENAME, PROCESS_BASENAME,
PROCESS_HIGH_PRIORITY, PROCESS_HIGH_PRIORITY,
PROCESS_LOW_PRIORITY, PROCESS_LOW_PRIORITY,
PROCESS_THREAD,
PROCESS_THREAD_BASENAME,
BAR_BORDER, BAR_BORDER,
BAR_SHADOW, BAR_SHADOW,
GRAPH_1, GRAPH_1,
@ -102,7 +98,6 @@ typedef enum ColorElements_ {
CPU_IOWAIT, CPU_IOWAIT,
CPU_IRQ, CPU_IRQ,
CPU_SOFTIRQ, CPU_SOFTIRQ,
HOSTNAME,
LAST_COLORELEMENT LAST_COLORELEMENT
} ColorElements; } ColorElements;
@ -129,6 +124,10 @@ void CRT_disableDelay();
void CRT_enableDelay(); void CRT_enableDelay();
void CRT_handleSIGSEGV(int signal);
void CRT_handleSIGTERM(int signal);
void CRT_setColors(int colorScheme); void CRT_setColors(int colorScheme);
#endif #endif

View File

@ -23,98 +23,17 @@ typedef struct CategoriesPanel_ {
}*/ }*/
static char* MetersFunctions[] = {" ", " ", " ", "Type ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done ", NULL}; static char* MetersFunctions[10] = {" ", " ", " ", "Type ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done "};
static char* AvailableMetersFunctions[] = {" ", " ", " ", " ", "Add L ", "Add R ", " ", " ", " ", "Done ", NULL}; static char* AvailableMetersFunctions[10] = {" ", " ", " ", " ", "Add L ", "Add R ", " ", " ", " ", "Done "};
static char* DisplayOptionsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL}; static char* DisplayOptionsFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
static char* ColumnsFunctions[] = {" ", " ", " ", " ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done ", NULL}; static char* ColumnsFunctions[10] = {" ", " ", " ", " ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done "};
static char* ColorsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL}; static char* ColorsFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
static char* AvailableColumnsFunctions[] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done ", NULL}; static char* AvailableColumnsFunctions[10] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done "};
static void CategoriesPanel_delete(Object* object) {
Panel* super = (Panel*) object;
CategoriesPanel* this = (CategoriesPanel*) object;
Panel_done(super);
free(this);
}
void CategoriesPanel_makeMetersPage(CategoriesPanel* this) {
Panel* leftMeters = (Panel*) MetersPanel_new(this->settings, "Left column", this->settings->header->leftMeters, this->scr);
Panel* rightMeters = (Panel*) MetersPanel_new(this->settings, "Right column", this->settings->header->rightMeters, this->scr);
Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->settings, leftMeters, rightMeters, this->scr);
ScreenManager_add(this->scr, leftMeters, FunctionBar_new(MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, rightMeters, FunctionBar_new(MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableMeters, FunctionBar_new(AvailableMetersFunctions, NULL, NULL), -1);
}
static void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this) {
Panel* displayOptions = (Panel*) DisplayOptionsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, displayOptions, FunctionBar_new(DisplayOptionsFunctions, NULL, NULL), -1);
}
static void CategoriesPanel_makeColorsPage(CategoriesPanel* this) {
Panel* colors = (Panel*) ColorsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, colors, FunctionBar_new(ColorsFunctions, NULL, NULL), -1);
}
static void CategoriesPanel_makeColumnsPage(CategoriesPanel* this) {
Panel* columns = (Panel*) ColumnsPanel_new(this->settings, this->scr);
Panel* availableColumns = (Panel*) AvailableColumnsPanel_new(this->settings, columns, this->scr);
ScreenManager_add(this->scr, columns, FunctionBar_new(ColumnsFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableColumns, FunctionBar_new(AvailableColumnsFunctions, NULL, NULL), -1);
}
static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
CategoriesPanel* this = (CategoriesPanel*) super;
HandlerResult result = IGNORED;
int selected = Panel_getSelectedIndex(super);
switch (ch) {
case EVENT_SETSELECTED:
result = HANDLED;
break;
case KEY_UP:
case KEY_DOWN:
case KEY_NPAGE:
case KEY_PPAGE:
case KEY_HOME:
case KEY_END: {
int previous = selected;
Panel_onKey(super, ch);
selected = Panel_getSelectedIndex(super);
if (previous != selected)
result = HANDLED;
break;
}
}
if (result == HANDLED) {
int size = ScreenManager_size(this->scr);
for (int i = 1; i < size; i++)
ScreenManager_remove(this->scr, 1);
switch (selected) {
case 0:
CategoriesPanel_makeMetersPage(this);
break;
case 1:
CategoriesPanel_makeDisplayOptionsPage(this);
break;
case 2:
CategoriesPanel_makeColorsPage(this);
break;
case 3:
CategoriesPanel_makeColumnsPage(this);
break;
}
}
return result;
}
CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr) { CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr) {
CategoriesPanel* this = (CategoriesPanel*) malloc(sizeof(CategoriesPanel)); CategoriesPanel* this = (CategoriesPanel*) malloc(sizeof(CategoriesPanel));
@ -132,3 +51,78 @@ CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr) {
Panel_add(super, (Object*) ListItem_new("Columns", 0)); Panel_add(super, (Object*) ListItem_new("Columns", 0));
return this; return this;
} }
void CategoriesPanel_delete(Object* object) {
Panel* super = (Panel*) object;
CategoriesPanel* this = (CategoriesPanel*) object;
Panel_done(super);
free(this);
}
HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
CategoriesPanel* this = (CategoriesPanel*) super;
HandlerResult result = IGNORED;
int previous = Panel_getSelectedIndex(super);
switch (ch) {
case KEY_UP:
case KEY_DOWN:
case KEY_NPAGE:
case KEY_PPAGE:
case KEY_HOME:
case KEY_END: {
Panel_onKey(super, ch);
int selected = Panel_getSelectedIndex(super);
if (previous != selected) {
int size = ScreenManager_size(this->scr);
for (int i = 1; i < size; i++)
ScreenManager_remove(this->scr, 1);
switch (selected) {
case 0:
CategoriesPanel_makeMetersPage(this);
break;
case 1:
CategoriesPanel_makeDisplayOptionsPage(this);
break;
case 2:
CategoriesPanel_makeColorsPage(this);
break;
case 3:
CategoriesPanel_makeColumnsPage(this);
break;
}
}
result = HANDLED;
}
}
return result;
}
void CategoriesPanel_makeMetersPage(CategoriesPanel* this) {
Panel* leftMeters = (Panel*) MetersPanel_new(this->settings, "Left column", this->settings->header->leftMeters, this->scr);
Panel* rightMeters = (Panel*) MetersPanel_new(this->settings, "Right column", this->settings->header->rightMeters, this->scr);
Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->settings, leftMeters, rightMeters, this->scr);
ScreenManager_add(this->scr, leftMeters, FunctionBar_new(10, MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, rightMeters, FunctionBar_new(10, MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableMeters, FunctionBar_new(10, AvailableMetersFunctions, NULL, NULL), -1);
}
void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this) {
Panel* displayOptions = (Panel*) DisplayOptionsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, displayOptions, FunctionBar_new(10, DisplayOptionsFunctions, NULL, NULL), -1);
}
void CategoriesPanel_makeColorsPage(CategoriesPanel* this) {
Panel* colors = (Panel*) ColorsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, colors, FunctionBar_new(10, ColorsFunctions, NULL, NULL), -1);
}
void CategoriesPanel_makeColumnsPage(CategoriesPanel* this) {
Panel* columns = (Panel*) ColumnsPanel_new(this->settings, this->scr);
Panel* availableColumns = (Panel*) AvailableColumnsPanel_new(this->settings, columns, this->scr);
ScreenManager_add(this->scr, columns, FunctionBar_new(10, ColumnsFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableColumns, FunctionBar_new(10, AvailableColumnsFunctions, NULL, NULL), -1);
}

View File

@ -24,8 +24,18 @@ typedef struct CategoriesPanel_ {
} CategoriesPanel; } CategoriesPanel;
void CategoriesPanel_makeMetersPage(CategoriesPanel* this);
CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr); CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr);
void CategoriesPanel_delete(Object* object);
HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch);
void CategoriesPanel_makeMetersPage(CategoriesPanel* this);
void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this);
void CategoriesPanel_makeColorsPage(CategoriesPanel* this);
void CategoriesPanel_makeColumnsPage(CategoriesPanel* this);
#endif #endif

100
ChangeLog
View File

@ -1,104 +1,4 @@
What's new in version 0.8.2
* Integrated lsof (press 'l')
* Fix display of gigabyte-sized values
(thanks to Andika Triwidada)
* Option to display hostname in the meters area
* Rename VEID to CTID in OpenVZ systems
(thanks to Thorsten Schifferdecker)
* Corrections to the desktop entry file
(thanks by Samuli Suominen)
* BUGFIX: Correct page size calculation for FreeBSD systems
(thanks to Andrew Paulsen)
* Allow compilation without PLPA on systems that don't support it
(thanks to Timothy Redaelli)
* BUGFIX: Fix missing tree view when userland threads are hidden
(thanks to Josh Stone)
* BUGFIX: Fix for VPID on OpenVZ systems
(thanks to Wolfgang Frisch)
What's new in version 0.8.1
* Linux-VServer support
(thanks to Jonathan Sambrook and Benedikt Bohm)
* Battery meter
(thanks to Ian Page Hands)
* BUGFIX: Fix collection of IO stats in multithreaded processes
(thanks to Gerhard Heift)
* Remove assertion that fails on hardened kernels
(thanks to Wolfram Schlich for the report)
What's new in version 0.8
* Ability to change sort column with the mouse by
clicking column titles (click again to invert order)
* Add support for Linux per-process IO statistics,
enabled with the --enable-taskstats flag, which
requires a kernel compiled with taskstats support.
(thanks to Tobias Oetiker)
* Add Unicode support, enabled with the --enable-unicode
flag, which requires libncursesw.
(thanks to Sergej Pupykin)
* BUGFIX: Fix display of CPU count for threaded processes.
When user threads are hidden, process now shows the
sum of processor usage for all processors. When user
threads are displayed, each thread shows its own
processor usage, including the root thread.
(thanks to Bert Wesarg for the report)
* BUGFIX: avoid crashing when using many meters
(thanks to David Cho for the report)
What's new in version 0.7
* CPU affinity configuration ('a' key)
* Improve display of tree view, properly nesting
threads of the same app based on TGID.
* IO-wait time now counts as idle time, which is a more
accurate description. It is still available in
split time, now called detailed CPU time.
(thanks to Samuel Thibault for the report)
* BUGFIX: Correct display of TPGID field
* Add TGID field
* BUGFIX: Don't crash with invalid command-line flags
(thanks to Nico Golde for the report)
* Fix GCC 4.3 compilation issues
(thanks to Martin Michlmayr for the report)
* OpenVZ support, enabled at compile-time with
the --enable-openvz flag.
(thanks to Sergey Lychko)
What's new in version 0.6.6
* Add support of NLWP field
(thanks to Bert Wesarg)
* BUGFIX: Fix use of configurable /proc location
(thanks to Florent Thoumie)
* Fix memory percentage calculation and make it saner
(thanks to Olev Kartau for the report)
* Added display of DRS, DT, LRS and TRS
(thanks to Matthias Lederhofer)
* BUGFIX: LRS and DRS memory values were flipped
(thanks to Matthias Lederhofer)
* BUGFIX: Don't crash on very high UIDs
(thanks to Egmont Koblinger)
What's new in version 0.6.5
* Add hardened-debug flags for debugging with Hardened GCC
* BUGFIX: Handle error condition when a directory vanishes
from /proc
* BUGFIX: Fix leak of process command line
* BUGFIX: Collect orphaned items when arranging the tree view.
(thanks to Wolfram Schlich for assistance with debugging)
* Separate proc and memory debugging into separate #defines.
* BUGFIX: Fix message when configure fails due to
missing libraries
(thanks to Jon)
* BUGFIX: Don't truncate value when displaying a very large
process
(thanks to Bo Liu)
What's new in version 0.6.4 What's new in version 0.6.4
* Add an option to split the display of kernel time * Add an option to split the display of kernel time

View File

@ -16,8 +16,7 @@ in the source distribution for its full text.
typedef struct CheckItem_ { typedef struct CheckItem_ {
Object super; Object super;
char* text; char* text;
bool value; bool* value;
bool* ref;
} CheckItem; } CheckItem;
}*/ }*/
@ -28,7 +27,17 @@ char* CHECKITEM_CLASS = "CheckItem";
#define CHECKITEM_CLASS NULL #define CHECKITEM_CLASS NULL
#endif #endif
static void CheckItem_delete(Object* cast) { CheckItem* CheckItem_new(char* text, bool* value) {
CheckItem* this = malloc(sizeof(CheckItem));
Object_setClass(this, CHECKITEM_CLASS);
((Object*)this)->display = CheckItem_display;
((Object*)this)->delete = CheckItem_delete;
this->text = text;
this->value = value;
return this;
}
void CheckItem_delete(Object* cast) {
CheckItem* this = (CheckItem*)cast; CheckItem* this = (CheckItem*)cast;
assert (this != NULL); assert (this != NULL);
@ -36,39 +45,14 @@ static void CheckItem_delete(Object* cast) {
free(this); free(this);
} }
static void CheckItem_display(Object* cast, RichString* out) { void CheckItem_display(Object* cast, RichString* out) {
CheckItem* this = (CheckItem*)cast; CheckItem* this = (CheckItem*)cast;
assert (this != NULL); assert (this != NULL);
RichString_write(out, CRT_colors[CHECK_BOX], "["); RichString_write(out, CRT_colors[CHECK_BOX], "[");
if (CheckItem_get(this)) if (*(this->value))
RichString_append(out, CRT_colors[CHECK_MARK], "x"); RichString_append(out, CRT_colors[CHECK_MARK], "x");
else else
RichString_append(out, CRT_colors[CHECK_MARK], " "); RichString_append(out, CRT_colors[CHECK_MARK], " ");
RichString_append(out, CRT_colors[CHECK_BOX], "] "); RichString_append(out, CRT_colors[CHECK_BOX], "] ");
RichString_append(out, CRT_colors[CHECK_TEXT], this->text); RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
} }
CheckItem* CheckItem_new(char* text, bool* ref, bool value) {
CheckItem* this = malloc(sizeof(CheckItem));
Object_setClass(this, CHECKITEM_CLASS);
((Object*)this)->display = CheckItem_display;
((Object*)this)->delete = CheckItem_delete;
this->text = text;
this->value = value;
this->ref = ref;
return this;
}
void CheckItem_set(CheckItem* this, bool value) {
if (this->ref)
*(this->ref) = value;
else
this->value = value;
}
bool CheckItem_get(CheckItem* this) {
if (this->ref)
return *(this->ref);
else
return this->value;
}

View File

@ -18,8 +18,7 @@ in the source distribution for its full text.
typedef struct CheckItem_ { typedef struct CheckItem_ {
Object super; Object super;
char* text; char* text;
bool value; bool* value;
bool* ref;
} CheckItem; } CheckItem;
@ -29,10 +28,10 @@ extern char* CHECKITEM_CLASS;
#define CHECKITEM_CLASS NULL #define CHECKITEM_CLASS NULL
#endif #endif
CheckItem* CheckItem_new(char* text, bool* ref, bool value); CheckItem* CheckItem_new(char* text, bool* value);
void CheckItem_set(CheckItem* this, bool value); void CheckItem_delete(Object* cast);
bool CheckItem_get(CheckItem* this); void CheckItem_display(Object* cast, RichString* out);
#endif #endif

View File

@ -16,13 +16,6 @@ int ClockMeter_attributes[] = {
CLOCK CLOCK
}; };
static void ClockMeter_setValues(Meter* this, char* buffer, int size) {
time_t t = time(NULL);
struct tm *lt = localtime(&t);
this->values[0] = lt->tm_hour * 60 + lt->tm_min;
strftime(buffer, size, "%H:%M:%S", lt);
}
MeterType ClockMeter = { MeterType ClockMeter = {
.setValues = ClockMeter_setValues, .setValues = ClockMeter_setValues,
.display = NULL, .display = NULL,
@ -34,3 +27,10 @@ MeterType ClockMeter = {
.uiName = "Clock", .uiName = "Clock",
.caption = "Time: ", .caption = "Time: ",
}; };
void ClockMeter_setValues(Meter* this, char* buffer, int size) {
time_t t = time(NULL);
struct tm *lt = localtime(&t);
this->values[0] = lt->tm_hour * 60 + lt->tm_min;
strftime(buffer, size, "%H:%M:%S", lt);
}

View File

@ -19,4 +19,6 @@ extern int ClockMeter_attributes[];
extern MeterType ClockMeter; extern MeterType ClockMeter;
void ClockMeter_setValues(Meter* this, char* buffer, int size);
#endif #endif

View File

@ -23,6 +23,7 @@ typedef struct ColorsPanel_ {
Settings* settings; Settings* settings;
ScreenManager* scr; ScreenManager* scr;
bool check[5];
} ColorsPanel; } ColorsPanel;
}*/ }*/
@ -37,14 +38,33 @@ static char* ColorSchemes[] = {
NULL NULL
}; };
static void ColorsPanel_delete(Object* object) { ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr) {
ColorsPanel* this = (ColorsPanel*) malloc(sizeof(ColorsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true);
((Object*)this)->delete = ColorsPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = ColorsPanel_EventHandler;
Panel_setHeader(super, "Colors");
for (int i = 0; ColorSchemes[i] != NULL; i++) {
Panel_add(super, (Object*) CheckItem_new(String_copy(ColorSchemes[i]), &(this->check[i])));
this->check[i] = false;
}
this->check[settings->colorScheme] = true;
return this;
}
void ColorsPanel_delete(Object* object) {
Panel* super = (Panel*) object; Panel* super = (Panel*) object;
ColorsPanel* this = (ColorsPanel*) object; ColorsPanel* this = (ColorsPanel*) object;
Panel_done(super); Panel_done(super);
free(this); free(this);
} }
static HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) { HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
ColorsPanel* this = (ColorsPanel*) super; ColorsPanel* this = (ColorsPanel*) super;
HandlerResult result = IGNORED; HandlerResult result = IGNORED;
@ -54,11 +74,11 @@ static HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
case 0x0a: case 0x0a:
case 0x0d: case 0x0d:
case KEY_ENTER: case KEY_ENTER:
case KEY_MOUSE:
case ' ': case ' ':
for (int i = 0; ColorSchemes[i] != NULL; i++) for (int i = 0; ColorSchemes[i] != NULL; i++) {
CheckItem_set((CheckItem*)Panel_get(super, i), false); this->check[i] = false;
CheckItem_set((CheckItem*)Panel_get(super, mark), true); }
this->check[mark] = true;
this->settings->colorScheme = mark; this->settings->colorScheme = mark;
result = HANDLED; result = HANDLED;
} }
@ -76,20 +96,3 @@ static HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
return result; return result;
} }
ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr) {
ColorsPanel* this = (ColorsPanel*) malloc(sizeof(ColorsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true);
((Object*)this)->delete = ColorsPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = ColorsPanel_EventHandler;
Panel_setHeader(super, "Colors");
for (int i = 0; ColorSchemes[i] != NULL; i++) {
Panel_add(super, (Object*) CheckItem_new(String_copy(ColorSchemes[i]), NULL, false));
}
CheckItem_set((CheckItem*)Panel_get(super, settings->colorScheme), true);
return this;
}

View File

@ -25,9 +25,15 @@ typedef struct ColorsPanel_ {
Settings* settings; Settings* settings;
ScreenManager* scr; ScreenManager* scr;
bool check[5];
} ColorsPanel; } ColorsPanel;
ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr); ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr);
void ColorsPanel_delete(Object* object);
HandlerResult ColorsPanel_EventHandler(Panel* super, int ch);
#endif #endif

View File

@ -19,18 +19,61 @@ typedef struct ColumnsPanel_ {
}*/ }*/
static void ColumnsPanel_delete(Object* object) { ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr) {
ColumnsPanel* this = (ColumnsPanel*) malloc(sizeof(ColumnsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = ColumnsPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = ColumnsPanel_eventHandler;
Panel_setHeader(super, "Active Columns");
ProcessField* fields = this->settings->pl->fields;
for (; *fields; fields++) {
Panel_add(super, (Object*) ListItem_new(Process_fieldNames[*fields], 0));
}
return this;
}
void ColumnsPanel_delete(Object* object) {
Panel* super = (Panel*) object; Panel* super = (Panel*) object;
ColumnsPanel* this = (ColumnsPanel*) object; ColumnsPanel* this = (ColumnsPanel*) object;
Panel_done(super); Panel_done(super);
free(this); free(this);
} }
static HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch) { int ColumnsPanel_fieldNameToIndex(const char* name) {
for (int j = 1; j <= LAST_PROCESSFIELD; j++) {
if (String_eq(name, Process_fieldNames[j])) {
return j;
}
}
return 0;
}
void ColumnsPanel_update(Panel* super) {
ColumnsPanel* this = (ColumnsPanel*) super;
int size = Panel_getSize(super);
this->settings->changed = true;
// FIXME: this is crappily inefficient
free(this->settings->pl->fields);
this->settings->pl->fields = (ProcessField*) malloc(sizeof(ProcessField) * (size+1));
for (int i = 0; i < size; i++) {
char* text = ((ListItem*) Panel_get(super, i))->value;
int j = ColumnsPanel_fieldNameToIndex(text);
if (j > 0)
this->settings->pl->fields[i] = j;
}
this->settings->pl->fields[size] = 0;
}
HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch) {
int selected = Panel_getSelectedIndex(super); int selected = Panel_getSelectedIndex(super);
HandlerResult result = IGNORED; HandlerResult result = IGNORED;
int size = Panel_size(super); int size = Panel_getSize(super);
switch(ch) { switch(ch) {
case KEY_F(7): case KEY_F(7):
@ -65,47 +108,3 @@ static HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch) {
ColumnsPanel_update(super); ColumnsPanel_update(super);
return result; return result;
} }
ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr) {
ColumnsPanel* this = (ColumnsPanel*) malloc(sizeof(ColumnsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = ColumnsPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = ColumnsPanel_eventHandler;
Panel_setHeader(super, "Active Columns");
ProcessField* fields = this->settings->pl->fields;
for (; *fields; fields++) {
Panel_add(super, (Object*) ListItem_new(Process_fieldNames[*fields], 0));
}
return this;
}
int ColumnsPanel_fieldNameToIndex(const char* name) {
for (int j = 1; j <= LAST_PROCESSFIELD; j++) {
if (String_eq(name, Process_fieldNames[j])) {
return j;
}
}
return 0;
}
void ColumnsPanel_update(Panel* super) {
ColumnsPanel* this = (ColumnsPanel*) super;
int size = Panel_size(super);
this->settings->changed = true;
// FIXME: this is crappily inefficient
free(this->settings->pl->fields);
this->settings->pl->fields = (ProcessField*) malloc(sizeof(ProcessField) * (size+1));
for (int i = 0; i < size; i++) {
char* text = ((ListItem*) Panel_get(super, i))->value;
int j = ColumnsPanel_fieldNameToIndex(text);
if (j > 0)
this->settings->pl->fields[i] = j;
}
this->settings->pl->fields[size] = 0;
}

View File

@ -22,9 +22,12 @@ typedef struct ColumnsPanel_ {
ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr); ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr);
void ColumnsPanel_delete(Object* object);
int ColumnsPanel_fieldNameToIndex(const char* name); int ColumnsPanel_fieldNameToIndex(const char* name);
void ColumnsPanel_update(Panel* super); void ColumnsPanel_update(Panel* super);
HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch);
#endif #endif

View File

@ -49,11 +49,7 @@ void DebugMemory_new() {
singleton->allocations = 0; singleton->allocations = 0;
singleton->deallocations = 0; singleton->deallocations = 0;
singleton->size = 0; singleton->size = 0;
#ifdef DEBUG_ALLOC
singleton->file = fopen("/tmp/htop-debug-alloc.txt", "w"); singleton->file = fopen("/tmp/htop-debug-alloc.txt", "w");
#else
singleton->file = NULL;
#endif
singleton->totals = true; singleton->totals = true;
//singleton->file = NULL; //singleton->file = NULL;
} }

View File

@ -20,14 +20,36 @@ typedef struct DisplayOptionsPanel_ {
}*/ }*/
static void DisplayOptionsPanel_delete(Object* object) { DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr) {
DisplayOptionsPanel* this = (DisplayOptionsPanel*) malloc(sizeof(DisplayOptionsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true);
((Object*)this)->delete = DisplayOptionsPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = DisplayOptionsPanel_EventHandler;
Panel_setHeader(super, "Display options");
Panel_add(super, (Object*) CheckItem_new(String_copy("Tree view"), &(settings->pl->treeView)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Shadow other users' processes"), &(settings->pl->shadowOtherUsers)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide kernel threads"), &(settings->pl->hideKernelThreads)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide userland threads"), &(settings->pl->hideUserlandThreads)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight program \"basename\""), &(settings->pl->highlightBaseName)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight megabytes in memory counters"), &(settings->pl->highlightMegabytes)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Leave a margin around header"), &(settings->header->margin)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Split System Time into System/IO-Wait/Hard-IRQ/Soft-IRQ"), &(settings->pl->expandSystemTime)));
return this;
}
void DisplayOptionsPanel_delete(Object* object) {
Panel* super = (Panel*) object; Panel* super = (Panel*) object;
DisplayOptionsPanel* this = (DisplayOptionsPanel*) object; DisplayOptionsPanel* this = (DisplayOptionsPanel*) object;
Panel_done(super); Panel_done(super);
free(this); free(this);
} }
static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) { HandlerResult DisplayOptionsPanel_EventHandler(Panel* super, int ch) {
DisplayOptionsPanel* this = (DisplayOptionsPanel*) super; DisplayOptionsPanel* this = (DisplayOptionsPanel*) super;
HandlerResult result = IGNORED; HandlerResult result = IGNORED;
@ -37,9 +59,8 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
case 0x0a: case 0x0a:
case 0x0d: case 0x0d:
case KEY_ENTER: case KEY_ENTER:
case KEY_MOUSE:
case ' ': case ' ':
CheckItem_set(selected, ! (CheckItem_get(selected)) ); *(selected->value) = ! *(selected->value);
result = HANDLED; result = HANDLED;
} }
@ -53,25 +74,3 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
return result; return result;
} }
DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr) {
DisplayOptionsPanel* this = (DisplayOptionsPanel*) malloc(sizeof(DisplayOptionsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true);
((Object*)this)->delete = DisplayOptionsPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = DisplayOptionsPanel_eventHandler;
Panel_setHeader(super, "Display options");
Panel_add(super, (Object*) CheckItem_new(String_copy("Tree view"), &(settings->pl->treeView), false));
Panel_add(super, (Object*) CheckItem_new(String_copy("Shadow other users' processes"), &(settings->pl->shadowOtherUsers), false));
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide kernel threads"), &(settings->pl->hideKernelThreads), false));
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide userland threads"), &(settings->pl->hideUserlandThreads), false));
Panel_add(super, (Object*) CheckItem_new(String_copy("Display threads in a different color"), &(settings->pl->highlightThreads), false));
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight program \"basename\""), &(settings->pl->highlightBaseName), false));
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight megabytes in memory counters"), &(settings->pl->highlightMegabytes), false));
Panel_add(super, (Object*) CheckItem_new(String_copy("Leave a margin around header"), &(settings->header->margin), false));
Panel_add(super, (Object*) CheckItem_new(String_copy("Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ)"), &(settings->pl->detailedCPUTime), false));
return this;
}

View File

@ -23,4 +23,9 @@ typedef struct DisplayOptionsPanel_ {
DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr); DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr);
void DisplayOptionsPanel_delete(Object* object);
HandlerResult DisplayOptionsPanel_EventHandler(Panel* super, int ch);
#endif #endif

View File

@ -36,36 +36,34 @@ char* FUNCTIONBAR_CLASS = "FunctionBar";
#define FUNCTIONBAR_CLASS NULL #define FUNCTIONBAR_CLASS NULL
#endif #endif
static char* FunctionBar_FKeys[] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", NULL}; static char* FunctionBar_FKeys[10] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"};
static char* FunctionBar_FLabels[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", NULL}; static char* FunctionBar_FLabels[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
static int FunctionBar_FEvents[] = {KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10)}; static int FunctionBar_FEvents[10] = {KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10)};
FunctionBar* FunctionBar_new(char** functions, char** keys, int* events) { FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events) {
FunctionBar* this = malloc(sizeof(FunctionBar)); FunctionBar* this = malloc(sizeof(FunctionBar));
Object_setClass(this, FUNCTIONBAR_CLASS); Object_setClass(this, FUNCTIONBAR_CLASS);
((Object*) this)->delete = FunctionBar_delete; ((Object*) this)->delete = FunctionBar_delete;
this->functions = functions; this->functions = functions;
this->size = size;
if (keys && events) { if (keys && events) {
this->staticData = false; this->staticData = false;
this->functions = malloc(sizeof(char*) * 15); this->functions = malloc(sizeof(char*) * size);
this->keys = malloc(sizeof(char*) * 15); this->keys = malloc(sizeof(char*) * size);
this->events = malloc(sizeof(int) * 15); this->events = malloc(sizeof(int) * size);
int i = 0; for (int i = 0; i < size; i++) {
while (i < 15 && functions[i]) {
this->functions[i] = String_copy(functions[i]); this->functions[i] = String_copy(functions[i]);
this->keys[i] = String_copy(keys[i]); this->keys[i] = String_copy(keys[i]);
this->events[i] = events[i]; this->events[i] = events[i];
i++;
} }
this->size = i;
} else { } else {
this->staticData = true; this->staticData = true;
this->functions = functions ? functions : FunctionBar_FLabels; this->functions = functions ? functions : FunctionBar_FLabels;
this->keys = FunctionBar_FKeys; this->keys = FunctionBar_FKeys;
this->events = FunctionBar_FEvents; this->events = FunctionBar_FEvents;
this->size = 10; assert((!functions) || this->size == 10);
} }
return this; return this;
} }

View File

@ -37,7 +37,7 @@ extern char* FUNCTIONBAR_CLASS;
#define FUNCTIONBAR_CLASS NULL #define FUNCTIONBAR_CLASS NULL
#endif #endif
FunctionBar* FunctionBar_new(char** functions, char** keys, int* events); FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events);
void FunctionBar_delete(Object* cast); void FunctionBar_delete(Object* cast);

View File

@ -9,7 +9,6 @@ in the source distribution for its full text.
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <assert.h>
#include "debug.h" #include "debug.h"
@ -19,7 +18,7 @@ typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*); typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef struct HashtableItem { typedef struct HashtableItem {
unsigned int key; int key;
void* value; void* value;
struct HashtableItem* next; struct HashtableItem* next;
} HashtableItem; } HashtableItem;
@ -32,36 +31,7 @@ struct Hashtable_ {
}; };
}*/ }*/
#ifdef DEBUG HashtableItem* HashtableItem_new(int key, void* value) {
static bool Hashtable_isConsistent(Hashtable* this) {
int items = 0;
for (int i = 0; i < this->size; i++) {
HashtableItem* bucket = this->buckets[i];
while (bucket) {
items++;
bucket = bucket->next;
}
}
return items == this->items;
}
int Hashtable_count(Hashtable* this) {
int items = 0;
for (int i = 0; i < this->size; i++) {
HashtableItem* bucket = this->buckets[i];
while (bucket) {
items++;
bucket = bucket->next;
}
}
assert(items == this->items);
return items;
}
#endif
static HashtableItem* HashtableItem_new(unsigned int key, void* value) {
HashtableItem* this; HashtableItem* this;
this = (HashtableItem*) malloc(sizeof(HashtableItem)); this = (HashtableItem*) malloc(sizeof(HashtableItem));
@ -75,16 +45,13 @@ Hashtable* Hashtable_new(int size, bool owner) {
Hashtable* this; Hashtable* this;
this = (Hashtable*) malloc(sizeof(Hashtable)); this = (Hashtable*) malloc(sizeof(Hashtable));
this->items = 0;
this->size = size; this->size = size;
this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size); this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size);
this->owner = owner; this->owner = owner;
assert(Hashtable_isConsistent(this));
return this; return this;
} }
void Hashtable_delete(Hashtable* this) { void Hashtable_delete(Hashtable* this) {
assert(Hashtable_isConsistent(this));
for (int i = 0; i < this->size; i++) { for (int i = 0; i < this->size; i++) {
HashtableItem* walk = this->buckets[i]; HashtableItem* walk = this->buckets[i];
while (walk != NULL) { while (walk != NULL) {
@ -99,8 +66,12 @@ void Hashtable_delete(Hashtable* this) {
free(this); free(this);
} }
void Hashtable_put(Hashtable* this, unsigned int key, void* value) { inline int Hashtable_size(Hashtable* this) {
unsigned int index = key % this->size; return this->items;
}
void Hashtable_put(Hashtable* this, int key, void* value) {
int index = key % this->size;
HashtableItem** bucketPtr = &(this->buckets[index]); HashtableItem** bucketPtr = &(this->buckets[index]);
while (true) while (true)
if (*bucketPtr == NULL) { if (*bucketPtr == NULL) {
@ -114,53 +85,47 @@ void Hashtable_put(Hashtable* this, unsigned int key, void* value) {
break; break;
} else } else
bucketPtr = &((*bucketPtr)->next); bucketPtr = &((*bucketPtr)->next);
assert(Hashtable_isConsistent(this));
} }
void* Hashtable_remove(Hashtable* this, unsigned int key) { void* Hashtable_remove(Hashtable* this, int key) {
unsigned int index = key % this->size; int index = key % this->size;
HashtableItem** bucketPtr = &(this->buckets[index]);
assert(Hashtable_isConsistent(this)); while (true)
if (*bucketPtr == NULL) {
HashtableItem** bucket; return NULL;
for (bucket = &(this->buckets[index]); *bucket; bucket = &((*bucket)->next) ) { break;
if ((*bucket)->key == key) { } else if ((*bucketPtr)->key == key) {
void* value = (*bucket)->value; void* savedValue = (*bucketPtr)->value;
HashtableItem* next = (*bucket)->next; HashtableItem* savedNext = (*bucketPtr)->next;
free(*bucket); free(*bucketPtr);
(*bucket) = next; (*bucketPtr) = savedNext;
this->items--; this->items--;
if (this->owner) { if (this->owner) {
free(value); free(savedValue);
assert(Hashtable_isConsistent(this));
return NULL; return NULL;
} else { } else {
assert(Hashtable_isConsistent(this)); return savedValue;
return value;
} }
} } else
} bucketPtr = &((*bucketPtr)->next);
assert(Hashtable_isConsistent(this));
return NULL;
} }
//#include <stdio.h>
inline void* Hashtable_get(Hashtable* this, unsigned int key) { inline void* Hashtable_get(Hashtable* this, int key) {
unsigned int index = key % this->size; int index = key % this->size;
HashtableItem* bucketPtr = this->buckets[index]; HashtableItem* bucketPtr = this->buckets[index];
// fprintf(stderr, "%d -> %d\n", key, index);
while (true) { while (true) {
if (bucketPtr == NULL) { if (bucketPtr == NULL) {
assert(Hashtable_isConsistent(this));
return NULL; return NULL;
} else if (bucketPtr->key == key) { } else if (bucketPtr->key == key) {
assert(Hashtable_isConsistent(this));
return bucketPtr->value; return bucketPtr->value;
} else } else
bucketPtr = bucketPtr->next; bucketPtr = bucketPtr->next;
// fprintf(stderr, "*\n");
} }
} }
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) { void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) {
assert(Hashtable_isConsistent(this));
for (int i = 0; i < this->size; i++) { for (int i = 0; i < this->size; i++) {
HashtableItem* walk = this->buckets[i]; HashtableItem* walk = this->buckets[i];
while (walk != NULL) { while (walk != NULL) {
@ -168,5 +133,4 @@ void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData
walk = walk->next; walk = walk->next;
} }
} }
assert(Hashtable_isConsistent(this));
} }

View File

@ -12,7 +12,6 @@ in the source distribution for its full text.
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <assert.h>
#include "debug.h" #include "debug.h"
@ -21,7 +20,7 @@ typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*); typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef struct HashtableItem { typedef struct HashtableItem {
unsigned int key; int key;
void* value; void* value;
struct HashtableItem* next; struct HashtableItem* next;
} HashtableItem; } HashtableItem;
@ -33,21 +32,19 @@ struct Hashtable_ {
bool owner; bool owner;
}; };
#ifdef DEBUG HashtableItem* HashtableItem_new(int key, void* value);
int Hashtable_count(Hashtable* this);
#endif
Hashtable* Hashtable_new(int size, bool owner); Hashtable* Hashtable_new(int size, bool owner);
void Hashtable_delete(Hashtable* this); void Hashtable_delete(Hashtable* this);
void Hashtable_put(Hashtable* this, unsigned int key, void* value); inline int Hashtable_size(Hashtable* this);
void* Hashtable_remove(Hashtable* this, unsigned int key); void Hashtable_put(Hashtable* this, int key, void* value);
extern void* Hashtable_get(Hashtable* this, unsigned int key); void* Hashtable_remove(Hashtable* this, int key);
//#include <stdio.h>
inline void* Hashtable_get(Hashtable* this, int key);
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData); void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData);

View File

@ -73,8 +73,6 @@ void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side) {
? this->leftMeters ? this->leftMeters
: this->rightMeters; : this->rightMeters;
if (i >= Vector_size(meters))
return;
Meter* meter = (Meter*) Vector_get(meters, i); Meter* meter = (Meter*) Vector_get(meters, i);
Meter_setMode(meter, mode); Meter_setMode(meter, mode);
} }

View File

@ -1,33 +0,0 @@
/*
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "HostnameMeter.h"
#include "Meter.h"
#include <unistd.h>
#include "debug.h"
int HostnameMeter_attributes[] = {
HOSTNAME
};
static void HostnameMeter_setValues(Meter* this, char* buffer, int size) {
gethostname(buffer, size-1);
}
MeterType HostnameMeter = {
.setValues = HostnameMeter_setValues,
.display = NULL,
.mode = TEXT_METERMODE,
.total = 100.0,
.items = 1,
.attributes = HostnameMeter_attributes,
.name = "Hostname",
.uiName = "Hostname",
.caption = "Hostname: ",
};

View File

@ -1,22 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_HostnameMeter
#define HEADER_HostnameMeter
/*
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Meter.h"
#include <unistd.h>
#include "debug.h"
extern int HostnameMeter_attributes[];
extern MeterType HostnameMeter;
#endif

View File

@ -29,21 +29,6 @@ char* LISTITEM_CLASS = "ListItem";
#define LISTITEM_CLASS NULL #define LISTITEM_CLASS NULL
#endif #endif
static void ListItem_delete(Object* cast) {
ListItem* this = (ListItem*)cast;
free(this->value);
free(this);
}
static void ListItem_display(Object* cast, RichString* out) {
ListItem* this = (ListItem*)cast;
assert (this != NULL);
int len = strlen(this->value)+1;
char buffer[len+1];
snprintf(buffer, len, "%s", this->value);
RichString_write(out, CRT_colors[DEFAULT_COLOR], buffer);
}
ListItem* ListItem_new(char* value, int key) { ListItem* ListItem_new(char* value, int key) {
ListItem* this = malloc(sizeof(ListItem)); ListItem* this = malloc(sizeof(ListItem));
Object_setClass(this, LISTITEM_CLASS); Object_setClass(this, LISTITEM_CLASS);
@ -61,6 +46,21 @@ void ListItem_append(ListItem* this, char* text) {
this->value = buf; this->value = buf;
} }
void ListItem_delete(Object* cast) {
ListItem* this = (ListItem*)cast;
free(this->value);
free(this);
}
void ListItem_display(Object* cast, RichString* out) {
ListItem* this = (ListItem*)cast;
assert (this != NULL);
int len = strlen(this->value)+1;
char buffer[len+1];
snprintf(buffer, len, "%s", this->value);
RichString_write(out, CRT_colors[DEFAULT_COLOR], buffer);
}
const char* ListItem_getRef(ListItem* this) { const char* ListItem_getRef(ListItem* this) {
return this->value; return this->value;
} }

View File

@ -34,6 +34,10 @@ ListItem* ListItem_new(char* value, int key);
void ListItem_append(ListItem* this, char* text); void ListItem_append(ListItem* this, char* text);
void ListItem_delete(Object* cast);
void ListItem_display(Object* cast, RichString* out);
const char* ListItem_getRef(ListItem* this); const char* ListItem_getRef(ListItem* this);
int ListItem_compare(const void* cast1, const void* cast2); int ListItem_compare(const void* cast1, const void* cast2);

View File

@ -16,52 +16,6 @@ int LoadAverageMeter_attributes[] = {
LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIVE, LOAD_AVERAGE_ONE LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIVE, LOAD_AVERAGE_ONE
}; };
int LoadMeter_attributes[] = { LOAD };
static inline void LoadAverageMeter_scan(double* one, double* five, double* fifteen) {
int activeProcs, totalProcs, lastProc;
FILE *fd = fopen(PROCDIR "/loadavg", "r");
int read = fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen,
&activeProcs, &totalProcs, &lastProc);
(void) read;
assert(read == 6);
fclose(fd);
}
static void LoadAverageMeter_setValues(Meter* this, char* buffer, int size) {
LoadAverageMeter_scan(&this->values[2], &this->values[1], &this->values[0]);
snprintf(buffer, size, "%.2f/%.2f/%.2f", this->values[2], this->values[1], this->values[0]);
}
static void LoadAverageMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
char buffer[20];
RichString_init(out);
sprintf(buffer, "%.2f ", this->values[2]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
sprintf(buffer, "%.2f ", this->values[1]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIVE], buffer);
sprintf(buffer, "%.2f ", this->values[0]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_ONE], buffer);
}
static void LoadMeter_setValues(Meter* this, char* buffer, int size) {
double five, fifteen;
LoadAverageMeter_scan(&this->values[0], &five, &fifteen);
if (this->values[0] > this->total) {
this->total = this->values[0];
}
snprintf(buffer, size, "%.2f", this->values[0]);
}
static void LoadMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
char buffer[20];
RichString_init(out);
sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
RichString_append(out, CRT_colors[LOAD], buffer);
}
MeterType LoadAverageMeter = { MeterType LoadAverageMeter = {
.setValues = LoadAverageMeter_setValues, .setValues = LoadAverageMeter_setValues,
.display = LoadAverageMeter_display, .display = LoadAverageMeter_display,
@ -74,6 +28,8 @@ MeterType LoadAverageMeter = {
.caption = "Load average: " .caption = "Load average: "
}; };
int LoadMeter_attributes[] = { LOAD };
MeterType LoadMeter = { MeterType LoadMeter = {
.setValues = LoadMeter_setValues, .setValues = LoadMeter_setValues,
.display = LoadMeter_display, .display = LoadMeter_display,
@ -85,3 +41,47 @@ MeterType LoadMeter = {
.uiName = "Load", .uiName = "Load",
.caption = "Load: " .caption = "Load: "
}; };
static inline void LoadAverageMeter_scan(double* one, double* five, double* fifteen) {
int activeProcs, totalProcs, lastProc;
FILE *fd = fopen(PROCDIR "/loadavg", "r");
int read = fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen,
&activeProcs, &totalProcs, &lastProc);
(void) read;
assert(read == 6);
fclose(fd);
}
void LoadAverageMeter_setValues(Meter* this, char* buffer, int size) {
LoadAverageMeter_scan(&this->values[2], &this->values[1], &this->values[0]);
snprintf(buffer, size, "%.2f/%.2f/%.2f", this->values[2], this->values[1], this->values[0]);
}
void LoadAverageMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
char buffer[20];
RichString_init(out);
sprintf(buffer, "%.2f ", this->values[2]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
sprintf(buffer, "%.2f ", this->values[1]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIVE], buffer);
sprintf(buffer, "%.2f ", this->values[0]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_ONE], buffer);
}
void LoadMeter_setValues(Meter* this, char* buffer, int size) {
double five, fifteen;
LoadAverageMeter_scan(&this->values[0], &five, &fifteen);
if (this->values[0] > this->total) {
this->total = this->values[0];
}
snprintf(buffer, size, "%.2f", this->values[0]);
}
void LoadMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
char buffer[20];
RichString_init(out);
sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
RichString_append(out, CRT_colors[LOAD], buffer);
}

View File

@ -17,10 +17,18 @@ in the source distribution for its full text.
extern int LoadAverageMeter_attributes[]; extern int LoadAverageMeter_attributes[];
extern int LoadMeter_attributes[];
extern MeterType LoadAverageMeter; extern MeterType LoadAverageMeter;
extern int LoadMeter_attributes[];
extern MeterType LoadMeter; extern MeterType LoadMeter;
void LoadAverageMeter_setValues(Meter* this, char* buffer, int size);
void LoadAverageMeter_display(Object* cast, RichString* out);
void LoadMeter_setValues(Meter* this, char* buffer, int size);
void LoadMeter_display(Object* cast, RichString* out);
#endif #endif

View File

@ -1,8 +1,4 @@
if HAVE_PLPA
SUBDIRS = plpa-1.1
endif
bin_PROGRAMS = htop bin_PROGRAMS = htop
dist_man_MANS = htop.1 dist_man_MANS = htop.1
EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png scripts/MakeHeader.py \ EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png scripts/MakeHeader.py \
@ -12,49 +8,31 @@ applications_DATA = htop.desktop
pixmapdir = $(datadir)/pixmaps pixmapdir = $(datadir)/pixmaps
pixmap_DATA = htop.png pixmap_DATA = htop.png
htop_CFLAGS = -pedantic -Wall -std=c99 -D_XOPEN_SOURCE_EXTENDED AM_CFLAGS = -pedantic -Wall -std=c99
AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
myhtopsources = AvailableMetersPanel.c CategoriesPanel.c CheckItem.c \ htop_SOURCES = AvailableMetersPanel.c CategoriesPanel.c ClockMeter.c \
ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c DebugMemory.c \ CPUMeter.c CRT.c DebugMemory.c DisplayOptionsPanel.c FunctionBar.c \
DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c \ Hashtable.c Header.c htop.c Panel.c ListItem.c LoadAverageMeter.c \
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.c \ MemoryMeter.c Meter.c MetersPanel.c Object.c Process.c \
BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c \ ProcessList.c RichString.c ScreenManager.c Settings.c SignalItem.c \
SignalItem.c SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \ SignalsPanel.c String.c SwapMeter.c TasksMeter.c Vector.c \
UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c \ UptimeMeter.c UsersTable.c AvailableMetersPanel.h CategoriesPanel.h \
HostnameMeter.c OpenFilesScreen.c ClockMeter.h config.h CPUMeter.h CRT.h debug.h DebugMemory.h \
DisplayOptionsPanel.h FunctionBar.h Hashtable.h Header.h htop.h Panel.h \
myhtopheaders = AvailableColumnsPanel.h AvailableMetersPanel.h \ ListItem.h LoadAverageMeter.h MemoryMeter.h Meter.h \
CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h \ MetersPanel.h Object.h Process.h ProcessList.h RichString.h ScreenManager.h \
CPUMeter.h CRT.h DebugMemory.h DisplayOptionsPanel.h FunctionBar.h \ Settings.h SignalItem.h SignalsPanel.h String.h SwapMeter.h TasksMeter.h \
Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.h \ Vector.h UptimeMeter.h UsersTable.h CheckItem.c CheckItem.h \
BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h \ ColorsPanel.c ColorsPanel.h TraceScreen.c TraceScreen.h \
ScreenManager.h Settings.h SignalItem.h SignalsPanel.h String.h \ AvailableColumnsPanel.c AvailableColumnsPanel.h ColumnsPanel.c \
SwapMeter.h TasksMeter.h TraceScreen.h UptimeMeter.h UsersTable.h Vector.h \ ColumnsPanel.h
Process.h AffinityPanel.h HostnameMeter.h OpenFilesScreen.h
SUFFIXES = .h
BUILT_SOURCES = $(myhtopheaders)
htop_SOURCES = $(myhtopheaders) $(myhtopsources) config.h debug.h
if HAVE_PLPA
htop_LDADD = $(top_builddir)/plpa-1.1/src/libplpa_included.la
endif
profile: profile:
$(MAKE) all CFLAGS="-pg -O2" $(MAKE) all CFLAGS="-pg -O2"
debug: debug:
$(MAKE) all CFLAGS="-ggdb -DDEBUG" $(MAKE) all CFLAGS="-g -DDEBUG"
hardened-debug:
$(MAKE) all CFLAGS="-ggdb -DDEBUG" LDFLAGS="-nopie"
debuglite: debuglite:
$(MAKE) all CFLAGS="-ggdb -DDEBUGLITE" $(MAKE) all CFLAGS="-g -DDEBUGLITE"
.c.h:
scripts/MakeHeader.py $<

View File

@ -23,7 +23,19 @@ int MemoryMeter_attributes[] = {
MEMORY_USED, MEMORY_BUFFERS, MEMORY_CACHE MEMORY_USED, MEMORY_BUFFERS, MEMORY_CACHE
}; };
static void MemoryMeter_setValues(Meter* this, char* buffer, int size) { MeterType MemoryMeter = {
.setValues = MemoryMeter_setValues,
.display = MemoryMeter_display,
.mode = BAR_METERMODE,
.items = 3,
.total = 100.0,
.attributes = MemoryMeter_attributes,
"Memory",
"Memory",
"Mem"
};
void MemoryMeter_setValues(Meter* this, char* buffer, int size) {
long int usedMem = this->pl->usedMem; long int usedMem = this->pl->usedMem;
long int buffersMem = this->pl->buffersMem; long int buffersMem = this->pl->buffersMem;
long int cachedMem = this->pl->cachedMem; long int cachedMem = this->pl->cachedMem;
@ -35,7 +47,7 @@ static void MemoryMeter_setValues(Meter* this, char* buffer, int size) {
snprintf(buffer, size, "%ld/%ldMB", (long int) usedMem / 1024, (long int) this->total / 1024); snprintf(buffer, size, "%ld/%ldMB", (long int) usedMem / 1024, (long int) this->total / 1024);
} }
static void MemoryMeter_display(Object* cast, RichString* out) { void MemoryMeter_display(Object* cast, RichString* out) {
char buffer[50]; char buffer[50];
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
int div = 1024; char* format = "%ldM "; int div = 1024; char* format = "%ldM ";
@ -57,15 +69,3 @@ static void MemoryMeter_display(Object* cast, RichString* out) {
RichString_append(out, CRT_colors[METER_TEXT], "cache:"); RichString_append(out, CRT_colors[METER_TEXT], "cache:");
RichString_append(out, CRT_colors[MEMORY_CACHE], buffer); RichString_append(out, CRT_colors[MEMORY_CACHE], buffer);
} }
MeterType MemoryMeter = {
.setValues = MemoryMeter_setValues,
.display = MemoryMeter_display,
.mode = BAR_METERMODE,
.items = 3,
.total = 100.0,
.attributes = MemoryMeter_attributes,
"Memory",
"Memory",
"Mem"
};

View File

@ -26,4 +26,8 @@ extern int MemoryMeter_attributes[];
extern MeterType MemoryMeter; extern MeterType MemoryMeter;
void MemoryMeter_setValues(Meter* this, char* buffer, int size);
void MemoryMeter_display(Object* cast, RichString* out);
#endif #endif

111
Meter.c
View File

@ -6,7 +6,12 @@ in the source distribution for its full text.
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include "RichString.h" #include <math.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <stdarg.h>
#include "Meter.h" #include "Meter.h"
#include "Object.h" #include "Object.h"
#include "CRT.h" #include "CRT.h"
@ -14,11 +19,6 @@ in the source distribution for its full text.
#include "String.h" #include "String.h"
#include "ProcessList.h" #include "ProcessList.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
@ -95,10 +95,7 @@ typedef enum {
#include "TasksMeter.h" #include "TasksMeter.h"
#include "LoadAverageMeter.h" #include "LoadAverageMeter.h"
#include "UptimeMeter.h" #include "UptimeMeter.h"
#include "BatteryMeter.h"
#include "ClockMeter.h" #include "ClockMeter.h"
#include "HostnameMeter.h"
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
@ -122,9 +119,46 @@ MeterType* Meter_types[] = {
&SwapMeter, &SwapMeter,
&TasksMeter, &TasksMeter,
&UptimeMeter, &UptimeMeter,
&BatteryMeter,
&AllCPUsMeter, &AllCPUsMeter,
&HostnameMeter, NULL
};
static MeterMode BarMeterMode = {
.uiName = "Bar",
.h = 1,
.draw = BarMeterMode_draw,
};
static MeterMode TextMeterMode = {
.uiName = "Text",
.h = 1,
.draw = TextMeterMode_draw,
};
#ifdef USE_FUNKY_MODES
static MeterMode GraphMeterMode = {
.uiName = "Graph",
.h = 3,
.draw = GraphMeterMode_draw,
};
static MeterMode LEDMeterMode = {
.uiName = "LED",
.h = 3,
.draw = LEDMeterMode_draw,
};
#endif
MeterMode* Meter_modes[] = {
NULL,
&BarMeterMode,
&TextMeterMode,
#ifdef USE_FUNKY_MODES
&GraphMeterMode,
&LEDMeterMode,
#endif
NULL NULL
}; };
@ -219,7 +253,7 @@ ListItem* Meter_toListItem(Meter* this) {
/* ---------- TextMeterMode ---------- */ /* ---------- TextMeterMode ---------- */
static void TextMeterMode_draw(Meter* this, int x, int y, int w) { void TextMeterMode_draw(Meter* this, int x, int y, int w) {
MeterType* type = this->type; MeterType* type = this->type;
char buffer[METER_BUFFER_LEN]; char buffer[METER_BUFFER_LEN];
type->setValues(this, buffer, METER_BUFFER_LEN - 1); type->setValues(this, buffer, METER_BUFFER_LEN - 1);
@ -232,22 +266,22 @@ static void TextMeterMode_draw(Meter* this, int x, int y, int w) {
Meter_displayToStringBuffer(this, buffer); Meter_displayToStringBuffer(this, buffer);
mvhline(y, x, ' ', CRT_colors[DEFAULT_COLOR]); mvhline(y, x, ' ', CRT_colors[DEFAULT_COLOR]);
attrset(CRT_colors[RESET_COLOR]); attrset(CRT_colors[RESET_COLOR]);
RichString_printVal(Meter_stringBuffer, y, x); mvaddchstr(y, x, Meter_stringBuffer.chstr);
} }
/* ---------- BarMeterMode ---------- */ /* ---------- BarMeterMode ---------- */
static char BarMeterMode_characters[] = "|#*@$%&"; static char BarMeterMode_characters[] = "|#*@$%&";
static void BarMeterMode_draw(Meter* this, int x, int y, int w) { void BarMeterMode_draw(Meter* this, int x, int y, int w) {
MeterType* type = this->type; MeterType* type = this->type;
char buffer[METER_BUFFER_LEN]; char buffer[METER_BUFFER_LEN];
type->setValues(this, buffer, METER_BUFFER_LEN - 1); type->setValues(this, buffer, METER_BUFFER_LEN - 1);
w -= 2; w -= 2;
attrset(CRT_colors[METER_TEXT]); attrset(CRT_colors[METER_TEXT]);
int captionLen = 3; mvaddstr(y, x, this->caption);
mvaddnstr(y, x, this->caption, captionLen); int captionLen = strlen(this->caption);
x += captionLen; x += captionLen;
w -= captionLen; w -= captionLen;
attrset(CRT_colors[BAR_BORDER]); attrset(CRT_colors[BAR_BORDER]);
@ -327,7 +361,7 @@ static int GraphMeterMode_colors[21] = {
static char* GraphMeterMode_characters = "^`'-.,_~'`-.,_~'`-.,_"; static char* GraphMeterMode_characters = "^`'-.,_~'`-.,_~'`-.,_";
static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
if (!this->drawBuffer) this->drawBuffer = calloc(sizeof(double), METER_BUFFER_LEN); if (!this->drawBuffer) this->drawBuffer = calloc(sizeof(double), METER_BUFFER_LEN);
double* drawBuffer = (double*) this->drawBuffer; double* drawBuffer = (double*) this->drawBuffer;
@ -373,7 +407,7 @@ static void LEDMeterMode_drawDigit(int x, int y, int n) {
mvaddstr(y+i, x, LEDMeterMode_digits[i][n]); mvaddstr(y+i, x, LEDMeterMode_digits[i][n]);
} }
static void LEDMeterMode_draw(Meter* this, int x, int y, int w) { void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
MeterType* type = this->type; MeterType* type = this->type;
char buffer[METER_BUFFER_LEN]; char buffer[METER_BUFFER_LEN];
type->setValues(this, buffer, METER_BUFFER_LEN - 1); type->setValues(this, buffer, METER_BUFFER_LEN - 1);
@ -384,7 +418,7 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
mvaddstr(y+2, x, this->caption); mvaddstr(y+2, x, this->caption);
int xx = x + strlen(this->caption); int xx = x + strlen(this->caption);
for (int i = 0; i < Meter_stringBuffer.len; i++) { for (int i = 0; i < Meter_stringBuffer.len; i++) {
char c = RichString_getCharVal(Meter_stringBuffer, i); char c = Meter_stringBuffer.chstr[i];
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
LEDMeterMode_drawDigit(xx, y, c-48); LEDMeterMode_drawDigit(xx, y, c-48);
xx += 4; xx += 4;
@ -397,42 +431,3 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
} }
#endif #endif
static MeterMode BarMeterMode = {
.uiName = "Bar",
.h = 1,
.draw = BarMeterMode_draw,
};
static MeterMode TextMeterMode = {
.uiName = "Text",
.h = 1,
.draw = TextMeterMode_draw,
};
#ifdef USE_FUNKY_MODES
static MeterMode GraphMeterMode = {
.uiName = "Graph",
.h = 3,
.draw = GraphMeterMode_draw,
};
static MeterMode LEDMeterMode = {
.uiName = "LED",
.h = 3,
.draw = LEDMeterMode_draw,
};
#endif
MeterMode* Meter_modes[] = {
NULL,
&BarMeterMode,
&TextMeterMode,
#ifdef USE_FUNKY_MODES
&GraphMeterMode,
&LEDMeterMode,
#endif
NULL
};

33
Meter.h
View File

@ -10,18 +10,18 @@ in the source distribution for its full text.
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include "RichString.h" #include <math.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <stdarg.h>
#include "Object.h" #include "Object.h"
#include "CRT.h" #include "CRT.h"
#include "ListItem.h" #include "ListItem.h"
#include "String.h" #include "String.h"
#include "ProcessList.h" #include "ProcessList.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
@ -96,10 +96,7 @@ typedef enum {
#include "TasksMeter.h" #include "TasksMeter.h"
#include "LoadAverageMeter.h" #include "LoadAverageMeter.h"
#include "UptimeMeter.h" #include "UptimeMeter.h"
#include "BatteryMeter.h"
#include "ClockMeter.h" #include "ClockMeter.h"
#include "HostnameMeter.h"
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
@ -116,6 +113,12 @@ extern char* METER_CLASS;
extern MeterType* Meter_types[]; extern MeterType* Meter_types[];
#ifdef USE_FUNKY_MODES
#endif
extern MeterMode* Meter_modes[];
Meter* Meter_new(ProcessList* pl, int param, MeterType* type); Meter* Meter_new(ProcessList* pl, int param, MeterType* type);
void Meter_delete(Object* cast); void Meter_delete(Object* cast);
@ -128,22 +131,24 @@ ListItem* Meter_toListItem(Meter* this);
/* ---------- TextMeterMode ---------- */ /* ---------- TextMeterMode ---------- */
void TextMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- BarMeterMode ---------- */ /* ---------- BarMeterMode ---------- */
void BarMeterMode_draw(Meter* this, int x, int y, int w);
#ifdef USE_FUNKY_MODES #ifdef USE_FUNKY_MODES
/* ---------- GraphMeterMode ---------- */ /* ---------- GraphMeterMode ---------- */
#define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0) #define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0)
void GraphMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- LEDMeterMode ---------- */ /* ---------- LEDMeterMode ---------- */
#endif void LEDMeterMode_draw(Meter* this, int x, int y, int w);
#ifdef USE_FUNKY_MODES
#endif #endif
extern MeterMode* Meter_modes[];
#endif #endif

View File

@ -20,14 +20,32 @@ typedef struct MetersPanel_ {
}*/ }*/
static void MetersPanel_delete(Object* object) { MetersPanel* MetersPanel_new(Settings* settings, char* header, Vector* meters, ScreenManager* scr) {
MetersPanel* this = (MetersPanel*) malloc(sizeof(MetersPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = MetersPanel_delete;
this->settings = settings;
this->meters = meters;
this->scr = scr;
super->eventHandler = MetersPanel_EventHandler;
Panel_setHeader(super, header);
for (int i = 0; i < Vector_size(meters); i++) {
Meter* meter = (Meter*) Vector_get(meters, i);
Panel_add(super, (Object*) Meter_toListItem(meter));
}
return this;
}
void MetersPanel_delete(Object* object) {
Panel* super = (Panel*) object; Panel* super = (Panel*) object;
MetersPanel* this = (MetersPanel*) object; MetersPanel* this = (MetersPanel*) object;
Panel_done(super); Panel_done(super);
free(this); free(this);
} }
static HandlerResult MetersPanel_EventHandler(Panel* super, int ch) { HandlerResult MetersPanel_EventHandler(Panel* super, int ch) {
MetersPanel* this = (MetersPanel*) super; MetersPanel* this = (MetersPanel*) super;
int selected = Panel_getSelectedIndex(super); int selected = Panel_getSelectedIndex(super);
@ -79,28 +97,9 @@ static HandlerResult MetersPanel_EventHandler(Panel* super, int ch) {
} }
if (result == HANDLED) { if (result == HANDLED) {
Header* header = this->settings->header; Header* header = this->settings->header;
this->settings->changed = true;
Header_calculateHeight(header); Header_calculateHeight(header);
Header_draw(header); Header_draw(header);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2); ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
} }
return result; return result;
} }
MetersPanel* MetersPanel_new(Settings* settings, char* header, Vector* meters, ScreenManager* scr) {
MetersPanel* this = (MetersPanel*) malloc(sizeof(MetersPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = MetersPanel_delete;
this->settings = settings;
this->meters = meters;
this->scr = scr;
super->eventHandler = MetersPanel_EventHandler;
Panel_setHeader(super, header);
for (int i = 0; i < Vector_size(meters); i++) {
Meter* meter = (Meter*) Vector_get(meters, i);
Panel_add(super, (Object*) Meter_toListItem(meter));
}
return this;
}

View File

@ -23,4 +23,8 @@ typedef struct MetersPanel_ {
MetersPanel* MetersPanel_new(Settings* settings, char* header, Vector* meters, ScreenManager* scr); MetersPanel* MetersPanel_new(Settings* settings, char* header, Vector* meters, ScreenManager* scr);
void MetersPanel_delete(Object* object);
HandlerResult MetersPanel_EventHandler(Panel* super, int ch);
#endif #endif

View File

@ -48,7 +48,7 @@ void Object_setClass(void* this, char* class) {
((Object*)this)->class = class; ((Object*)this)->class = class;
} }
static void Object_display(Object* this, RichString* out) { void Object_display(Object* this, RichString* out) {
char objAddress[50]; char objAddress[50];
sprintf(objAddress, "%s @ %p", this->class, (void*) this); sprintf(objAddress, "%s @ %p", this->class, (void*) this);
RichString_write(out, CRT_colors[DEFAULT_COLOR], objAddress); RichString_write(out, CRT_colors[DEFAULT_COLOR], objAddress);

View File

@ -47,6 +47,8 @@ extern char* OBJECT_CLASS;
void Object_setClass(void* this, char* class); void Object_setClass(void* this, char* class);
void Object_display(Object* this, RichString* out);
#endif #endif
#endif #endif

View File

@ -1,194 +0,0 @@
/*
htop - OpenFilesScreen.c
(C) 2005-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "OpenFilesScreen.h"
#include "ProcessList.h"
#include "Process.h"
#include "ListItem.h"
#include "Panel.h"
#include "FunctionBar.h"
/*{
typedef struct OpenFiles_ProcessData_ {
char* data[256];
struct OpenFiles_FileData_* files;
bool failed;
} OpenFiles_ProcessData;
typedef struct OpenFiles_FileData_ {
char* data[256];
struct OpenFiles_FileData_* next;
} OpenFiles_FileData;
typedef struct OpenFilesScreen_ {
Process* process;
Panel* display;
FunctionBar* bar;
bool tracing;
} OpenFilesScreen;
}*/
static char* tbFunctions[] = {"Refresh", "Done ", NULL};
static char* tbKeys[] = {"F5", "Esc"};
static int tbEvents[] = {KEY_F(5), 27};
OpenFilesScreen* OpenFilesScreen_new(Process* process) {
OpenFilesScreen* this = (OpenFilesScreen*) malloc(sizeof(OpenFilesScreen));
this->process = process;
this->display = Panel_new(0, 1, COLS, LINES-3, LISTITEM_CLASS, true, ListItem_compare);
this->bar = FunctionBar_new(tbFunctions, tbKeys, tbEvents);
this->tracing = true;
return this;
}
void OpenFilesScreen_delete(OpenFilesScreen* this) {
Panel_delete((Object*)this->display);
FunctionBar_delete((Object*)this->bar);
free(this);
}
static void OpenFilesScreen_draw(OpenFilesScreen* this) {
attrset(CRT_colors[METER_TEXT]);
mvhline(0, 0, ' ', COLS);
mvprintw(0, 0, "Files open in process %d - %s", this->process->pid, this->process->comm);
attrset(CRT_colors[DEFAULT_COLOR]);
Panel_draw(this->display, true);
FunctionBar_draw(this->bar, NULL);
}
static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(int pid) {
char command[1025];
snprintf(command, 1024, "lsof -p %d -F 2> /dev/null", pid);
FILE* fd = popen(command, "r");
OpenFiles_ProcessData* process = calloc(sizeof(OpenFiles_ProcessData), 1);
OpenFiles_FileData* file = NULL;
OpenFiles_ProcessData* item = process;
process->failed = true;
bool anyRead = false;
while (!feof(fd)) {
int cmd = fgetc(fd);
if (cmd == EOF && !anyRead) {
process->failed = true;
break;
}
anyRead = true;
process->failed = false;
char* entry = malloc(1024);
if (!fgets(entry, 1024, fd)) break;
char* newline = strrchr(entry, '\n');
*newline = '\0';
if (cmd == 'f') {
OpenFiles_FileData* nextFile = calloc(sizeof(OpenFiles_ProcessData), 1);
if (file == NULL) {
process->files = nextFile;
} else {
file->next = nextFile;
}
file = nextFile;
item = (OpenFiles_ProcessData*) file;
}
item->data[cmd] = entry;
}
pclose(fd);
return process;
}
static void OpenFilesScreen_scan(OpenFilesScreen* this) {
Panel* panel = this->display;
int index = MAX(Panel_getSelectedIndex(panel), 0);
Panel_prune(panel);
OpenFiles_ProcessData* process = OpenFilesScreen_getProcessData(this->process->pid);
if (process->failed) {
Panel_add(panel, (Object*) ListItem_new("Could not execute 'lsof'. Please make sure it is available in your $PATH.", 0));
} else {
OpenFiles_FileData* file = process->files;
while (file) {
char entry[1024];
sprintf(entry, "%5s %4s %10s %10s %10s %s",
file->data['f'] ? file->data['f'] : "",
file->data['t'] ? file->data['t'] : "",
file->data['D'] ? file->data['D'] : "",
file->data['s'] ? file->data['s'] : "",
file->data['i'] ? file->data['i'] : "",
file->data['n'] ? file->data['n'] : "");
Panel_add(panel, (Object*) ListItem_new(entry, 0));
for (int i = 0; i < 255; i++)
if (file->data[i])
free(file->data[i]);
OpenFiles_FileData* old = file;
file = file->next;
free(old);
}
for (int i = 0; i < 255; i++)
if (process->data[i])
free(process->data[i]);
}
free(process);
Vector_sort(panel->items);
Panel_setSelected(panel, index);
}
void OpenFilesScreen_run(OpenFilesScreen* this) {
Panel* panel = this->display;
Panel_setHeader(panel, " FD TYPE DEVICE SIZE NODE NAME");
OpenFilesScreen_scan(this);
OpenFilesScreen_draw(this);
//CRT_disableDelay();
bool looping = true;
while (looping) {
Panel_draw(panel, true);
int ch = getch();
if (ch == KEY_MOUSE) {
MEVENT mevent;
int ok = getmouse(&mevent);
if (ok == OK)
if (mevent.y >= panel->y && mevent.y < LINES - 1) {
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV);
ch = 0;
} if (mevent.y == LINES - 1)
ch = FunctionBar_synthesizeEvent(this->bar, mevent.x);
}
switch(ch) {
case ERR:
continue;
case KEY_F(5):
clear();
OpenFilesScreen_scan(this);
OpenFilesScreen_draw(this);
break;
case '\014': // Ctrl+L
clear();
OpenFilesScreen_draw(this);
break;
case 'q':
case 27:
looping = false;
break;
case KEY_RESIZE:
Panel_resize(panel, COLS, LINES-2);
OpenFilesScreen_draw(this);
break;
default:
Panel_onKey(panel, ch);
}
}
//CRT_enableDelay();
}

View File

@ -1,53 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_OpenFilesScreen
#define HEADER_OpenFilesScreen
/*
htop - OpenFilesScreen.h
(C) 2005-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "ProcessList.h"
#include "Process.h"
#include "ListItem.h"
#include "Panel.h"
#include "FunctionBar.h"
typedef struct OpenFiles_ProcessData_ {
char* data[256];
struct OpenFiles_FileData_* files;
bool failed;
} OpenFiles_ProcessData;
typedef struct OpenFiles_FileData_ {
char* data[256];
struct OpenFiles_FileData_* next;
} OpenFiles_FileData;
typedef struct OpenFilesScreen_ {
Process* process;
Panel* display;
FunctionBar* bar;
bool tracing;
} OpenFilesScreen;
OpenFilesScreen* OpenFilesScreen_new(Process* process);
void OpenFilesScreen_delete(OpenFilesScreen* this);
void OpenFilesScreen_run(OpenFilesScreen* this);
#endif

82
Panel.c
View File

@ -31,8 +31,6 @@ typedef enum HandlerResult_ {
BREAK_LOOP BREAK_LOOP
} HandlerResult; } HandlerResult;
#define EVENT_SETSELECTED -1
typedef HandlerResult(*Panel_EventHandler)(Panel*, int); typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
struct Panel_ { struct Panel_ {
@ -94,9 +92,9 @@ void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner)
this->selected = 0; this->selected = 0;
this->oldSelected = 0; this->oldSelected = 0;
this->needsRedraw = true; this->needsRedraw = true;
RichString_prune(&(this->header)); this->header.len = 0;
if (String_eq(CRT_termType, "linux")) if (String_eq(CRT_termType, "linux"))
this->scrollHAmount = 20; this->scrollHAmount = 40;
else else
this->scrollHAmount = 5; this->scrollHAmount = 5;
} }
@ -213,7 +211,7 @@ int Panel_getSelectedIndex(Panel* this) {
return this->selected; return this->selected;
} }
int Panel_size(Panel* this) { int Panel_getSize(Panel* this) {
assert (this != NULL); assert (this != NULL);
return Vector_size(this->items); return Vector_size(this->items);
@ -224,9 +222,6 @@ void Panel_setSelected(Panel* this, int selected) {
selected = MAX(0, MIN(Vector_size(this->items) - 1, selected)); selected = MAX(0, MIN(Vector_size(this->items) - 1, selected));
this->selected = selected; this->selected = selected;
if (this->eventHandler) {
this->eventHandler(this, EVENT_SETSELECTED);
}
} }
void Panel_draw(Panel* this, bool focus) { void Panel_draw(Panel* this, bool focus) {
@ -265,8 +260,8 @@ void Panel_draw(Panel* this, bool focus) {
attrset(attr); attrset(attr);
mvhline(y, x, ' ', this->w); mvhline(y, x, ' ', this->w);
if (scrollH < this->header.len) { if (scrollH < this->header.len) {
RichString_printoffnVal(this->header, y, x, scrollH, mvaddchnstr(y, x, this->header.chstr + scrollH,
MIN(this->header.len - scrollH, this->w)); MIN(this->header.len - scrollH, this->w));
} }
attrset(CRT_colors[RESET_COLOR]); attrset(CRT_colors[RESET_COLOR]);
y++; y++;
@ -289,12 +284,12 @@ void Panel_draw(Panel* this, bool focus) {
RichString_setAttr(&itemRef, highlight); RichString_setAttr(&itemRef, highlight);
mvhline(y + j, x+0, ' ', this->w); mvhline(y + j, x+0, ' ', this->w);
if (amt > 0) if (amt > 0)
RichString_printoffnVal(itemRef, y+j, x+0, scrollH, amt); mvaddchnstr(y+j, x+0, itemRef.chstr + scrollH, amt);
attrset(CRT_colors[RESET_COLOR]); attrset(CRT_colors[RESET_COLOR]);
} else { } else {
mvhline(y+j, x+0, ' ', this->w); mvhline(y+j, x+0, ' ', this->w);
if (amt > 0) if (amt > 0)
RichString_printoffnVal(itemRef, y+j, x+0, scrollH, amt); mvaddchnstr(y+j, x+0, itemRef.chstr + scrollH, amt);
} }
} }
for (int i = y + (last - first); i < y + this->h; i++) for (int i = y + (last - first); i < y + this->h; i++)
@ -312,88 +307,55 @@ void Panel_draw(Panel* this, bool focus) {
newObj->display(newObj, &newRef); newObj->display(newObj, &newRef);
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w); mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
if (scrollH < oldRef.len) if (scrollH < oldRef.len)
RichString_printoffnVal(oldRef, y+this->oldSelected - this->scrollV, x, mvaddchnstr(y+ this->oldSelected - this->scrollV, x+0, oldRef.chstr + this->scrollH, MIN(oldRef.len - scrollH, this->w));
this->scrollH, MIN(oldRef.len - scrollH, this->w));
attrset(highlight); attrset(highlight);
mvhline(y+this->selected - this->scrollV, x+0, ' ', this->w); mvhline(y+this->selected - this->scrollV, x+0, ' ', this->w);
RichString_setAttr(&newRef, highlight); RichString_setAttr(&newRef, highlight);
if (scrollH < newRef.len) if (scrollH < newRef.len)
RichString_printoffnVal(newRef, y+this->selected - this->scrollV, x, mvaddchnstr(y+this->selected - this->scrollV, x+0, newRef.chstr + this->scrollH, MIN(newRef.len - scrollH, this->w));
this->scrollH, MIN(newRef.len - scrollH, this->w));
attrset(CRT_colors[RESET_COLOR]); attrset(CRT_colors[RESET_COLOR]);
} }
this->oldSelected = this->selected; this->oldSelected = this->selected;
move(0, 0); move(0, 0);
} }
bool Panel_onKey(Panel* this, int key) { void Panel_onKey(Panel* this, int key) {
assert (this != NULL); assert (this != NULL);
switch (key) { switch (key) {
case KEY_DOWN: case KEY_DOWN:
if (this->selected + 1 < Vector_size(this->items)) if (this->selected + 1 < Vector_size(this->items))
this->selected++; this->selected++;
return true; break;
case KEY_UP: case KEY_UP:
if (this->selected > 0) if (this->selected > 0)
this->selected--; this->selected--;
return true; break;
#ifdef KEY_C_DOWN
case KEY_C_DOWN:
if (this->selected + 1 < Vector_size(this->items)) {
this->selected++;
if (this->scrollV < Vector_size(this->items) - this->h) {
this->scrollV++;
this->needsRedraw = true;
}
}
return true;
#endif
#ifdef KEY_C_UP
case KEY_C_UP:
if (this->selected > 0) {
this->selected--;
if (this->scrollV > 0) {
this->scrollV--;
this->needsRedraw = true;
}
}
return true;
#endif
case KEY_LEFT: case KEY_LEFT:
if (this->scrollH > 0) { if (this->scrollH > 0) {
this->scrollH -= 5; this->scrollH -= this->scrollHAmount;
this->needsRedraw = true; this->needsRedraw = true;
} }
return true; break;
case KEY_RIGHT: case KEY_RIGHT:
this->scrollH += 5; this->scrollH += this->scrollHAmount;
this->needsRedraw = true; this->needsRedraw = true;
return true; break;
case KEY_PPAGE: case KEY_PPAGE:
this->selected -= (this->h - 1); this->selected -= this->h;
this->scrollV -= (this->h - 1);
if (this->selected < 0) if (this->selected < 0)
this->selected = 0; this->selected = 0;
if (this->scrollV < 0) break;
this->scrollV = 0;
this->needsRedraw = true;
return true;
case KEY_NPAGE: case KEY_NPAGE:
this->selected += (this->h - 1); this->selected += this->h;
int size = Vector_size(this->items); int size = Vector_size(this->items);
if (this->selected >= size) if (this->selected >= size)
this->selected = size - 1; this->selected = size - 1;
this->scrollV += (this->h - 1); break;
if (this->scrollV >= MAX(0, size - this->h))
this->scrollV = MAX(0, size - this->h - 1);
this->needsRedraw = true;
return true;
case KEY_HOME: case KEY_HOME:
this->selected = 0; this->selected = 0;
return true; break;
case KEY_END: case KEY_END:
this->selected = Vector_size(this->items) - 1; this->selected = Vector_size(this->items) - 1;
return true; break;
} }
return false;
} }

10
Panel.h
View File

@ -33,8 +33,6 @@ typedef enum HandlerResult_ {
BREAK_LOOP BREAK_LOOP
} HandlerResult; } HandlerResult;
#define EVENT_SETSELECTED -1
typedef HandlerResult(*Panel_EventHandler)(Panel*, int); typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
struct Panel_ { struct Panel_ {
@ -74,9 +72,9 @@ void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner)
void Panel_done(Panel* this); void Panel_done(Panel* this);
extern void Panel_setRichHeader(Panel* this, RichString header); inline void Panel_setRichHeader(Panel* this, RichString header);
extern void Panel_setHeader(Panel* this, char* header); inline void Panel_setHeader(Panel* this, char* header);
void Panel_setEventHandler(Panel* this, Panel_EventHandler eh); void Panel_setEventHandler(Panel* this, Panel_EventHandler eh);
@ -104,12 +102,12 @@ void Panel_moveSelectedDown(Panel* this);
int Panel_getSelectedIndex(Panel* this); int Panel_getSelectedIndex(Panel* this);
int Panel_size(Panel* this); int Panel_getSize(Panel* this);
void Panel_setSelected(Panel* this, int selected); void Panel_setSelected(Panel* this, int selected);
void Panel_draw(Panel* this, bool focus); void Panel_draw(Panel* this, bool focus);
bool Panel_onKey(Panel* this, int key); void Panel_onKey(Panel* this, int key);
#endif #endif

428
Process.c
View File

@ -11,7 +11,6 @@ in the source distribution for its full text.
#include "CRT.h" #include "CRT.h"
#include "String.h" #include "String.h"
#include "Process.h" #include "Process.h"
#include "RichString.h"
#include "debug.h" #include "debug.h"
@ -26,18 +25,10 @@ in the source distribution for its full text.
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <pwd.h> #include <pwd.h>
#include <sched.h>
#ifdef HAVE_PLPA
#include <plpa.h>
#endif
// This works only with glibc 2.1+. On earlier versions // This works only with glibc 2.1+. On earlier versions
// the behavior is similar to have a hardcoded page size. // the behavior is similar to have a hardcoded page size.
#ifndef PAGE_SIZE #define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
#endif
#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )
#define PROCESS_COMM_LEN 300 #define PROCESS_COMM_LEN 300
@ -48,17 +39,7 @@ typedef enum ProcessField_ {
STIME, CUTIME, CSTIME, PRIORITY, NICE, ITREALVALUE, STARTTIME, VSIZE, RSS, RLIM, STARTCODE, ENDCODE, STIME, CUTIME, CSTIME, PRIORITY, NICE, ITREALVALUE, STARTTIME, VSIZE, RSS, RLIM, STARTCODE, ENDCODE,
STARTSTACK, KSTKESP, KSTKEIP, SIGNAL, BLOCKED, SSIGIGNORE, SIGCATCH, WCHAN, NSWAP, CNSWAP, EXIT_SIGNAL, 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, 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, USER, TIME, LAST_PROCESSFIELD
#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
LAST_PROCESSFIELD
} ProcessField; } ProcessField;
struct ProcessList_; struct ProcessList_;
@ -69,16 +50,15 @@ typedef struct Process_ {
struct ProcessList_ *pl; struct ProcessList_ *pl;
bool updated; bool updated;
unsigned int pid; int pid;
char* comm; char* comm;
int indent; int indent;
char state; char state;
bool tag; bool tag;
unsigned int ppid; int ppid;
unsigned int pgrp; int pgrp;
unsigned int session; int session;
unsigned int tty_nr; int tty_nr;
unsigned int tgid;
int tpgid; int tpgid;
unsigned long int flags; unsigned long int flags;
#ifdef DEBUG #ifdef DEBUG
@ -93,7 +73,6 @@ typedef struct Process_ {
long int cstime; long int cstime;
long int priority; long int priority;
long int nice; long int nice;
long int nlwp;
#ifdef DEBUG #ifdef DEBUG
long int itrealvalue; long int itrealvalue;
unsigned long int starttime; unsigned long int starttime;
@ -126,26 +105,6 @@ typedef struct Process_ {
float percent_cpu; float percent_cpu;
float percent_mem; float percent_mem;
char* user; char* user;
#ifdef HAVE_OPENVZ
unsigned int ctid;
unsigned int vpid;
#endif
#ifdef HAVE_VSERVER
unsigned int vxid;
#endif
#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
} Process; } Process;
}*/ }*/
@ -157,74 +116,92 @@ char* PROCESS_CLASS = "Process";
#endif #endif
char *Process_fieldNames[] = { char *Process_fieldNames[] = {
"", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION", "", "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", "*** report bug! ***"
"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
"*** report bug! ***"
};
char *Process_fieldTitles[] = {
"", " PID ", "Command ", "S ", " PPID ", " PGRP ", " SESN ",
" TTY ", "TPGID ", "- ", "- ", "- ", "- ", "- ",
" UTIME+ ", " STIME+ ", "- ", "- ", "PRI ", " NI ", "- ",
"- ", "- ", "- ", "- ", "- ", "- ", "- ",
"- ", "- ", "- ", "- ", "- ", "- ", "- ",
"- ", "- ", "- ", "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_RD ", " IO_WR ", " IO_CANCEL ",
" IORR ", " IOWR ", " IO ",
#endif
}; };
static int Process_getuid = -1; static int Process_getuid = -1;
Process* Process_new(struct ProcessList_ *pl) {
Process* this = malloc(sizeof(Process));
Object_setClass(this, PROCESS_CLASS);
((Object*)this)->display = Process_display;
((Object*)this)->delete = Process_delete;
this->pl = pl;
this->tag = false;
this->updated = false;
this->utime = 0;
this->stime = 0;
this->comm = NULL;
if (Process_getuid == -1) Process_getuid = getuid();
return this;
}
Process* Process_clone(Process* this) {
Process* clone = malloc(sizeof(Process));
memcpy(clone, this, sizeof(Process));
return clone;
}
void Process_delete(Object* cast) {
Process* this = (Process*) cast;
if (this->comm) free(this->comm);
assert (this != NULL);
free(this);
}
void Process_display(Object* cast, RichString* out) {
Process* this = (Process*) cast;
ProcessField* fields = this->pl->fields;
RichString_init(out);
for (int i = 0; fields[i]; i++)
Process_writeField(this, out, fields[i]);
if (this->pl->shadowOtherUsers && 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->len > 0);
}
void Process_toggleTag(Process* this) {
this->tag = this->tag == true ? false : true;
}
void Process_setPriority(Process* this, int priority) {
int old_prio = getpriority(PRIO_PROCESS, this->pid);
int err = setpriority(PRIO_PROCESS, this->pid, priority);
if (err == 0 && old_prio != getpriority(PRIO_PROCESS, this->pid)) {
this->nice = priority;
}
}
void Process_sendSignal(Process* this, int signal) {
kill(this->pid, signal);
}
#define ONE_K 1024 #define ONE_K 1024
#define ONE_M (ONE_K * ONE_K) #define ONE_M (ONE_K * ONE_K)
#define ONE_G (ONE_M * ONE_K) #define ONE_G (ONE_M * ONE_K)
static void Process_printLargeNumber(Process* this, RichString *str, unsigned long number) { static void Process_printLargeNumber(Process* this, RichString *str, unsigned int number) {
char buffer[11]; char buffer[11];
int len; int len;
if(number >= (10 * ONE_M)) { if(number >= (1000 * ONE_M)) {
len = snprintf(buffer, 10, "%3.1fG ", (float)number / ONE_M); len = snprintf(buffer, 10, "%4.2fG ", (float)number / ONE_M);
RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len); RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len);
} else if(number >= (100000)) { } else if(number >= (100000)) {
len = snprintf(buffer, 10, "%4ldM ", number / ONE_K); len = snprintf(buffer, 10, "%4dM ", number / ONE_K);
int attr = this->pl->highlightMegabytes int attr = this->pl->highlightMegabytes
? CRT_colors[PROCESS_MEGABYTES] ? CRT_colors[PROCESS_MEGABYTES]
: CRT_colors[PROCESS]; : CRT_colors[PROCESS];
RichString_appendn(str, attr, buffer, len); RichString_appendn(str, attr, buffer, len);
} else if (this->pl->highlightMegabytes && number >= 1000) { } else if (this->pl->highlightMegabytes && number >= 1000) {
len = snprintf(buffer, 10, "%2ld", number/1000); len = snprintf(buffer, 10, "%2d", number/1000);
RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer, len); RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer, len);
number %= 1000; number %= 1000;
len = snprintf(buffer, 10, "%03ld ", number); len = snprintf(buffer, 10, "%03d ", number);
RichString_appendn(str, CRT_colors[PROCESS], buffer, len); RichString_appendn(str, CRT_colors[PROCESS], buffer, len);
} else { } else {
len = snprintf(buffer, 10, "%5ld ", number); len = snprintf(buffer, 10, "%5d ", number);
RichString_appendn(str, CRT_colors[PROCESS], buffer, len); RichString_appendn(str, CRT_colors[PROCESS], buffer, len);
} }
} }
@ -253,62 +230,43 @@ static void Process_printTime(RichString* str, unsigned long t) {
RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer); RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer);
} }
static inline void Process_writeCommand(Process* this, int attr, int baseattr, RichString* str) { static inline void Process_writeCommand(Process* this, int attr, RichString* str) {
int start = str->len;
RichString_append(str, attr, this->comm);
if (this->pl->highlightBaseName) { if (this->pl->highlightBaseName) {
int finish = str->len - 1; char* firstSpace = strchr(this->comm, ' ');
int space = RichString_findChar(str, ' ', start); if (firstSpace) {
if (space != -1) char* slash = firstSpace;
finish = space - 1; while (slash > this->comm && *slash != '/')
for (;;) { slash--;
int slash = RichString_findChar(str, '/', start); if (slash > this->comm) {
if (slash == -1 || slash > finish) slash++;
break; RichString_appendn(str, attr, this->comm, slash - this->comm);
start = slash + 1; }
RichString_appendn(str, CRT_colors[PROCESS_BASENAME], slash, firstSpace - slash);
RichString_append(str, attr, firstSpace);
} else {
RichString_append(str, CRT_colors[PROCESS_BASENAME], this->comm);
} }
RichString_setAttrn(str, baseattr, start, finish); } else {
RichString_append(str, attr, this->comm);
} }
} }
static inline void Process_outputRate(Process* this, RichString* str, int attr, char* buffer, int n, double rate) { void Process_writeField(Process* this, RichString* str, ProcessField field) {
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_printLargeNumber(this, str, rate);
return;
}
RichString_append(str, attr, buffer);
}
static void Process_writeField(Process* this, RichString* str, ProcessField field) {
char buffer[PROCESS_COMM_LEN]; char buffer[PROCESS_COMM_LEN];
int attr = CRT_colors[DEFAULT_COLOR]; int attr = CRT_colors[DEFAULT_COLOR];
int baseattr = CRT_colors[PROCESS_BASENAME];
int n = PROCESS_COMM_LEN; int n = PROCESS_COMM_LEN;
switch (field) { switch (field) {
case PID: snprintf(buffer, n, "%5u ", this->pid); break; case PID: snprintf(buffer, n, "%5d ", this->pid); break;
case PPID: snprintf(buffer, n, "%5u ", this->ppid); break; case PPID: snprintf(buffer, n, "%5d ", this->ppid); break;
case PGRP: snprintf(buffer, n, "%5u ", this->pgrp); break; case PGRP: snprintf(buffer, n, "%5d ", this->pgrp); break;
case SESSION: snprintf(buffer, n, "%5u ", this->session); break; case SESSION: snprintf(buffer, n, "%5d ", this->session); break;
case TTY_NR: snprintf(buffer, n, "%5u ", this->tty_nr); break; case TTY_NR: snprintf(buffer, n, "%5d ", this->tty_nr); break;
case TGID: snprintf(buffer, n, "%5u ", this->tgid); break;
case TPGID: snprintf(buffer, n, "%5d ", this->tpgid); break; case TPGID: snprintf(buffer, n, "%5d ", this->tpgid); break;
case PROCESSOR: snprintf(buffer, n, "%3d ", this->processor+1); break; case PROCESSOR: snprintf(buffer, n, "%3d ", this->processor+1); break;
case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
case COMM: { case COMM: {
if (this->pl->highlightThreads && (this->pid != this->tgid || this->m_size == 0)) {
attr = CRT_colors[PROCESS_THREAD];
baseattr = CRT_colors[PROCESS_THREAD_BASENAME];
}
if (!this->pl->treeView || this->indent == 0) { if (!this->pl->treeView || this->indent == 0) {
Process_writeCommand(this, attr, baseattr, str); Process_writeCommand(this, attr, str);
return; return;
} else { } else {
char* buf = buffer; char* buf = buffer;
@ -329,7 +287,7 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
else else
snprintf(buf, n, " ,- "); snprintf(buf, n, " ,- ");
RichString_append(str, CRT_colors[PROCESS_TREE], buffer); RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
Process_writeCommand(this, attr, baseattr, str); Process_writeCommand(this, attr, str);
return; return;
} }
} }
@ -354,13 +312,9 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
: attr; : attr;
break; break;
} }
case M_DRS: Process_printLargeNumber(this, str, this->m_drs * PAGE_SIZE_KB); return; case M_SIZE: Process_printLargeNumber(this, str, this->m_size * PAGE_SIZE); return;
case M_DT: Process_printLargeNumber(this, str, this->m_dt * PAGE_SIZE_KB); return; case M_RESIDENT: Process_printLargeNumber(this, str, this->m_resident * PAGE_SIZE); return;
case M_LRS: Process_printLargeNumber(this, str, this->m_lrs * PAGE_SIZE_KB); return; case M_SHARE: Process_printLargeNumber(this, str, this->m_share * PAGE_SIZE); return;
case M_TRS: Process_printLargeNumber(this, str, this->m_trs * PAGE_SIZE_KB); return;
case M_SIZE: Process_printLargeNumber(this, str, this->m_size * PAGE_SIZE_KB); return;
case M_RESIDENT: Process_printLargeNumber(this, str, this->m_resident * PAGE_SIZE_KB); return;
case M_SHARE: Process_printLargeNumber(this, str, this->m_share * PAGE_SIZE_KB); return;
case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break; case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break;
case USER: { case USER: {
if (Process_getuid != this->st_uid) if (Process_getuid != this->st_uid)
@ -382,10 +336,8 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
case CSTIME: Process_printTime(str, this->cstime); return; case CSTIME: Process_printTime(str, this->cstime); return;
case TIME: Process_printTime(str, this->utime + this->stime); return; case TIME: Process_printTime(str, this->utime + this->stime); return;
case PERCENT_CPU: { case PERCENT_CPU: {
if (this->percent_cpu > 999.9) { if (this->percent_cpu > 99.9) {
snprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu); snprintf(buffer, n, "100. ");
} else if (this->percent_cpu > 99.9) {
snprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu);
} else { } else {
snprintf(buffer, n, "%4.1f ", this->percent_cpu); snprintf(buffer, n, "%4.1f ", this->percent_cpu);
} }
@ -399,117 +351,11 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
} }
break; 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: snprintf(buffer, n, "%10llu ", this->io_rchar); break;
case WCHAR: snprintf(buffer, n, "%10llu ", this->io_wchar); break;
case SYSCR: snprintf(buffer, n, "%10llu ", this->io_syscr); break;
case SYSCW: snprintf(buffer, n, "%10llu ", this->io_syscw); break;
case RBYTES: snprintf(buffer, n, "%10llu ", this->io_read_bytes); break;
case WBYTES: snprintf(buffer, n, "%10llu ", this->io_write_bytes); break;
case CNCLWB: snprintf(buffer, n, "%10llu ", this->io_cancelled_write_bytes); break;
case IO_READ_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_read_bps); return;
case IO_WRITE_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_write_bps); return;
case IO_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_read_bps + this->io_rate_write_bps); return;
#endif
default: default:
snprintf(buffer, n, "- "); snprintf(buffer, n, "- ");
} }
RichString_append(str, attr, buffer); RichString_append(str, attr, buffer);
} return;
static void Process_display(Object* cast, RichString* out) {
Process* this = (Process*) cast;
ProcessField* fields = this->pl->fields;
RichString_init(out);
for (int i = 0; fields[i]; i++)
Process_writeField(this, out, fields[i]);
if (this->pl->shadowOtherUsers && 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->len > 0);
}
void Process_delete(Object* cast) {
Process* this = (Process*) cast;
assert (this != NULL);
if (this->comm) free(this->comm);
free(this);
}
Process* Process_new(struct ProcessList_ *pl) {
Process* this = calloc(sizeof(Process), 1);
Object_setClass(this, PROCESS_CLASS);
((Object*)this)->display = Process_display;
((Object*)this)->delete = Process_delete;
this->pid = 0;
this->pl = pl;
this->tag = false;
this->updated = false;
this->utime = 0;
this->stime = 0;
this->comm = NULL;
this->indent = 0;
if (Process_getuid == -1) Process_getuid = getuid();
return this;
}
Process* Process_clone(Process* this) {
Process* clone = malloc(sizeof(Process));
#if HAVE_TASKSTATS
this->io_rchar = 0;
this->io_wchar = 0;
this->io_syscr = 0;
this->io_syscw = 0;
this->io_read_bytes = 0;
this->io_rate_read_bps = 0;
this->io_rate_read_time = 0;
this->io_write_bytes = 0;
this->io_rate_write_bps = 0;
this->io_rate_write_time = 0;
this->io_cancelled_write_bytes = 0;
#endif
memcpy(clone, this, sizeof(Process));
this->comm = NULL;
this->pid = 0;
return clone;
}
void Process_toggleTag(Process* this) {
this->tag = this->tag == true ? false : true;
}
bool Process_setPriority(Process* this, int priority) {
int old_prio = getpriority(PRIO_PROCESS, this->pid);
int err = setpriority(PRIO_PROCESS, this->pid, priority);
if (err == 0 && old_prio != getpriority(PRIO_PROCESS, this->pid)) {
this->nice = priority;
}
return (err == 0);
}
#ifdef HAVE_PLPA
unsigned long Process_getAffinity(Process* this) {
unsigned long mask = 0;
plpa_sched_getaffinity(this->pid, sizeof(unsigned long), (plpa_cpu_set_t*) &mask);
return mask;
}
bool Process_setAffinity(Process* this, unsigned long mask) {
return (plpa_sched_setaffinity(this->pid, sizeof(unsigned long), (plpa_cpu_set_t*) &mask) == 0);
}
#endif
void Process_sendSignal(Process* this, int signal) {
kill(this->pid, signal);
} }
int Process_pidCompare(const void* v1, const void* v2) { int Process_pidCompare(const void* v1, const void* v2) {
@ -528,32 +374,19 @@ int Process_compare(const void* v1, const void* v2) {
p2 = (Process*)v1; p2 = (Process*)v1;
p1 = (Process*)v2; p1 = (Process*)v2;
} }
long long diff;
switch (pl->sortKey) { switch (pl->sortKey) {
case PID: case PID:
return (p1->pid - p2->pid); return (p1->pid - p2->pid);
case PPID: case PPID:
return (p1->ppid - p2->ppid); return (p1->ppid - p2->ppid);
case USER: case USER:
return strcmp(p1->user ? p1->user : "", p2->user ? p2->user : ""); return strcmp(p1->user, p2->user);
case PRIORITY: case PRIORITY:
return (p1->priority - p2->priority); return (p1->priority - p2->priority);
case PROCESSOR:
return (p1->processor - p2->processor);
case SESSION:
return (p1->session - p2->session);
case STATE: case STATE:
return (p1->state - p2->state); return (p1->state - p2->state);
case NICE: case NICE:
return (p1->nice - p2->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: case M_SIZE:
return (p2->m_size - p1->m_size); return (p2->m_size - p1->m_size);
case M_RESIDENT: case M_RESIDENT:
@ -572,34 +405,35 @@ int Process_compare(const void* v1, const void* v2) {
return ((p2->utime+p2->stime) - (p1->utime+p1->stime)); return ((p2->utime+p2->stime) - (p1->utime+p1->stime));
case COMM: case COMM:
return strcmp(p1->comm, p2->comm); return strcmp(p1->comm, p2->comm);
case NLWP:
return (p1->nlwp - p2->nlwp);
#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
default: default:
return (p1->pid - p2->pid); return (p1->pid - p2->pid);
} }
test_diff:
return (diff > 0) ? 1 : (diff < 0 ? -1 : 0); }
char* Process_printField(ProcessField field) {
switch (field) {
case PID: return " PID ";
case PPID: return " PPID ";
case PGRP: return " PGRP ";
case SESSION: return " SESN ";
case TTY_NR: return " TTY ";
case TPGID: return " TGID ";
case COMM: return "Command ";
case STATE: return "S ";
case PRIORITY: return "PRI ";
case NICE: return " NI ";
case M_SIZE: return " VIRT ";
case M_RESIDENT: return " RES ";
case M_SHARE: return " SHR ";
case ST_UID: return " UID ";
case USER: return "USER ";
case UTIME: return " UTIME+ ";
case STIME: return " STIME+ ";
case TIME: return " TIME+ ";
case PERCENT_CPU: return "CPU% ";
case PERCENT_MEM: return "MEM% ";
case PROCESSOR: return "CPU ";
default: return "- ";
}
} }

View File

@ -14,7 +14,6 @@ in the source distribution for its full text.
#include "Object.h" #include "Object.h"
#include "CRT.h" #include "CRT.h"
#include "String.h" #include "String.h"
#include "RichString.h"
#include "debug.h" #include "debug.h"
@ -29,18 +28,10 @@ in the source distribution for its full text.
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <pwd.h> #include <pwd.h>
#include <sched.h>
#ifdef HAVE_PLPA
#include <plpa.h>
#endif
// This works only with glibc 2.1+. On earlier versions // This works only with glibc 2.1+. On earlier versions
// the behavior is similar to have a hardcoded page size. // the behavior is similar to have a hardcoded page size.
#ifndef PAGE_SIZE #define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
#endif
#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )
#define PROCESS_COMM_LEN 300 #define PROCESS_COMM_LEN 300
@ -50,17 +41,7 @@ typedef enum ProcessField_ {
STIME, CUTIME, CSTIME, PRIORITY, NICE, ITREALVALUE, STARTTIME, VSIZE, RSS, RLIM, STARTCODE, ENDCODE, STIME, CUTIME, CSTIME, PRIORITY, NICE, ITREALVALUE, STARTTIME, VSIZE, RSS, RLIM, STARTCODE, ENDCODE,
STARTSTACK, KSTKESP, KSTKEIP, SIGNAL, BLOCKED, SSIGIGNORE, SIGCATCH, WCHAN, NSWAP, CNSWAP, EXIT_SIGNAL, 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, 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, USER, TIME, LAST_PROCESSFIELD
#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
LAST_PROCESSFIELD
} ProcessField; } ProcessField;
struct ProcessList_; struct ProcessList_;
@ -71,16 +52,15 @@ typedef struct Process_ {
struct ProcessList_ *pl; struct ProcessList_ *pl;
bool updated; bool updated;
unsigned int pid; int pid;
char* comm; char* comm;
int indent; int indent;
char state; char state;
bool tag; bool tag;
unsigned int ppid; int ppid;
unsigned int pgrp; int pgrp;
unsigned int session; int session;
unsigned int tty_nr; int tty_nr;
unsigned int tgid;
int tpgid; int tpgid;
unsigned long int flags; unsigned long int flags;
#ifdef DEBUG #ifdef DEBUG
@ -95,7 +75,6 @@ typedef struct Process_ {
long int cstime; long int cstime;
long int priority; long int priority;
long int nice; long int nice;
long int nlwp;
#ifdef DEBUG #ifdef DEBUG
long int itrealvalue; long int itrealvalue;
unsigned long int starttime; unsigned long int starttime;
@ -128,26 +107,6 @@ typedef struct Process_ {
float percent_cpu; float percent_cpu;
float percent_mem; float percent_mem;
char* user; char* user;
#ifdef HAVE_OPENVZ
unsigned int ctid;
unsigned int vpid;
#endif
#ifdef HAVE_VSERVER
unsigned int vxid;
#endif
#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
} Process; } Process;
@ -159,32 +118,30 @@ extern char* PROCESS_CLASS;
extern char *Process_fieldNames[]; extern char *Process_fieldNames[];
extern char *Process_fieldTitles[]; Process* Process_new(struct ProcessList_ *pl);
Process* Process_clone(Process* this);
void Process_delete(Object* cast);
void Process_display(Object* cast, RichString* out);
void Process_toggleTag(Process* this);
void Process_setPriority(Process* this, int priority);
void Process_sendSignal(Process* this, int signal);
#define ONE_K 1024 #define ONE_K 1024
#define ONE_M (ONE_K * ONE_K) #define ONE_M (ONE_K * ONE_K)
#define ONE_G (ONE_M * ONE_K) #define ONE_G (ONE_M * ONE_K)
void Process_delete(Object* cast); void Process_writeField(Process* this, RichString* str, ProcessField field);
Process* Process_new(struct ProcessList_ *pl);
Process* Process_clone(Process* this);
void Process_toggleTag(Process* this);
bool Process_setPriority(Process* this, int priority);
#ifdef HAVE_PLPA
unsigned long Process_getAffinity(Process* this);
bool Process_setAffinity(Process* this, unsigned long mask);
#endif
void Process_sendSignal(Process* this, int signal);
int Process_pidCompare(const void* v1, const void* v2); int Process_pidCompare(const void* v1, const void* v2);
int Process_compare(const void* v1, const void* v2); int Process_compare(const void* v1, const void* v2);
char* Process_printField(ProcessField field);
#endif #endif

View File

@ -37,11 +37,11 @@ in the source distribution for its full text.
#endif #endif
#ifndef PROCSTATFILE #ifndef PROCSTATFILE
#define PROCSTATFILE PROCDIR "/stat" #define PROCSTATFILE "/proc/stat"
#endif #endif
#ifndef PROCMEMINFOFILE #ifndef PROCMEMINFOFILE
#define PROCMEMINFOFILE PROCDIR "/meminfo" #define PROCMEMINFOFILE "/proc/meminfo"
#endif #endif
#ifndef MAX_NAME #ifndef MAX_NAME
@ -53,14 +53,14 @@ in the source distribution for its full text.
#endif #endif
#ifndef PER_PROCESSOR_FIELDS #ifndef PER_PROCESSOR_FIELDS
#define PER_PROCESSOR_FIELDS 22 #define PER_PROCESSOR_FIELDS 20
#endif #endif
}*/ }*/
/*{ /*{
#ifdef DEBUG_PROC #ifdef DEBUG
typedef int(*vxscanf)(void*, const char*, va_list); typedef int(*vxscanf)(void*, const char*, va_list);
#endif #endif
@ -80,7 +80,6 @@ typedef struct ProcessList_ {
unsigned long long int* userTime; unsigned long long int* userTime;
unsigned long long int* systemTime; unsigned long long int* systemTime;
unsigned long long int* systemAllTime; unsigned long long int* systemAllTime;
unsigned long long int* idleAllTime;
unsigned long long int* idleTime; unsigned long long int* idleTime;
unsigned long long int* niceTime; unsigned long long int* niceTime;
unsigned long long int* ioWaitTime; unsigned long long int* ioWaitTime;
@ -91,7 +90,6 @@ typedef struct ProcessList_ {
unsigned long long int* userPeriod; unsigned long long int* userPeriod;
unsigned long long int* systemPeriod; unsigned long long int* systemPeriod;
unsigned long long int* systemAllPeriod; unsigned long long int* systemAllPeriod;
unsigned long long int* idleAllPeriod;
unsigned long long int* idlePeriod; unsigned long long int* idlePeriod;
unsigned long long int* nicePeriod; unsigned long long int* nicePeriod;
unsigned long long int* ioWaitPeriod; unsigned long long int* ioWaitPeriod;
@ -119,9 +117,8 @@ typedef struct ProcessList_ {
bool treeView; bool treeView;
bool highlightBaseName; bool highlightBaseName;
bool highlightMegabytes; bool highlightMegabytes;
bool highlightThreads; bool expandSystemTime;
bool detailedCPUTime; #ifdef DEBUG
#ifdef DEBUG_PROC
FILE* traceFile; FILE* traceFile;
#endif #endif
@ -130,7 +127,7 @@ typedef struct ProcessList_ {
static ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 }; static ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
#ifdef DEBUG_PROC #ifdef DEBUG
#define ProcessList_read(this, buffer, format, ...) ProcessList_xread(this, (vxscanf) vsscanf, buffer, format, ## __VA_ARGS__ ) #define ProcessList_read(this, buffer, format, ...) ProcessList_xread(this, (vxscanf) vsscanf, buffer, format, ## __VA_ARGS__ )
#define ProcessList_fread(this, file, format, ...) ProcessList_xread(this, (vxscanf) vfscanf, file, format, ## __VA_ARGS__ ) #define ProcessList_fread(this, file, format, ...) ProcessList_xread(this, (vxscanf) vfscanf, file, format, ## __VA_ARGS__ )
@ -207,14 +204,13 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
this = malloc(sizeof(ProcessList)); this = malloc(sizeof(ProcessList));
this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare); this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
this->processTable = Hashtable_new(70, false); this->processTable = Hashtable_new(70, false);
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
this->prototype = Process_new(this); this->prototype = Process_new(this);
this->usersTable = usersTable; this->usersTable = usersTable;
/* tree-view auxiliary buffers */ /* tree-view auxiliary buffers */
this->processes2 = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare); this->processes2 = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
#ifdef DEBUG_PROC #ifdef DEBUG
this->traceFile = fopen("/tmp/htop-proc-trace", "w"); this->traceFile = fopen("/tmp/htop-proc-trace", "w");
#endif #endif
@ -251,7 +247,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
this->treeView = false; this->treeView = false;
this->highlightBaseName = false; this->highlightBaseName = false;
this->highlightMegabytes = false; this->highlightMegabytes = false;
this->detailedCPUTime = false; this->expandSystemTime = false;
return this; return this;
} }
@ -266,7 +262,7 @@ void ProcessList_delete(ProcessList* this) {
// other fields are offsets of the same buffer // other fields are offsets of the same buffer
free(this->totalTime); free(this->totalTime);
#ifdef DEBUG_PROC #ifdef DEBUG
fclose(this->traceFile); fclose(this->traceFile);
#endif #endif
@ -283,10 +279,10 @@ void ProcessList_invertSortOrder(ProcessList* this) {
RichString ProcessList_printHeader(ProcessList* this) { RichString ProcessList_printHeader(ProcessList* this) {
RichString out; RichString out;
RichString_initVal(out); RichString_init(&out);
ProcessField* fields = this->fields; ProcessField* fields = this->fields;
for (int i = 0; fields[i]; i++) { for (int i = 0; fields[i]; i++) {
char* field = Process_fieldTitles[fields[i]]; char* field = Process_printField(fields[i]);
if (this->sortKey == fields[i]) if (this->sortKey == fields[i])
RichString_append(&out, CRT_colors[PANEL_HIGHLIGHT_FOCUS], field); RichString_append(&out, CRT_colors[PANEL_HIGHLIGHT_FOCUS], field);
else else
@ -295,27 +291,20 @@ RichString ProcessList_printHeader(ProcessList* this) {
return out; return out;
} }
static void ProcessList_add(ProcessList* this, Process* p) {
assert(Vector_indexOf(this->processes, p, Process_pidCompare) == -1); void ProcessList_prune(ProcessList* this) {
assert(Hashtable_get(this->processTable, p->pid) == NULL); Vector_prune(this->processes);
Vector_add(this->processes, p);
Hashtable_put(this->processTable, p->pid, p);
assert(Vector_indexOf(this->processes, p, Process_pidCompare) != -1);
assert(Hashtable_get(this->processTable, p->pid) != NULL);
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
} }
static void ProcessList_remove(ProcessList* this, Process* p) { void ProcessList_add(ProcessList* this, Process* p) {
assert(Vector_indexOf(this->processes, p, Process_pidCompare) != -1); Vector_add(this->processes, p);
assert(Hashtable_get(this->processTable, p->pid) != NULL); Hashtable_put(this->processTable, p->pid, p);
Process* pp = Hashtable_remove(this->processTable, p->pid); }
assert(pp == p); (void)pp;
unsigned int pid = p->pid; void ProcessList_remove(ProcessList* this, Process* p) {
Hashtable_remove(this->processTable, p->pid);
int index = Vector_indexOf(this->processes, p, Process_pidCompare); int index = Vector_indexOf(this->processes, p, Process_pidCompare);
assert(index != -1);
Vector_remove(this->processes, index); Vector_remove(this->processes, index);
assert(Hashtable_get(this->processTable, pid) == NULL); (void)pid;
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
} }
Process* ProcessList_get(ProcessList* this, int index) { Process* ProcessList_get(ProcessList* this, int index) {
@ -329,22 +318,21 @@ int ProcessList_size(ProcessList* this) {
static void ProcessList_buildTree(ProcessList* this, int pid, int level, int indent, int direction) { static void ProcessList_buildTree(ProcessList* this, int pid, int level, int indent, int direction) {
Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare); Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare);
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) { for (int i = 0; i < Vector_size(this->processes); i++) {
Process* process = (Process*) (Vector_get(this->processes, i)); Process* process = (Process*) (Vector_get(this->processes, i));
if (process->tgid == pid || (process->tgid == process->pid && process->ppid == pid)) { if (process->ppid == pid) {
Process* process = (Process*) (Vector_take(this->processes, i)); Process* process = (Process*) (Vector_take(this->processes, i));
Vector_add(children, process); Vector_add(children, process);
i--;
} }
} }
int size = Vector_size(children); int size = Vector_size(children);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Process* process = (Process*) (Vector_get(children, i)); Process* process = (Process*) (Vector_get(children, i));
int s = this->processes2->items;
if (direction == 1) if (direction == 1)
Vector_add(this->processes2, process); Vector_add(this->processes2, process);
else else
Vector_insert(this->processes2, 0, process); Vector_insert(this->processes2, 0, process);
assert(this->processes2->items == s+1); (void)s;
int nextIndent = indent; int nextIndent = indent;
if (i < size - 1) if (i < size - 1)
nextIndent = indent | (1 << level); nextIndent = indent | (1 << level);
@ -358,36 +346,18 @@ void ProcessList_sort(ProcessList* this) {
if (!this->treeView) { if (!this->treeView) {
Vector_sort(this->processes); Vector_sort(this->processes);
} else { } else {
// Save settings
int direction = this->direction; int direction = this->direction;
int sortKey = this->sortKey; int sortKey = this->sortKey;
// Sort by PID
this->sortKey = PID; this->sortKey = PID;
this->direction = 1; this->direction = 1;
Vector_sort(this->processes); Vector_sort(this->processes);
// Restore settings
this->sortKey = sortKey; this->sortKey = sortKey;
this->direction = direction; this->direction = direction;
// 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)); Process* init = (Process*) (Vector_take(this->processes, 0));
// This assertion crashes on hardened kernels. assert(init->pid == 1);
// I wonder how well tree view works on those systems.
// assert(init->pid == 1);
init->indent = 0; init->indent = 0;
Vector_add(this->processes2, init); Vector_add(this->processes2, init);
// Recursively empty list
ProcessList_buildTree(this, init->pid, 0, 0, direction); ProcessList_buildTree(this, init->pid, 0, 0, direction);
// Add leftovers
while (Vector_size(this->processes)) {
Process* p = (Process*) (Vector_take(this->processes, 0));
p->indent = 0;
Vector_add(this->processes2, p);
ProcessList_buildTree(this, p->pid, 0, 0, direction);
}
assert(Vector_size(this->processes2) == vsize); (void)vsize;
assert(Vector_size(this->processes) == 0);
// Swap listings around
Vector* t = this->processes; Vector* t = this->processes;
this->processes = this->processes2; this->processes = this->processes2;
this->processes2 = t; this->processes2 = t;
@ -401,7 +371,7 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
int size = fread(buf, 1, MAX_READ, f); int size = fread(buf, 1, MAX_READ, f);
if(!size) return 0; if(!size) return 0;
assert(proc->pid == atoi(buf)); proc->pid = atoi(buf);
char *location = strchr(buf, ' '); char *location = strchr(buf, ' ');
if(!location) return 0; if(!location) return 0;
@ -414,9 +384,9 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
command[commsize] = '\0'; command[commsize] = '\0';
location = end + 2; location = end + 2;
#ifdef DEBUG_PROC #ifdef DEBUG
int num = ProcessList_read(this, location, int num = ProcessList_read(this, location,
"%c %u %u %u %u %d %lu %lu %lu %lu " "%c %d %d %d %d %d %lu %lu %lu %lu "
"%lu %lu %lu %ld %ld %ld %ld %ld %ld " "%lu %lu %lu %ld %ld %ld %ld %ld %ld "
"%lu %lu %ld %lu %lu %lu %lu %lu " "%lu %lu %ld %lu %lu %lu %lu %lu "
"%lu %lu %lu %lu %lu %lu %lu %lu " "%lu %lu %lu %lu %lu %lu %lu %lu "
@ -425,7 +395,7 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
&proc->tpgid, &proc->flags, &proc->tpgid, &proc->flags,
&proc->minflt, &proc->cminflt, &proc->majflt, &proc->cmajflt, &proc->minflt, &proc->cminflt, &proc->majflt, &proc->cmajflt,
&proc->utime, &proc->stime, &proc->cutime, &proc->cstime, &proc->utime, &proc->stime, &proc->cutime, &proc->cstime,
&proc->priority, &proc->nice, &proc->nlwp, &proc->itrealvalue, &proc->priority, &proc->nice, &zero, &proc->itrealvalue,
&proc->starttime, &proc->vsize, &proc->rss, &proc->rlim, &proc->starttime, &proc->vsize, &proc->rss, &proc->rlim,
&proc->startcode, &proc->endcode, &proc->startstack, &proc->kstkesp, &proc->startcode, &proc->endcode, &proc->startstack, &proc->kstkesp,
&proc->kstkeip, &proc->signal, &proc->blocked, &proc->sigignore, &proc->kstkeip, &proc->signal, &proc->blocked, &proc->sigignore,
@ -434,7 +404,7 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
#else #else
long int uzero; long int uzero;
int num = ProcessList_read(this, location, int num = ProcessList_read(this, location,
"%c %u %u %u %u %d %lu %lu %lu %lu " "%c %d %d %d %d %d %lu %lu %lu %lu "
"%lu %lu %lu %ld %ld %ld %ld %ld %ld " "%lu %lu %lu %ld %ld %ld %ld %ld %ld "
"%lu %lu %ld %lu %lu %lu %lu %lu " "%lu %lu %ld %lu %lu %lu %lu %lu "
"%lu %lu %lu %lu %lu %lu %lu %lu " "%lu %lu %lu %lu %lu %lu %lu %lu "
@ -443,7 +413,7 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
&proc->tpgid, &proc->flags, &proc->tpgid, &proc->flags,
&zero, &zero, &zero, &zero, &zero, &zero, &zero, &zero,
&proc->utime, &proc->stime, &proc->cutime, &proc->cstime, &proc->utime, &proc->stime, &proc->cutime, &proc->cstime,
&proc->priority, &proc->nice, &proc->nlwp, &uzero, &proc->priority, &proc->nice, &uzero, &uzero,
&zero, &zero, &uzero, &zero, &zero, &zero, &uzero, &zero,
&zero, &zero, &zero, &zero, &zero, &zero, &zero, &zero,
&zero, &zero, &zero, &zero, &zero, &zero, &zero, &zero,
@ -459,72 +429,55 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
return 1; return 1;
} }
static bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name) { bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name) {
char statusfilename[MAX_NAME+1]; char statusfilename[MAX_NAME+1];
statusfilename[MAX_NAME] = '\0'; statusfilename[MAX_NAME] = '\0';
/*
snprintf(statusfilename, MAX_NAME, "%s/%s", dirname, name); bool success = false;
struct stat sstat; char buffer[256];
int statok = stat(statusfilename, &sstat); buffer[255] = '\0';
if (statok == -1) snprintf(statusfilename, MAX_NAME, "%s/%s/status", dirname, name);
return false; FILE* status = ProcessList_fopen(this, statusfilename, "r");
proc->st_uid = sstat.st_uid; if (status) {
return true; while (!feof(status)) {
} char* ok = fgets(buffer, 255, status);
#ifdef HAVE_TASKSTATS
static void ProcessList_readIoFile(ProcessList* this, Process* proc, char* dirname, char* name) {
char iofilename[MAX_NAME+1];
iofilename[MAX_NAME] = '\0';
snprintf(iofilename, MAX_NAME, "%s/%s/io", dirname, name);
FILE* io = ProcessList_fopen(this, iofilename, "r");
if (io) {
char buffer[256];
buffer[255] = '\0';
struct timeval tv;
gettimeofday(&tv,NULL);
unsigned long long now = tv.tv_sec*1000+tv.tv_usec/1000;
unsigned long long last_read = proc->io_read_bytes;
unsigned long long last_write = proc->io_write_bytes;
while (!feof(io)) {
char* ok = fgets(buffer, 255, io);
if (!ok) if (!ok)
break; break;
if (ProcessList_read(this, buffer, "rchar: %llu", &proc->io_rchar)) continue; if (String_startsWith(buffer, "Uid:")) {
if (ProcessList_read(this, buffer, "wchar: %llu", &proc->io_wchar)) continue; int uid1, uid2, uid3, uid4;
if (ProcessList_read(this, buffer, "syscr: %llu", &proc->io_syscr)) continue; // TODO: handle other uid's.
if (ProcessList_read(this, buffer, "syscw: %llu", &proc->io_syscw)) continue; int ok = ProcessList_read(this, buffer, "Uid:\t%d\t%d\t%d\t%d", &uid1, &uid2, &uid3, &uid4);
if (ProcessList_read(this, buffer, "read_bytes: %llu", &proc->io_read_bytes)) { if (ok >= 1) {
proc->io_rate_read_bps = proc->st_uid = uid1;
((double)(proc->io_read_bytes - last_read))/(((double)(now - proc->io_rate_read_time))/1000); success = true;
proc->io_rate_read_time = now; }
continue; break;
} }
if (ProcessList_read(this, buffer, "write_bytes: %llu", &proc->io_write_bytes)) {
proc->io_rate_write_bps =
((double)(proc->io_write_bytes - last_write))/(((double)(now - proc->io_rate_write_time))/1000);
proc->io_rate_write_time = now;
continue;
}
ProcessList_read(this, buffer, "cancelled_write_bytes: %llu", &proc->io_cancelled_write_bytes);
} }
fclose(io); fclose(status);
} }
if (!success) {
*/
snprintf(statusfilename, MAX_NAME, "%s/%s", dirname, name);
struct stat sstat;
int statok = stat(statusfilename, &sstat);
if (statok == -1)
return false;
proc->st_uid = sstat.st_uid;
return true;
/*
} else
return true;
*/
} }
#endif void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period) {
static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process* parent, float period) {
DIR* dir; DIR* dir;
struct dirent* entry; struct dirent* entry;
Process* prototype = this->prototype; Process* prototype = this->prototype;
dir = opendir(dirname); dir = opendir(dirname);
if (!dir) return false; assert(dir != NULL);
int processors = this->processorCount;
bool showUserlandThreads = !this->hideUserlandThreads;
while ((entry = readdir(dir)) != NULL) { while ((entry = readdir(dir)) != NULL) {
char* name = entry->d_name; char* name = entry->d_name;
int pid; int pid;
@ -541,47 +494,33 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
isThread = true; isThread = true;
} }
if (pid > 0) { if (pid > 0 && pid != parent) {
if (!this->hideUserlandThreads) {
char subdirname[MAX_NAME+1];
snprintf(subdirname, MAX_NAME, "%s/%s/task", dirname, name);
if (access(subdirname, X_OK) == 0) {
ProcessList_processEntries(this, subdirname, pid, period);
}
}
FILE* status; FILE* status;
char statusfilename[MAX_NAME+1]; char statusfilename[MAX_NAME+1];
char command[PROCESS_COMM_LEN + 1]; char command[PROCESS_COMM_LEN + 1];
Process* process = NULL; Process* process;
Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid); Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid);
if (existingProcess) { if (existingProcess) {
assert(Vector_indexOf(this->processes, existingProcess, Process_pidCompare) != -1);
process = existingProcess; process = existingProcess;
assert(process->pid == pid);
} else { } else {
if (parent && parent->pid == pid) { process = prototype;
process = parent; process->comm = NULL;
} else { process->pid = pid;
process = prototype;
assert(process->comm == NULL);
process->pid = pid;
}
}
process->tgid = parent ? parent->pid : pid;
if (showUserlandThreads && (!parent || pid != parent->pid)) {
char subdirname[MAX_NAME+1];
snprintf(subdirname, MAX_NAME, "%s/%s/task", dirname, name);
if (ProcessList_processEntries(this, subdirname, process, period))
continue;
}
#ifdef HAVE_TASKSTATS
ProcessList_readIoFile(this, process, dirname, name);
#endif
process->updated = true;
if (!existingProcess)
if (! ProcessList_readStatusFile(this, process, dirname, name)) if (! ProcessList_readStatusFile(this, process, dirname, name))
goto errorReadingProcess; goto errorReadingProcess;
}
process->updated = true;
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name); snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r"); status = ProcessList_fopen(this, statusfilename, "r");
@ -591,7 +530,7 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
} }
int num = ProcessList_fread(this, status, "%d %d %d %d %d %d %d", int num = ProcessList_fread(this, status, "%d %d %d %d %d %d %d",
&process->m_size, &process->m_resident, &process->m_share, &process->m_size, &process->m_resident, &process->m_share,
&process->m_trs, &process->m_lrs, &process->m_drs, &process->m_trs, &process->m_drs, &process->m_lrs,
&process->m_dt); &process->m_dt);
fclose(status); fclose(status);
@ -606,73 +545,16 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name); snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r"); status = ProcessList_fopen(this, statusfilename, "r");
if (status == NULL) if (status == NULL)
goto errorReadingProcess; goto errorReadingProcess;
int success = ProcessList_readStatFile(this, process, status, command); int success = ProcessList_readStatFile(this, process, status, command);
fclose(status); fclose(status);
if(!success) { if(!success)
goto errorReadingProcess; goto errorReadingProcess;
}
if(!existingProcess) { if(!existingProcess) {
process->user = UsersTable_getRef(this->usersTable, process->st_uid); process->user = UsersTable_getRef(this->usersTable, process->st_uid);
#ifdef HAVE_OPENVZ
if (access("/proc/vz", R_OK) != 0) {
process->vpid = process->pid;
process->ctid = 0;
} else {
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r");
if (status == NULL)
goto errorReadingProcess;
num = ProcessList_fread(this, status,
"%*u %*s %*c %*u %*u %*u %*u %*u %*u %*u "
"%*u %*u %*u %*u %*u %*u %*u %*u "
"%*u %*u %*u %*u %*u %*u %*u %*u "
"%*u %*u %*u %*u %*u %*u %*u %*u "
"%*u %*u %*u %*u %*u %*u %*u %*u "
"%*u %*u %*u %*u %*u %*u %*u "
"%*u %*u %u %u",
&process->vpid, &process->ctid);
fclose(status);
}
#endif
#ifdef HAVE_VSERVER
snprintf(statusfilename, MAX_NAME, "%s/%s/status", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r");
if (status == NULL)
goto errorReadingProcess;
else {
char buffer[256];
process->vxid = 0;
while (!feof(status)) {
char* ok = fgets(buffer, 255, status);
if (!ok)
break;
if (String_startsWith(buffer, "VxID:")) {
int vxid;
int ok = ProcessList_read(this, buffer, "VxID:\t%d", &vxid);
if (ok >= 1) {
process->vxid = vxid;
}
}
#if defined HAVE_ANCIENT_VSERVER
else if (String_startsWith(buffer, "s_context:")) {
int vxid;
int ok = ProcessList_read(this, buffer, "s_context:\t%d", &vxid);
if (ok >= 1) {
process->vxid = vxid;
}
}
#endif
}
fclose(status);
}
#endif
snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name); snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r"); status = ProcessList_fopen(this, statusfilename, "r");
@ -692,12 +574,11 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
fclose(status); fclose(status);
} }
int percent_cpu = (process->utime + process->stime - lasttimes) / process->percent_cpu = (process->utime + process->stime - lasttimes) /
period * 100.0; period * 100.0;
process->percent_cpu = MAX(MIN(percent_cpu, processors*100.0), 0.0);
process->percent_mem = (process->m_resident * PAGE_SIZE_KB) / process->percent_mem = process->m_resident /
(float)(this->totalMem) * (float)(this->usedMem - this->cachedMem - this->buffersMem) *
100.0; 100.0;
this->totalTasks++; this->totalTasks++;
@ -714,29 +595,27 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
// Exception handler. // Exception handler.
errorReadingProcess: { errorReadingProcess: {
if (process->comm) {
free(process->comm);
process->comm = NULL;
}
if (existingProcess) if (existingProcess)
ProcessList_remove(this, process); ProcessList_remove(this, process);
assert(Hashtable_count(this->processTable) == Vector_count(this->processes)); else {
if (process->comm)
free(process->comm);
}
} }
} }
} }
prototype->comm = NULL;
closedir(dir); closedir(dir);
return true;
} }
void ProcessList_scan(ProcessList* this) { void ProcessList_scan(ProcessList* this) {
unsigned long long int usertime, nicetime, systemtime, systemalltime, idlealltime, idletime, totaltime; unsigned long long int usertime, nicetime, systemtime, systemalltime, idletime, totaltime;
unsigned long long int swapFree; unsigned long long int swapFree;
FILE* status; FILE* status;
char buffer[128]; char buffer[128];
status = ProcessList_fopen(this, PROCMEMINFOFILE, "r"); status = ProcessList_fopen(this, PROCMEMINFOFILE, "r");
assert(status != NULL); assert(status != NULL);
int processors = this->processorCount;
while (!feof(status)) { while (!feof(status)) {
fgets(buffer, 128, status); fgets(buffer, 128, status);
@ -773,7 +652,7 @@ void ProcessList_scan(ProcessList* this) {
status = ProcessList_fopen(this, PROCSTATFILE, "r"); status = ProcessList_fopen(this, PROCSTATFILE, "r");
assert(status != NULL); assert(status != NULL);
for (int i = 0; i <= processors; i++) { for (int i = 0; i <= this->processorCount; i++) {
char buffer[256]; char buffer[256];
int cpuid; int cpuid;
unsigned long long int ioWait, irq, softIrq, steal; unsigned long long int ioWait, irq, softIrq, steal;
@ -790,16 +669,14 @@ void ProcessList_scan(ProcessList* this) {
} }
// Fields existing on kernels >= 2.6 // Fields existing on kernels >= 2.6
// (and RHEL's patched kernel 2.4...) // (and RHEL's patched kernel 2.4...)
idlealltime = idletime + ioWait; systemalltime = systemtime + ioWait + irq + softIrq + steal;
systemalltime = systemtime + irq + softIrq + steal; totaltime = usertime + nicetime + systemalltime + idletime;
totaltime = usertime + nicetime + systemalltime + idlealltime;
assert (usertime >= this->userTime[i]); assert (usertime >= this->userTime[i]);
assert (nicetime >= this->niceTime[i]); assert (nicetime >= this->niceTime[i]);
assert (systemtime >= this->systemTime[i]); assert (systemtime >= this->systemTime[i]);
assert (idletime >= this->idleTime[i]); assert (idletime >= this->idleTime[i]);
assert (totaltime >= this->totalTime[i]); assert (totaltime >= this->totalTime[i]);
assert (systemalltime >= this->systemAllTime[i]); assert (systemalltime >= this->systemAllTime[i]);
assert (idlealltime >= this->idleAllTime[i]);
assert (ioWait >= this->ioWaitTime[i]); assert (ioWait >= this->ioWaitTime[i]);
assert (irq >= this->irqTime[i]); assert (irq >= this->irqTime[i]);
assert (softIrq >= this->softIrqTime[i]); assert (softIrq >= this->softIrqTime[i]);
@ -808,7 +685,6 @@ void ProcessList_scan(ProcessList* this) {
this->nicePeriod[i] = nicetime - this->niceTime[i]; this->nicePeriod[i] = nicetime - this->niceTime[i];
this->systemPeriod[i] = systemtime - this->systemTime[i]; this->systemPeriod[i] = systemtime - this->systemTime[i];
this->systemAllPeriod[i] = systemalltime - this->systemAllTime[i]; this->systemAllPeriod[i] = systemalltime - this->systemAllTime[i];
this->idleAllPeriod[i] = idlealltime - this->idleAllTime[i];
this->idlePeriod[i] = idletime - this->idleTime[i]; this->idlePeriod[i] = idletime - this->idleTime[i];
this->ioWaitPeriod[i] = ioWait - this->ioWaitTime[i]; this->ioWaitPeriod[i] = ioWait - this->ioWaitTime[i];
this->irqPeriod[i] = irq - this->irqTime[i]; this->irqPeriod[i] = irq - this->irqTime[i];
@ -819,7 +695,6 @@ void ProcessList_scan(ProcessList* this) {
this->niceTime[i] = nicetime; this->niceTime[i] = nicetime;
this->systemTime[i] = systemtime; this->systemTime[i] = systemtime;
this->systemAllTime[i] = systemalltime; this->systemAllTime[i] = systemalltime;
this->idleAllTime[i] = idlealltime;
this->idleTime[i] = idletime; this->idleTime[i] = idletime;
this->ioWaitTime[i] = ioWait; this->ioWaitTime[i] = ioWait;
this->irqTime[i] = irq; this->irqTime[i] = irq;
@ -827,7 +702,7 @@ void ProcessList_scan(ProcessList* this) {
this->stealTime[i] = steal; this->stealTime[i] = steal;
this->totalTime[i] = totaltime; this->totalTime[i] = totaltime;
} }
float period = (float)this->totalPeriod[0] / processors; float period = (float)this->totalPeriod[0] / this->processorCount;
fclose(status); fclose(status);
// mark all process as "dirty" // mark all process as "dirty"
@ -838,8 +713,8 @@ void ProcessList_scan(ProcessList* this) {
this->totalTasks = 0; this->totalTasks = 0;
this->runningTasks = 0; this->runningTasks = 0;
ProcessList_processEntries(this, PROCDIR, NULL, period); ProcessList_processEntries(this, PROCDIR, 0, period);
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) { for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
Process* p = (Process*) Vector_get(this->processes, i); Process* p = (Process*) Vector_get(this->processes, i);
@ -850,17 +725,3 @@ void ProcessList_scan(ProcessList* this) {
} }
} }
ProcessField ProcessList_keyAt(ProcessList* this, int at) {
int x = 0;
ProcessField* fields = this->fields;
ProcessField field;
for (int i = 0; (field = fields[i]); i++) {
int len = strlen(Process_fieldTitles[field]);
if (at >= x && at <= x + len) {
return field;
}
x += len;
}
return COMM;
}

View File

@ -39,11 +39,11 @@ in the source distribution for its full text.
#endif #endif
#ifndef PROCSTATFILE #ifndef PROCSTATFILE
#define PROCSTATFILE PROCDIR "/stat" #define PROCSTATFILE "/proc/stat"
#endif #endif
#ifndef PROCMEMINFOFILE #ifndef PROCMEMINFOFILE
#define PROCMEMINFOFILE PROCDIR "/meminfo" #define PROCMEMINFOFILE "/proc/meminfo"
#endif #endif
#ifndef MAX_NAME #ifndef MAX_NAME
@ -55,12 +55,12 @@ in the source distribution for its full text.
#endif #endif
#ifndef PER_PROCESSOR_FIELDS #ifndef PER_PROCESSOR_FIELDS
#define PER_PROCESSOR_FIELDS 22 #define PER_PROCESSOR_FIELDS 20
#endif #endif
#ifdef DEBUG_PROC #ifdef DEBUG
typedef int(*vxscanf)(void*, const char*, va_list); typedef int(*vxscanf)(void*, const char*, va_list);
#endif #endif
@ -80,7 +80,6 @@ typedef struct ProcessList_ {
unsigned long long int* userTime; unsigned long long int* userTime;
unsigned long long int* systemTime; unsigned long long int* systemTime;
unsigned long long int* systemAllTime; unsigned long long int* systemAllTime;
unsigned long long int* idleAllTime;
unsigned long long int* idleTime; unsigned long long int* idleTime;
unsigned long long int* niceTime; unsigned long long int* niceTime;
unsigned long long int* ioWaitTime; unsigned long long int* ioWaitTime;
@ -91,7 +90,6 @@ typedef struct ProcessList_ {
unsigned long long int* userPeriod; unsigned long long int* userPeriod;
unsigned long long int* systemPeriod; unsigned long long int* systemPeriod;
unsigned long long int* systemAllPeriod; unsigned long long int* systemAllPeriod;
unsigned long long int* idleAllPeriod;
unsigned long long int* idlePeriod; unsigned long long int* idlePeriod;
unsigned long long int* nicePeriod; unsigned long long int* nicePeriod;
unsigned long long int* ioWaitPeriod; unsigned long long int* ioWaitPeriod;
@ -119,15 +117,14 @@ typedef struct ProcessList_ {
bool treeView; bool treeView;
bool highlightBaseName; bool highlightBaseName;
bool highlightMegabytes; bool highlightMegabytes;
bool highlightThreads; bool expandSystemTime;
bool detailedCPUTime; #ifdef DEBUG
#ifdef DEBUG_PROC
FILE* traceFile; FILE* traceFile;
#endif #endif
} ProcessList; } ProcessList;
#ifdef DEBUG_PROC #ifdef DEBUG
#define ProcessList_read(this, buffer, format, ...) ProcessList_xread(this, (vxscanf) vsscanf, buffer, format, ## __VA_ARGS__ ) #define ProcessList_read(this, buffer, format, ...) ProcessList_xread(this, (vxscanf) vsscanf, buffer, format, ## __VA_ARGS__ )
#define ProcessList_fread(this, file, format, ...) ProcessList_xread(this, (vxscanf) vfscanf, file, format, ## __VA_ARGS__ ) #define ProcessList_fread(this, file, format, ...) ProcessList_xread(this, (vxscanf) vfscanf, file, format, ## __VA_ARGS__ )
@ -150,18 +147,23 @@ void ProcessList_invertSortOrder(ProcessList* this);
RichString ProcessList_printHeader(ProcessList* this); RichString ProcessList_printHeader(ProcessList* this);
void ProcessList_prune(ProcessList* this);
void ProcessList_add(ProcessList* this, Process* p);
void ProcessList_remove(ProcessList* this, Process* p);
Process* ProcessList_get(ProcessList* this, int index); Process* ProcessList_get(ProcessList* this, int index);
int ProcessList_size(ProcessList* this); int ProcessList_size(ProcessList* this);
void ProcessList_sort(ProcessList* this); void ProcessList_sort(ProcessList* this);
#ifdef HAVE_TASKSTATS bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name);
#endif void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period);
void ProcessList_scan(ProcessList* this); void ProcessList_scan(ProcessList* this);
ProcessField ProcessList_keyAt(ProcessList* this, int at);
#endif #endif

2
README
View File

@ -2,7 +2,7 @@
htop htop
by Hisham Muhammad <loderunner@users.sourceforge.net> by Hisham Muhammad <loderunner@users.sourceforge.net>
May, 2004 - June, 2009 May, 2004 - July, 2006
Introduction Introduction
~~~~~~~~~~~~ ~~~~~~~~~~~~

View File

@ -1,22 +1,12 @@
#include "RichString.h" #include "RichString.h"
#ifndef CONFIG_H
#define CONFIG_H
#include "config.h"
#endif
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <curses.h>
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
#ifdef HAVE_LIBNCURSESW
#include <curses.h>
#else
#include <ncursesw/curses.h>
#endif
#define RICHSTRING_MAXLEN 300 #define RICHSTRING_MAXLEN 300
@ -25,23 +15,9 @@
#define RichString_init(this) (this)->len = 0 #define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0 #define RichString_initVal(this) (this).len = 0
#ifdef HAVE_LIBNCURSESW
#define RichString_printVal(this, y, x) mvadd_wchstr(y, x, this.chstr)
#define RichString_printoffnVal(this, y, x, off, n) mvadd_wchnstr(y, x, this.chstr + off, n)
#define RichString_getCharVal(this, i) (this.chstr[i].chars[0] & 255)
#else
#define RichString_printVal(this, y, x) mvaddchstr(y, x, this.chstr)
#define RichString_printoffnVal(this, y, x, off, n) mvaddchnstr(y, x, this.chstr + off, n)
#define RichString_getCharVal(this, i) (this.chstr[i])
#endif
typedef struct RichString_ { typedef struct RichString_ {
int len; int len;
#ifdef HAVE_LIBNCURSESW
cchar_t chstr[RICHSTRING_MAXLEN+1];
#else
chtype chstr[RICHSTRING_MAXLEN+1]; chtype chstr[RICHSTRING_MAXLEN+1];
#endif
} RichString; } RichString;
}*/ }*/
@ -50,88 +26,37 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
#endif #endif
#ifdef HAVE_LIBNCURSESW void RichString_write(RichString* this, int attrs, char* data) {
RichString_init(this);
inline void RichString_appendn(RichString* this, int attrs, char* data_c, int len) { RichString_append(this, attrs, data);
wchar_t data[RICHSTRING_MAXLEN];
len = mbstowcs(data, data_c, RICHSTRING_MAXLEN);
if (len<0)
return;
int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
for (int i = this->len, j = 0; i < last; i++, j++) {
memset(&this->chstr[i], 0, sizeof(this->chstr[i]));
this->chstr[i].chars[0] = data[j];
this->chstr[i].attr = attrs;
}
this->chstr[last].chars[0] = 0;
this->len = last;
}
inline void RichString_setAttrn(RichString *this, int attrs, int start, int finish) {
cchar_t* ch = this->chstr + start;
for (int i = start; i <= finish; i++) {
ch->attr = attrs;
ch++;
}
}
int RichString_findChar(RichString *this, char c, int start) {
wchar_t wc = btowc(c);
cchar_t* ch = this->chstr + start;
for (int i = start; i < this->len; i++) {
if (ch->chars[0] == wc)
return i;
ch++;
}
return -1;
}
#else
inline void RichString_appendn(RichString* this, int attrs, char* data_c, int len) {
int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
for (int i = this->len, j = 0; i < last; i++, j++)
this->chstr[i] = (isprint(data_c[j]) ? data_c[j] : '?') | attrs;
this->chstr[last] = 0;
this->len = last;
}
void RichString_setAttrn(RichString *this, int attrs, int start, int finish) {
chtype* ch = this->chstr + start;
for (int i = start; i <= finish; i++) {
*ch = (*ch & 0xff) | attrs;
ch++;
}
}
int RichString_findChar(RichString *this, char c, int start) {
chtype* ch = this->chstr + start;
for (int i = start; i < this->len; i++) {
if ((*ch & 0xff) == c)
return i;
ch++;
}
return -1;
}
#endif
void RichString_prune(RichString* this) {
this->len = 0;
}
void RichString_setAttr(RichString *this, int attrs) {
RichString_setAttrn(this, attrs, 0, this->len - 1);
} }
inline void RichString_append(RichString* this, int attrs, char* data) { inline void RichString_append(RichString* this, int attrs, char* data) {
RichString_appendn(this, attrs, data, strlen(data)); RichString_appendn(this, attrs, data, strlen(data));
} }
void RichString_write(RichString* this, int attrs, char* data) { inline void RichString_appendn(RichString* this, int attrs, char* data, int len) {
RichString_init(this); int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
RichString_append(this, attrs, data); for (int i = this->len, j = 0; i < last; i++, j++)
this->chstr[i] = data[j] | attrs;
this->chstr[last] = 0;
this->len = last;
}
void RichString_setAttr(RichString *this, int attrs) {
chtype* ch = this->chstr;
for (int i = 0; i < this->len; i++) {
*ch = (*ch & 0xff) | attrs;
ch++;
}
}
void RichString_applyAttr(RichString *this, int attrs) {
chtype* ch = this->chstr;
for (int i = 0; i < this->len; i++) {
*ch |= attrs;
ch++;
}
} }
RichString RichString_quickString(int attrs, char* data) { RichString RichString_quickString(int attrs, char* data) {

View File

@ -4,22 +4,12 @@
#define HEADER_RichString #define HEADER_RichString
#ifndef CONFIG_H
#define CONFIG_H
#include "config.h"
#endif
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <curses.h>
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
#ifdef HAVE_LIBNCURSESW
#include <curses.h>
#else
#include <ncursesw/curses.h>
#endif
#define RICHSTRING_MAXLEN 300 #define RICHSTRING_MAXLEN 300
@ -27,23 +17,9 @@
#define RichString_init(this) (this)->len = 0 #define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0 #define RichString_initVal(this) (this).len = 0
#ifdef HAVE_LIBNCURSESW
#define RichString_printVal(this, y, x) mvadd_wchstr(y, x, this.chstr)
#define RichString_printoffnVal(this, y, x, off, n) mvadd_wchnstr(y, x, this.chstr + off, n)
#define RichString_getCharVal(this, i) (this.chstr[i].chars[0] & 255)
#else
#define RichString_printVal(this, y, x) mvaddchstr(y, x, this.chstr)
#define RichString_printoffnVal(this, y, x, off, n) mvaddchnstr(y, x, this.chstr + off, n)
#define RichString_getCharVal(this, i) (this.chstr[i])
#endif
typedef struct RichString_ { typedef struct RichString_ {
int len; int len;
#ifdef HAVE_LIBNCURSESW
cchar_t chstr[RICHSTRING_MAXLEN+1];
#else
chtype chstr[RICHSTRING_MAXLEN+1]; chtype chstr[RICHSTRING_MAXLEN+1];
#endif
} RichString; } RichString;
@ -51,31 +27,15 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
#endif #endif
#ifdef HAVE_LIBNCURSESW void RichString_write(RichString* this, int attrs, char* data);
extern void RichString_appendn(RichString* this, int attrs, char* data_c, int len); inline void RichString_append(RichString* this, int attrs, char* data);
extern void RichString_setAttrn(RichString *this, int attrs, int start, int finish); inline void RichString_appendn(RichString* this, int attrs, char* data, int len);
int RichString_findChar(RichString *this, char c, int start);
#else
extern void RichString_appendn(RichString* this, int attrs, char* data_c, int len);
void RichString_setAttrn(RichString *this, int attrs, int start, int finish);
int RichString_findChar(RichString *this, char c, int start);
#endif
void RichString_prune(RichString* this);
void RichString_setAttr(RichString *this, int attrs); void RichString_setAttr(RichString *this, int attrs);
extern void RichString_append(RichString* this, int attrs, char* data); void RichString_applyAttr(RichString *this, int attrs);
void RichString_write(RichString* this, int attrs, char* data);
RichString RichString_quickString(int attrs, char* data); RichString RichString_quickString(int attrs, char* data);

View File

@ -83,7 +83,7 @@ void ScreenManager_add(ScreenManager* this, Panel* item, FunctionBar* fuBar, int
if (fuBar) if (fuBar)
Vector_add(this->fuBars, fuBar); Vector_add(this->fuBars, fuBar);
else else
Vector_add(this->fuBars, FunctionBar_new(NULL, NULL, NULL)); Vector_add(this->fuBars, FunctionBar_new(0, NULL, NULL, NULL));
if (!this->fuBar && fuBar) this->fuBar = fuBar; if (!this->fuBar && fuBar) this->fuBar = fuBar;
item->needsRedraw = true; item->needsRedraw = true;
this->itemCount++; this->itemCount++;
@ -98,6 +98,12 @@ Panel* ScreenManager_remove(ScreenManager* this, int index) {
return panel; return panel;
} }
void ScreenManager_setFunctionBar(ScreenManager* this, FunctionBar* fuBar) {
if (this->owner && this->fuBar)
FunctionBar_delete((Object*)this->fuBar);
this->fuBar = fuBar;
}
void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2) { void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2) {
this->x1 = x1; this->x1 = x1;
this->y1 = y1; this->y1 = y1;
@ -144,6 +150,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
ch = getch(); ch = getch();
bool loop = false;
if (ch == KEY_MOUSE) { if (ch == KEY_MOUSE) {
MEVENT mevent; MEVENT mevent;
int ok = getmouse(&mevent); int ok = getmouse(&mevent);
@ -158,12 +165,14 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
focus = i; focus = i;
panelFocus = panel; panelFocus = panel;
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1); Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
loop = true;
break; break;
} }
} }
} }
} }
} }
if (loop) continue;
if (panelFocus->eventHandler) { if (panelFocus->eventHandler) {
HandlerResult result = panelFocus->eventHandler(panelFocus, ch); HandlerResult result = panelFocus->eventHandler(panelFocus, ch);
@ -188,7 +197,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
if (focus > 0) if (focus > 0)
focus--; focus--;
panelFocus = (Panel*) Vector_get(this->items, focus); panelFocus = (Panel*) Vector_get(this->items, focus);
if (Panel_size(panelFocus) == 0 && focus > 0) if (Panel_getSize(panelFocus) == 0 && focus > 0)
goto tryLeft; goto tryLeft;
break; break;
case KEY_RIGHT: case KEY_RIGHT:
@ -197,7 +206,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
if (focus < this->itemCount - 1) if (focus < this->itemCount - 1)
focus++; focus++;
panelFocus = (Panel*) Vector_get(this->items, focus); panelFocus = (Panel*) Vector_get(this->items, focus);
if (Panel_size(panelFocus) == 0 && focus < this->itemCount - 1) if (Panel_getSize(panelFocus) == 0 && focus < this->itemCount - 1)
goto tryRight; goto tryRight;
break; break;
case KEY_F(10): case KEY_F(10):

View File

@ -43,12 +43,14 @@ ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation ori
void ScreenManager_delete(ScreenManager* this); void ScreenManager_delete(ScreenManager* this);
extern int ScreenManager_size(ScreenManager* this); inline int ScreenManager_size(ScreenManager* this);
void ScreenManager_add(ScreenManager* this, Panel* item, FunctionBar* fuBar, int size); void ScreenManager_add(ScreenManager* this, Panel* item, FunctionBar* fuBar, int size);
Panel* ScreenManager_remove(ScreenManager* this, int index); Panel* ScreenManager_remove(ScreenManager* this, int index);
void ScreenManager_setFunctionBar(ScreenManager* this, FunctionBar* fuBar);
void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2); void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2);
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey); void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey);

View File

@ -27,6 +27,39 @@ typedef struct Settings_ {
}*/ }*/
Settings* Settings_new(ProcessList* pl, Header* header) {
Settings* this = malloc(sizeof(Settings));
this->pl = pl;
this->header = header;
char* home;
char* rcfile;
home = getenv("HOME_ETC");
if (!home) home = getenv("HOME");
if (!home) home = "";
rcfile = getenv("HOMERC");
if (!rcfile)
this->userSettings = String_cat(home, "/.htoprc");
else
this->userSettings = String_copy(rcfile);
this->colorScheme = 0;
this->changed = false;
this->delay = DEFAULT_DELAY;
bool ok = Settings_read(this, this->userSettings);
if (!ok) {
this->changed = true;
// TODO: how to get SYSCONFDIR correctly through Autoconf?
char* systemSettings = String_cat(SYSCONFDIR, "/htoprc");
ok = Settings_read(this, systemSettings);
free(systemSettings);
if (!ok) {
Header_defaultMeters(this->header);
pl->hideKernelThreads = true;
pl->highlightMegabytes = true;
}
}
return this;
}
void Settings_delete(Settings* this) { void Settings_delete(Settings* this) {
free(this->userSettings); free(this->userSettings);
free(this); free(this);
@ -55,7 +88,7 @@ static void Settings_readMeterModes(Settings* this, char* line, HeaderSide side)
String_freeArray(ids); String_freeArray(ids);
} }
static bool Settings_read(Settings* this, char* fileName) { bool Settings_read(Settings* this, char* fileName) {
// TODO: implement File object and make // TODO: implement File object and make
// file I/O object-oriented. // file I/O object-oriented.
FILE* fd; FILE* fd;
@ -63,7 +96,7 @@ static bool Settings_read(Settings* this, char* fileName) {
if (fd == NULL) { if (fd == NULL) {
return false; return false;
} }
const int maxLine = 65535; const int maxLine = 512;
char buffer[maxLine]; char buffer[maxLine];
bool readMeters = false; bool readMeters = false;
while (!feof(fd)) { while (!feof(fd)) {
@ -104,15 +137,10 @@ static bool Settings_read(Settings* this, char* fileName) {
this->pl->highlightBaseName = atoi(option[1]); this->pl->highlightBaseName = atoi(option[1]);
} else if (String_eq(option[0], "highlight_megabytes")) { } else if (String_eq(option[0], "highlight_megabytes")) {
this->pl->highlightMegabytes = atoi(option[1]); this->pl->highlightMegabytes = atoi(option[1]);
} else if (String_eq(option[0], "highlight_threads")) {
this->pl->highlightThreads = atoi(option[1]);
} else if (String_eq(option[0], "header_margin")) { } else if (String_eq(option[0], "header_margin")) {
this->header->margin = atoi(option[1]); this->header->margin = atoi(option[1]);
} else if (String_eq(option[0], "expand_system_time")) { } else if (String_eq(option[0], "expand_system_time")) {
// Compatibility option. this->pl->expandSystemTime = atoi(option[1]);
this->pl->detailedCPUTime = atoi(option[1]);
} else if (String_eq(option[0], "detailed_cpu_time")) {
this->pl->detailedCPUTime = atoi(option[1]);
} else if (String_eq(option[0], "delay")) { } else if (String_eq(option[0], "delay")) {
this->delay = atoi(option[1]); this->delay = atoi(option[1]);
} else if (String_eq(option[0], "color_scheme")) { } else if (String_eq(option[0], "color_scheme")) {
@ -167,10 +195,9 @@ bool Settings_write(Settings* this) {
fprintf(fd, "shadow_other_users=%d\n", (int) this->pl->shadowOtherUsers); fprintf(fd, "shadow_other_users=%d\n", (int) this->pl->shadowOtherUsers);
fprintf(fd, "highlight_base_name=%d\n", (int) this->pl->highlightBaseName); fprintf(fd, "highlight_base_name=%d\n", (int) this->pl->highlightBaseName);
fprintf(fd, "highlight_megabytes=%d\n", (int) this->pl->highlightMegabytes); fprintf(fd, "highlight_megabytes=%d\n", (int) this->pl->highlightMegabytes);
fprintf(fd, "highlight_threads=%d\n", (int) this->pl->highlightThreads);
fprintf(fd, "tree_view=%d\n", (int) this->pl->treeView); fprintf(fd, "tree_view=%d\n", (int) this->pl->treeView);
fprintf(fd, "header_margin=%d\n", (int) this->header->margin); fprintf(fd, "header_margin=%d\n", (int) this->header->margin);
fprintf(fd, "detailed_cpu_time=%d\n", (int) this->pl->detailedCPUTime); fprintf(fd, "expand_system_time=%d\n", (int) this->pl->expandSystemTime);
fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme); fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme);
fprintf(fd, "delay=%d\n", (int) this->delay); fprintf(fd, "delay=%d\n", (int) this->delay);
fprintf(fd, "left_meters="); fprintf(fd, "left_meters=");
@ -194,41 +221,6 @@ bool Settings_write(Settings* this) {
fprintf(fd, "right_meter_modes="); fprintf(fd, "right_meter_modes=");
for (int i = 0; i < Header_size(this->header, RIGHT_HEADER); i++) for (int i = 0; i < Header_size(this->header, RIGHT_HEADER); i++)
fprintf(fd, "%d ", Header_readMeterMode(this->header, i, RIGHT_HEADER)); fprintf(fd, "%d ", Header_readMeterMode(this->header, i, RIGHT_HEADER));
fprintf(fd, "\n");
fclose(fd); fclose(fd);
return true; return true;
} }
Settings* Settings_new(ProcessList* pl, Header* header) {
Settings* this = malloc(sizeof(Settings));
this->pl = pl;
this->header = header;
char* home;
char* rcfile;
home = getenv("HOME_ETC");
if (!home) home = getenv("HOME");
if (!home) home = "";
rcfile = getenv("HOMERC");
if (!rcfile)
this->userSettings = String_cat(home, "/.htoprc");
else
this->userSettings = String_copy(rcfile);
this->colorScheme = 0;
this->changed = false;
this->delay = DEFAULT_DELAY;
bool ok = Settings_read(this, this->userSettings);
if (!ok) {
this->changed = true;
// TODO: how to get SYSCONFDIR correctly through Autoconf?
char* systemSettings = String_cat(SYSCONFDIR, "/htoprc");
ok = Settings_read(this, systemSettings);
free(systemSettings);
if (!ok) {
Header_defaultMeters(this->header);
pl->hideKernelThreads = true;
pl->highlightMegabytes = true;
pl->highlightThreads = false;
}
}
return this;
}

View File

@ -28,10 +28,12 @@ typedef struct Settings_ {
} Settings; } Settings;
Settings* Settings_new(ProcessList* pl, Header* header);
void Settings_delete(Settings* this); void Settings_delete(Settings* this);
bool Settings_read(Settings* this, char* fileName);
bool Settings_write(Settings* this); bool Settings_write(Settings* this);
Settings* Settings_new(ProcessList* pl, Header* header);
#endif #endif

View File

@ -31,23 +31,7 @@ char* SIGNAL_CLASS = "Signal";
#define SIGNAL_CLASS NULL #define SIGNAL_CLASS NULL
#endif #endif
static void Signal_delete(Object* cast) { Signal* Signal_new(char* name, int number) {
Signal* this = (Signal*)cast;
assert (this != NULL);
// names are string constants, so we're not deleting them.
free(this);
}
static void Signal_display(Object* cast, RichString* out) {
Signal* this = (Signal*)cast;
assert (this != NULL);
char buffer[31];
snprintf(buffer, 30, "%2d %s", this->number, this->name);
RichString_write(out, CRT_colors[DEFAULT_COLOR], buffer);
}
static Signal* Signal_new(char* name, int number) {
Signal* this = malloc(sizeof(Signal)); Signal* this = malloc(sizeof(Signal));
Object_setClass(this, SIGNAL_CLASS); Object_setClass(this, SIGNAL_CLASS);
((Object*)this)->display = Signal_display; ((Object*)this)->display = Signal_display;
@ -57,6 +41,22 @@ static Signal* Signal_new(char* name, int number) {
return this; return this;
} }
void Signal_delete(Object* cast) {
Signal* this = (Signal*)cast;
assert (this != NULL);
// names are string constants, so we're not deleting them.
free(this);
}
void Signal_display(Object* cast, RichString* out) {
Signal* this = (Signal*)cast;
assert (this != NULL);
char buffer[31];
snprintf(buffer, 30, "%2d %s", this->number, this->name);
RichString_write(out, CRT_colors[DEFAULT_COLOR], buffer);
}
int Signal_getSignalCount() { int Signal_getSignalCount() {
return SIGNAL_COUNT; return SIGNAL_COUNT;
} }

View File

@ -32,6 +32,12 @@ extern char* SIGNAL_CLASS;
#define SIGNAL_CLASS NULL #define SIGNAL_CLASS NULL
#endif #endif
Signal* Signal_new(char* name, int number);
void Signal_delete(Object* cast);
void Signal_display(Object* cast, RichString* out);
int Signal_getSignalCount(); int Signal_getSignalCount();
Signal** Signal_getSignalTable(); Signal** Signal_getSignalTable();

View File

@ -20,10 +20,41 @@ typedef struct SignalsPanel_ {
}*/ }*/
static HandlerResult SignalsPanel_eventHandler(Panel* super, int ch) { SignalsPanel* SignalsPanel_new(int x, int y, int w, int h) {
SignalsPanel* this = (SignalsPanel*) malloc(sizeof(SignalsPanel));
Panel* super = (Panel*) this;
Panel_init(super, x, y, w, h, SIGNAL_CLASS, true);
((Object*)this)->delete = SignalsPanel_delete;
this->signals = Signal_getSignalTable();
super->eventHandler = SignalsPanel_EventHandler;
int sigCount = Signal_getSignalCount();
for(int i = 0; i < sigCount; i++)
Panel_set(super, i, (Object*) this->signals[i]);
SignalsPanel_reset(this);
return this;
}
void SignalsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
SignalsPanel* this = (SignalsPanel*) object;
Panel_done(super);
free(this->signals);
free(this);
}
void SignalsPanel_reset(SignalsPanel* this) {
Panel* super = (Panel*) this;
Panel_setHeader(super, "Send signal:");
Panel_setSelected(super, 16); // 16th item is SIGTERM
this->state = 0;
}
HandlerResult SignalsPanel_EventHandler(Panel* super, int ch) {
SignalsPanel* this = (SignalsPanel*) super; SignalsPanel* this = (SignalsPanel*) super;
int size = Panel_size(super); int size = Panel_getSize(super);
if (ch <= 255 && isdigit(ch)) { if (ch <= 255 && isdigit(ch)) {
int signal = ch-48 + this->state; int signal = ch-48 + this->state;
@ -44,34 +75,3 @@ static HandlerResult SignalsPanel_eventHandler(Panel* super, int ch) {
} }
return IGNORED; return IGNORED;
} }
static void SignalsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
SignalsPanel* this = (SignalsPanel*) object;
Panel_done(super);
free(this->signals);
free(this);
}
SignalsPanel* SignalsPanel_new(int x, int y, int w, int h) {
SignalsPanel* this = (SignalsPanel*) malloc(sizeof(SignalsPanel));
Panel* super = (Panel*) this;
Panel_init(super, x, y, w, h, SIGNAL_CLASS, true);
((Object*)this)->delete = SignalsPanel_delete;
this->signals = Signal_getSignalTable();
super->eventHandler = SignalsPanel_eventHandler;
int sigCount = Signal_getSignalCount();
for(int i = 0; i < sigCount; i++)
Panel_set(super, i, (Object*) this->signals[i]);
SignalsPanel_reset(this);
return this;
}
void SignalsPanel_reset(SignalsPanel* this) {
Panel* super = (Panel*) this;
Panel_setHeader(super, "Send signal:");
Panel_setSelected(super, 16); // 16th item is SIGTERM
this->state = 0;
}

View File

@ -23,6 +23,10 @@ typedef struct SignalsPanel_ {
SignalsPanel* SignalsPanel_new(int x, int y, int w, int h); SignalsPanel* SignalsPanel_new(int x, int y, int w, int h);
void SignalsPanel_delete(Object* object);
void SignalsPanel_reset(SignalsPanel* this); void SignalsPanel_reset(SignalsPanel* this);
HandlerResult SignalsPanel_EventHandler(Panel* super, int ch);
#endif #endif

View File

@ -18,6 +18,10 @@ in the source distribution for its full text.
#define String_startsWith(s, match) (strstr((s), (match)) == (s)) #define String_startsWith(s, match) (strstr((s), (match)) == (s))
}*/ }*/
inline void String_delete(char* s) {
free(s);
}
inline char* String_copy(char* orig) { inline char* String_copy(char* orig) {
return strdup(orig); return strdup(orig);
} }
@ -45,6 +49,53 @@ char* String_trim(char* in) {
return out; return out;
} }
char* String_copyUpTo(char* orig, char upTo) {
int len;
int origLen = strlen(orig);
char* at = strchr(orig, upTo);
if (at != NULL)
len = at - orig;
else
len = origLen;
char* copy = (char*) malloc(len+1);
strncpy(copy, orig, len);
copy[len] = '\0';
return copy;
}
char* String_sub(char* orig, int from, int to) {
char* copy;
int len;
len = strlen(orig);
if (to > len)
to = len;
if (from > len)
to = len;
len = to-from+1;
copy = (char*) malloc(len+1);
strncpy(copy, orig+from, len);
copy[len] = '\0';
return copy;
}
void String_println(char* s) {
printf("%s\n", s);
}
void String_print(char* s) {
printf("%s", s);
}
void String_printInt(int i) {
printf("%i", i);
}
void String_printPointer(void* p) {
printf("%p", p);
}
inline int String_eq(const char* s1, const char* s2) { inline int String_eq(const char* s1, const char* s2) {
if (s1 == NULL || s2 == NULL) { if (s1 == NULL || s2 == NULL) {
if (s1 == NULL && s2 == NULL) if (s1 == NULL && s2 == NULL)
@ -93,6 +144,10 @@ void String_freeArray(char** s) {
free(s); free(s);
} }
int String_startsWith_i(char* s, char* match) {
return (strncasecmp(s, match, strlen(match)) == 0);
}
int String_contains_i(char* s, char* match) { int String_contains_i(char* s, char* match) {
int lens = strlen(s); int lens = strlen(s);
int lenmatch = strlen(match); int lenmatch = strlen(match);
@ -103,30 +158,3 @@ int String_contains_i(char* s, char* match) {
} }
return 0; return 0;
} }
char* String_getToken(const char* line, const unsigned short int numMatch) {
const unsigned short int len = strlen(line);
char inWord = 0;
unsigned short int count = 0;
char match[50];
unsigned short int foundCount = 0;
for (unsigned short int i = 0; i < len; i++) {
char lastState = inWord;
inWord = line[i] == ' ' ? 0:1;
if (lastState == 0 && inWord == 1)
count++;
if(inWord == 1){
if (count == numMatch && line[i] != ' ' && line[i] != '\0' && line[i] != '\n' && line[i] != EOF) {
match[foundCount] = line[i];
foundCount++;
}
}
}
match[foundCount] = '\0';
return((char*)strdup(match));
}

View File

@ -19,20 +19,34 @@ in the source distribution for its full text.
#define String_startsWith(s, match) (strstr((s), (match)) == (s)) #define String_startsWith(s, match) (strstr((s), (match)) == (s))
extern char* String_copy(char* orig); inline void String_delete(char* s);
inline char* String_copy(char* orig);
char* String_cat(char* s1, char* s2); char* String_cat(char* s1, char* s2);
char* String_trim(char* in); char* String_trim(char* in);
extern int String_eq(const char* s1, const char* s2); char* String_copyUpTo(char* orig, char upTo);
char* String_sub(char* orig, int from, int to);
void String_println(char* s);
void String_print(char* s);
void String_printInt(int i);
void String_printPointer(void* p);
inline int String_eq(const char* s1, const char* s2);
char** String_split(char* s, char sep); char** String_split(char* s, char sep);
void String_freeArray(char** s); void String_freeArray(char** s);
int String_startsWith_i(char* s, char* match);
int String_contains_i(char* s, char* match); int String_contains_i(char* s, char* match);
char* String_getToken(const char* line, const unsigned short int numMatch);
#endif #endif

View File

@ -23,26 +23,6 @@ int SwapMeter_attributes[] = {
SWAP SWAP
}; };
static void SwapMeter_setValues(Meter* this, char* buffer, int len) {
long int usedSwap = this->pl->usedSwap;
this->total = this->pl->totalSwap;
this->values[0] = usedSwap;
snprintf(buffer, len, "%ld/%ldMB", (long int) usedSwap / 1024, (long int) this->total / 1024);
}
static void SwapMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* this = (Meter*)cast;
long int swap = (long int) this->values[0];
RichString_init(out);
RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, "%ldM ", (long int) this->total / 1024);
RichString_append(out, CRT_colors[METER_VALUE], buffer);
sprintf(buffer, "%ldk", swap);
RichString_append(out, CRT_colors[METER_TEXT], "used:");
RichString_append(out, CRT_colors[METER_VALUE], buffer);
}
MeterType SwapMeter = { MeterType SwapMeter = {
.setValues = SwapMeter_setValues, .setValues = SwapMeter_setValues,
.display = SwapMeter_display, .display = SwapMeter_display,
@ -54,3 +34,23 @@ MeterType SwapMeter = {
.uiName = "Swap", .uiName = "Swap",
.caption = "Swp" .caption = "Swp"
}; };
void SwapMeter_setValues(Meter* this, char* buffer, int len) {
long int usedSwap = this->pl->usedSwap;
this->total = this->pl->totalSwap;
this->values[0] = usedSwap;
snprintf(buffer, len, "%ld/%ldMB", (long int) usedSwap / 1024, (long int) this->total / 1024);
}
void SwapMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* this = (Meter*)cast;
long int swap = (long int) this->values[0];
RichString_init(out);
RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, "%ldM ", (long int) this->total / 1024);
RichString_append(out, CRT_colors[METER_VALUE], buffer);
sprintf(buffer, "%ldk", swap);
RichString_append(out, CRT_colors[METER_TEXT], "used:");
RichString_append(out, CRT_colors[METER_VALUE], buffer);
}

View File

@ -26,4 +26,8 @@ extern int SwapMeter_attributes[];
extern MeterType SwapMeter; extern MeterType SwapMeter;
void SwapMeter_setValues(Meter* this, char* buffer, int len);
void SwapMeter_display(Object* cast, RichString* out);
#endif #endif

2
TODO
View File

@ -5,8 +5,6 @@ BUGS:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=375219 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=375219
* add swap column for swap usage in MB * add swap column for swap usage in MB
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=365038 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=365038
* Filter out nonprintable characters in command lines
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=419140
FEATURES: FEATURES:

View File

@ -18,24 +18,6 @@ int TasksMeter_attributes[] = {
TASKS_RUNNING TASKS_RUNNING
}; };
static void TasksMeter_setValues(Meter* this, char* buffer, int len) {
this->total = this->pl->totalTasks;
this->values[0] = this->pl->runningTasks;
snprintf(buffer, len, "%d/%d", (int) this->values[0], (int) this->total);
}
static void TasksMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
RichString_init(out);
char buffer[20];
sprintf(buffer, "%d", (int)this->total);
RichString_append(out, CRT_colors[METER_VALUE], buffer);
RichString_append(out, CRT_colors[METER_TEXT], " total, ");
sprintf(buffer, "%d", (int)this->values[0]);
RichString_append(out, CRT_colors[TASKS_RUNNING], buffer);
RichString_append(out, CRT_colors[METER_TEXT], " running");
}
MeterType TasksMeter = { MeterType TasksMeter = {
.setValues = TasksMeter_setValues, .setValues = TasksMeter_setValues,
.display = TasksMeter_display, .display = TasksMeter_display,
@ -47,3 +29,21 @@ MeterType TasksMeter = {
.uiName = "Task counter", .uiName = "Task counter",
.caption = "Tasks: " .caption = "Tasks: "
}; };
void TasksMeter_setValues(Meter* this, char* buffer, int len) {
this->total = this->pl->totalTasks;
this->values[0] = this->pl->runningTasks;
snprintf(buffer, len, "%d/%d", (int) this->values[0], (int) this->total);
}
void TasksMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
RichString_init(out);
char buffer[20];
sprintf(buffer, "%d", (int)this->total);
RichString_append(out, CRT_colors[METER_VALUE], buffer);
RichString_append(out, CRT_colors[METER_TEXT], " total, ");
sprintf(buffer, "%d", (int)this->values[0]);
RichString_append(out, CRT_colors[TASKS_RUNNING], buffer);
RichString_append(out, CRT_colors[METER_TEXT], " running");
}

View File

@ -21,4 +21,8 @@ extern int TasksMeter_attributes[];
extern MeterType TasksMeter; extern MeterType TasksMeter;
void TasksMeter_setValues(Meter* this, char* buffer, int len);
void TasksMeter_display(Object* cast, RichString* out);
#endif #endif

View File

@ -32,17 +32,17 @@ typedef struct TraceScreen_ {
}*/ }*/
static char* tbFunctions[] = {"AutoScroll ", "Stop Tracing ", "Done ", NULL}; static char* tbFunctions[3] = {"AutoScroll ", "Stop Tracing ", "Done "};
static char* tbKeys[] = {"F4", "F5", "Esc"}; static char* tbKeys[3] = {"F4", "F5", "Esc"};
static int tbEvents[] = {KEY_F(4), KEY_F(5), 27}; static int tbEvents[3] = {KEY_F(4), KEY_F(5), 27};
TraceScreen* TraceScreen_new(Process* process) { TraceScreen* TraceScreen_new(Process* process) {
TraceScreen* this = (TraceScreen*) malloc(sizeof(TraceScreen)); TraceScreen* this = (TraceScreen*) malloc(sizeof(TraceScreen));
this->process = process; this->process = process;
this->display = Panel_new(0, 1, COLS, LINES-2, LISTITEM_CLASS, true, ListItem_compare); this->display = Panel_new(0, 1, COLS, LINES-2, LISTITEM_CLASS, true, ListItem_compare);
this->bar = FunctionBar_new(tbFunctions, tbKeys, tbEvents); this->bar = FunctionBar_new(3, tbFunctions, tbKeys, tbEvents);
this->tracing = true; this->tracing = true;
return this; return this;
} }
@ -53,7 +53,7 @@ void TraceScreen_delete(TraceScreen* this) {
free(this); free(this);
} }
static void TraceScreen_draw(TraceScreen* this) { void TraceScreen_draw(TraceScreen* this) {
attrset(CRT_colors[PANEL_HEADER_FOCUS]); attrset(CRT_colors[PANEL_HEADER_FOCUS]);
mvhline(0, 0, ' ', COLS); mvhline(0, 0, ' ', COLS);
mvprintw(0, 0, "Trace of process %d - %s", this->process->pid, this->process->comm); mvprintw(0, 0, "Trace of process %d - %s", this->process->pid, this->process->comm);
@ -105,7 +105,7 @@ void TraceScreen_run(TraceScreen* this) {
buffer[i] = '\0'; buffer[i] = '\0';
if (contLine) { if (contLine) {
ListItem_append((ListItem*)Panel_get(panel, ListItem_append((ListItem*)Panel_get(panel,
Panel_size(panel)-1), line); Panel_getSize(panel)-1), line);
contLine = false; contLine = false;
} else { } else {
Panel_add(panel, (Object*) ListItem_new(line, 0)); Panel_add(panel, (Object*) ListItem_new(line, 0));
@ -119,7 +119,7 @@ void TraceScreen_run(TraceScreen* this) {
contLine = true; contLine = true;
} }
if (follow) if (follow)
Panel_setSelected(panel, Panel_size(panel)-1); Panel_setSelected(panel, Panel_getSize(panel)-1);
Panel_draw(panel, true); Panel_draw(panel, true);
} }
int ch = getch(); int ch = getch();
@ -146,7 +146,7 @@ void TraceScreen_run(TraceScreen* this) {
case KEY_F(4): case KEY_F(4):
follow = !follow; follow = !follow;
if (follow) if (follow)
Panel_setSelected(panel, Panel_size(panel)-1); Panel_setSelected(panel, Panel_getSize(panel)-1);
break; break;
case 'q': case 'q':
case 27: case 27:

View File

@ -37,6 +37,8 @@ TraceScreen* TraceScreen_new(Process* process);
void TraceScreen_delete(TraceScreen* this); void TraceScreen_delete(TraceScreen* this);
void TraceScreen_draw(TraceScreen* this);
void TraceScreen_run(TraceScreen* this); void TraceScreen_run(TraceScreen* this);
#endif #endif

View File

@ -18,16 +18,28 @@ int UptimeMeter_attributes[] = {
UPTIME UPTIME
}; };
static void UptimeMeter_setValues(Meter* this, char* buffer, int len) { MeterType UptimeMeter = {
.setValues = UptimeMeter_setValues,
.display = NULL,
.mode = TEXT_METERMODE,
.items = 1,
.total = 100.0,
.attributes = UptimeMeter_attributes,
.name = "Uptime",
.uiName = "Uptime",
.caption = "Uptime: "
};
void UptimeMeter_setValues(Meter* this, char* buffer, int len) {
double uptime; double uptime;
FILE* fd = fopen(PROCDIR "/uptime", "r"); FILE* fd = fopen(PROCDIR "/uptime", "r");
fscanf(fd, "%lf", &uptime); fscanf(fd, "%lf", &uptime);
fclose(fd); fclose(fd);
int totalseconds = (int) ceil(uptime); int totalseconds = (int) ceil(uptime);
int seconds = totalseconds % 60; int seconds = totalseconds % 60;
int minutes = (totalseconds/60) % 60; int minutes = (totalseconds-seconds) % 3600 / 60;
int hours = (totalseconds/3600) % 24; int hours = (totalseconds-seconds-(minutes*60)) % 86400 / 3600;
int days = (totalseconds/86400); int days = (totalseconds-seconds-(minutes*60)-(hours*3600)) / 86400;
this->values[0] = days; this->values[0] = days;
if (days > this->total) { if (days > this->total) {
this->total = days; this->total = days;
@ -44,15 +56,3 @@ static void UptimeMeter_setValues(Meter* this, char* buffer, int len) {
} }
snprintf(buffer, len, "%s%02d:%02d:%02d", daysbuf, hours, minutes, seconds); snprintf(buffer, len, "%s%02d:%02d:%02d", daysbuf, hours, minutes, seconds);
} }
MeterType UptimeMeter = {
.setValues = UptimeMeter_setValues,
.display = NULL,
.mode = TEXT_METERMODE,
.items = 1,
.total = 100.0,
.attributes = UptimeMeter_attributes,
.name = "Uptime",
.uiName = "Uptime",
.caption = "Uptime: "
};

View File

@ -21,4 +21,6 @@ extern int UptimeMeter_attributes[];
extern MeterType UptimeMeter; extern MeterType UptimeMeter;
void UptimeMeter_setValues(Meter* this, char* buffer, int len);
#endif #endif

View File

@ -35,7 +35,7 @@ void UsersTable_delete(UsersTable* this) {
free(this); free(this);
} }
char* UsersTable_getRef(UsersTable* this, unsigned int uid) { char* UsersTable_getRef(UsersTable* this, int uid) {
char* name = (char*) (Hashtable_get(this->users, uid)); char* name = (char*) (Hashtable_get(this->users, uid));
if (name == NULL) { if (name == NULL) {
struct passwd* userData = getpwuid(uid); struct passwd* userData = getpwuid(uid);
@ -47,6 +47,10 @@ char* UsersTable_getRef(UsersTable* this, unsigned int uid) {
return name; return name;
} }
inline int UsersTable_size(UsersTable* this) {
return (Hashtable_size(this->users));
}
inline void UsersTable_foreach(UsersTable* this, Hashtable_PairFunction f, void* userData) { inline void UsersTable_foreach(UsersTable* this, Hashtable_PairFunction f, void* userData) {
Hashtable_foreach(this->users, f, userData); Hashtable_foreach(this->users, f, userData);
} }

View File

@ -28,8 +28,10 @@ UsersTable* UsersTable_new();
void UsersTable_delete(UsersTable* this); void UsersTable_delete(UsersTable* this);
char* UsersTable_getRef(UsersTable* this, unsigned int uid); char* UsersTable_getRef(UsersTable* this, int uid);
extern void UsersTable_foreach(UsersTable* this, Hashtable_PairFunction f, void* userData); inline int UsersTable_size(UsersTable* this);
inline void UsersTable_foreach(UsersTable* this, Hashtable_PairFunction f, void* userData);
#endif #endif

View File

@ -63,7 +63,6 @@ void Vector_delete(Vector* this) {
#ifdef DEBUG #ifdef DEBUG
static inline bool Vector_isConsistent(Vector* this) { static inline bool Vector_isConsistent(Vector* this) {
assert(this->items <= this->arraySize);
if (this->owner) { if (this->owner) {
for (int i = 0; i < this->items; i++) for (int i = 0; i < this->items; i++)
if (this->array[i] && this->array[i]->class != this->vectorType) if (this->array[i] && this->array[i]->class != this->vectorType)
@ -74,16 +73,6 @@ static inline bool Vector_isConsistent(Vector* this) {
} }
} }
int Vector_count(Vector* this) {
int items = 0;
for (int i = 0; i < this->items; i++) {
if (this->array[i])
items++;
}
assert(items == this->items);
return items;
}
#endif #endif
void Vector_prune(Vector* this) { void Vector_prune(Vector* this) {
@ -218,9 +207,7 @@ inline int Vector_size(Vector* this) {
return this->items; return this->items;
} }
/* void Vector_merge(Vector* this, Vector* v2) {
static void Vector_merge(Vector* this, Vector* v2) {
int i; int i;
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
@ -231,15 +218,12 @@ static void Vector_merge(Vector* this, Vector* v2) {
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
*/
void Vector_add(Vector* this, void* data_) { void Vector_add(Vector* this, void* data_) {
assert(data_ && ((Object*)data_)->class == this->vectorType); assert(data_ && ((Object*)data_)->class == this->vectorType);
Object* data = data_; Object* data = data_;
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
int i = this->items;
Vector_set(this, this->items, data); Vector_set(this, this->items, data);
assert(this->items == i+1); (void)(i);
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
@ -256,9 +240,7 @@ inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) {
return -1; return -1;
} }
/* void Vector_foreach(Vector* this, Vector_procedure f) {
static void Vector_foreach(Vector* this, Vector_procedure f) {
int i; int i;
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
@ -266,5 +248,3 @@ static void Vector_foreach(Vector* this, Vector_procedure f) {
f(this->array[i]); f(this->array[i]);
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
*/

View File

@ -41,8 +41,6 @@ void Vector_delete(Vector* this);
#ifdef DEBUG #ifdef DEBUG
int Vector_count(Vector* this);
#endif #endif
void Vector_prune(Vector* this); void Vector_prune(Vector* this);
@ -61,20 +59,16 @@ void Vector_moveDown(Vector* this, int index);
void Vector_set(Vector* this, int index, void* data_); void Vector_set(Vector* this, int index, void* data_);
extern Object* Vector_get(Vector* this, int index); inline Object* Vector_get(Vector* this, int index);
extern int Vector_size(Vector* this); inline int Vector_size(Vector* this);
/* void Vector_merge(Vector* this, Vector* v2);
*/
void Vector_add(Vector* this, void* data_); void Vector_add(Vector* this, void* data_);
extern int Vector_indexOf(Vector* this, void* search_, Object_Compare compare); inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare);
/* void Vector_foreach(Vector* this, Vector_procedure f);
*/
#endif #endif

View File

@ -1 +0,0 @@
m4_include(plpa-1.1/plpa.m4)

View File

@ -3,7 +3,6 @@
aclocal aclocal
autoconf autoconf
autoheader autoheader
libtoolize --copy
automake --add-missing --copy automake --add-missing --copy

View File

@ -2,24 +2,20 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57) AC_PREREQ(2.57)
AC_INIT([htop],[0.8.2],[loderunner@users.sourceforge.net]) AC_INIT([htop],[0.6.4],[loderunner@users.sourceforge.net])
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([htop.c]) AC_CONFIG_SRCDIR([htop.c])
AC_CONFIG_HEADER([config.h]) AC_CONFIG_HEADER([config.h])
# Checks for programs. # Checks for programs.
AC_PROG_CC AC_PROG_CC
AM_PROG_CC_C_O
AM_DISABLE_SHARED
AM_ENABLE_STATIC
AC_PROG_LIBTOOL
# Checks for libraries. # Checks for libraries.
AC_CHECK_LIB([ncurses], [refresh], [], [missing_libraries="$missing_libraries libncurses"])
AC_CHECK_LIB([m], [ceil], [], [missing_libraries="$missing_libraries libm"]) AC_CHECK_LIB([m], [ceil], [], [missing_libraries="$missing_libraries libm"])
if test ! -z "$missing_libraries"; then if test ! -z "$missing_libraries"; then
AC_MSG_ERROR([missing libraries: $missing_libraries]) AC_MSG_ERROR([missing libraries:$missing_headers])
fi fi
# Checks for header files. # Checks for header files.
@ -30,7 +26,7 @@ AC_CHECK_HEADERS([stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h cu
]) ])
if test ! -z "$missing_headers"; then if test ! -z "$missing_headers"; then
AC_MSG_ERROR([missing headers: $missing_headers]) AC_MSG_ERROR([missing headers:$missing_headers])
fi fi
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
@ -47,13 +43,11 @@ AC_TYPE_SIGNAL
AC_FUNC_STAT AC_FUNC_STAT
AC_CHECK_FUNCS([memmove strncasecmp strstr strdup]) AC_CHECK_FUNCS([memmove strncasecmp strstr strdup])
save_cflags="${CFLAGS}"
CFLAGS="${CFLAGS} -std=c99" CFLAGS="${CFLAGS} -std=c99"
AC_MSG_CHECKING([whether gcc -std=c99 option works]) AC_MSG_CHECKING([whether gcc -std=c99 option works])
AC_TRY_COMPILE(AC_INCLUDES_DEFAULT, [char *a; a = strdup("foo"); int i = 0; i++; // C99], AC_TRY_COMPILE(AC_INCLUDES_DEFAULT, [char *a; a = strdup("foo"); int i = 0; i++; // C99],
AC_MSG_RESULT([yes]), AC_MSG_RESULT([yes]),
AC_MSG_ERROR([htop is written in C99. A newer version of gcc is required.])) AC_MSG_ERROR([htop is written in C99. A newer version of gcc is required.]))
CFLAGS="$save_cflags"
PROCDIR=/proc PROCDIR=/proc
AC_ARG_WITH(proc, [ --with-proc=DIR Location of a Linux-compatible proc filesystem (default=/proc).], AC_ARG_WITH(proc, [ --with-proc=DIR Location of a Linux-compatible proc filesystem (default=/proc).],
@ -64,45 +58,8 @@ AC_ARG_WITH(proc, [ --with-proc=DIR Location of a Linux-compatible proc fi
fi, fi,
AC_DEFINE(PROCDIR, "/proc", [Path of proc filesystem])) AC_DEFINE(PROCDIR, "/proc", [Path of proc filesystem]))
AC_ARG_ENABLE(openvz, [AC_HELP_STRING([--enable-openvz], [enable OpenVZ support])], ,enable_openvz="no")
if test "x$enable_openvz" = xyes; then
AC_DEFINE(HAVE_OPENVZ, 1, [Define if openvz support enabled.])
fi
AC_ARG_ENABLE(vserver, [AC_HELP_STRING([--enable-vserver], [enable VServer support])], ,enable_vserver="no")
if test "x$enable_vserver" = xyes; then
AC_DEFINE(HAVE_VSERVER, 1, [Define if vserver support enabled.])
fi
AC_ARG_ENABLE(ancient_vserver, [AC_HELP_STRING([--enable-ancient-vserver], [enable ancient VServer support (implies --enable-vserver)])], ,enable_ancient_vserver="no")
if test "x$enable_ancient_vserver" = xyes; then
AC_DEFINE(HAVE_VSERVER, 1, [Define if vserver support enabled.])
AC_DEFINE(HAVE_ANCIENT_VSERVER, 1, [Define if ancient vserver support enabled.])
fi
AC_ARG_ENABLE(taskstats, [AC_HELP_STRING([--enable-taskstats], [enable per-task IO Stats (taskstats kernel sup required)])], ,enable_taskstats="yes")
if test "x$enable_taskstats" = xyes; then
AC_DEFINE(HAVE_TASKSTATS, 1, [Define if taskstats support enabled.])
fi
AC_ARG_ENABLE(unicode, [AC_HELP_STRING([--enable-unicode], [enable Unicode support])], ,enable_unicode="no")
if test "x$enable_unicode" = xyes; then
AC_CHECK_LIB([ncursesw], [refresh], [], [missing_libraries="$missing_libraries libncursesw"])
AC_CHECK_HEADERS([ncursesw/curses.h],[:],[missing_headers="$missing_headers $ac_header"])
else
AC_CHECK_LIB([ncurses], [refresh], [], [missing_libraries="$missing_libraries libncurses"])
AC_CHECK_HEADERS([curses.h],[:],[missing_headers="$missing_headers $ac_header"])
fi
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/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.)) 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.))
PLPA_INCLUDED(plpa-1.1)
PLPA_INIT(plpa_happy=yes, plpa_happy=no)
AM_CONDITIONAL([HAVE_PLPA], [test "$plpa_happy" = "yes"])
if test "$plpa_happy" = "yes"; then
AC_DEFINE([HAVE_PLPA], [1], [Have plpa])
fi
AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([Makefile])
AC_OUTPUT AC_OUTPUT

24
htop.1
View File

@ -1,4 +1,4 @@
.TH "htop" "1" "0.8.2" "Bartosz Fenski <fenio@o2.pl>" "Utils" .TH "htop" "1" "0.6.4" "Bartosz Fenski <fenio@o2.pl>" "Utils"
.SH "NAME" .SH "NAME"
htop \- interactive process viewer htop \- interactive process viewer
.SH "SYNTAX" .SH "SYNTAX"
@ -14,21 +14,6 @@ horizontally to see all processes and their full command lines.
Tasks related to processes (killing, renicing) can be done without Tasks related to processes (killing, renicing) can be done without
entering their PIDs. entering their PIDs.
.br .br
.SH "COMMAND-LINE OPTIONS"
.LP
The following flags are supported:
.LP
.TP
\fB\-d DELAY\fR
Delay between updates, in tenths of seconds
.TP
\fB\-u USERNAME\fR
Show only processes of a given user
.TP
\fB\-\-sort\-key COLUMN\fR
Sort by this column (use --sort-key help for a column list)
.PP
.br
.SH "INTERACTIVE COMMANDS" .SH "INTERACTIVE COMMANDS"
.LP .LP
The following commands are supported: The following commands are supported:
@ -50,10 +35,6 @@ Trace process system calls: if strace(1) is installed, pressing this key
will attach it to the currently selected process, presenting a live will attach it to the currently selected process, presenting a live
update of system calls issued by the process. update of system calls issued by the process.
.TP .TP
.B l
Display open files for a process: if lsof(1) is installed, pressing this key
will display the list of file descriptors opened by the process.
.TP
.B F1, h .B F1, h
Help screen Help screen
.TP .TP
@ -96,9 +77,6 @@ If none is tagged, sends to the currently selected process.
.B F10, q .B F10, q
Quit Quit
.TP .TP
.B a (on multiprocessor machines)
Set CPU affinity: mark which CPUs a process is allowed to use.
.TP
.B u .B u
Show only processes owned by a specified user. Show only processes owned by a specified user.
.TP .TP

312
htop.c
View File

@ -1,6 +1,6 @@
/* /*
htop - htop.c htop - htop.c
(C) 2004-2008 Hisham H. Muhammad (C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file Released under the GNU GPL, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
@ -11,7 +11,6 @@ in the source distribution for its full text.
#include <sys/param.h> #include <sys/param.h>
#include <ctype.h> #include <ctype.h>
#include <stdbool.h> #include <stdbool.h>
#include <locale.h>
#include "ProcessList.h" #include "ProcessList.h"
#include "CRT.h" #include "CRT.h"
@ -26,8 +25,6 @@ in the source distribution for its full text.
#include "CategoriesPanel.h" #include "CategoriesPanel.h"
#include "SignalsPanel.h" #include "SignalsPanel.h"
#include "TraceScreen.h" #include "TraceScreen.h"
#include "OpenFilesScreen.h"
#include "AffinityPanel.h"
#include "config.h" #include "config.h"
#include "debug.h" #include "debug.h"
@ -36,16 +33,16 @@ in the source distribution for its full text.
#define INCSEARCH_MAX 40 #define INCSEARCH_MAX 40
static void printVersionFlag() { void printVersionFlag() {
clear(); clear();
printf("htop " VERSION " - (C) 2004-2008 Hisham Muhammad.\n"); printf("htop " VERSION " - (C) 2004-2006 Hisham Muhammad.\n");
printf("Released under the GNU GPL.\n\n"); printf("Released under the GNU GPL.\n\n");
exit(0); exit(0);
} }
static void printHelpFlag() { void printHelpFlag() {
clear(); clear();
printf("htop " VERSION " - (C) 2004-2008 Hisham Muhammad.\n"); printf("htop " VERSION " - (C) 2004-2006 Hisham Muhammad.\n");
printf("Released under the GNU GPL.\n\n"); printf("Released under the GNU GPL.\n\n");
printf("-d DELAY Delay between updates, in tenths of seconds\n\n"); printf("-d DELAY Delay between updates, in tenths of seconds\n\n");
printf("-u USERNAME Show only processes of a given user\n\n"); printf("-u USERNAME Show only processes of a given user\n\n");
@ -55,27 +52,23 @@ static void printHelpFlag() {
exit(0); exit(0);
} }
static void showHelp(ProcessList* pl) { void showHelp(ProcessList* pl) {
clear(); clear();
attrset(CRT_colors[HELP_BOLD]); attrset(CRT_colors[HELP_BOLD]);
mvaddstr(0, 0, "htop " VERSION " - (C) 2004-2006 Hisham Muhammad.");
for (int i = 0; i < LINES-1; i++)
mvhline(i, 0, ' ', COLS);
mvaddstr(0, 0, "htop " VERSION " - (C) 2004-2008 Hisham Muhammad.");
mvaddstr(1, 0, "Released under the GNU GPL. See 'man' page for more info."); mvaddstr(1, 0, "Released under the GNU GPL. See 'man' page for more info.");
attrset(CRT_colors[DEFAULT_COLOR]); attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(3, 0, "CPU usage bar: "); mvaddstr(3, 0, "CPU usage bar: ");
#define addattrstr(a,s) attrset(a);addstr(s) #define addattrstr(a,s) attrset(a);addstr(s)
addattrstr(CRT_colors[BAR_BORDER], "["); addattrstr(CRT_colors[BAR_BORDER], "[");
if (pl->detailedCPUTime) { if (pl->expandSystemTime) {
addattrstr(CRT_colors[CPU_NICE], "low"); addstr("/"); addattrstr(CRT_colors[CPU_NICE], "low"); addstr("/");
addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/"); addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/");
addattrstr(CRT_colors[CPU_KERNEL], "kernel"); addstr("/"); addattrstr(CRT_colors[CPU_KERNEL], "kernel"); addstr("/");
addattrstr(CRT_colors[CPU_IOWAIT], "io-wait"); addstr("/");
addattrstr(CRT_colors[CPU_IRQ], "irq"); addstr("/"); addattrstr(CRT_colors[CPU_IRQ], "irq"); addstr("/");
addattrstr(CRT_colors[CPU_SOFTIRQ], "soft-irq"); addstr("/"); addattrstr(CRT_colors[CPU_SOFTIRQ], "soft-irq");
addattrstr(CRT_colors[CPU_IOWAIT], "io-wait");
addattrstr(CRT_colors[BAR_SHADOW], " used%"); addattrstr(CRT_colors[BAR_SHADOW], " used%");
} else { } else {
addattrstr(CRT_colors[CPU_NICE], "low-priority"); addstr("/"); addattrstr(CRT_colors[CPU_NICE], "low-priority"); addstr("/");
@ -100,47 +93,35 @@ static void showHelp(ProcessList* pl) {
addattrstr(CRT_colors[BAR_BORDER], "]"); addattrstr(CRT_colors[BAR_BORDER], "]");
attrset(CRT_colors[DEFAULT_COLOR]); attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(6,0, "Type and layout of header meters are configurable in the setup screen."); mvaddstr(6,0, "Type and layout of header meters are configurable in the setup screen.");
if (CRT_colorScheme == COLORSCHEME_MONOCHROME) {
mvaddstr(7, 0, "In monochrome, meters are displayed through different chars, in order: |#*@$%&"); mvaddstr( 8, 0, " Arrows: scroll process list F5 t: tree view");
} mvaddstr( 9, 0, " Digits: incremental PID search u: show processes of a single user");
mvaddstr( 8, 0, " Status: R: running; S: sleeping; T: traced/stopped; Z: zombie; D: disk sleep"); mvaddstr(10, 0, " F3 /: incremental name search H: hide/show user threads");
mvaddstr( 9, 0, " Arrows: scroll process list F5 t: tree view"); mvaddstr(11, 0, " K: hide/show kernel threads");
mvaddstr(10, 0, " Digits: incremental PID search u: show processes of a single user"); mvaddstr(12, 0, " Space: tag processes F: cursor follows process");
mvaddstr(11, 0, " F3 /: incremental name search H: hide/show user threads"); mvaddstr(13, 0, " U: untag all processes");
mvaddstr(12, 0, " K: hide/show kernel threads"); mvaddstr(14, 0, " F9 k: kill process/tagged processes P: sort by CPU%");
mvaddstr(13, 0, " Space: tag processes F: cursor follows process"); mvaddstr(15, 0, " + [ F7: lower priority (+ nice) M: sort by MEM%");
mvaddstr(14, 0, " U: untag all processes"); mvaddstr(16, 0, " - ] F8: higher priority (root only) T: sort by TIME");
mvaddstr(15, 0, " F9 k: kill process/tagged processes P: sort by CPU%"); mvaddstr(17, 0, " F4 I: invert sort order");
mvaddstr(16, 0, " - ] F7: higher priority (root only) M: sort by MEM%"); mvaddstr(18, 0, " F2 S: setup F6 >: select sort column");
mvaddstr(17, 0, " + [ F8: lower priority (+ nice) T: sort by TIME"); mvaddstr(19, 0, " F1 h: show this help screen");
#ifdef HAVE_PLPA mvaddstr(20, 0, " F10 q: quit s: trace syscalls with strace");
if (pl->processorCount > 1)
mvaddstr(18, 0, " a: set CPU affinity F4 I: invert sort order");
else
#endif
mvaddstr(18, 0, " F4 I: invert sort order");
mvaddstr(19, 0, " F2 S: setup F6 >: select sort column");
mvaddstr(20, 0, " F1 h: show this help screen l: list open files with lsof");
mvaddstr(21, 0, " F10 q: quit s: trace syscalls with strace");
attrset(CRT_colors[HELP_BOLD]); attrset(CRT_colors[HELP_BOLD]);
mvaddstr( 9, 0, " Arrows"); mvaddstr( 9,40, " F5 t"); mvaddstr( 8, 0, " Arrows"); mvaddstr( 8,40, " F5 t");
mvaddstr(10, 0, " Digits"); mvaddstr(10,40, " u"); mvaddstr( 9, 0, " Digits"); mvaddstr( 9,40, " u");
mvaddstr(11, 0, " F3 /"); mvaddstr(11,40, " H"); mvaddstr(10, 0, " F3 /"); mvaddstr(10,40, " H");
mvaddstr(12,40, " K"); mvaddstr(11,40, " K");
mvaddstr(13, 0, " Space"); mvaddstr(13,40, " F"); mvaddstr(12, 0, " Space"); mvaddstr(12,40, " F");
mvaddstr(14, 0, " U"); mvaddstr(13, 0, " U");
mvaddstr(15, 0, " F9 k"); mvaddstr(15,40, " P"); mvaddstr(14, 0, " F9 k"); mvaddstr(14,40, " P");
mvaddstr(16, 0, " + [ F7"); mvaddstr(16,40, " M"); mvaddstr(15, 0, " + [ F7"); mvaddstr(15,40, " M");
mvaddstr(17, 0, " - ] F8"); mvaddstr(17,40, " T"); mvaddstr(16, 0, " - ] F8"); mvaddstr(16,40, " T");
mvaddstr(18,40, " F4 I"); mvaddstr(17,40, " F4 I");
#if HAVE_PLPA mvaddstr(18, 0, " F2 S"); mvaddstr(18,40, " F6 >");
if (pl->processorCount > 1) mvaddstr(19, 0, " F1 h");
mvaddstr(18, 0, " a:"); mvaddstr(20, 0, " F10 q"); mvaddstr(20,40, " s");
#endif
mvaddstr(19, 0, " F2 S"); mvaddstr(19,40, " F6 >");
mvaddstr(20, 0, " F1 h"); mvaddstr(20,40, " l");
mvaddstr(21, 0, " F10 q"); mvaddstr(21,40, " s");
attrset(CRT_colors[DEFAULT_COLOR]); attrset(CRT_colors[DEFAULT_COLOR]);
attrset(CRT_colors[HELP_BOLD]); attrset(CRT_colors[HELP_BOLD]);
@ -151,12 +132,10 @@ static void showHelp(ProcessList* pl) {
clear(); clear();
} }
static char* CategoriesFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
static void Setup_run(Settings* settings, int headerHeight) { static void Setup_run(Settings* settings, int headerHeight) {
ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true); ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true);
CategoriesPanel* panelCategories = CategoriesPanel_new(settings, scr); CategoriesPanel* panelCategories = CategoriesPanel_new(settings, scr);
ScreenManager_add(scr, (Panel*) panelCategories, FunctionBar_new(CategoriesFunctions, NULL, NULL), 16); ScreenManager_add(scr, (Panel*) panelCategories, NULL, 16);
CategoriesPanel_makeMetersPage(panelCategories); CategoriesPanel_makeMetersPage(panelCategories);
Panel* panelFocus; Panel* panelFocus;
int ch; int ch;
@ -165,21 +144,18 @@ static void Setup_run(Settings* settings, int headerHeight) {
} }
static bool changePriority(Panel* panel, int delta) { static bool changePriority(Panel* panel, int delta) {
bool ok = true;
bool anyTagged = false; bool anyTagged = false;
for (int i = 0; i < Panel_size(panel); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i); Process* p = (Process*) Panel_get(panel, i);
if (p->tag) { if (p->tag) {
ok = Process_setPriority(p, p->nice + delta) && ok; Process_setPriority(p, p->nice + delta);
anyTagged = true; anyTagged = true;
} }
} }
if (!anyTagged) { if (!anyTagged) {
Process* p = (Process*) Panel_getSelected(panel); Process* p = (Process*) Panel_getSelected(panel);
ok = Process_setPriority(p, p->nice + delta) && ok; Process_setPriority(p, p->nice + delta);
} }
if (!ok)
beep();
return anyTagged; return anyTagged;
} }
@ -189,13 +165,13 @@ static HandlerResult pickWithEnter(Panel* panel, int ch) {
return IGNORED; return IGNORED;
} }
static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, char** keyLabels, FunctionBar* prevBar) { static Object* pickFromList(Panel* panel, Panel* list, int x, int y, char** keyLabels, FunctionBar* prevBar) {
char* fuKeys[2] = {"Enter", "Esc"}; char* fuKeys[2] = {"Enter", "Esc"};
int fuEvents[2] = {13, 27}; int fuEvents[2] = {13, 27};
if (!list->eventHandler) if (!panel->eventHandler)
Panel_setEventHandler(list, pickWithEnter); Panel_setEventHandler(list, pickWithEnter);
ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, false); ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, false);
ScreenManager_add(scr, list, FunctionBar_new(keyLabels, fuKeys, fuEvents), x - 1); ScreenManager_add(scr, list, FunctionBar_new(2, keyLabels, fuKeys, fuEvents), x - 1);
ScreenManager_add(scr, panel, NULL, -1); ScreenManager_add(scr, panel, NULL, -1);
Panel* panelFocus; Panel* panelFocus;
int ch; int ch;
@ -210,13 +186,13 @@ static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, char** ke
return NULL; return NULL;
} }
static void addUserToVector(int key, void* userCast, void* panelCast) { void addUserToList(int key, void* userCast, void* panelCast) {
char* user = (char*) userCast; char* user = (char*) userCast;
Panel* panel = (Panel*) panelCast; Panel* panel = (Panel*) panelCast;
Panel_add(panel, (Object*) ListItem_new(user, key)); Panel_add(panel, (Object*) ListItem_new(user, key));
} }
static void setUserOnly(const char* userName, bool* userOnly, uid_t* userId) { void setUserOnly(const char* userName, bool* userOnly, uid_t* userId) {
struct passwd* user = getpwnam(userName); struct passwd* user = getpwnam(userName);
if (user) { if (user) {
*userOnly = true; *userOnly = true;
@ -224,14 +200,6 @@ static void setUserOnly(const char* userName, bool* userOnly, uid_t* userId) {
} }
} }
static inline void setSortKey(ProcessList* pl, ProcessField sortKey, Panel* panel, Settings* settings) {
pl->sortKey = sortKey;
pl->direction = 1;
pl->treeView = false;
settings->changed = true;
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
int delay = -1; int delay = -1;
@ -239,47 +207,32 @@ int main(int argc, char** argv) {
uid_t userId = 0; uid_t userId = 0;
int sortKey = 0; int sortKey = 0;
char *lc_ctype = getenv("LC_CTYPE"); if (argc > 0) {
if(lc_ctype != NULL) if (String_eq(argv[1], "--help")) {
setlocale(LC_CTYPE, lc_ctype);
else
setlocale(LC_CTYPE, getenv("LC_ALL"));
int arg = 1;
while (arg < argc) {
if (String_eq(argv[arg], "--help")) {
printHelpFlag(); printHelpFlag();
} else if (String_eq(argv[arg], "--version")) { } else if (String_eq(argv[1], "--version")) {
printVersionFlag(); printVersionFlag();
} else if (String_eq(argv[arg], "--sort-key")) { } else if (String_eq(argv[1], "--sort-key")) {
if (arg == argc - 1) printHelpFlag(); if (argc < 2) printHelpFlag();
arg++; if (String_eq(argv[2], "help")) {
char* field = argv[arg];
if (String_eq(field, "help")) {
for (int j = 1; j < LAST_PROCESSFIELD; j++) for (int j = 1; j < LAST_PROCESSFIELD; j++)
printf ("%s\n", Process_fieldNames[j]); printf ("%s\n", Process_fieldNames[j]);
exit(0); exit(0);
} }
sortKey = ColumnsPanel_fieldNameToIndex(field); sortKey = ColumnsPanel_fieldNameToIndex(argv[2]);
if (sortKey == -1) { if (sortKey == -1) {
fprintf(stderr, "Error: invalid column \"%s\".\n", field); fprintf(stderr, "Error: invalid column \"%s\".\n", argv[2]);
exit(1); exit(1);
} }
} else if (String_eq(argv[arg], "-d")) { } else if (String_eq(argv[1], "-d")) {
if (arg == argc - 1) printHelpFlag(); if (argc < 2) printHelpFlag();
arg++; sscanf(argv[2], "%d", &delay);
sscanf(argv[arg], "%d", &delay);
if (delay < 1) delay = 1; if (delay < 1) delay = 1;
if (delay > 100) delay = 100; if (delay > 100) delay = 100;
} else if (String_eq(argv[arg], "-u")) { } else if (String_eq(argv[1], "-u")) {
if (arg == argc - 1) printHelpFlag(); if (argc < 2) printHelpFlag();
arg++; setUserOnly(argv[2], &userOnly, &userId);
setUserOnly(argv[arg], &userOnly, &userId);
} else {
fprintf(stderr, "Error: unknown flag: %s\n", argv[arg]);
exit(1);
} }
arg++;
} }
if (access(PROCDIR, R_OK) != 0) { if (access(PROCDIR, R_OK) != 0) {
@ -292,7 +245,6 @@ int main(int argc, char** argv) {
int refreshTimeout = 0; int refreshTimeout = 0;
int resetRefreshTimeout = 5; int resetRefreshTimeout = 5;
bool doRefresh = true; bool doRefresh = true;
bool doRecalculate = false;
Settings* settings; Settings* settings;
Panel* killPanel = NULL; Panel* killPanel = NULL;
@ -309,6 +261,10 @@ int main(int argc, char** argv) {
Header* header = Header_new(pl); Header* header = Header_new(pl);
settings = Settings_new(pl, header); settings = Settings_new(pl, header);
if (sortKey > 0) {
pl->sortKey = sortKey;
pl->treeView = false;
}
int headerHeight = Header_calculateHeight(header); int headerHeight = Header_calculateHeight(header);
// FIXME: move delay code to settings // FIXME: move delay code to settings
@ -318,21 +274,16 @@ int main(int argc, char** argv) {
CRT_init(settings->delay, settings->colorScheme); CRT_init(settings->delay, settings->colorScheme);
panel = Panel_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false, NULL); panel = Panel_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false, NULL);
if (sortKey > 0) {
pl->sortKey = sortKey;
pl->treeView = false;
pl->direction = 1;
}
Panel_setRichHeader(panel, ProcessList_printHeader(pl)); Panel_setRichHeader(panel, ProcessList_printHeader(pl));
char* searchFunctions[] = {"Next ", "Exit ", " Search: ", NULL}; char* searchFunctions[3] = {"Next ", "Exit ", " Search: "};
char* searchKeys[] = {"F3", "Esc", " "}; char* searchKeys[3] = {"F3", "Esc", " "};
int searchEvents[] = {KEY_F(3), 27, ERR}; int searchEvents[3] = {KEY_F(3), 27, ERR};
FunctionBar* searchBar = FunctionBar_new(searchFunctions, searchKeys, searchEvents); FunctionBar* searchBar = FunctionBar_new(3, searchFunctions, searchKeys, searchEvents);
char* defaultFunctions[] = {"Help ", "Setup ", "Search", "Invert", "Tree ", char* defaultFunctions[10] = {"Help ", "Setup ", "Search", "Invert", "Tree ",
"SortBy", "Nice -", "Nice +", "Kill ", "Quit ", NULL}; "SortBy", "Nice -", "Nice +", "Kill ", "Quit "};
FunctionBar* defaultBar = FunctionBar_new(defaultFunctions, NULL, NULL); FunctionBar* defaultBar = FunctionBar_new(10, defaultFunctions, NULL, NULL);
ProcessList_scan(pl); ProcessList_scan(pl);
usleep(75000); usleep(75000);
@ -357,15 +308,15 @@ int main(int argc, char** argv) {
if (recalculate) if (recalculate)
oldTime = newTime; oldTime = newTime;
if (doRefresh) { if (doRefresh) {
incSearchIndex = 0;
incSearchBuffer[0] = 0;
int currPos = Panel_getSelectedIndex(panel); int currPos = Panel_getSelectedIndex(panel);
unsigned int currPid = 0; int currPid = 0;
int currScrollV = panel->scrollV; int currScrollV = panel->scrollV;
if (follow) if (follow)
currPid = ProcessList_get(pl, currPos)->pid; currPid = ProcessList_get(pl, currPos)->pid;
if (recalculate || doRecalculate) { if (recalculate)
ProcessList_scan(pl); ProcessList_scan(pl);
doRecalculate = false;
}
if (refreshTimeout == 0) { if (refreshTimeout == 0) {
ProcessList_sort(pl); ProcessList_sort(pl);
refreshTimeout = 1; refreshTimeout = 1;
@ -431,6 +382,8 @@ int main(int argc, char** argv) {
incSearchBuffer[incSearchIndex] = 0; incSearchBuffer[incSearchIndex] = 0;
} else { } else {
incSearchMode = false; incSearchMode = false;
incSearchIndex = 0;
incSearchBuffer[0] = 0;
FunctionBar_draw(defaultBar, NULL); FunctionBar_draw(defaultBar, NULL);
continue; continue;
} }
@ -452,7 +405,7 @@ int main(int argc, char** argv) {
continue; continue;
} }
if (isdigit((char)ch)) { if (isdigit((char)ch)) {
unsigned int pid = ch-48 + acc; int pid = ch-48 + acc;
for (int i = 0; i < ProcessList_size(pl) && ((Process*) Panel_getSelected(panel))->pid != pid; i++) for (int i = 0; i < ProcessList_size(pl) && ((Process*) Panel_getSelected(panel))->pid != pid; i++)
Panel_setSelected(panel, i); Panel_setSelected(panel, i);
acc = pid * 10; acc = pid * 10;
@ -467,18 +420,7 @@ int main(int argc, char** argv) {
MEVENT mevent; MEVENT mevent;
int ok = getmouse(&mevent); int ok = getmouse(&mevent);
if (ok == OK) { if (ok == OK) {
if (mevent.y == panel->y) { if (mevent.y >= panel->y + 1 && mevent.y < LINES - 1) {
int x = panel->scrollH + mevent.x + 1;
ProcessField field = ProcessList_keyAt(pl, x);
if (field == pl->sortKey) {
ProcessList_invertSortOrder(pl);
pl->treeView = false;
} else {
setSortKey(pl, field, panel, settings);
}
refreshTimeout = 0;
continue;
} else if (mevent.y >= panel->y + 1 && mevent.y < LINES - 1) {
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1); Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
doRefresh = false; doRefresh = false;
refreshTimeout = resetRefreshTimeout; refreshTimeout = resetRefreshTimeout;
@ -505,18 +447,24 @@ int main(int argc, char** argv) {
case 'M': case 'M':
{ {
refreshTimeout = 0; refreshTimeout = 0;
setSortKey(pl, PERCENT_MEM, panel, settings); pl->sortKey = PERCENT_MEM;
pl->treeView = false;
settings->changed = true;
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
break; break;
} }
case 'T': case 'T':
{ {
refreshTimeout = 0; refreshTimeout = 0;
setSortKey(pl, TIME, panel, settings); pl->sortKey = TIME;
pl->treeView = false;
settings->changed = true;
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
break; break;
} }
case 'U': case 'U':
{ {
for (int i = 0; i < Panel_size(panel); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i); Process* p = (Process*) Panel_get(panel, i);
p->tag = false; p->tag = false;
} }
@ -526,7 +474,10 @@ int main(int argc, char** argv) {
case 'P': case 'P':
{ {
refreshTimeout = 0; refreshTimeout = 0;
setSortKey(pl, PERCENT_CPU, panel, settings); pl->sortKey = PERCENT_CPU;
pl->treeView = false;
settings->changed = true;
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
break; break;
} }
case KEY_F(1): case KEY_F(1):
@ -562,17 +513,6 @@ int main(int argc, char** argv) {
CRT_enableDelay(); CRT_enableDelay();
break; break;
} }
case 'l':
{
OpenFilesScreen* ts = OpenFilesScreen_new((Process*) Panel_getSelected(panel));
OpenFilesScreen_run(ts);
OpenFilesScreen_delete(ts);
clear();
FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0;
CRT_enableDelay();
break;
}
case 'S': case 'S':
case 'C': case 'C':
case KEY_F(2): case KEY_F(2):
@ -596,12 +536,12 @@ int main(int argc, char** argv) {
{ {
Panel* usersPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare); Panel* usersPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare);
Panel_setHeader(usersPanel, "Show processes of:"); Panel_setHeader(usersPanel, "Show processes of:");
UsersTable_foreach(ut, addUserToVector, usersPanel); UsersTable_foreach(ut, addUserToList, usersPanel);
Vector_sort(usersPanel->items); Vector_sort(usersPanel->items);
ListItem* allUsers = ListItem_new("All users", -1); ListItem* allUsers = ListItem_new("All users", -1);
Panel_insert(usersPanel, 0, (Object*) allUsers); Panel_insert(usersPanel, 0, (Object*) allUsers);
char* fuFunctions[] = {"Show ", "Cancel ", NULL}; char* fuFunctions[2] = {"Show ", "Cancel "};
ListItem* picked = (ListItem*) pickFromVector(panel, usersPanel, 20, headerHeight, fuFunctions, defaultBar); ListItem* picked = (ListItem*) pickFromList(panel, usersPanel, 20, headerHeight, fuFunctions, defaultBar);
if (picked) { if (picked) {
if (picked == allUsers) { if (picked == allUsers) {
userOnly = false; userOnly = false;
@ -619,15 +559,15 @@ int main(int argc, char** argv) {
killPanel = (Panel*) SignalsPanel_new(0, 0, 0, 0); killPanel = (Panel*) SignalsPanel_new(0, 0, 0, 0);
} }
SignalsPanel_reset((SignalsPanel*) killPanel); SignalsPanel_reset((SignalsPanel*) killPanel);
char* fuFunctions[] = {"Send ", "Cancel ", NULL}; char* fuFunctions[2] = {"Send ", "Cancel "};
Signal* signal = (Signal*) pickFromVector(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar); Signal* signal = (Signal*) pickFromList(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar);
if (signal) { if (signal) {
if (signal->number != 0) { if (signal->number != 0) {
Panel_setHeader(panel, "Sending..."); Panel_setHeader(panel, "Sending...");
Panel_draw(panel, true); Panel_draw(panel, true);
refresh(); refresh();
bool anyTagged = false; bool anyTagged = false;
for (int i = 0; i < Panel_size(panel); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i); Process* p = (Process*) Panel_get(panel, i);
if (p->tag) { if (p->tag) {
Process_sendSignal(p, signal->number); Process_sendSignal(p, signal->number);
@ -645,43 +585,6 @@ int main(int argc, char** argv) {
refreshTimeout = 0; refreshTimeout = 0;
break; break;
} }
#ifdef HAVE_PLPA
case 'a':
{
if (pl->processorCount == 1)
break;
Process* p = (Process*) Panel_getSelected(panel);
unsigned long curr = Process_getAffinity(p);
Panel* affinityPanel = AffinityPanel_new(pl->processorCount, curr);
char* fuFunctions[2] = {"Set ", "Cancel "};
void* set = pickFromVector(panel, affinityPanel, 15, headerHeight, fuFunctions, defaultBar);
if (set) {
unsigned long new = AffinityPanel_getAffinity(affinityPanel);
bool anyTagged = false;
bool ok = true;
for (int i = 0; i < Panel_size(panel); i++) {
Process* p = (Process*) Panel_get(panel, i);
if (p->tag) {
ok = Process_setAffinity(p, new) && ok;
anyTagged = true;
}
}
if (!anyTagged) {
Process* p = (Process*) Panel_getSelected(panel);
ok = Process_setAffinity(p, new) && ok;
}
if (!ok)
beep();
}
((Object*)affinityPanel)->delete((Object*)affinityPanel);
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
refreshTimeout = 0;
break;
}
#endif
case KEY_F(10): case KEY_F(10):
case 'q': case 'q':
quit = 1; quit = 1;
@ -698,20 +601,20 @@ int main(int argc, char** argv) {
char* fuFunctions[2] = {"Sort ", "Cancel "}; char* fuFunctions[2] = {"Sort ", "Cancel "};
ProcessField* fields = pl->fields; ProcessField* fields = pl->fields;
for (int i = 0; fields[i]; i++) { for (int i = 0; fields[i]; i++) {
char* name = String_trim(Process_fieldTitles[fields[i]]); char* name = String_trim(Process_printField(fields[i]));
Panel_add(sortPanel, (Object*) ListItem_new(name, fields[i])); Panel_add(sortPanel, (Object*) ListItem_new(name, fields[i]));
if (fields[i] == pl->sortKey) if (fields[i] == pl->sortKey)
Panel_setSelected(sortPanel, i); Panel_setSelected(sortPanel, i);
free(name); free(name);
} }
ListItem* field = (ListItem*) pickFromVector(panel, sortPanel, 15, headerHeight, fuFunctions, defaultBar); ListItem* field = (ListItem*) pickFromList(panel, sortPanel, 15, headerHeight, fuFunctions, defaultBar);
if (field) { if (field) {
pl->treeView = false;
settings->changed = true; settings->changed = true;
setSortKey(pl, field->key, panel, settings); pl->sortKey = field->key;
} else {
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
} }
((Object*)sortPanel)->delete((Object*)sortPanel); ((Object*)sortPanel)->delete((Object*)sortPanel);
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
refreshTimeout = 0; refreshTimeout = 0;
break; break;
} }
@ -740,10 +643,8 @@ int main(int argc, char** argv) {
} }
case KEY_F(3): case KEY_F(3):
case '/': case '/':
incSearchIndex = 0;
incSearchBuffer[0] = 0;
incSearchMode = true;
FunctionBar_draw(searchBar, incSearchBuffer); FunctionBar_draw(searchBar, incSearchBuffer);
incSearchMode = true;
break; break;
case 't': case 't':
case KEY_F(5): case KEY_F(5):
@ -752,14 +653,11 @@ int main(int argc, char** argv) {
settings->changed = true; settings->changed = true;
break; break;
case 'H': case 'H':
doRecalculate = true;
refreshTimeout = 0; refreshTimeout = 0;
pl->hideUserlandThreads = !pl->hideUserlandThreads; pl->hideThreads = !pl->hideThreads;
pl->hideThreads = pl->hideUserlandThreads;
settings->changed = true; settings->changed = true;
break; break;
case 'K': case 'K':
doRecalculate = true;
refreshTimeout = 0; refreshTimeout = 0;
pl->hideKernelThreads = !pl->hideKernelThreads; pl->hideKernelThreads = !pl->hideKernelThreads;
settings->changed = true; settings->changed = true;

View File

@ -1,10 +1,12 @@
[Desktop Entry] [Desktop Entry]
Version=1.0 Encoding=UTF-8
Version=0.6.4
Name=Htop Name=Htop
Type=Application Type=Application
Comment=Show System Processes Comment=Show System Processes
Terminal=true Terminal=true
Exec=htop Exec=htop
Path=
Icon=htop Icon=htop
Categories=ConsoleOnly;System; Categories=ConsoleOnly;System;Application;
GenericName=Process Viewer GenericName=Process Viewer

15
htop.h
View File

@ -4,7 +4,7 @@
#define HEADER_htop #define HEADER_htop
/* /*
htop - htop.h htop - htop.h
(C) 2004-2008 Hisham H. Muhammad (C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file Released under the GNU GPL, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
@ -15,7 +15,6 @@ in the source distribution for its full text.
#include <sys/param.h> #include <sys/param.h>
#include <ctype.h> #include <ctype.h>
#include <stdbool.h> #include <stdbool.h>
#include <locale.h>
#include "ProcessList.h" #include "ProcessList.h"
#include "CRT.h" #include "CRT.h"
@ -30,8 +29,6 @@ in the source distribution for its full text.
#include "CategoriesPanel.h" #include "CategoriesPanel.h"
#include "SignalsPanel.h" #include "SignalsPanel.h"
#include "TraceScreen.h" #include "TraceScreen.h"
#include "OpenFilesScreen.h"
#include "AffinityPanel.h"
#include "config.h" #include "config.h"
#include "debug.h" #include "debug.h"
@ -40,6 +37,16 @@ in the source distribution for its full text.
#define INCSEARCH_MAX 40 #define INCSEARCH_MAX 40
void printVersionFlag();
void printHelpFlag();
void showHelp();
void addUserToList(int key, void* userCast, void* panelCast);
void setUserOnly(const char* userName, bool* userOnly, uid_t* userId);
int main(int argc, char** argv); int main(int argc, char** argv);
#endif #endif

View File

@ -1,13 +0,0 @@
PLPA Authors
============
The IDs in parenthesis are those used in Subversion commit notices.
Current Authors
---------------
Indiana University:
- Jeff Squyres (jsquyres)
Lawrence Berkeley National Lab:
- Paul Hargrove (phargrov)

View File

@ -1,57 +0,0 @@
Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
University Research and Technology
Corporation. All rights reserved.
Copyright (c) 2004-2005 The Regents of the University of California.
All rights reserved.
Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
Portions copyright:
Copyright (c) 2004-2005 The University of Tennessee and The University
of Tennessee Research Foundation. All rights
reserved.
Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
University of Stuttgart. All rights reserved.
Copyright (c) 2006, 2007 Advanced Micro Devices, Inc.
All rights reserved.
$COPYRIGHT$
Additional copyrights may follow
$HEADER$
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer listed
in this license in the documentation and/or other materials
provided with the distribution.
- Neither the name of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
The copyright holders provide no reassurances that the source code
provided does not infringe any patent, copyright, or any other
intellectual property rights of third parties. The copyright holders
disclaim any liability to any recipient for claims brought against
recipient by any third party for infringement of that parties
intellectual property rights.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,17 +0,0 @@
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
SUBDIRS = src
DIST_SUBDIRS = $(SUBDIRS)
EXTRA_DIST = README VERSION LICENSE AUTHORS plpa.m4

View File

@ -1,499 +0,0 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = plpa-1.1
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
AUTHORS
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/plpa-1.1/plpa.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
$(top_builddir)/plpa-1.1/src/plpa_config.h \
$(top_builddir)/plpa-1.1/src/plpa.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = src
DIST_SUBDIRS = $(SUBDIRS)
EXTRA_DIST = README VERSION LICENSE AUTHORS plpa.m4
all: all-recursive
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plpa-1.1/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu plpa-1.1/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
am__remove_distdir=: \
am__skip_length_check=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-exec-am:
install-html: install-html-recursive
install-info: install-info-recursive
install-man:
install-pdf: install-pdf-recursive
install-ps: install-ps-recursive
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
install-strip
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am check check-am clean clean-generic clean-libtool \
ctags ctags-recursive distclean distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,29 +0,0 @@
This is a stripped-down version of the PLPA 1.1 package, adapted to
be embedded in the htop code base. For the full PLPA package, go to
http://www.open-mpi.org/projects/plpa/. Copyright notice for PLPA
follows below.
-- Hisham Muhammad, htop author. March 2008.
===========================================================================
This is the Portable Linux Processor Affinity (PLPA) package
(pronounced "pli-pa"). It is intended for developers who wish to use
Linux processor affinity via the sched_setaffinity() and
sched_getaffinity() library calls, but don't want to wade through the
morass of 3 different APIs that have been offered through the life of
these calls in various Linux distributions and glibc versions.
Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
University Research and Technology
Corporation. All rights reserved.
Copyright (c) 2004-2005 The Regents of the University of California.
All rights reserved.
Copyright (c) 2006-2008 Cisco Systems, Inc. All rights reserved.
$COPYRIGHT$
See LICENSE file for a rollup of all copyright notices.
$HEADER$
===========================================================================

View File

@ -1,36 +0,0 @@
# This is the VERSION file for PLPA, describing the precise version of
# PLPA in this distribution. The various components of the version
# number below are combined to form a single version number string.
# major, minor, and release are generally combined in the form
# <major>.<minor>.<release>. If release is zero, then it is omitted.
major=1
minor=1
release=0
# greek is used for alpha or beta release tags. If it is non-empty,
# it will be appended to the version number. It does not have to be
# numeric. Common examples include a1 (alpha release 1), b1 (beta
# release 1), sc2005 (Super Computing 2005 release). The only
# requirement is that it must be entirely printable ASCII characters
# and have no white space.
greek=
# If want_svn=1, then the SVN r number will be included in the overall
# PLPA version number in some form.
want_svn=0
# If svn_r=-1, then the SVN r numbere will be obtained dynamically at
# run time, either 1) via the "svnversion" command (if this is a
# Subversion checkout) in the form "r<svn_r>", or b) with the date (if
# this is not a Subversion checkout, and the svnversion command cannot
# be used) in the form of "svn<date>". Alternatively, if svn_r is not
# -1, the value of svn_r will be directly appended to the version
# string. This happens during "make dist", for example: if the
# distribution tarball is being made from an SVN checkout, the value
# of svn_r in this file is replaced with the output of "svnversion".
svn_r=r147:149

View File

@ -1,274 +0,0 @@
# -*- shell-script -*-
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2006-2008 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# Main PLPA m4 macro, to be invoked by the user
#
# Expects two paramters:
# 1. What to do upon success
# 2. What to do upon failure
#
AC_DEFUN([PLPA_INIT],[
AC_REQUIRE([_PLPA_INTERNAL_SETUP])
AC_REQUIRE([AC_PROG_CC])
# Check for syscall()
AC_CHECK_FUNC([syscall], [happy=1], [happy=0])
# Look for syscall.h
if test "$happy" = 1; then
AC_CHECK_HEADER([sys/syscall.h], [happy=1], [happy=0])
fi
# Look for unistd.h
if test "$happy" = 1; then
AC_CHECK_HEADER([unistd.h], [happy=1], [happy=0])
fi
# Check for __NR_sched_setaffinity
if test "$happy" = 1; then
AC_MSG_CHECKING([for __NR_sched_setaffinity])
if test "$plpa_emulate" = "yes"; then
AC_MSG_RESULT([emulated])
AC_DEFINE([__NR_sched_setaffinity], [0], [Emulated value])
else
AC_TRY_COMPILE([#include <syscall.h>
#include <unistd.h>], [#ifndef __NR_sched_setaffinity
#error __NR_sched_setaffinity_not found!
#endif
int i = 1;],
[AC_MSG_RESULT([yes])
happy=1],
[AC_MSG_RESULT([no])
happy=0])
fi
fi
# Check for __NR_sched_getaffinity (probably overkill, but what
# the heck?)
if test "$happy" = 1; then
AC_MSG_CHECKING([for __NR_sched_getaffinity])
if test "$plpa_emulate" = "yes"; then
AC_MSG_RESULT([emulated])
AC_DEFINE([__NR_sched_getaffinity], [0], [Emulated value])
else
AC_TRY_COMPILE([#include <syscall.h>
#include <unistd.h>], [#ifndef __NR_sched_getaffinity
#error __NR_sched_getaffinity_not found!
#endif
int i = 1;],
[AC_MSG_RESULT([yes])
happy=1],
[AC_MSG_RESULT([no])
happy=0])
fi
fi
# If all was good, do the real init
AS_IF([test "$happy" = "1"],
[_PLPA_INIT($1, $2)],
[$2])
PLPA_DO_AM_CONDITIONALS
AC_CONFIG_FILES(
plpa_config_prefix[/Makefile]
plpa_config_prefix[/src/Makefile]
)
# Cleanup
unset happy
])dnl
#-----------------------------------------------------------------------
# Build PLPA as a standalone package
AC_DEFUN([PLPA_STANDALONE],[
m4_define([plpa_config_prefix],[.])
AC_REQUIRE([_PLPA_INTERNAL_SETUP])
plpa_mode=standalone
])dnl
#-----------------------------------------------------------------------
# Build PLPA as an included package
AC_DEFUN([PLPA_INCLUDED],[
m4_define([plpa_config_prefix],[$1])
AC_REQUIRE([_PLPA_INTERNAL_SETUP])
plpa_mode=included
PLPA_DISABLE_EXECUTABLES
])dnl
#-----------------------------------------------------------------------
dnl JMS: No fortran bindings yet
dnl # Set whether the fortran bindings will be built or not
dnl AC_DEFUN([PLPA_FORTRAN],[
dnl AC_REQUIRE([_PLPA_INTERNAL_SETUP])
dnl
dnl # Need [] around entire following line to escape m4 properly
dnl [plpa_tmp=`echo $1 | tr '[:upper:]' '[:lower:]'`]
dnl if test "$1" = "0" -o "$1" = "n"; then
dnl plpa_fortran=no
dnl elif test "$1" = "1" -o "$1" = "y"; then
dnl plpa_fortran=yes
dnl else
dnl AC_MSG_WARN([Did not understand PLPA_FORTRAN argument ($1) -- ignored])
dnl fi
dnl ])dnl
#-----------------------------------------------------------------------
# Disable building the executables
AC_DEFUN([PLPA_DISABLE_EXECUTABLES],[
AC_REQUIRE([_PLPA_INTERNAL_SETUP])
plpa_executables=no
])dnl
#-----------------------------------------------------------------------
# Specify the symbol prefix
AC_DEFUN([PLPA_SET_SYMBOL_PREFIX],[
AC_REQUIRE([_PLPA_INTERNAL_SETUP])
plpa_symbol_prefix_value=$1
])dnl
#-----------------------------------------------------------------------
# Internals
AC_DEFUN([_PLPA_INTERNAL_SETUP],[
AC_ARG_ENABLE([plpa_emulate],
AC_HELP_STRING([--enable-plpa-emulate],
[Emulate __NR_sched_setaffinity and __NR_sched_getaffinity, to allow building on non-Linux systems (for testing)]))
if test "$enable_plpa_emulate" = "yes"; then
plpa_emulate=yes
else
plpa_emulate=no
fi
dnl Hisham Muhammad: don't expose flags to htop's configure
dnl
dnl # Included mode, or standalone?
dnl AC_ARG_ENABLE([included-mode],
dnl AC_HELP_STRING([--enable-included-mode],
dnl [Using --enable-included-mode puts the PLPA into "included" mode. The default is --disable-included-mode, meaning that the PLPA is in "standalone" mode.]))
dnl if test "$enable_included_mode" = "yes"; then
plpa_mode=included
dnl else
dnl plpa_mode=standalone
dnl fi
dnl JMS: No fortran bindings yet
dnl # Fortran bindings, or no?
dnl AC_ARG_ENABLE([fortran],
dnl AC_HELP_STRING([--disable-fortran],
dnl [Using --disable-fortran disables building the Fortran PLPA API bindings]))
dnl if test "$enable_fortran" = "yes" -o "$enable_fortran" = ""; then
dnl plpa_fortran=yes
dnl else
dnl plpa_fortran=no
dnl fi
dnl Hisham Muhammad: don't expose flags to htop's configure
dnl
dnl # Build and install the executables or no?
dnl AC_ARG_ENABLE([executables],
dnl AC_HELP_STRING([--disable-executables],
dnl [Using --disable-executables disables building and installing the PLPA executables]))
dnl if test "$enable_executables" = "yes" -o "$enable_executables" = ""; then
dnl plpa_executables=yes
dnl else
plpa_executables=no
dnl fi
dnl Hisham Muhammad: don't expose flags to htop's configure
dnl
dnl # Change the symbol prefix?
dnl AC_ARG_WITH([plpa-symbol-prefix],
dnl AC_HELP_STRING([--with-plpa-symbol-prefix=STRING],
dnl [STRING can be any valid C symbol name. It will be prefixed to all public PLPA symbols. Default: "plpa_"]))
dnl if test "$with_plpa_symbol_prefix" = ""; then
plpa_symbol_prefix_value=plpa_
dnl else
dnl plpa_symbol_prefix_value=$with_plpa_symbol_prefix
dnl fi
])dnl
#-----------------------------------------------------------------------
# Internals for PLPA_INIT
AC_DEFUN([_PLPA_INIT],[
AC_REQUIRE([_PLPA_INTERNAL_SETUP])
# Are we building as standalone or included?
AC_MSG_CHECKING([for PLPA building mode])
AC_MSG_RESULT([$plpa_mode])
# We need to set a path for header, etc files depending on whether
# we're standalone or included. this is taken care of by PLPA_INCLUDED.
AC_MSG_CHECKING([for PLPA config prefix])
AC_MSG_RESULT(plpa_config_prefix)
# Note that plpa_config.h *MUST* be listed first so that it
# becomes the "main" config header file. Any AM_CONFIG_HEADERs
# after that (plpa.h) will only have selective #defines replaced,
# not the entire file.
AM_CONFIG_HEADER(plpa_config_prefix[/src/plpa_config.h])
AM_CONFIG_HEADER(plpa_config_prefix[/src/plpa.h])
# What prefix are we using?
AC_MSG_CHECKING([for PLPA symbol prefix])
AC_DEFINE_UNQUOTED(PLPA_SYM_PREFIX, [$plpa_symbol_prefix_value],
[The PLPA symbol prefix])
# Ensure to [] escape the whole next line so that we can get the
# proper tr tokens
[plpa_symbol_prefix_value_caps="`echo $plpa_symbol_prefix_value | tr '[:lower:]' '[:upper:]'`"]
AC_DEFINE_UNQUOTED(PLPA_SYM_PREFIX_CAPS, [$plpa_symbol_prefix_value_caps],
[The PLPA symbol prefix in all caps])
AC_MSG_RESULT([$plpa_symbol_prefix_value])
dnl JMS: No fortran bindings yet
dnl # Check for fortran
dnl AC_MSG_CHECKING([whether to build PLPA Fortran API])
dnl AC_MSG_RESULT([$plpa_fortran])
# Check whether to build the exectuables or not
AC_MSG_CHECKING([whether to build PLPA executables])
AC_MSG_RESULT([$plpa_executables])
# If we're building executables, we need some things for plpa-taskset
if test "$plpa_executables" = "yes"; then
AC_C_INLINE
fi
# Success
$1
])dnl
#-----------------------------------------------------------------------
# This must be a standalone routine so that it can be called both by
# PLPA_INIT and an external caller (if PLPA_INIT is not invoked).
AC_DEFUN([PLPA_DO_AM_CONDITIONALS],[
if test "$plpa_did_am_conditionals" != "yes"; then
AM_CONDITIONAL([PLPA_BUILD_STANDALONE], [test "$plpa_mode" = "standalone"])
dnl JMS: No fortran bindings yet
dnl AM_CONDITIONAL(PLPA_BUILD_FORTRAN, [test "$plpa_fortran" = "yes"])
AM_CONDITIONAL(PLPA_BUILD_EXECUTABLES, [test "$plpa_executables" = "yes"])
fi
plpa_did_am_conditionals=yes
])dnl

View File

@ -1,49 +0,0 @@
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# Defaults
lib_LTLIBRARIES =
noinst_LTLIBRARIES =
nodist_include_HEADERS =
nodist_noinst_HEADERS =
# Note that this file is generated by configure, so we don't want to
# ship it in the tarball. Hence the "nodist_" prefixes to the HEADERS
# macros, below.
public_headers = plpa.h
# See which mode we're building in
if PLPA_BUILD_STANDALONE
lib_LTLIBRARIES += libplpa.la
nodist_include_HEADERS += $(public_headers)
else
noinst_LTLIBRARIES += libplpa_included.la
nodist_noinst_HEADERS += $(public_headers)
endif
# The sources
plpa_sources = \
plpa_internal.h \
plpa_api_probe.c \
plpa_dispatch.c \
plpa_runtime.c \
plpa_map.c
libplpa_la_SOURCES = $(plpa_sources)
libplpa_included_la_SOURCES = $(plpa_sources)

View File

@ -1,579 +0,0 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
# See which mode we're building in
@PLPA_BUILD_STANDALONE_TRUE@am__append_1 = libplpa.la
@PLPA_BUILD_STANDALONE_TRUE@am__append_2 = $(public_headers)
@PLPA_BUILD_STANDALONE_FALSE@am__append_3 = libplpa_included.la
@PLPA_BUILD_STANDALONE_FALSE@am__append_4 = $(public_headers)
subdir = plpa-1.1/src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/plpa.h.in $(srcdir)/plpa_config.h.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/plpa-1.1/plpa.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h plpa_config.h plpa.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
libplpa_la_LIBADD =
am__objects_1 = plpa_api_probe.lo plpa_dispatch.lo plpa_runtime.lo \
plpa_map.lo
am_libplpa_la_OBJECTS = $(am__objects_1)
libplpa_la_OBJECTS = $(am_libplpa_la_OBJECTS)
@PLPA_BUILD_STANDALONE_TRUE@am_libplpa_la_rpath = -rpath $(libdir)
libplpa_included_la_LIBADD =
am_libplpa_included_la_OBJECTS = $(am__objects_1)
libplpa_included_la_OBJECTS = $(am_libplpa_included_la_OBJECTS)
@PLPA_BUILD_STANDALONE_FALSE@am_libplpa_included_la_rpath =
DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libplpa_la_SOURCES) $(libplpa_included_la_SOURCES)
DIST_SOURCES = $(libplpa_la_SOURCES) $(libplpa_included_la_SOURCES)
nodist_includeHEADERS_INSTALL = $(INSTALL_HEADER)
HEADERS = $(nodist_include_HEADERS) $(nodist_noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
# Defaults
lib_LTLIBRARIES = $(am__append_1)
noinst_LTLIBRARIES = $(am__append_3)
nodist_include_HEADERS = $(am__append_2)
nodist_noinst_HEADERS = $(am__append_4)
# Note that this file is generated by configure, so we don't want to
# ship it in the tarball. Hence the "nodist_" prefixes to the HEADERS
# macros, below.
public_headers = plpa.h
# The sources
plpa_sources = \
plpa_internal.h \
plpa_api_probe.c \
plpa_dispatch.c \
plpa_runtime.c \
plpa_map.c
libplpa_la_SOURCES = $(plpa_sources)
libplpa_included_la_SOURCES = $(plpa_sources)
all: plpa_config.h plpa.h
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plpa-1.1/src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu plpa-1.1/src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
plpa_config.h: stamp-h2
@if test ! -f $@; then \
rm -f stamp-h2; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h2; \
else :; fi
stamp-h2: $(srcdir)/plpa_config.h.in $(top_builddir)/config.status
@rm -f stamp-h2
cd $(top_builddir) && $(SHELL) ./config.status plpa-1.1/src/plpa_config.h
$(srcdir)/plpa_config.h.in: $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f stamp-h2
touch $@
plpa.h: stamp-h3
@if test ! -f $@; then \
rm -f stamp-h3; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h3; \
else :; fi
stamp-h3: $(srcdir)/plpa.h.in $(top_builddir)/config.status
@rm -f stamp-h3
cd $(top_builddir) && $(SHELL) ./config.status plpa-1.1/src/plpa.h
distclean-hdr:
-rm -f plpa_config.h stamp-h2 plpa.h stamp-h3
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
$(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libplpa.la: $(libplpa_la_OBJECTS) $(libplpa_la_DEPENDENCIES)
$(LINK) $(am_libplpa_la_rpath) $(libplpa_la_OBJECTS) $(libplpa_la_LIBADD) $(LIBS)
libplpa_included.la: $(libplpa_included_la_OBJECTS) $(libplpa_included_la_DEPENDENCIES)
$(LINK) $(am_libplpa_included_la_rpath) $(libplpa_included_la_OBJECTS) $(libplpa_included_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plpa_api_probe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plpa_dispatch.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plpa_map.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plpa_runtime.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-nodist_includeHEADERS: $(nodist_include_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
@list='$(nodist_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(nodist_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
$(nodist_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
done
uninstall-nodist_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(nodist_include_HEADERS)'; for p in $$list; do \
f=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
rm -f "$(DESTDIR)$(includedir)/$$f"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) plpa_config.h.in plpa.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) plpa_config.h.in plpa.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) plpa_config.h.in plpa.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) plpa_config.h.in plpa.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS) plpa_config.h plpa.h
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
clean-noinstLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-nodist_includeHEADERS
install-dvi: install-dvi-am
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES uninstall-nodist_includeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
ctags distclean distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-libLTLIBRARIES \
install-man install-nodist_includeHEADERS install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-libLTLIBRARIES \
uninstall-nodist_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,214 +0,0 @@
/* -*- c -*-
*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2006-2008 Cisco, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/*
* Some notes about the declarations and definitions in this file:
*
* This file is a mix of internal and public declarations.
* Applications are warned against using the internal types; they are
* subject to change with no warning.
*
* The PLPA_NAME() and PLPA_NAME_CAPS() macros are used for prefixing
* the PLPA type names, enum names, and symbol names when embedding
* PLPA. When not embedding, the default prefix is "plpa_" (or
* "PLPA_" when using PLPA_NAME_CAPS()). Hence, if you see a
* declaration like this:
*
* int PLPA_NAME(foo)(void);
*
* It's a function named plpa_foo() that returns an int and takes no
* arguments when building PLPA as a standalone library. It's a
* function with a different prefix than "plpa_" when the
* --enable-included-mode and --with-plpa-symbol-prefix options are
* supplied to PLPA's configure script.
*/
#ifndef PLPA_H
#define PLPA_H
/* Absolutely must not include <sched.h> here or it will generate
conflicts. */
/* For memset() */
#include <string.h>
/* For pid_t and size_t */
#include <sys/types.h>
/***************************************************************************
* Internal types
***************************************************************************/
/* If we're building PLPA itself, <plpa_config.h> will have already
been included. But <plpa_config.h> is a private header file; it is
not installed into $includedir. Hence, applications including
<plpa.h> will not have included <plpa_config.h> (this is by
design). So include just enough information here to allow us to
continue. */
#ifndef PLPA_CONFIG_H
/* The PLPA symbol prefix */
#define PLPA_SYM_PREFIX plpa_
/* The PLPA symbol prefix in all caps */
#define PLPA_SYM_PREFIX_CAPS PLPA_
#endif
/* Preprocessors are fun -- the double inderection is unfortunately
necessary. */
#define PLPA_MUNGE_NAME(a, b) PLPA_MUNGE_NAME2(a, b)
#define PLPA_MUNGE_NAME2(a, b) a ## b
#define PLPA_NAME(name) PLPA_MUNGE_NAME(PLPA_SYM_PREFIX, name)
#define PLPA_NAME_CAPS(name) PLPA_MUNGE_NAME(PLPA_SYM_PREFIX_CAPS, name)
/***************************************************************************
* Public type
***************************************************************************/
/* Values that can be returned from plpa_api_probe() */
typedef enum {
/* Sentinel value */
PLPA_NAME_CAPS(PROBE_UNSET),
/* sched_setaffinity syscall available */
PLPA_NAME_CAPS(PROBE_OK),
/* syscall unavailable/unimplemented */
PLPA_NAME_CAPS(PROBE_NOT_SUPPORTED),
/* we experienced some strange failure that the user should report */
PLPA_NAME_CAPS(PROBE_UNKNOWN)
} PLPA_NAME(api_type_t);
/***************************************************************************
* Internal types
***************************************************************************/
/* Internal PLPA bitmask type. This type should not be used by
external applications! */
typedef unsigned long int PLPA_NAME(bitmask_t);
#define PLPA_BITMASK_T_NUM_BITS (sizeof(PLPA_NAME(bitmask_t)) * 8)
#define PLPA_BITMASK_CPU_MAX 1024
#define PLPA_BITMASK_NUM_ELEMENTS (PLPA_BITMASK_CPU_MAX / PLPA_BITMASK_T_NUM_BITS)
/***************************************************************************
* Public type
***************************************************************************/
/* Public type for the PLPA cpu set. */
typedef struct { PLPA_NAME(bitmask_t) bitmask[PLPA_BITMASK_NUM_ELEMENTS]; } PLPA_NAME(cpu_set_t);
/***************************************************************************
* Internal macros
***************************************************************************/
/* Internal macro for identifying the byte in a bitmask array. This
macro should not be used by external applications! */
#define PLPA_CPU_BYTE(num) ((num) / PLPA_BITMASK_T_NUM_BITS)
/* Internal macro for identifying the bit in a bitmask array. This
macro should not be used by external applications! */
#define PLPA_CPU_BIT(num) ((num) % PLPA_BITMASK_T_NUM_BITS)
/***************************************************************************
* Public macros
***************************************************************************/
/* Public macro to zero out a PLPA cpu set (analogous to the FD_ZERO()
macro; see select(2)). */
#define PLPA_CPU_ZERO(cpuset) \
memset((cpuset), 0, sizeof(PLPA_NAME(cpu_set_t)))
/* Public macro to set a bit in a PLPA cpu set (analogous to the
FD_SET() macro; see select(2)). */
#define PLPA_CPU_SET(num, cpuset) \
(cpuset)->bitmask[PLPA_CPU_BYTE(num)] |= ((PLPA_NAME(bitmask_t))1 << PLPA_CPU_BIT(num))
/* Public macro to clear a bit in a PLPA cpu set (analogous to the
FD_CLR() macro; see select(2)). */
#define PLPA_CPU_CLR(num, cpuset) \
(cpuset)->bitmask[PLPA_CPU_BYTE(num)] &= ~((PLPA_NAME(bitmask_t))1 << PLPA_CPU_BIT(num))
/* Public macro to test if a bit is set in a PLPA cpu set (analogous
to the FD_ISSET() macro; see select(2)). */
#define PLPA_CPU_ISSET(num, cpuset) \
(0 != (((cpuset)->bitmask[PLPA_CPU_BYTE(num)]) & ((PLPA_NAME(bitmask_t))1 << PLPA_CPU_BIT(num))))
/***************************************************************************
* Public functions
***************************************************************************/
/* Setup PLPA internals. This function is optional; it will be
automatically invoked by all the other API functions if you do not
invoke it explicitly. Returns 0 upon success. */
int PLPA_NAME(init)(void);
/* Check what API is on this machine. If api_type returns
PLPA_PROBE_OK, then PLPA can function properly on this machine.
Returns 0 upon success. */
int PLPA_NAME(api_probe)(PLPA_NAME(api_type_t) *api_type);
/* Set processor affinity. Use the PLPA_CPU_* macros to set the
cpuset value. The same rules and restrictions about pid apply as
they do for the sched_setaffinity(2) system call. Returns 0 upon
success. */
int PLPA_NAME(sched_setaffinity)(pid_t pid, size_t cpusetsize,
const PLPA_NAME(cpu_set_t) *cpuset);
/* Get processor affinity. Use the PLPA_CPU_* macros to analyze the
returned value of cpuset. The same rules and restrictions about
pid apply as they do for the sched_getaffinity(2) system call.
Returns 0 upon success. */
int PLPA_NAME(sched_getaffinity)(pid_t pid, size_t cpusetsize,
PLPA_NAME(cpu_set_t) *cpuset);
/* Return whether topology information is available (i.e.,
plpa_map_to_*, plpa_max_*). The topology functions will be
available if supported == 1 and the function returns 0. */
int PLPA_NAME(have_topology_information)(int *supported);
/* Map (socket,core) tuple to virtual processor ID. processor_id is
then suitable for use with the PLPA_CPU_* macros, probably leading
to a call to plpa_sched_setaffinity(). Returns 0 upon success. */
int PLPA_NAME(map_to_processor_id)(int socket, int core, int *processor_id);
/* Map processor_id to (socket,core) tuple. The processor_id input is
usually obtained from the return from the plpa_sched_getaffinity()
call, using PLPA_CPU_ISSET to find individual bits in the map that
were set/unset. plpa_map_to_socket_core() can map the bit indexes
to a socket/core tuple. Returns 0 upon success. */
int PLPA_NAME(map_to_socket_core)(int processor_id, int *socket, int *core);
/* Return the max processor ID. Returns both the number of processors
(cores) in a system and the maximum Linux virtual processor ID
(because it may be higher than the number of processors if there
are "holes" in the available Linux virtual processor IDs). Returns
0 upon success. */
int PLPA_NAME(get_processor_info)(int *num_processors, int *max_processor_id);
/* Returns both the number of sockets in the system and the maximum
socket ID number (in case there are "holes" in the list of available
socket IDs). Returns 0 upon sucess. */
int PLPA_NAME(get_socket_info)(int *num_sockets, int *max_socket_id);
/* Return both the number of cores and the max code ID for a given
socket (in case there are "holes" in the list of available core
IDs). Returns 0 upon success. */
int PLPA_NAME(get_core_info)(int socket, int *num_cores, int *max_core_id);
/* Shut down PLPA. This function releases resources used by the PLPA.
It should be the last PLPA function invoked, or can be used to
forcibly cause PLPA to dump its topology cache and re-analyze the
underlying system the next time another PLPA function is called.
Specifically: it is safe to call plpa_init() (or any other PLPA
function) again after plpa_finalized(). Returns 0 upon success. */
int PLPA_NAME(finalize)(void);
#endif /* PLPA_H */

View File

@ -1,90 +0,0 @@
/* -*- c -*-
*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2007-2008 Cisco, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "plpa_config.h"
#include "plpa.h"
#include "plpa_internal.h"
#include <errno.h>
#include <sys/syscall.h>
#include <unistd.h>
/* Cache, just to make things a little more efficient */
static PLPA_NAME(api_type_t) cache = PLPA_NAME_CAPS(PROBE_UNSET);
/* The len value we find - not in public header, but used by the lib */
size_t PLPA_NAME(len) = 0;
int PLPA_NAME(api_probe_init)(void)
{
PLPA_NAME(cpu_set_t) mask;
int rc;
size_t len;
for (len = sizeof(mask); len != 0; len >>= 1) {
rc = syscall(__NR_sched_getaffinity, 0, len, &mask);
if (rc >= 0) {
/* OK, kernel is happy with a get(). Validate w/ a set(). */
/* Note that kernel may have told us the "proper" size */
size_t tmp = (0 != rc) ? ((size_t) rc) : len;
/* Pass mask=NULL, expect errno==EFAULT if tmp was OK
as a length */
rc = syscall(__NR_sched_setaffinity, 0, tmp, NULL);
if ((rc < 0) && (errno == EFAULT)) {
cache = PLPA_NAME_CAPS(PROBE_OK);
PLPA_NAME(len) = tmp;
rc = 0;
break;
}
}
if (errno == ENOSYS) {
break; /* No point in looping */
}
}
if (rc >= 0) {
/* OK */
} else if (errno == ENOSYS) {
/* Kernel returns ENOSYS because there is no support for
processor affinity */
cache = PLPA_NAME_CAPS(PROBE_NOT_SUPPORTED);
} else {
/* Unknown! */
cache = PLPA_NAME_CAPS(PROBE_UNKNOWN);
}
return 0;
}
int PLPA_NAME(api_probe)(PLPA_NAME(api_type_t) *api_type)
{
int ret;
/* Check to see that we're initialized */
if (!PLPA_NAME(initialized)) {
if (0 != (ret = PLPA_NAME(init)())) {
return ret;
}
}
/* Check for bozo arguments */
if (NULL == api_type) {
return EINVAL;
}
/* All done */
*api_type = cache;
return 0;
}

View File

@ -1,112 +0,0 @@
/* ./src/libplpa/plpa_config.h.in. Generated from configure.ac by autoheader. */
/* -*- c -*-
*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2006-2008 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef PLPA_CONFIG_H
#define PLPA_CONFIG_H
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Whether we're in debugging mode or not */
#undef PLPA_DEBUG
/* Major version of PLPA */
#undef PLPA_MAJOR_VERSION
/* Minor version of PLPA */
#undef PLPA_MINOR_VERSION
/* Release version of PLPA */
#undef PLPA_RELEASE_VERSION
/* The PLPA symbol prefix */
#undef PLPA_SYM_PREFIX
/* The PLPA symbol prefix in all caps */
#undef PLPA_SYM_PREFIX_CAPS
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
/* Emulated value */
#undef __NR_sched_getaffinity
/* Emulated value */
#undef __NR_sched_setaffinity
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
#endif /* PLPA_CONFIG_H */

View File

@ -1,201 +0,0 @@
/* -*- c -*-
*
* Copyright (c) 2004-2006 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "plpa_config.h"
#include "plpa.h"
#include "plpa_internal.h"
#include <errno.h>
#include <sys/syscall.h>
#include <unistd.h>
/**
* Call the kernel's setaffinity, massaging the user's input
* parameters as necessary
*/
int PLPA_NAME(sched_setaffinity)(pid_t pid, size_t cpusetsize,
const PLPA_NAME(cpu_set_t) *cpuset)
{
int ret;
size_t i;
PLPA_NAME(cpu_set_t) tmp;
PLPA_NAME(api_type_t) api;
/* Check to see that we're initialized */
if (!PLPA_NAME(initialized)) {
if (0 != (ret = PLPA_NAME(init)())) {
return ret;
}
}
/* Check for bozo arguments */
if (NULL == cpuset) {
return EINVAL;
}
/* Probe the API type */
if (0 != (ret = PLPA_NAME(api_probe)(&api))) {
return ret;
}
switch (api) {
case PLPA_NAME_CAPS(PROBE_OK):
/* This shouldn't happen, but check anyway */
if (cpusetsize > sizeof(*cpuset)) {
return EINVAL;
}
/* If the user-supplied bitmask is smaller than what the
kernel wants, zero out a temporary buffer of the size that
the kernel wants and copy the user-supplied bitmask to the
lower part of the temporary buffer. This could be done
more efficiently, but we're looking for clarity/simplicity
of code here -- this is not intended to be
performance-critical. */
if (cpusetsize < PLPA_NAME(len)) {
memset(&tmp, 0, sizeof(tmp));
for (i = 0; i < cpusetsize * 8; ++i) {
if (PLPA_CPU_ISSET(i, cpuset)) {
PLPA_CPU_SET(i, &tmp);
}
}
}
/* If the user-supplied bitmask is larger than what the kernel
will accept, scan it and see if there are any set bits in
the part larger than what the kernel will accept. If so,
return EINVAL. Otherwise, copy the part that the kernel
will accept into a temporary and use that. Again,
efficinency is not the issue of this code -- clarity is. */
else if (cpusetsize > PLPA_NAME(len)) {
for (i = PLPA_NAME(len) * 8; i < cpusetsize * 8; ++i) {
if (PLPA_CPU_ISSET(i, cpuset)) {
return EINVAL;
}
}
/* No upper-level bits are set, so now copy over the bits
that the kernel will look at */
memset(&tmp, 0, sizeof(tmp));
for (i = 0; i < PLPA_NAME(len) * 8; ++i) {
if (PLPA_CPU_ISSET(i, cpuset)) {
PLPA_CPU_SET(i, &tmp);
}
}
}
/* Otherwise, the user supplied a buffer that is exactly the
right size. Just for clarity of code, copy the user's
buffer into the temporary and use that. */
else {
memcpy(&tmp, cpuset, cpusetsize);
}
/* Now do the syscall */
ret = syscall(__NR_sched_setaffinity, pid, PLPA_NAME(len), &tmp);
/* Return 0 upon success. According to
http://www.open-mpi.org/community/lists/plpa-users/2006/02/0016.php,
all the kernel implementations return >= 0 upon success. */
if (ret >= 0) {
return 0;
} else {
return ret;
}
break;
case PLPA_NAME_CAPS(PROBE_NOT_SUPPORTED):
/* Process affinity not supported here */
return ENOSYS;
break;
default:
/* Something went wrong */
/* JMS: would be good to have something other than EINVAL here
-- suggestions? */
return EINVAL;
break;
}
}
/**
* Call the kernel's getaffinity, massaging the user's input
* parameters as necessary
*/
int PLPA_NAME(sched_getaffinity)(pid_t pid, size_t cpusetsize,
PLPA_NAME(cpu_set_t) *cpuset)
{
int ret;
PLPA_NAME(api_type_t) api;
/* Check to see that we're initialized */
if (!PLPA_NAME(initialized)) {
if (0 != (ret = PLPA_NAME(init)())) {
return ret;
}
}
/* Check for bozo arguments */
if (NULL == cpuset) {
return EINVAL;
}
/* Probe the API type */
if (0 != (ret = PLPA_NAME(api_probe)(&api))) {
return ret;
}
switch (api) {
case PLPA_NAME_CAPS(PROBE_OK):
/* This shouldn't happen, but check anyway */
if (PLPA_NAME(len) > sizeof(*cpuset)) {
return EINVAL;
}
/* If the user supplied a buffer that is too small, then don't
even bother */
if (cpusetsize < PLPA_NAME(len)) {
return EINVAL;
}
/* Now we know that the user's buffer is >= the size required
by the kernel. If it's >, then zero it out so that the
bits at the top are cleared (since they won't be set by the
kernel) */
if (cpusetsize > PLPA_NAME(len)) {
memset(cpuset, 0, cpusetsize);
}
/* Now do the syscall */
ret = syscall(__NR_sched_getaffinity, pid, PLPA_NAME(len), cpuset);
/* Return 0 upon success. According to
http://www.open-mpi.org/community/lists/plpa-users/2006/02/0016.php,
all the kernel implementations return >= 0 upon success. */
if (ret >= 0) {
return 0;
} else {
return ret;
}
break;
case PLPA_NAME_CAPS(PROBE_NOT_SUPPORTED):
/* Process affinity not supported here */
return ENOSYS;
break;
default:
/* Something went wrong */
return EINVAL;
break;
}
}

View File

@ -1,36 +0,0 @@
/* -*- c -*-
*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef PLPA_INTERNAL_H
#define PLPA_INTERNAL_H
#include <plpa.h>
/* Have we initialized yet? */
extern int PLPA_NAME(initialized);
/* Cached size of the affinity buffers that the kernel expects */
extern size_t PLPA_NAME(len);
/* Setup topology information */
int PLPA_NAME(map_init)(void);
/* Setup API type */
int PLPA_NAME(api_probe_init)(void);
/* Free all mapping memory */
void PLPA_NAME(map_finalize)(void);
#endif /* PLPA_INTERNAL_H */

Some files were not shown because too many files have changed in this diff Show More