mirror of
https://github.com/xzeldon/htop.git
synced 2025-07-14 21:14:35 +03:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
0384613450 |
@ -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;
|
||||
}
|
@ -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
|
@ -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* this = (AvailableColumnsPanel*) malloc(sizeof(AvailableColumnsPanel));
|
||||
Panel* super = (Panel*) this;
|
||||
@ -69,3 +41,32 @@ AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* colu
|
||||
this->columns = columns;
|
||||
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;
|
||||
}
|
||||
|
@ -25,4 +25,8 @@ typedef struct AvailableColumnsPanel_ {
|
||||
|
||||
AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr);
|
||||
|
||||
void AvailableColumnsPanel_delete(Object* object);
|
||||
|
||||
HandlerResult AvailableColumnsPanel_eventHandler(Panel* super, int ch);
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
AvailableMetersPanel* this = (AvailableMetersPanel*) object;
|
||||
Panel_done(super);
|
||||
@ -35,7 +69,7 @@ static inline void AvailableMetersPanel_addHeader(Header* header, Panel* panel,
|
||||
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;
|
||||
Header* header = this->settings->header;
|
||||
|
||||
@ -70,37 +104,3 @@ static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) {
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -26,4 +26,8 @@ typedef struct AvailableMetersPanel_ {
|
||||
|
||||
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr);
|
||||
|
||||
void AvailableMetersPanel_delete(Object* object);
|
||||
|
||||
HandlerResult AvailableMetersPanel_EventHandler(Panel* super, int ch);
|
||||
|
||||
#endif
|
||||
|
331
BatteryMeter.c
331
BatteryMeter.c
@ -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: "
|
||||
};
|
226
CPUMeter.c
226
CPUMeter.c
@ -19,125 +19,9 @@ in the source distribution for its full text.
|
||||
#include <assert.h>
|
||||
|
||||
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 = {
|
||||
.setValues = CPUMeter_setValues,
|
||||
.display = CPUMeter_display,
|
||||
@ -164,3 +48,111 @@ MeterType AllCPUsMeter = {
|
||||
.setMode = AllCPUsMeter_setMode,
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
18
CPUMeter.h
18
CPUMeter.h
@ -23,6 +23,10 @@ in the source distribution for its full text.
|
||||
|
||||
extern int CPUMeter_attributes[];
|
||||
|
||||
extern MeterType CPUMeter;
|
||||
|
||||
extern MeterType AllCPUsMeter;
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
@ -30,8 +34,18 @@ extern int CPUMeter_attributes[];
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
#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
|
||||
|
73
CRT.c
73
CRT.c
@ -14,7 +14,6 @@ in the source distribution for its full text.
|
||||
|
||||
#include "String.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
|
||||
@ -56,7 +55,6 @@ typedef enum ColorElements_ {
|
||||
METER_VALUE,
|
||||
LED_COLOR,
|
||||
UPTIME,
|
||||
BATTERY,
|
||||
TASKS_TOTAL,
|
||||
TASKS_RUNNING,
|
||||
SWAP,
|
||||
@ -69,8 +67,6 @@ typedef enum ColorElements_ {
|
||||
PROCESS_BASENAME,
|
||||
PROCESS_HIGH_PRIORITY,
|
||||
PROCESS_LOW_PRIORITY,
|
||||
PROCESS_THREAD,
|
||||
PROCESS_THREAD_BASENAME,
|
||||
BAR_BORDER,
|
||||
BAR_SHADOW,
|
||||
GRAPH_1,
|
||||
@ -100,7 +96,6 @@ typedef enum ColorElements_ {
|
||||
CPU_IOWAIT,
|
||||
CPU_IRQ,
|
||||
CPU_SOFTIRQ,
|
||||
HOSTNAME,
|
||||
LAST_COLORELEMENT
|
||||
} ColorElements;
|
||||
|
||||
@ -116,17 +111,6 @@ int CRT_colors[LAST_COLORELEMENT] = { 0 };
|
||||
|
||||
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.
|
||||
|
||||
void CRT_init(int delay, int colorScheme) {
|
||||
@ -195,6 +179,17 @@ void CRT_enableDelay() {
|
||||
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) {
|
||||
CRT_colorScheme = colorScheme;
|
||||
if (colorScheme == COLORSCHEME_BLACKNIGHT) {
|
||||
@ -214,11 +209,10 @@ void CRT_setColors(int colorScheme) {
|
||||
CRT_colors[FUNCTION_KEY] = A_NORMAL;
|
||||
CRT_colors[PANEL_HEADER_FOCUS] = A_REVERSE;
|
||||
CRT_colors[PANEL_HEADER_UNFOCUS] = A_REVERSE;
|
||||
CRT_colors[PANEL_HIGHLIGHT_FOCUS] = A_REVERSE;
|
||||
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD;
|
||||
CRT_colors[PANEL_HIGHLIGHT_FOCUS] = A_REVERSE | A_BOLD;
|
||||
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_REVERSE;
|
||||
CRT_colors[FAILED_SEARCH] = A_REVERSE | A_BOLD;
|
||||
CRT_colors[UPTIME] = A_BOLD;
|
||||
CRT_colors[BATTERY] = A_BOLD;
|
||||
CRT_colors[LARGE_NUMBER] = A_BOLD;
|
||||
CRT_colors[METER_TEXT] = A_NORMAL;
|
||||
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_HIGH_PRIORITY] = A_BOLD;
|
||||
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_SHADOW] = A_DIM;
|
||||
CRT_colors[SWAP] = A_BOLD;
|
||||
@ -262,10 +254,9 @@ void CRT_setColors(int colorScheme) {
|
||||
CRT_colors[CHECK_BOX] = A_BOLD;
|
||||
CRT_colors[CHECK_MARK] = 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_SOFTIRQ] = A_BOLD;
|
||||
CRT_colors[HOSTNAME] = A_BOLD;
|
||||
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE) {
|
||||
CRT_colors[RESET_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[FAILED_SEARCH] = ColorPair(Red,Cyan);
|
||||
CRT_colors[UPTIME] = ColorPair(Yellow,White);
|
||||
CRT_colors[BATTERY] = ColorPair(Yellow,White);
|
||||
CRT_colors[LARGE_NUMBER] = ColorPair(Red,White);
|
||||
CRT_colors[METER_TEXT] = ColorPair(Blue,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_TAG] = ColorPair(White,Blue);
|
||||
CRT_colors[PROCESS_MEGABYTES] = ColorPair(Blue,White);
|
||||
CRT_colors[PROCESS_BASENAME] = ColorPair(Blue,White);
|
||||
CRT_colors[PROCESS_TREE] = ColorPair(Green,White);
|
||||
CRT_colors[PROCESS_BASENAME] = ColorPair(Green,White);
|
||||
CRT_colors[PROCESS_TREE] = ColorPair(Blue,White);
|
||||
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,White);
|
||||
CRT_colors[PROCESS_HIGH_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_SHADOW] = ColorPair(Black,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_NORMAL] = ColorPair(Green,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_MARK] = 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_SOFTIRQ] = ColorPair(Blue,White);
|
||||
CRT_colors[HOSTNAME] = ColorPair(Black,White);
|
||||
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE2) {
|
||||
CRT_colors[RESET_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[FAILED_SEARCH] = ColorPair(Red,Cyan);
|
||||
CRT_colors[UPTIME] = ColorPair(Yellow,Black);
|
||||
CRT_colors[BATTERY] = ColorPair(Yellow,Black);
|
||||
CRT_colors[LARGE_NUMBER] = ColorPair(Red,Black);
|
||||
CRT_colors[METER_TEXT] = ColorPair(Blue,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_HIGH_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_SHADOW] = ColorPair(Black,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_MARK] = 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_SOFTIRQ] = ColorPair(Blue,Black);
|
||||
CRT_colors[HOSTNAME] = ColorPair(White,Black);
|
||||
} else if (CRT_colorScheme == COLORSCHEME_MIDNIGHT) {
|
||||
CRT_colors[RESET_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[FAILED_SEARCH] = ColorPair(Red,Cyan);
|
||||
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[METER_TEXT] = 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_HIGH_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_SHADOW] = ColorPair(Cyan,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_MARK] = A_BOLD | 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_SOFTIRQ] = ColorPair(Black,Blue);
|
||||
CRT_colors[HOSTNAME] = ColorPair(White,Blue);
|
||||
} else if (CRT_colorScheme == COLORSCHEME_BLACKNIGHT) {
|
||||
CRT_colors[RESET_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[FAILED_SEARCH] = ColorPair(Red,Cyan);
|
||||
CRT_colors[UPTIME] = ColorPair(Green,Black);
|
||||
CRT_colors[BATTERY] = ColorPair(Green,Black);
|
||||
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black);
|
||||
CRT_colors[METER_TEXT] = ColorPair(Cyan,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_BASENAME] = A_BOLD | ColorPair(Green,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_HIGH_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_NORMAL] = ColorPair(Green,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_MARK] = A_BOLD | ColorPair(Green,Black);
|
||||
CRT_colors[CHECK_TEXT] = ColorPair(Cyan,Black);
|
||||
CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black);
|
||||
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black);
|
||||
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black);
|
||||
CRT_colors[HOSTNAME] = ColorPair(Green,Black);
|
||||
} else {
|
||||
/* Default */
|
||||
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[FAILED_SEARCH] = ColorPair(Red,Cyan);
|
||||
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[METER_TEXT] = 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_HIGH_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_SHADOW] = A_BOLD | ColorPair(Black,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_MARK] = A_BOLD;
|
||||
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_SOFTIRQ] = ColorPair(Magenta,Black);
|
||||
CRT_colors[HOSTNAME] = A_BOLD;
|
||||
}
|
||||
}
|
||||
|
9
CRT.h
9
CRT.h
@ -17,7 +17,6 @@ in the source distribution for its full text.
|
||||
|
||||
#include "String.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
|
||||
@ -58,7 +57,6 @@ typedef enum ColorElements_ {
|
||||
METER_VALUE,
|
||||
LED_COLOR,
|
||||
UPTIME,
|
||||
BATTERY,
|
||||
TASKS_TOTAL,
|
||||
TASKS_RUNNING,
|
||||
SWAP,
|
||||
@ -71,8 +69,6 @@ typedef enum ColorElements_ {
|
||||
PROCESS_BASENAME,
|
||||
PROCESS_HIGH_PRIORITY,
|
||||
PROCESS_LOW_PRIORITY,
|
||||
PROCESS_THREAD,
|
||||
PROCESS_THREAD_BASENAME,
|
||||
BAR_BORDER,
|
||||
BAR_SHADOW,
|
||||
GRAPH_1,
|
||||
@ -102,7 +98,6 @@ typedef enum ColorElements_ {
|
||||
CPU_IOWAIT,
|
||||
CPU_IRQ,
|
||||
CPU_SOFTIRQ,
|
||||
HOSTNAME,
|
||||
LAST_COLORELEMENT
|
||||
} ColorElements;
|
||||
|
||||
@ -129,6 +124,10 @@ void CRT_disableDelay();
|
||||
|
||||
void CRT_enableDelay();
|
||||
|
||||
void CRT_handleSIGSEGV(int signal);
|
||||
|
||||
void CRT_handleSIGTERM(int signal);
|
||||
|
||||
void CRT_setColors(int colorScheme);
|
||||
|
||||
#endif
|
||||
|
@ -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 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;
|
||||
}
|
||||
static char* AvailableColumnsFunctions[10] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done "};
|
||||
|
||||
CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr) {
|
||||
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));
|
||||
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);
|
||||
}
|
||||
|
@ -24,8 +24,18 @@ typedef struct CategoriesPanel_ {
|
||||
} CategoriesPanel;
|
||||
|
||||
|
||||
void CategoriesPanel_makeMetersPage(CategoriesPanel* this);
|
||||
|
||||
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
|
||||
|
100
ChangeLog
100
ChangeLog
@ -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
|
||||
|
||||
* Add an option to split the display of kernel time
|
||||
|
44
CheckItem.c
44
CheckItem.c
@ -16,8 +16,7 @@ in the source distribution for its full text.
|
||||
typedef struct CheckItem_ {
|
||||
Object super;
|
||||
char* text;
|
||||
bool value;
|
||||
bool* ref;
|
||||
bool* value;
|
||||
} CheckItem;
|
||||
|
||||
}*/
|
||||
@ -28,7 +27,17 @@ char* CHECKITEM_CLASS = "CheckItem";
|
||||
#define CHECKITEM_CLASS NULL
|
||||
#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;
|
||||
assert (this != NULL);
|
||||
|
||||
@ -36,39 +45,14 @@ static void CheckItem_delete(Object* cast) {
|
||||
free(this);
|
||||
}
|
||||
|
||||
static void CheckItem_display(Object* cast, RichString* out) {
|
||||
void CheckItem_display(Object* cast, RichString* out) {
|
||||
CheckItem* this = (CheckItem*)cast;
|
||||
assert (this != NULL);
|
||||
RichString_write(out, CRT_colors[CHECK_BOX], "[");
|
||||
if (CheckItem_get(this))
|
||||
if (*(this->value))
|
||||
RichString_append(out, CRT_colors[CHECK_MARK], "x");
|
||||
else
|
||||
RichString_append(out, CRT_colors[CHECK_MARK], " ");
|
||||
RichString_append(out, CRT_colors[CHECK_BOX], "] ");
|
||||
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;
|
||||
}
|
||||
|
@ -18,8 +18,7 @@ in the source distribution for its full text.
|
||||
typedef struct CheckItem_ {
|
||||
Object super;
|
||||
char* text;
|
||||
bool value;
|
||||
bool* ref;
|
||||
bool* value;
|
||||
} CheckItem;
|
||||
|
||||
|
||||
@ -29,10 +28,10 @@ extern char* CHECKITEM_CLASS;
|
||||
#define CHECKITEM_CLASS NULL
|
||||
#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
|
||||
|
14
ClockMeter.c
14
ClockMeter.c
@ -16,13 +16,6 @@ int ClockMeter_attributes[] = {
|
||||
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 = {
|
||||
.setValues = ClockMeter_setValues,
|
||||
.display = NULL,
|
||||
@ -34,3 +27,10 @@ MeterType ClockMeter = {
|
||||
.uiName = "Clock",
|
||||
.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);
|
||||
}
|
||||
|
@ -19,4 +19,6 @@ extern int ClockMeter_attributes[];
|
||||
|
||||
extern MeterType ClockMeter;
|
||||
|
||||
void ClockMeter_setValues(Meter* this, char* buffer, int size);
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,7 @@ typedef struct ColorsPanel_ {
|
||||
|
||||
Settings* settings;
|
||||
ScreenManager* scr;
|
||||
bool check[5];
|
||||
} ColorsPanel;
|
||||
|
||||
}*/
|
||||
@ -37,14 +38,33 @@ static char* ColorSchemes[] = {
|
||||
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;
|
||||
ColorsPanel* this = (ColorsPanel*) object;
|
||||
Panel_done(super);
|
||||
free(this);
|
||||
}
|
||||
|
||||
static HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
|
||||
HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
|
||||
ColorsPanel* this = (ColorsPanel*) super;
|
||||
|
||||
HandlerResult result = IGNORED;
|
||||
@ -54,11 +74,11 @@ static HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
|
||||
case 0x0a:
|
||||
case 0x0d:
|
||||
case KEY_ENTER:
|
||||
case KEY_MOUSE:
|
||||
case ' ':
|
||||
for (int i = 0; ColorSchemes[i] != NULL; i++)
|
||||
CheckItem_set((CheckItem*)Panel_get(super, i), false);
|
||||
CheckItem_set((CheckItem*)Panel_get(super, mark), true);
|
||||
for (int i = 0; ColorSchemes[i] != NULL; i++) {
|
||||
this->check[i] = false;
|
||||
}
|
||||
this->check[mark] = true;
|
||||
this->settings->colorScheme = mark;
|
||||
result = HANDLED;
|
||||
}
|
||||
@ -76,20 +96,3 @@ static HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
|
||||
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;
|
||||
}
|
||||
|
@ -25,9 +25,15 @@ typedef struct ColorsPanel_ {
|
||||
|
||||
Settings* settings;
|
||||
ScreenManager* scr;
|
||||
bool check[5];
|
||||
} ColorsPanel;
|
||||
|
||||
|
||||
ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr);
|
||||
|
||||
void ColorsPanel_delete(Object* object);
|
||||
|
||||
HandlerResult ColorsPanel_EventHandler(Panel* super, int ch);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
ColumnsPanel* this = (ColumnsPanel*) object;
|
||||
Panel_done(super);
|
||||
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);
|
||||
HandlerResult result = IGNORED;
|
||||
int size = Panel_size(super);
|
||||
int size = Panel_getSize(super);
|
||||
|
||||
switch(ch) {
|
||||
case KEY_F(7):
|
||||
@ -65,47 +108,3 @@ static HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch) {
|
||||
ColumnsPanel_update(super);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,12 @@ typedef struct ColumnsPanel_ {
|
||||
|
||||
ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr);
|
||||
|
||||
void ColumnsPanel_delete(Object* object);
|
||||
|
||||
int ColumnsPanel_fieldNameToIndex(const char* name);
|
||||
|
||||
void ColumnsPanel_update(Panel* super);
|
||||
|
||||
HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch);
|
||||
|
||||
#endif
|
||||
|
@ -49,11 +49,7 @@ void DebugMemory_new() {
|
||||
singleton->allocations = 0;
|
||||
singleton->deallocations = 0;
|
||||
singleton->size = 0;
|
||||
#ifdef DEBUG_ALLOC
|
||||
singleton->file = fopen("/tmp/htop-debug-alloc.txt", "w");
|
||||
#else
|
||||
singleton->file = NULL;
|
||||
#endif
|
||||
singleton->totals = true;
|
||||
//singleton->file = NULL;
|
||||
}
|
||||
|
@ -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;
|
||||
DisplayOptionsPanel* this = (DisplayOptionsPanel*) object;
|
||||
Panel_done(super);
|
||||
free(this);
|
||||
}
|
||||
|
||||
static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
|
||||
HandlerResult DisplayOptionsPanel_EventHandler(Panel* super, int ch) {
|
||||
DisplayOptionsPanel* this = (DisplayOptionsPanel*) super;
|
||||
|
||||
HandlerResult result = IGNORED;
|
||||
@ -37,9 +59,8 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
|
||||
case 0x0a:
|
||||
case 0x0d:
|
||||
case KEY_ENTER:
|
||||
case KEY_MOUSE:
|
||||
case ' ':
|
||||
CheckItem_set(selected, ! (CheckItem_get(selected)) );
|
||||
*(selected->value) = ! *(selected->value);
|
||||
result = HANDLED;
|
||||
}
|
||||
|
||||
@ -53,25 +74,3 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
|
||||
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;
|
||||
}
|
||||
|
@ -23,4 +23,9 @@ typedef struct DisplayOptionsPanel_ {
|
||||
|
||||
DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr);
|
||||
|
||||
void DisplayOptionsPanel_delete(Object* object);
|
||||
|
||||
HandlerResult DisplayOptionsPanel_EventHandler(Panel* super, int ch);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -36,36 +36,34 @@ char* FUNCTIONBAR_CLASS = "FunctionBar";
|
||||
#define FUNCTIONBAR_CLASS NULL
|
||||
#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));
|
||||
Object_setClass(this, FUNCTIONBAR_CLASS);
|
||||
((Object*) this)->delete = FunctionBar_delete;
|
||||
this->functions = functions;
|
||||
this->size = size;
|
||||
if (keys && events) {
|
||||
this->staticData = false;
|
||||
this->functions = malloc(sizeof(char*) * 15);
|
||||
this->keys = malloc(sizeof(char*) * 15);
|
||||
this->events = malloc(sizeof(int) * 15);
|
||||
int i = 0;
|
||||
while (i < 15 && functions[i]) {
|
||||
this->functions = malloc(sizeof(char*) * size);
|
||||
this->keys = malloc(sizeof(char*) * size);
|
||||
this->events = malloc(sizeof(int) * size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
this->functions[i] = String_copy(functions[i]);
|
||||
this->keys[i] = String_copy(keys[i]);
|
||||
this->events[i] = events[i];
|
||||
i++;
|
||||
}
|
||||
this->size = i;
|
||||
} else {
|
||||
this->staticData = true;
|
||||
this->functions = functions ? functions : FunctionBar_FLabels;
|
||||
this->keys = FunctionBar_FKeys;
|
||||
this->events = FunctionBar_FEvents;
|
||||
this->size = 10;
|
||||
assert((!functions) || this->size == 10);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ extern char* FUNCTIONBAR_CLASS;
|
||||
#define FUNCTIONBAR_CLASS NULL
|
||||
#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);
|
||||
|
||||
|
94
Hashtable.c
94
Hashtable.c
@ -9,7 +9,6 @@ in the source distribution for its full text.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
@ -19,7 +18,7 @@ typedef struct Hashtable_ Hashtable;
|
||||
typedef void(*Hashtable_PairFunction)(int, void*, void*);
|
||||
|
||||
typedef struct HashtableItem {
|
||||
unsigned int key;
|
||||
int key;
|
||||
void* value;
|
||||
struct HashtableItem* next;
|
||||
} HashtableItem;
|
||||
@ -32,36 +31,7 @@ struct Hashtable_ {
|
||||
};
|
||||
}*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
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* HashtableItem_new(int key, void* value) {
|
||||
HashtableItem* this;
|
||||
|
||||
this = (HashtableItem*) malloc(sizeof(HashtableItem));
|
||||
@ -75,16 +45,13 @@ Hashtable* Hashtable_new(int size, bool owner) {
|
||||
Hashtable* this;
|
||||
|
||||
this = (Hashtable*) malloc(sizeof(Hashtable));
|
||||
this->items = 0;
|
||||
this->size = size;
|
||||
this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size);
|
||||
this->owner = owner;
|
||||
assert(Hashtable_isConsistent(this));
|
||||
return this;
|
||||
}
|
||||
|
||||
void Hashtable_delete(Hashtable* this) {
|
||||
assert(Hashtable_isConsistent(this));
|
||||
for (int i = 0; i < this->size; i++) {
|
||||
HashtableItem* walk = this->buckets[i];
|
||||
while (walk != NULL) {
|
||||
@ -99,8 +66,12 @@ void Hashtable_delete(Hashtable* this) {
|
||||
free(this);
|
||||
}
|
||||
|
||||
void Hashtable_put(Hashtable* this, unsigned int key, void* value) {
|
||||
unsigned int index = key % this->size;
|
||||
inline int Hashtable_size(Hashtable* this) {
|
||||
return this->items;
|
||||
}
|
||||
|
||||
void Hashtable_put(Hashtable* this, int key, void* value) {
|
||||
int index = key % this->size;
|
||||
HashtableItem** bucketPtr = &(this->buckets[index]);
|
||||
while (true)
|
||||
if (*bucketPtr == NULL) {
|
||||
@ -114,53 +85,47 @@ void Hashtable_put(Hashtable* this, unsigned int key, void* value) {
|
||||
break;
|
||||
} else
|
||||
bucketPtr = &((*bucketPtr)->next);
|
||||
assert(Hashtable_isConsistent(this));
|
||||
}
|
||||
|
||||
void* Hashtable_remove(Hashtable* this, unsigned int key) {
|
||||
unsigned int index = key % this->size;
|
||||
|
||||
assert(Hashtable_isConsistent(this));
|
||||
|
||||
HashtableItem** bucket;
|
||||
for (bucket = &(this->buckets[index]); *bucket; bucket = &((*bucket)->next) ) {
|
||||
if ((*bucket)->key == key) {
|
||||
void* value = (*bucket)->value;
|
||||
HashtableItem* next = (*bucket)->next;
|
||||
free(*bucket);
|
||||
(*bucket) = next;
|
||||
void* Hashtable_remove(Hashtable* this, int key) {
|
||||
int index = key % this->size;
|
||||
HashtableItem** bucketPtr = &(this->buckets[index]);
|
||||
while (true)
|
||||
if (*bucketPtr == NULL) {
|
||||
return NULL;
|
||||
break;
|
||||
} else if ((*bucketPtr)->key == key) {
|
||||
void* savedValue = (*bucketPtr)->value;
|
||||
HashtableItem* savedNext = (*bucketPtr)->next;
|
||||
free(*bucketPtr);
|
||||
(*bucketPtr) = savedNext;
|
||||
this->items--;
|
||||
if (this->owner) {
|
||||
free(value);
|
||||
assert(Hashtable_isConsistent(this));
|
||||
free(savedValue);
|
||||
return NULL;
|
||||
} else {
|
||||
assert(Hashtable_isConsistent(this));
|
||||
return value;
|
||||
return savedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(Hashtable_isConsistent(this));
|
||||
return NULL;
|
||||
} else
|
||||
bucketPtr = &((*bucketPtr)->next);
|
||||
}
|
||||
|
||||
inline void* Hashtable_get(Hashtable* this, unsigned int key) {
|
||||
unsigned int index = key % this->size;
|
||||
//#include <stdio.h>
|
||||
inline void* Hashtable_get(Hashtable* this, int key) {
|
||||
int index = key % this->size;
|
||||
HashtableItem* bucketPtr = this->buckets[index];
|
||||
// fprintf(stderr, "%d -> %d\n", key, index);
|
||||
while (true) {
|
||||
if (bucketPtr == NULL) {
|
||||
assert(Hashtable_isConsistent(this));
|
||||
return NULL;
|
||||
} else if (bucketPtr->key == key) {
|
||||
assert(Hashtable_isConsistent(this));
|
||||
return bucketPtr->value;
|
||||
} else
|
||||
bucketPtr = bucketPtr->next;
|
||||
// fprintf(stderr, "*\n");
|
||||
}
|
||||
}
|
||||
|
||||
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) {
|
||||
assert(Hashtable_isConsistent(this));
|
||||
for (int i = 0; i < this->size; i++) {
|
||||
HashtableItem* walk = this->buckets[i];
|
||||
while (walk != NULL) {
|
||||
@ -168,5 +133,4 @@ void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData
|
||||
walk = walk->next;
|
||||
}
|
||||
}
|
||||
assert(Hashtable_isConsistent(this));
|
||||
}
|
||||
|
17
Hashtable.h
17
Hashtable.h
@ -12,7 +12,6 @@ in the source distribution for its full text.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
@ -21,7 +20,7 @@ typedef struct Hashtable_ Hashtable;
|
||||
typedef void(*Hashtable_PairFunction)(int, void*, void*);
|
||||
|
||||
typedef struct HashtableItem {
|
||||
unsigned int key;
|
||||
int key;
|
||||
void* value;
|
||||
struct HashtableItem* next;
|
||||
} HashtableItem;
|
||||
@ -33,21 +32,19 @@ struct Hashtable_ {
|
||||
bool owner;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
int Hashtable_count(Hashtable* this);
|
||||
|
||||
#endif
|
||||
HashtableItem* HashtableItem_new(int key, void* value);
|
||||
|
||||
Hashtable* Hashtable_new(int size, bool owner);
|
||||
|
||||
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);
|
||||
|
||||
|
2
Header.c
2
Header.c
@ -73,8 +73,6 @@ void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side) {
|
||||
? this->leftMeters
|
||||
: this->rightMeters;
|
||||
|
||||
if (i >= Vector_size(meters))
|
||||
return;
|
||||
Meter* meter = (Meter*) Vector_get(meters, i);
|
||||
Meter_setMode(meter, mode);
|
||||
}
|
||||
|
@ -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: ",
|
||||
};
|
@ -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
|
30
ListItem.c
30
ListItem.c
@ -29,21 +29,6 @@ char* LISTITEM_CLASS = "ListItem";
|
||||
#define LISTITEM_CLASS NULL
|
||||
#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* this = malloc(sizeof(ListItem));
|
||||
Object_setClass(this, LISTITEM_CLASS);
|
||||
@ -61,6 +46,21 @@ void ListItem_append(ListItem* this, char* text) {
|
||||
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) {
|
||||
return this->value;
|
||||
}
|
||||
|
@ -34,6 +34,10 @@ ListItem* ListItem_new(char* value, int key);
|
||||
|
||||
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);
|
||||
|
||||
int ListItem_compare(const void* cast1, const void* cast2);
|
||||
|
@ -16,52 +16,6 @@ int LoadAverageMeter_attributes[] = {
|
||||
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 = {
|
||||
.setValues = LoadAverageMeter_setValues,
|
||||
.display = LoadAverageMeter_display,
|
||||
@ -74,6 +28,8 @@ MeterType LoadAverageMeter = {
|
||||
.caption = "Load average: "
|
||||
};
|
||||
|
||||
int LoadMeter_attributes[] = { LOAD };
|
||||
|
||||
MeterType LoadMeter = {
|
||||
.setValues = LoadMeter_setValues,
|
||||
.display = LoadMeter_display,
|
||||
@ -85,3 +41,47 @@ MeterType LoadMeter = {
|
||||
.uiName = "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);
|
||||
}
|
||||
|
@ -17,10 +17,18 @@ in the source distribution for its full text.
|
||||
|
||||
extern int LoadAverageMeter_attributes[];
|
||||
|
||||
extern int LoadMeter_attributes[];
|
||||
|
||||
extern MeterType LoadAverageMeter;
|
||||
|
||||
extern int LoadMeter_attributes[];
|
||||
|
||||
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
|
||||
|
60
Makefile.am
60
Makefile.am
@ -1,8 +1,4 @@
|
||||
|
||||
if HAVE_PLPA
|
||||
SUBDIRS = plpa-1.1
|
||||
endif
|
||||
|
||||
bin_PROGRAMS = htop
|
||||
dist_man_MANS = htop.1
|
||||
EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png scripts/MakeHeader.py \
|
||||
@ -12,49 +8,31 @@ applications_DATA = htop.desktop
|
||||
pixmapdir = $(datadir)/pixmaps
|
||||
pixmap_DATA = htop.png
|
||||
|
||||
htop_CFLAGS = -pedantic -Wall -std=c99 -D_XOPEN_SOURCE_EXTENDED
|
||||
AM_CFLAGS = -pedantic -Wall -std=c99
|
||||
AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
|
||||
|
||||
myhtopsources = AvailableMetersPanel.c CategoriesPanel.c CheckItem.c \
|
||||
ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c DebugMemory.c \
|
||||
DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c \
|
||||
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.c \
|
||||
BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c \
|
||||
SignalItem.c SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \
|
||||
UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c \
|
||||
HostnameMeter.c OpenFilesScreen.c
|
||||
|
||||
myhtopheaders = AvailableColumnsPanel.h AvailableMetersPanel.h \
|
||||
CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h \
|
||||
CPUMeter.h CRT.h DebugMemory.h DisplayOptionsPanel.h FunctionBar.h \
|
||||
Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.h \
|
||||
BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h \
|
||||
ScreenManager.h Settings.h SignalItem.h SignalsPanel.h String.h \
|
||||
SwapMeter.h TasksMeter.h TraceScreen.h UptimeMeter.h UsersTable.h Vector.h \
|
||||
Process.h AffinityPanel.h HostnameMeter.h OpenFilesScreen.h
|
||||
|
||||
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
|
||||
htop_SOURCES = AvailableMetersPanel.c CategoriesPanel.c ClockMeter.c \
|
||||
CPUMeter.c CRT.c DebugMemory.c DisplayOptionsPanel.c FunctionBar.c \
|
||||
Hashtable.c Header.c htop.c Panel.c ListItem.c LoadAverageMeter.c \
|
||||
MemoryMeter.c Meter.c MetersPanel.c Object.c Process.c \
|
||||
ProcessList.c RichString.c ScreenManager.c Settings.c SignalItem.c \
|
||||
SignalsPanel.c String.c SwapMeter.c TasksMeter.c Vector.c \
|
||||
UptimeMeter.c UsersTable.c AvailableMetersPanel.h CategoriesPanel.h \
|
||||
ClockMeter.h config.h CPUMeter.h CRT.h debug.h DebugMemory.h \
|
||||
DisplayOptionsPanel.h FunctionBar.h Hashtable.h Header.h htop.h Panel.h \
|
||||
ListItem.h LoadAverageMeter.h MemoryMeter.h Meter.h \
|
||||
MetersPanel.h Object.h Process.h ProcessList.h RichString.h ScreenManager.h \
|
||||
Settings.h SignalItem.h SignalsPanel.h String.h SwapMeter.h TasksMeter.h \
|
||||
Vector.h UptimeMeter.h UsersTable.h CheckItem.c CheckItem.h \
|
||||
ColorsPanel.c ColorsPanel.h TraceScreen.c TraceScreen.h \
|
||||
AvailableColumnsPanel.c AvailableColumnsPanel.h ColumnsPanel.c \
|
||||
ColumnsPanel.h
|
||||
|
||||
profile:
|
||||
$(MAKE) all CFLAGS="-pg -O2"
|
||||
|
||||
debug:
|
||||
$(MAKE) all CFLAGS="-ggdb -DDEBUG"
|
||||
$(MAKE) all CFLAGS="-g -DDEBUG"
|
||||
|
||||
hardened-debug:
|
||||
$(MAKE) all CFLAGS="-ggdb -DDEBUG" LDFLAGS="-nopie"
|
||||
|
||||
debuglite:
|
||||
$(MAKE) all CFLAGS="-ggdb -DDEBUGLITE"
|
||||
|
||||
.c.h:
|
||||
scripts/MakeHeader.py $<
|
||||
|
||||
|
||||
|
||||
$(MAKE) all CFLAGS="-g -DDEBUGLITE"
|
||||
|
@ -23,7 +23,19 @@ int MemoryMeter_attributes[] = {
|
||||
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 buffersMem = this->pl->buffersMem;
|
||||
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);
|
||||
}
|
||||
|
||||
static void MemoryMeter_display(Object* cast, RichString* out) {
|
||||
void MemoryMeter_display(Object* cast, RichString* out) {
|
||||
char buffer[50];
|
||||
Meter* this = (Meter*)cast;
|
||||
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[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"
|
||||
};
|
||||
|
@ -26,4 +26,8 @@ extern int MemoryMeter_attributes[];
|
||||
|
||||
extern MeterType MemoryMeter;
|
||||
|
||||
void MemoryMeter_setValues(Meter* this, char* buffer, int size);
|
||||
|
||||
void MemoryMeter_display(Object* cast, RichString* out);
|
||||
|
||||
#endif
|
||||
|
111
Meter.c
111
Meter.c
@ -6,7 +6,12 @@ in the source distribution for its full text.
|
||||
*/
|
||||
|
||||
#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 "Object.h"
|
||||
#include "CRT.h"
|
||||
@ -14,11 +19,6 @@ in the source distribution for its full text.
|
||||
#include "String.h"
|
||||
#include "ProcessList.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include <assert.h>
|
||||
|
||||
@ -95,10 +95,7 @@ typedef enum {
|
||||
#include "TasksMeter.h"
|
||||
#include "LoadAverageMeter.h"
|
||||
#include "UptimeMeter.h"
|
||||
#include "BatteryMeter.h"
|
||||
#include "ClockMeter.h"
|
||||
#include "HostnameMeter.h"
|
||||
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
@ -122,9 +119,46 @@ MeterType* Meter_types[] = {
|
||||
&SwapMeter,
|
||||
&TasksMeter,
|
||||
&UptimeMeter,
|
||||
&BatteryMeter,
|
||||
&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
|
||||
};
|
||||
|
||||
@ -219,7 +253,7 @@ ListItem* Meter_toListItem(Meter* this) {
|
||||
|
||||
/* ---------- 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;
|
||||
char buffer[METER_BUFFER_LEN];
|
||||
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);
|
||||
mvhline(y, x, ' ', CRT_colors[DEFAULT_COLOR]);
|
||||
attrset(CRT_colors[RESET_COLOR]);
|
||||
RichString_printVal(Meter_stringBuffer, y, x);
|
||||
mvaddchstr(y, x, Meter_stringBuffer.chstr);
|
||||
}
|
||||
|
||||
/* ---------- BarMeterMode ---------- */
|
||||
|
||||
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;
|
||||
char buffer[METER_BUFFER_LEN];
|
||||
type->setValues(this, buffer, METER_BUFFER_LEN - 1);
|
||||
|
||||
w -= 2;
|
||||
attrset(CRT_colors[METER_TEXT]);
|
||||
int captionLen = 3;
|
||||
mvaddnstr(y, x, this->caption, captionLen);
|
||||
mvaddstr(y, x, this->caption);
|
||||
int captionLen = strlen(this->caption);
|
||||
x += captionLen;
|
||||
w -= captionLen;
|
||||
attrset(CRT_colors[BAR_BORDER]);
|
||||
@ -327,7 +361,7 @@ static int GraphMeterMode_colors[21] = {
|
||||
|
||||
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);
|
||||
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]);
|
||||
}
|
||||
|
||||
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;
|
||||
char buffer[METER_BUFFER_LEN];
|
||||
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);
|
||||
int xx = x + strlen(this->caption);
|
||||
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') {
|
||||
LEDMeterMode_drawDigit(xx, y, c-48);
|
||||
xx += 4;
|
||||
@ -397,42 +431,3 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
|
||||
}
|
||||
|
||||
#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
33
Meter.h
@ -10,18 +10,18 @@ in the source distribution for its full text.
|
||||
*/
|
||||
|
||||
#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 "CRT.h"
|
||||
#include "ListItem.h"
|
||||
#include "String.h"
|
||||
#include "ProcessList.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include <assert.h>
|
||||
|
||||
@ -96,10 +96,7 @@ typedef enum {
|
||||
#include "TasksMeter.h"
|
||||
#include "LoadAverageMeter.h"
|
||||
#include "UptimeMeter.h"
|
||||
#include "BatteryMeter.h"
|
||||
#include "ClockMeter.h"
|
||||
#include "HostnameMeter.h"
|
||||
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
@ -116,6 +113,12 @@ extern char* METER_CLASS;
|
||||
|
||||
extern MeterType* Meter_types[];
|
||||
|
||||
#ifdef USE_FUNKY_MODES
|
||||
|
||||
#endif
|
||||
|
||||
extern MeterMode* Meter_modes[];
|
||||
|
||||
Meter* Meter_new(ProcessList* pl, int param, MeterType* type);
|
||||
|
||||
void Meter_delete(Object* cast);
|
||||
@ -128,22 +131,24 @@ ListItem* Meter_toListItem(Meter* this);
|
||||
|
||||
/* ---------- TextMeterMode ---------- */
|
||||
|
||||
void TextMeterMode_draw(Meter* this, int x, int y, int w);
|
||||
|
||||
/* ---------- BarMeterMode ---------- */
|
||||
|
||||
void BarMeterMode_draw(Meter* this, int x, int y, int w);
|
||||
|
||||
#ifdef USE_FUNKY_MODES
|
||||
|
||||
/* ---------- GraphMeterMode ---------- */
|
||||
|
||||
#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 ---------- */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_FUNKY_MODES
|
||||
void LEDMeterMode_draw(Meter* this, int x, int y, int w);
|
||||
|
||||
#endif
|
||||
|
||||
extern MeterMode* Meter_modes[];
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
MetersPanel* this = (MetersPanel*) object;
|
||||
Panel_done(super);
|
||||
free(this);
|
||||
}
|
||||
|
||||
static HandlerResult MetersPanel_EventHandler(Panel* super, int ch) {
|
||||
HandlerResult MetersPanel_EventHandler(Panel* super, int ch) {
|
||||
MetersPanel* this = (MetersPanel*) super;
|
||||
|
||||
int selected = Panel_getSelectedIndex(super);
|
||||
@ -79,28 +97,9 @@ static HandlerResult MetersPanel_EventHandler(Panel* super, int ch) {
|
||||
}
|
||||
if (result == HANDLED) {
|
||||
Header* header = this->settings->header;
|
||||
this->settings->changed = true;
|
||||
Header_calculateHeight(header);
|
||||
Header_draw(header);
|
||||
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -23,4 +23,8 @@ typedef struct MetersPanel_ {
|
||||
|
||||
MetersPanel* MetersPanel_new(Settings* settings, char* header, Vector* meters, ScreenManager* scr);
|
||||
|
||||
void MetersPanel_delete(Object* object);
|
||||
|
||||
HandlerResult MetersPanel_EventHandler(Panel* super, int ch);
|
||||
|
||||
#endif
|
||||
|
2
Object.c
2
Object.c
@ -48,7 +48,7 @@ void Object_setClass(void* this, char* class) {
|
||||
((Object*)this)->class = class;
|
||||
}
|
||||
|
||||
static void Object_display(Object* this, RichString* out) {
|
||||
void Object_display(Object* this, RichString* out) {
|
||||
char objAddress[50];
|
||||
sprintf(objAddress, "%s @ %p", this->class, (void*) this);
|
||||
RichString_write(out, CRT_colors[DEFAULT_COLOR], objAddress);
|
||||
|
2
Object.h
2
Object.h
@ -47,6 +47,8 @@ extern char* OBJECT_CLASS;
|
||||
|
||||
void Object_setClass(void* this, char* class);
|
||||
|
||||
void Object_display(Object* this, RichString* out);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -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();
|
||||
}
|
@ -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
82
Panel.c
@ -31,8 +31,6 @@ typedef enum HandlerResult_ {
|
||||
BREAK_LOOP
|
||||
} HandlerResult;
|
||||
|
||||
#define EVENT_SETSELECTED -1
|
||||
|
||||
typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
|
||||
|
||||
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->oldSelected = 0;
|
||||
this->needsRedraw = true;
|
||||
RichString_prune(&(this->header));
|
||||
this->header.len = 0;
|
||||
if (String_eq(CRT_termType, "linux"))
|
||||
this->scrollHAmount = 20;
|
||||
this->scrollHAmount = 40;
|
||||
else
|
||||
this->scrollHAmount = 5;
|
||||
}
|
||||
@ -213,7 +211,7 @@ int Panel_getSelectedIndex(Panel* this) {
|
||||
return this->selected;
|
||||
}
|
||||
|
||||
int Panel_size(Panel* this) {
|
||||
int Panel_getSize(Panel* this) {
|
||||
assert (this != NULL);
|
||||
|
||||
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));
|
||||
this->selected = selected;
|
||||
if (this->eventHandler) {
|
||||
this->eventHandler(this, EVENT_SETSELECTED);
|
||||
}
|
||||
}
|
||||
|
||||
void Panel_draw(Panel* this, bool focus) {
|
||||
@ -265,8 +260,8 @@ void Panel_draw(Panel* this, bool focus) {
|
||||
attrset(attr);
|
||||
mvhline(y, x, ' ', this->w);
|
||||
if (scrollH < this->header.len) {
|
||||
RichString_printoffnVal(this->header, y, x, scrollH,
|
||||
MIN(this->header.len - scrollH, this->w));
|
||||
mvaddchnstr(y, x, this->header.chstr + scrollH,
|
||||
MIN(this->header.len - scrollH, this->w));
|
||||
}
|
||||
attrset(CRT_colors[RESET_COLOR]);
|
||||
y++;
|
||||
@ -289,12 +284,12 @@ void Panel_draw(Panel* this, bool focus) {
|
||||
RichString_setAttr(&itemRef, highlight);
|
||||
mvhline(y + j, x+0, ' ', this->w);
|
||||
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]);
|
||||
} else {
|
||||
mvhline(y+j, x+0, ' ', this->w);
|
||||
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++)
|
||||
@ -312,88 +307,55 @@ void Panel_draw(Panel* this, bool focus) {
|
||||
newObj->display(newObj, &newRef);
|
||||
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
|
||||
if (scrollH < oldRef.len)
|
||||
RichString_printoffnVal(oldRef, y+this->oldSelected - this->scrollV, x,
|
||||
this->scrollH, MIN(oldRef.len - scrollH, this->w));
|
||||
mvaddchnstr(y+ this->oldSelected - this->scrollV, x+0, oldRef.chstr + this->scrollH, MIN(oldRef.len - scrollH, this->w));
|
||||
attrset(highlight);
|
||||
mvhline(y+this->selected - this->scrollV, x+0, ' ', this->w);
|
||||
RichString_setAttr(&newRef, highlight);
|
||||
if (scrollH < newRef.len)
|
||||
RichString_printoffnVal(newRef, y+this->selected - this->scrollV, x,
|
||||
this->scrollH, MIN(newRef.len - scrollH, this->w));
|
||||
mvaddchnstr(y+this->selected - this->scrollV, x+0, newRef.chstr + this->scrollH, MIN(newRef.len - scrollH, this->w));
|
||||
attrset(CRT_colors[RESET_COLOR]);
|
||||
}
|
||||
this->oldSelected = this->selected;
|
||||
move(0, 0);
|
||||
}
|
||||
|
||||
bool Panel_onKey(Panel* this, int key) {
|
||||
void Panel_onKey(Panel* this, int key) {
|
||||
assert (this != NULL);
|
||||
switch (key) {
|
||||
case KEY_DOWN:
|
||||
if (this->selected + 1 < Vector_size(this->items))
|
||||
this->selected++;
|
||||
return true;
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (this->selected > 0)
|
||||
this->selected--;
|
||||
return true;
|
||||
#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
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (this->scrollH > 0) {
|
||||
this->scrollH -= 5;
|
||||
this->scrollH -= this->scrollHAmount;
|
||||
this->needsRedraw = true;
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
this->scrollH += 5;
|
||||
this->scrollH += this->scrollHAmount;
|
||||
this->needsRedraw = true;
|
||||
return true;
|
||||
break;
|
||||
case KEY_PPAGE:
|
||||
this->selected -= (this->h - 1);
|
||||
this->scrollV -= (this->h - 1);
|
||||
this->selected -= this->h;
|
||||
if (this->selected < 0)
|
||||
this->selected = 0;
|
||||
if (this->scrollV < 0)
|
||||
this->scrollV = 0;
|
||||
this->needsRedraw = true;
|
||||
return true;
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
this->selected += (this->h - 1);
|
||||
this->selected += this->h;
|
||||
int size = Vector_size(this->items);
|
||||
if (this->selected >= size)
|
||||
this->selected = size - 1;
|
||||
this->scrollV += (this->h - 1);
|
||||
if (this->scrollV >= MAX(0, size - this->h))
|
||||
this->scrollV = MAX(0, size - this->h - 1);
|
||||
this->needsRedraw = true;
|
||||
return true;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
this->selected = 0;
|
||||
return true;
|
||||
break;
|
||||
case KEY_END:
|
||||
this->selected = Vector_size(this->items) - 1;
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
10
Panel.h
10
Panel.h
@ -33,8 +33,6 @@ typedef enum HandlerResult_ {
|
||||
BREAK_LOOP
|
||||
} HandlerResult;
|
||||
|
||||
#define EVENT_SETSELECTED -1
|
||||
|
||||
typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
@ -104,12 +102,12 @@ void Panel_moveSelectedDown(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_draw(Panel* this, bool focus);
|
||||
|
||||
bool Panel_onKey(Panel* this, int key);
|
||||
void Panel_onKey(Panel* this, int key);
|
||||
|
||||
#endif
|
||||
|
428
Process.c
428
Process.c
@ -11,7 +11,6 @@ in the source distribution for its full text.
|
||||
#include "CRT.h"
|
||||
#include "String.h"
|
||||
#include "Process.h"
|
||||
#include "RichString.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
@ -26,18 +25,10 @@ in the source distribution for its full text.
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <pwd.h>
|
||||
#include <sched.h>
|
||||
|
||||
#ifdef HAVE_PLPA
|
||||
#include <plpa.h>
|
||||
#endif
|
||||
|
||||
// This works only with glibc 2.1+. On earlier versions
|
||||
// the behavior is similar to have a hardcoded page size.
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
|
||||
#endif
|
||||
#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )
|
||||
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
|
||||
|
||||
#define PROCESS_COMM_LEN 300
|
||||
|
||||
@ -48,17 +39,7 @@ typedef enum ProcessField_ {
|
||||
STIME, CUTIME, CSTIME, PRIORITY, NICE, ITREALVALUE, STARTTIME, VSIZE, RSS, RLIM, STARTCODE, ENDCODE,
|
||||
STARTSTACK, KSTKESP, KSTKEIP, SIGNAL, BLOCKED, SSIGIGNORE, SIGCATCH, WCHAN, NSWAP, CNSWAP, EXIT_SIGNAL,
|
||||
PROCESSOR, M_SIZE, M_RESIDENT, M_SHARE, M_TRS, M_DRS, M_LRS, M_DT, ST_UID, PERCENT_CPU, PERCENT_MEM,
|
||||
USER, TIME, NLWP, TGID,
|
||||
#ifdef HAVE_OPENVZ
|
||||
CTID, VPID,
|
||||
#endif
|
||||
#ifdef HAVE_VSERVER
|
||||
VXID,
|
||||
#endif
|
||||
#ifdef HAVE_TASKSTATS
|
||||
RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
|
||||
#endif
|
||||
LAST_PROCESSFIELD
|
||||
USER, TIME, LAST_PROCESSFIELD
|
||||
} ProcessField;
|
||||
|
||||
struct ProcessList_;
|
||||
@ -69,16 +50,15 @@ typedef struct Process_ {
|
||||
struct ProcessList_ *pl;
|
||||
bool updated;
|
||||
|
||||
unsigned int pid;
|
||||
int pid;
|
||||
char* comm;
|
||||
int indent;
|
||||
char state;
|
||||
bool tag;
|
||||
unsigned int ppid;
|
||||
unsigned int pgrp;
|
||||
unsigned int session;
|
||||
unsigned int tty_nr;
|
||||
unsigned int tgid;
|
||||
int ppid;
|
||||
int pgrp;
|
||||
int session;
|
||||
int tty_nr;
|
||||
int tpgid;
|
||||
unsigned long int flags;
|
||||
#ifdef DEBUG
|
||||
@ -93,7 +73,6 @@ typedef struct Process_ {
|
||||
long int cstime;
|
||||
long int priority;
|
||||
long int nice;
|
||||
long int nlwp;
|
||||
#ifdef DEBUG
|
||||
long int itrealvalue;
|
||||
unsigned long int starttime;
|
||||
@ -126,26 +105,6 @@ typedef struct Process_ {
|
||||
float percent_cpu;
|
||||
float percent_mem;
|
||||
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;
|
||||
|
||||
}*/
|
||||
@ -157,74 +116,92 @@ char* PROCESS_CLASS = "Process";
|
||||
#endif
|
||||
|
||||
char *Process_fieldNames[] = {
|
||||
"", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION",
|
||||
"TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT",
|
||||
"UTIME", "STIME", "CUTIME", "CSTIME", "PRIORITY", "NICE", "ITREALVALUE",
|
||||
"STARTTIME", "VSIZE", "RSS", "RLIM", "STARTCODE", "ENDCODE", "STARTSTACK",
|
||||
"KSTKESP", "KSTKEIP", "SIGNAL", "BLOCKED", "SIGIGNORE", "SIGCATCH", "WCHAN",
|
||||
"NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE",
|
||||
"M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM",
|
||||
"USER", "TIME", "NLWP", "TGID",
|
||||
#ifdef HAVE_OPENVZ
|
||||
"CTID", "VPID",
|
||||
#endif
|
||||
#ifdef HAVE_VSERVER
|
||||
"VXID",
|
||||
#endif
|
||||
#ifdef HAVE_TASKSTATS
|
||||
"RCHAR", "WCHAR", "SYSCR", "SYSCW", "RBYTES", "WBYTES", "CNCLWB",
|
||||
"IO_READ_RATE", "IO_WRITE_RATE", "IO_RATE",
|
||||
#endif
|
||||
"*** 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
|
||||
"", "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! ***"
|
||||
};
|
||||
|
||||
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_M (ONE_K * 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];
|
||||
int len;
|
||||
if(number >= (10 * ONE_M)) {
|
||||
len = snprintf(buffer, 10, "%3.1fG ", (float)number / ONE_M);
|
||||
if(number >= (1000 * ONE_M)) {
|
||||
len = snprintf(buffer, 10, "%4.2fG ", (float)number / ONE_M);
|
||||
RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len);
|
||||
} 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
|
||||
? CRT_colors[PROCESS_MEGABYTES]
|
||||
: CRT_colors[PROCESS];
|
||||
RichString_appendn(str, attr, buffer, len);
|
||||
} 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);
|
||||
number %= 1000;
|
||||
len = snprintf(buffer, 10, "%03ld ", number);
|
||||
len = snprintf(buffer, 10, "%03d ", number);
|
||||
RichString_appendn(str, CRT_colors[PROCESS], buffer, len);
|
||||
} else {
|
||||
len = snprintf(buffer, 10, "%5ld ", number);
|
||||
len = snprintf(buffer, 10, "%5d ", number);
|
||||
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);
|
||||
}
|
||||
|
||||
static inline void Process_writeCommand(Process* this, int attr, int baseattr, RichString* str) {
|
||||
int start = str->len;
|
||||
RichString_append(str, attr, this->comm);
|
||||
static inline void Process_writeCommand(Process* this, int attr, RichString* str) {
|
||||
if (this->pl->highlightBaseName) {
|
||||
int finish = str->len - 1;
|
||||
int space = RichString_findChar(str, ' ', start);
|
||||
if (space != -1)
|
||||
finish = space - 1;
|
||||
for (;;) {
|
||||
int slash = RichString_findChar(str, '/', start);
|
||||
if (slash == -1 || slash > finish)
|
||||
break;
|
||||
start = slash + 1;
|
||||
char* firstSpace = strchr(this->comm, ' ');
|
||||
if (firstSpace) {
|
||||
char* slash = firstSpace;
|
||||
while (slash > this->comm && *slash != '/')
|
||||
slash--;
|
||||
if (slash > this->comm) {
|
||||
slash++;
|
||||
RichString_appendn(str, attr, this->comm, slash - this->comm);
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
void Process_writeField(Process* this, RichString* str, ProcessField field) {
|
||||
char buffer[PROCESS_COMM_LEN];
|
||||
int attr = CRT_colors[DEFAULT_COLOR];
|
||||
int baseattr = CRT_colors[PROCESS_BASENAME];
|
||||
int n = PROCESS_COMM_LEN;
|
||||
|
||||
switch (field) {
|
||||
case PID: snprintf(buffer, n, "%5u ", this->pid); break;
|
||||
case PPID: snprintf(buffer, n, "%5u ", this->ppid); break;
|
||||
case PGRP: snprintf(buffer, n, "%5u ", this->pgrp); break;
|
||||
case SESSION: snprintf(buffer, n, "%5u ", this->session); break;
|
||||
case TTY_NR: snprintf(buffer, n, "%5u ", this->tty_nr); break;
|
||||
case TGID: snprintf(buffer, n, "%5u ", this->tgid); break;
|
||||
case PID: snprintf(buffer, n, "%5d ", this->pid); break;
|
||||
case PPID: snprintf(buffer, n, "%5d ", this->ppid); break;
|
||||
case PGRP: snprintf(buffer, n, "%5d ", this->pgrp); break;
|
||||
case SESSION: snprintf(buffer, n, "%5d ", this->session); break;
|
||||
case TTY_NR: snprintf(buffer, n, "%5d ", this->tty_nr); break;
|
||||
case TPGID: snprintf(buffer, n, "%5d ", this->tpgid); break;
|
||||
case PROCESSOR: snprintf(buffer, n, "%3d ", this->processor+1); break;
|
||||
case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
|
||||
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) {
|
||||
Process_writeCommand(this, attr, baseattr, str);
|
||||
Process_writeCommand(this, attr, str);
|
||||
return;
|
||||
} else {
|
||||
char* buf = buffer;
|
||||
@ -329,7 +287,7 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
|
||||
else
|
||||
snprintf(buf, n, " ,- ");
|
||||
RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
|
||||
Process_writeCommand(this, attr, baseattr, str);
|
||||
Process_writeCommand(this, attr, str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -354,13 +312,9 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
|
||||
: attr;
|
||||
break;
|
||||
}
|
||||
case M_DRS: Process_printLargeNumber(this, str, this->m_drs * PAGE_SIZE_KB); return;
|
||||
case M_DT: Process_printLargeNumber(this, str, this->m_dt * PAGE_SIZE_KB); return;
|
||||
case M_LRS: Process_printLargeNumber(this, str, this->m_lrs * PAGE_SIZE_KB); 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 M_SIZE: Process_printLargeNumber(this, str, this->m_size * PAGE_SIZE); return;
|
||||
case M_RESIDENT: Process_printLargeNumber(this, str, this->m_resident * PAGE_SIZE); return;
|
||||
case M_SHARE: Process_printLargeNumber(this, str, this->m_share * PAGE_SIZE); return;
|
||||
case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break;
|
||||
case USER: {
|
||||
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 TIME: Process_printTime(str, this->utime + this->stime); return;
|
||||
case PERCENT_CPU: {
|
||||
if (this->percent_cpu > 999.9) {
|
||||
snprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu);
|
||||
} else if (this->percent_cpu > 99.9) {
|
||||
snprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu);
|
||||
if (this->percent_cpu > 99.9) {
|
||||
snprintf(buffer, n, "100. ");
|
||||
} else {
|
||||
snprintf(buffer, n, "%4.1f ", this->percent_cpu);
|
||||
}
|
||||
@ -399,117 +351,11 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
|
||||
}
|
||||
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:
|
||||
snprintf(buffer, n, "- ");
|
||||
}
|
||||
RichString_append(str, attr, buffer);
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
p1 = (Process*)v2;
|
||||
}
|
||||
long long diff;
|
||||
switch (pl->sortKey) {
|
||||
case PID:
|
||||
return (p1->pid - p2->pid);
|
||||
case PPID:
|
||||
return (p1->ppid - p2->ppid);
|
||||
case USER:
|
||||
return strcmp(p1->user ? p1->user : "", p2->user ? p2->user : "");
|
||||
return strcmp(p1->user, p2->user);
|
||||
case PRIORITY:
|
||||
return (p1->priority - p2->priority);
|
||||
case PROCESSOR:
|
||||
return (p1->processor - p2->processor);
|
||||
case SESSION:
|
||||
return (p1->session - p2->session);
|
||||
case STATE:
|
||||
return (p1->state - p2->state);
|
||||
case NICE:
|
||||
return (p1->nice - p2->nice);
|
||||
case M_DRS:
|
||||
return (p2->m_drs - p1->m_drs);
|
||||
case M_DT:
|
||||
return (p2->m_dt - p1->m_dt);
|
||||
case M_LRS:
|
||||
return (p2->m_lrs - p1->m_lrs);
|
||||
case M_TRS:
|
||||
return (p2->m_trs - p1->m_trs);
|
||||
case M_SIZE:
|
||||
return (p2->m_size - p1->m_size);
|
||||
case M_RESIDENT:
|
||||
@ -572,34 +405,35 @@ int Process_compare(const void* v1, const void* v2) {
|
||||
return ((p2->utime+p2->stime) - (p1->utime+p1->stime));
|
||||
case 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:
|
||||
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 "- ";
|
||||
}
|
||||
}
|
||||
|
89
Process.h
89
Process.h
@ -14,7 +14,6 @@ in the source distribution for its full text.
|
||||
#include "Object.h"
|
||||
#include "CRT.h"
|
||||
#include "String.h"
|
||||
#include "RichString.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
@ -29,18 +28,10 @@ in the source distribution for its full text.
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <pwd.h>
|
||||
#include <sched.h>
|
||||
|
||||
#ifdef HAVE_PLPA
|
||||
#include <plpa.h>
|
||||
#endif
|
||||
|
||||
// This works only with glibc 2.1+. On earlier versions
|
||||
// the behavior is similar to have a hardcoded page size.
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
|
||||
#endif
|
||||
#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )
|
||||
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
|
||||
|
||||
#define PROCESS_COMM_LEN 300
|
||||
|
||||
@ -50,17 +41,7 @@ typedef enum ProcessField_ {
|
||||
STIME, CUTIME, CSTIME, PRIORITY, NICE, ITREALVALUE, STARTTIME, VSIZE, RSS, RLIM, STARTCODE, ENDCODE,
|
||||
STARTSTACK, KSTKESP, KSTKEIP, SIGNAL, BLOCKED, SSIGIGNORE, SIGCATCH, WCHAN, NSWAP, CNSWAP, EXIT_SIGNAL,
|
||||
PROCESSOR, M_SIZE, M_RESIDENT, M_SHARE, M_TRS, M_DRS, M_LRS, M_DT, ST_UID, PERCENT_CPU, PERCENT_MEM,
|
||||
USER, TIME, NLWP, TGID,
|
||||
#ifdef HAVE_OPENVZ
|
||||
CTID, VPID,
|
||||
#endif
|
||||
#ifdef HAVE_VSERVER
|
||||
VXID,
|
||||
#endif
|
||||
#ifdef HAVE_TASKSTATS
|
||||
RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
|
||||
#endif
|
||||
LAST_PROCESSFIELD
|
||||
USER, TIME, LAST_PROCESSFIELD
|
||||
} ProcessField;
|
||||
|
||||
struct ProcessList_;
|
||||
@ -71,16 +52,15 @@ typedef struct Process_ {
|
||||
struct ProcessList_ *pl;
|
||||
bool updated;
|
||||
|
||||
unsigned int pid;
|
||||
int pid;
|
||||
char* comm;
|
||||
int indent;
|
||||
char state;
|
||||
bool tag;
|
||||
unsigned int ppid;
|
||||
unsigned int pgrp;
|
||||
unsigned int session;
|
||||
unsigned int tty_nr;
|
||||
unsigned int tgid;
|
||||
int ppid;
|
||||
int pgrp;
|
||||
int session;
|
||||
int tty_nr;
|
||||
int tpgid;
|
||||
unsigned long int flags;
|
||||
#ifdef DEBUG
|
||||
@ -95,7 +75,6 @@ typedef struct Process_ {
|
||||
long int cstime;
|
||||
long int priority;
|
||||
long int nice;
|
||||
long int nlwp;
|
||||
#ifdef DEBUG
|
||||
long int itrealvalue;
|
||||
unsigned long int starttime;
|
||||
@ -128,26 +107,6 @@ typedef struct Process_ {
|
||||
float percent_cpu;
|
||||
float percent_mem;
|
||||
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;
|
||||
|
||||
|
||||
@ -159,32 +118,30 @@ extern char* PROCESS_CLASS;
|
||||
|
||||
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_M (ONE_K * ONE_K)
|
||||
#define ONE_G (ONE_M * ONE_K)
|
||||
|
||||
void Process_delete(Object* cast);
|
||||
|
||||
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);
|
||||
void Process_writeField(Process* this, RichString* str, ProcessField field);
|
||||
|
||||
int Process_pidCompare(const void* v1, const void* v2);
|
||||
|
||||
int Process_compare(const void* v1, const void* v2);
|
||||
|
||||
char* Process_printField(ProcessField field);
|
||||
|
||||
#endif
|
||||
|
341
ProcessList.c
341
ProcessList.c
@ -37,11 +37,11 @@ in the source distribution for its full text.
|
||||
#endif
|
||||
|
||||
#ifndef PROCSTATFILE
|
||||
#define PROCSTATFILE PROCDIR "/stat"
|
||||
#define PROCSTATFILE "/proc/stat"
|
||||
#endif
|
||||
|
||||
#ifndef PROCMEMINFOFILE
|
||||
#define PROCMEMINFOFILE PROCDIR "/meminfo"
|
||||
#define PROCMEMINFOFILE "/proc/meminfo"
|
||||
#endif
|
||||
|
||||
#ifndef MAX_NAME
|
||||
@ -53,14 +53,14 @@ in the source distribution for its full text.
|
||||
#endif
|
||||
|
||||
#ifndef PER_PROCESSOR_FIELDS
|
||||
#define PER_PROCESSOR_FIELDS 22
|
||||
#define PER_PROCESSOR_FIELDS 20
|
||||
#endif
|
||||
|
||||
}*/
|
||||
|
||||
/*{
|
||||
|
||||
#ifdef DEBUG_PROC
|
||||
#ifdef DEBUG
|
||||
typedef int(*vxscanf)(void*, const char*, va_list);
|
||||
#endif
|
||||
|
||||
@ -80,7 +80,6 @@ typedef struct ProcessList_ {
|
||||
unsigned long long int* userTime;
|
||||
unsigned long long int* systemTime;
|
||||
unsigned long long int* systemAllTime;
|
||||
unsigned long long int* idleAllTime;
|
||||
unsigned long long int* idleTime;
|
||||
unsigned long long int* niceTime;
|
||||
unsigned long long int* ioWaitTime;
|
||||
@ -91,7 +90,6 @@ typedef struct ProcessList_ {
|
||||
unsigned long long int* userPeriod;
|
||||
unsigned long long int* systemPeriod;
|
||||
unsigned long long int* systemAllPeriod;
|
||||
unsigned long long int* idleAllPeriod;
|
||||
unsigned long long int* idlePeriod;
|
||||
unsigned long long int* nicePeriod;
|
||||
unsigned long long int* ioWaitPeriod;
|
||||
@ -119,9 +117,8 @@ typedef struct ProcessList_ {
|
||||
bool treeView;
|
||||
bool highlightBaseName;
|
||||
bool highlightMegabytes;
|
||||
bool highlightThreads;
|
||||
bool detailedCPUTime;
|
||||
#ifdef DEBUG_PROC
|
||||
bool expandSystemTime;
|
||||
#ifdef DEBUG
|
||||
FILE* traceFile;
|
||||
#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 };
|
||||
|
||||
#ifdef DEBUG_PROC
|
||||
#ifdef DEBUG
|
||||
|
||||
#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__ )
|
||||
@ -207,14 +204,13 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
|
||||
this = malloc(sizeof(ProcessList));
|
||||
this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
|
||||
this->processTable = Hashtable_new(70, false);
|
||||
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
|
||||
this->prototype = Process_new(this);
|
||||
this->usersTable = usersTable;
|
||||
|
||||
/* tree-view auxiliary buffers */
|
||||
this->processes2 = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
|
||||
|
||||
#ifdef DEBUG_PROC
|
||||
#ifdef DEBUG
|
||||
this->traceFile = fopen("/tmp/htop-proc-trace", "w");
|
||||
#endif
|
||||
|
||||
@ -251,7 +247,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
|
||||
this->treeView = false;
|
||||
this->highlightBaseName = false;
|
||||
this->highlightMegabytes = false;
|
||||
this->detailedCPUTime = false;
|
||||
this->expandSystemTime = false;
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -266,7 +262,7 @@ void ProcessList_delete(ProcessList* this) {
|
||||
// other fields are offsets of the same buffer
|
||||
free(this->totalTime);
|
||||
|
||||
#ifdef DEBUG_PROC
|
||||
#ifdef DEBUG
|
||||
fclose(this->traceFile);
|
||||
#endif
|
||||
|
||||
@ -283,10 +279,10 @@ void ProcessList_invertSortOrder(ProcessList* this) {
|
||||
|
||||
RichString ProcessList_printHeader(ProcessList* this) {
|
||||
RichString out;
|
||||
RichString_initVal(out);
|
||||
RichString_init(&out);
|
||||
ProcessField* fields = this->fields;
|
||||
for (int i = 0; fields[i]; i++) {
|
||||
char* field = Process_fieldTitles[fields[i]];
|
||||
char* field = Process_printField(fields[i]);
|
||||
if (this->sortKey == fields[i])
|
||||
RichString_append(&out, CRT_colors[PANEL_HIGHLIGHT_FOCUS], field);
|
||||
else
|
||||
@ -295,27 +291,20 @@ RichString ProcessList_printHeader(ProcessList* this) {
|
||||
return out;
|
||||
}
|
||||
|
||||
static void ProcessList_add(ProcessList* this, Process* p) {
|
||||
assert(Vector_indexOf(this->processes, p, Process_pidCompare) == -1);
|
||||
assert(Hashtable_get(this->processTable, p->pid) == NULL);
|
||||
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));
|
||||
|
||||
void ProcessList_prune(ProcessList* this) {
|
||||
Vector_prune(this->processes);
|
||||
}
|
||||
|
||||
static void ProcessList_remove(ProcessList* this, Process* p) {
|
||||
assert(Vector_indexOf(this->processes, p, Process_pidCompare) != -1);
|
||||
assert(Hashtable_get(this->processTable, p->pid) != NULL);
|
||||
Process* pp = Hashtable_remove(this->processTable, p->pid);
|
||||
assert(pp == p); (void)pp;
|
||||
unsigned int pid = p->pid;
|
||||
void ProcessList_add(ProcessList* this, Process* p) {
|
||||
Vector_add(this->processes, p);
|
||||
Hashtable_put(this->processTable, p->pid, p);
|
||||
}
|
||||
|
||||
void ProcessList_remove(ProcessList* this, Process* p) {
|
||||
Hashtable_remove(this->processTable, p->pid);
|
||||
int index = Vector_indexOf(this->processes, p, Process_pidCompare);
|
||||
assert(index != -1);
|
||||
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) {
|
||||
@ -329,22 +318,21 @@ int ProcessList_size(ProcessList* this) {
|
||||
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);
|
||||
|
||||
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));
|
||||
if (process->tgid == pid || (process->tgid == process->pid && process->ppid == pid)) {
|
||||
if (process->ppid == pid) {
|
||||
Process* process = (Process*) (Vector_take(this->processes, i));
|
||||
Vector_add(children, process);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
int size = Vector_size(children);
|
||||
for (int i = 0; i < size; i++) {
|
||||
Process* process = (Process*) (Vector_get(children, i));
|
||||
int s = this->processes2->items;
|
||||
if (direction == 1)
|
||||
Vector_add(this->processes2, process);
|
||||
else
|
||||
Vector_insert(this->processes2, 0, process);
|
||||
assert(this->processes2->items == s+1); (void)s;
|
||||
int nextIndent = indent;
|
||||
if (i < size - 1)
|
||||
nextIndent = indent | (1 << level);
|
||||
@ -358,36 +346,18 @@ void ProcessList_sort(ProcessList* this) {
|
||||
if (!this->treeView) {
|
||||
Vector_sort(this->processes);
|
||||
} else {
|
||||
// Save settings
|
||||
int direction = this->direction;
|
||||
int sortKey = this->sortKey;
|
||||
// Sort by PID
|
||||
this->sortKey = PID;
|
||||
this->direction = 1;
|
||||
Vector_sort(this->processes);
|
||||
// Restore settings
|
||||
this->sortKey = sortKey;
|
||||
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));
|
||||
// This assertion crashes on hardened kernels.
|
||||
// I wonder how well tree view works on those systems.
|
||||
// assert(init->pid == 1);
|
||||
assert(init->pid == 1);
|
||||
init->indent = 0;
|
||||
Vector_add(this->processes2, init);
|
||||
// Recursively empty list
|
||||
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;
|
||||
this->processes = this->processes2;
|
||||
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);
|
||||
if(!size) return 0;
|
||||
|
||||
assert(proc->pid == atoi(buf));
|
||||
proc->pid = atoi(buf);
|
||||
char *location = strchr(buf, ' ');
|
||||
if(!location) return 0;
|
||||
|
||||
@ -414,9 +384,9 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
|
||||
command[commsize] = '\0';
|
||||
location = end + 2;
|
||||
|
||||
#ifdef DEBUG_PROC
|
||||
#ifdef DEBUG
|
||||
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 %ld %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->minflt, &proc->cminflt, &proc->majflt, &proc->cmajflt,
|
||||
&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->startcode, &proc->endcode, &proc->startstack, &proc->kstkesp,
|
||||
&proc->kstkeip, &proc->signal, &proc->blocked, &proc->sigignore,
|
||||
@ -434,7 +404,7 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
|
||||
#else
|
||||
long int uzero;
|
||||
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 %ld %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,
|
||||
&zero, &zero, &zero, &zero,
|
||||
&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, &zero, &zero,
|
||||
&zero, &zero, &zero, &zero,
|
||||
@ -459,72 +429,55 @@ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, c
|
||||
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];
|
||||
statusfilename[MAX_NAME] = '\0';
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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);
|
||||
/*
|
||||
bool success = false;
|
||||
char buffer[256];
|
||||
buffer[255] = '\0';
|
||||
snprintf(statusfilename, MAX_NAME, "%s/%s/status", dirname, name);
|
||||
FILE* status = ProcessList_fopen(this, statusfilename, "r");
|
||||
if (status) {
|
||||
while (!feof(status)) {
|
||||
char* ok = fgets(buffer, 255, status);
|
||||
if (!ok)
|
||||
break;
|
||||
if (ProcessList_read(this, buffer, "rchar: %llu", &proc->io_rchar)) continue;
|
||||
if (ProcessList_read(this, buffer, "wchar: %llu", &proc->io_wchar)) continue;
|
||||
if (ProcessList_read(this, buffer, "syscr: %llu", &proc->io_syscr)) continue;
|
||||
if (ProcessList_read(this, buffer, "syscw: %llu", &proc->io_syscw)) continue;
|
||||
if (ProcessList_read(this, buffer, "read_bytes: %llu", &proc->io_read_bytes)) {
|
||||
proc->io_rate_read_bps =
|
||||
((double)(proc->io_read_bytes - last_read))/(((double)(now - proc->io_rate_read_time))/1000);
|
||||
proc->io_rate_read_time = now;
|
||||
continue;
|
||||
if (String_startsWith(buffer, "Uid:")) {
|
||||
int uid1, uid2, uid3, uid4;
|
||||
// TODO: handle other uid's.
|
||||
int ok = ProcessList_read(this, buffer, "Uid:\t%d\t%d\t%d\t%d", &uid1, &uid2, &uid3, &uid4);
|
||||
if (ok >= 1) {
|
||||
proc->st_uid = uid1;
|
||||
success = true;
|
||||
}
|
||||
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
|
||||
|
||||
static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process* parent, float period) {
|
||||
void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period) {
|
||||
DIR* dir;
|
||||
struct dirent* entry;
|
||||
Process* prototype = this->prototype;
|
||||
|
||||
dir = opendir(dirname);
|
||||
if (!dir) return false;
|
||||
int processors = this->processorCount;
|
||||
bool showUserlandThreads = !this->hideUserlandThreads;
|
||||
assert(dir != NULL);
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
char* name = entry->d_name;
|
||||
int pid;
|
||||
@ -541,47 +494,33 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
|
||||
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;
|
||||
char statusfilename[MAX_NAME+1];
|
||||
char command[PROCESS_COMM_LEN + 1];
|
||||
|
||||
Process* process = NULL;
|
||||
Process* process;
|
||||
|
||||
Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid);
|
||||
|
||||
if (existingProcess) {
|
||||
assert(Vector_indexOf(this->processes, existingProcess, Process_pidCompare) != -1);
|
||||
process = existingProcess;
|
||||
assert(process->pid == pid);
|
||||
} else {
|
||||
if (parent && parent->pid == pid) {
|
||||
process = parent;
|
||||
} else {
|
||||
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)
|
||||
process = prototype;
|
||||
process->comm = NULL;
|
||||
process->pid = pid;
|
||||
if (! ProcessList_readStatusFile(this, process, dirname, name))
|
||||
goto errorReadingProcess;
|
||||
}
|
||||
process->updated = true;
|
||||
|
||||
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
|
||||
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",
|
||||
&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);
|
||||
|
||||
fclose(status);
|
||||
@ -606,73 +545,16 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
|
||||
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
|
||||
|
||||
status = ProcessList_fopen(this, statusfilename, "r");
|
||||
if (status == NULL)
|
||||
if (status == NULL)
|
||||
goto errorReadingProcess;
|
||||
|
||||
int success = ProcessList_readStatFile(this, process, status, command);
|
||||
fclose(status);
|
||||
if(!success) {
|
||||
if(!success)
|
||||
goto errorReadingProcess;
|
||||
}
|
||||
|
||||
if(!existingProcess) {
|
||||
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);
|
||||
status = ProcessList_fopen(this, statusfilename, "r");
|
||||
@ -692,12 +574,11 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
|
||||
fclose(status);
|
||||
}
|
||||
|
||||
int percent_cpu = (process->utime + process->stime - lasttimes) /
|
||||
process->percent_cpu = (process->utime + process->stime - lasttimes) /
|
||||
period * 100.0;
|
||||
process->percent_cpu = MAX(MIN(percent_cpu, processors*100.0), 0.0);
|
||||
|
||||
process->percent_mem = (process->m_resident * PAGE_SIZE_KB) /
|
||||
(float)(this->totalMem) *
|
||||
process->percent_mem = process->m_resident /
|
||||
(float)(this->usedMem - this->cachedMem - this->buffersMem) *
|
||||
100.0;
|
||||
|
||||
this->totalTasks++;
|
||||
@ -714,29 +595,27 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
|
||||
|
||||
// Exception handler.
|
||||
errorReadingProcess: {
|
||||
if (process->comm) {
|
||||
free(process->comm);
|
||||
process->comm = NULL;
|
||||
}
|
||||
if (existingProcess)
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
FILE* status;
|
||||
char buffer[128];
|
||||
status = ProcessList_fopen(this, PROCMEMINFOFILE, "r");
|
||||
assert(status != NULL);
|
||||
int processors = this->processorCount;
|
||||
while (!feof(status)) {
|
||||
fgets(buffer, 128, status);
|
||||
|
||||
@ -773,7 +652,7 @@ void ProcessList_scan(ProcessList* this) {
|
||||
status = ProcessList_fopen(this, PROCSTATFILE, "r");
|
||||
|
||||
assert(status != NULL);
|
||||
for (int i = 0; i <= processors; i++) {
|
||||
for (int i = 0; i <= this->processorCount; i++) {
|
||||
char buffer[256];
|
||||
int cpuid;
|
||||
unsigned long long int ioWait, irq, softIrq, steal;
|
||||
@ -790,16 +669,14 @@ void ProcessList_scan(ProcessList* this) {
|
||||
}
|
||||
// Fields existing on kernels >= 2.6
|
||||
// (and RHEL's patched kernel 2.4...)
|
||||
idlealltime = idletime + ioWait;
|
||||
systemalltime = systemtime + irq + softIrq + steal;
|
||||
totaltime = usertime + nicetime + systemalltime + idlealltime;
|
||||
systemalltime = systemtime + ioWait + irq + softIrq + steal;
|
||||
totaltime = usertime + nicetime + systemalltime + idletime;
|
||||
assert (usertime >= this->userTime[i]);
|
||||
assert (nicetime >= this->niceTime[i]);
|
||||
assert (systemtime >= this->systemTime[i]);
|
||||
assert (idletime >= this->idleTime[i]);
|
||||
assert (totaltime >= this->totalTime[i]);
|
||||
assert (systemalltime >= this->systemAllTime[i]);
|
||||
assert (idlealltime >= this->idleAllTime[i]);
|
||||
assert (ioWait >= this->ioWaitTime[i]);
|
||||
assert (irq >= this->irqTime[i]);
|
||||
assert (softIrq >= this->softIrqTime[i]);
|
||||
@ -808,7 +685,6 @@ void ProcessList_scan(ProcessList* this) {
|
||||
this->nicePeriod[i] = nicetime - this->niceTime[i];
|
||||
this->systemPeriod[i] = systemtime - this->systemTime[i];
|
||||
this->systemAllPeriod[i] = systemalltime - this->systemAllTime[i];
|
||||
this->idleAllPeriod[i] = idlealltime - this->idleAllTime[i];
|
||||
this->idlePeriod[i] = idletime - this->idleTime[i];
|
||||
this->ioWaitPeriod[i] = ioWait - this->ioWaitTime[i];
|
||||
this->irqPeriod[i] = irq - this->irqTime[i];
|
||||
@ -819,7 +695,6 @@ void ProcessList_scan(ProcessList* this) {
|
||||
this->niceTime[i] = nicetime;
|
||||
this->systemTime[i] = systemtime;
|
||||
this->systemAllTime[i] = systemalltime;
|
||||
this->idleAllTime[i] = idlealltime;
|
||||
this->idleTime[i] = idletime;
|
||||
this->ioWaitTime[i] = ioWait;
|
||||
this->irqTime[i] = irq;
|
||||
@ -827,7 +702,7 @@ void ProcessList_scan(ProcessList* this) {
|
||||
this->stealTime[i] = steal;
|
||||
this->totalTime[i] = totaltime;
|
||||
}
|
||||
float period = (float)this->totalPeriod[0] / processors;
|
||||
float period = (float)this->totalPeriod[0] / this->processorCount;
|
||||
fclose(status);
|
||||
|
||||
// mark all process as "dirty"
|
||||
@ -838,8 +713,8 @@ void ProcessList_scan(ProcessList* this) {
|
||||
|
||||
this->totalTasks = 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--) {
|
||||
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;
|
||||
}
|
||||
|
@ -39,11 +39,11 @@ in the source distribution for its full text.
|
||||
#endif
|
||||
|
||||
#ifndef PROCSTATFILE
|
||||
#define PROCSTATFILE PROCDIR "/stat"
|
||||
#define PROCSTATFILE "/proc/stat"
|
||||
#endif
|
||||
|
||||
#ifndef PROCMEMINFOFILE
|
||||
#define PROCMEMINFOFILE PROCDIR "/meminfo"
|
||||
#define PROCMEMINFOFILE "/proc/meminfo"
|
||||
#endif
|
||||
|
||||
#ifndef MAX_NAME
|
||||
@ -55,12 +55,12 @@ in the source distribution for its full text.
|
||||
#endif
|
||||
|
||||
#ifndef PER_PROCESSOR_FIELDS
|
||||
#define PER_PROCESSOR_FIELDS 22
|
||||
#define PER_PROCESSOR_FIELDS 20
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_PROC
|
||||
#ifdef DEBUG
|
||||
typedef int(*vxscanf)(void*, const char*, va_list);
|
||||
#endif
|
||||
|
||||
@ -80,7 +80,6 @@ typedef struct ProcessList_ {
|
||||
unsigned long long int* userTime;
|
||||
unsigned long long int* systemTime;
|
||||
unsigned long long int* systemAllTime;
|
||||
unsigned long long int* idleAllTime;
|
||||
unsigned long long int* idleTime;
|
||||
unsigned long long int* niceTime;
|
||||
unsigned long long int* ioWaitTime;
|
||||
@ -91,7 +90,6 @@ typedef struct ProcessList_ {
|
||||
unsigned long long int* userPeriod;
|
||||
unsigned long long int* systemPeriod;
|
||||
unsigned long long int* systemAllPeriod;
|
||||
unsigned long long int* idleAllPeriod;
|
||||
unsigned long long int* idlePeriod;
|
||||
unsigned long long int* nicePeriod;
|
||||
unsigned long long int* ioWaitPeriod;
|
||||
@ -119,15 +117,14 @@ typedef struct ProcessList_ {
|
||||
bool treeView;
|
||||
bool highlightBaseName;
|
||||
bool highlightMegabytes;
|
||||
bool highlightThreads;
|
||||
bool detailedCPUTime;
|
||||
#ifdef DEBUG_PROC
|
||||
bool expandSystemTime;
|
||||
#ifdef DEBUG
|
||||
FILE* traceFile;
|
||||
#endif
|
||||
|
||||
} ProcessList;
|
||||
|
||||
#ifdef DEBUG_PROC
|
||||
#ifdef DEBUG
|
||||
|
||||
#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__ )
|
||||
@ -150,18 +147,23 @@ void ProcessList_invertSortOrder(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);
|
||||
|
||||
int ProcessList_size(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);
|
||||
|
||||
ProcessField ProcessList_keyAt(ProcessList* this, int at);
|
||||
|
||||
#endif
|
||||
|
2
README
2
README
@ -2,7 +2,7 @@
|
||||
htop
|
||||
by Hisham Muhammad <loderunner@users.sourceforge.net>
|
||||
|
||||
May, 2004 - June, 2009
|
||||
May, 2004 - July, 2006
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
|
127
RichString.c
127
RichString.c
@ -1,22 +1,12 @@
|
||||
|
||||
#include "RichString.h"
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <curses.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_LIBNCURSESW
|
||||
#include <curses.h>
|
||||
#else
|
||||
#include <ncursesw/curses.h>
|
||||
#endif
|
||||
|
||||
#define RICHSTRING_MAXLEN 300
|
||||
|
||||
@ -25,23 +15,9 @@
|
||||
#define RichString_init(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_ {
|
||||
int len;
|
||||
#ifdef HAVE_LIBNCURSESW
|
||||
cchar_t chstr[RICHSTRING_MAXLEN+1];
|
||||
#else
|
||||
chtype chstr[RICHSTRING_MAXLEN+1];
|
||||
#endif
|
||||
} RichString;
|
||||
|
||||
}*/
|
||||
@ -50,88 +26,37 @@ typedef struct RichString_ {
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBNCURSESW
|
||||
|
||||
inline void RichString_appendn(RichString* this, int attrs, char* data_c, int len) {
|
||||
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);
|
||||
void RichString_write(RichString* this, int attrs, char* data) {
|
||||
RichString_init(this);
|
||||
RichString_append(this, attrs, data);
|
||||
}
|
||||
|
||||
inline void RichString_append(RichString* this, int attrs, char* data) {
|
||||
RichString_appendn(this, attrs, data, strlen(data));
|
||||
}
|
||||
|
||||
void RichString_write(RichString* this, int attrs, char* data) {
|
||||
RichString_init(this);
|
||||
RichString_append(this, attrs, data);
|
||||
inline void RichString_appendn(RichString* this, int attrs, char* data, 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] = 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) {
|
||||
|
50
RichString.h
50
RichString.h
@ -4,22 +4,12 @@
|
||||
#define HEADER_RichString
|
||||
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <curses.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_LIBNCURSESW
|
||||
#include <curses.h>
|
||||
#else
|
||||
#include <ncursesw/curses.h>
|
||||
#endif
|
||||
|
||||
#define RICHSTRING_MAXLEN 300
|
||||
|
||||
@ -27,23 +17,9 @@
|
||||
#define RichString_init(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_ {
|
||||
int len;
|
||||
#ifdef HAVE_LIBNCURSESW
|
||||
cchar_t chstr[RICHSTRING_MAXLEN+1];
|
||||
#else
|
||||
chtype chstr[RICHSTRING_MAXLEN+1];
|
||||
#endif
|
||||
} RichString;
|
||||
|
||||
|
||||
@ -51,31 +27,15 @@ typedef struct RichString_ {
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#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);
|
||||
|
||||
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);
|
||||
inline void RichString_appendn(RichString* this, int attrs, char* data, int len);
|
||||
|
||||
void RichString_setAttr(RichString *this, int attrs);
|
||||
|
||||
extern void RichString_append(RichString* this, int attrs, char* data);
|
||||
|
||||
void RichString_write(RichString* this, int attrs, char* data);
|
||||
void RichString_applyAttr(RichString *this, int attrs);
|
||||
|
||||
RichString RichString_quickString(int attrs, char* data);
|
||||
|
||||
|
@ -83,7 +83,7 @@ void ScreenManager_add(ScreenManager* this, Panel* item, FunctionBar* fuBar, int
|
||||
if (fuBar)
|
||||
Vector_add(this->fuBars, fuBar);
|
||||
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;
|
||||
item->needsRedraw = true;
|
||||
this->itemCount++;
|
||||
@ -98,6 +98,12 @@ Panel* ScreenManager_remove(ScreenManager* this, int index) {
|
||||
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) {
|
||||
this->x1 = x1;
|
||||
this->y1 = y1;
|
||||
@ -144,6 +150,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||
|
||||
ch = getch();
|
||||
|
||||
bool loop = false;
|
||||
if (ch == KEY_MOUSE) {
|
||||
MEVENT mevent;
|
||||
int ok = getmouse(&mevent);
|
||||
@ -158,12 +165,14 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||
focus = i;
|
||||
panelFocus = panel;
|
||||
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
|
||||
loop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (loop) continue;
|
||||
|
||||
if (panelFocus->eventHandler) {
|
||||
HandlerResult result = panelFocus->eventHandler(panelFocus, ch);
|
||||
@ -188,7 +197,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||
if (focus > 0)
|
||||
focus--;
|
||||
panelFocus = (Panel*) Vector_get(this->items, focus);
|
||||
if (Panel_size(panelFocus) == 0 && focus > 0)
|
||||
if (Panel_getSize(panelFocus) == 0 && focus > 0)
|
||||
goto tryLeft;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
@ -197,7 +206,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||
if (focus < this->itemCount - 1)
|
||||
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;
|
||||
break;
|
||||
case KEY_F(10):
|
||||
|
@ -43,12 +43,14 @@ ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation ori
|
||||
|
||||
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);
|
||||
|
||||
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_run(ScreenManager* this, Panel** lastFocus, int* lastKey);
|
||||
|
82
Settings.c
82
Settings.c
@ -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) {
|
||||
free(this->userSettings);
|
||||
free(this);
|
||||
@ -55,7 +88,7 @@ static void Settings_readMeterModes(Settings* this, char* line, HeaderSide side)
|
||||
String_freeArray(ids);
|
||||
}
|
||||
|
||||
static bool Settings_read(Settings* this, char* fileName) {
|
||||
bool Settings_read(Settings* this, char* fileName) {
|
||||
// TODO: implement File object and make
|
||||
// file I/O object-oriented.
|
||||
FILE* fd;
|
||||
@ -63,7 +96,7 @@ static bool Settings_read(Settings* this, char* fileName) {
|
||||
if (fd == NULL) {
|
||||
return false;
|
||||
}
|
||||
const int maxLine = 65535;
|
||||
const int maxLine = 512;
|
||||
char buffer[maxLine];
|
||||
bool readMeters = false;
|
||||
while (!feof(fd)) {
|
||||
@ -104,15 +137,10 @@ static bool Settings_read(Settings* this, char* fileName) {
|
||||
this->pl->highlightBaseName = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "highlight_megabytes")) {
|
||||
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")) {
|
||||
this->header->margin = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "expand_system_time")) {
|
||||
// Compatibility option.
|
||||
this->pl->detailedCPUTime = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "detailed_cpu_time")) {
|
||||
this->pl->detailedCPUTime = atoi(option[1]);
|
||||
this->pl->expandSystemTime = atoi(option[1]);
|
||||
} else if (String_eq(option[0], "delay")) {
|
||||
this->delay = atoi(option[1]);
|
||||
} 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, "highlight_base_name=%d\n", (int) this->pl->highlightBaseName);
|
||||
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, "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, "delay=%d\n", (int) this->delay);
|
||||
fprintf(fd, "left_meters=");
|
||||
@ -194,41 +221,6 @@ bool Settings_write(Settings* this) {
|
||||
fprintf(fd, "right_meter_modes=");
|
||||
for (int i = 0; i < Header_size(this->header, RIGHT_HEADER); i++)
|
||||
fprintf(fd, "%d ", Header_readMeterMode(this->header, i, RIGHT_HEADER));
|
||||
fprintf(fd, "\n");
|
||||
fclose(fd);
|
||||
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;
|
||||
}
|
||||
|
@ -28,10 +28,12 @@ typedef struct Settings_ {
|
||||
} Settings;
|
||||
|
||||
|
||||
Settings* Settings_new(ProcessList* pl, Header* header);
|
||||
|
||||
void Settings_delete(Settings* this);
|
||||
|
||||
bool Settings_read(Settings* this, char* fileName);
|
||||
|
||||
bool Settings_write(Settings* this);
|
||||
|
||||
Settings* Settings_new(ProcessList* pl, Header* header);
|
||||
|
||||
#endif
|
||||
|
34
SignalItem.c
34
SignalItem.c
@ -31,23 +31,7 @@ char* SIGNAL_CLASS = "Signal";
|
||||
#define SIGNAL_CLASS NULL
|
||||
#endif
|
||||
|
||||
static void Signal_delete(Object* cast) {
|
||||
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* Signal_new(char* name, int number) {
|
||||
Signal* this = malloc(sizeof(Signal));
|
||||
Object_setClass(this, SIGNAL_CLASS);
|
||||
((Object*)this)->display = Signal_display;
|
||||
@ -57,6 +41,22 @@ static Signal* Signal_new(char* name, int number) {
|
||||
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() {
|
||||
return SIGNAL_COUNT;
|
||||
}
|
||||
|
@ -32,6 +32,12 @@ extern char* SIGNAL_CLASS;
|
||||
#define SIGNAL_CLASS NULL
|
||||
#endif
|
||||
|
||||
Signal* Signal_new(char* name, int number);
|
||||
|
||||
void Signal_delete(Object* cast);
|
||||
|
||||
void Signal_display(Object* cast, RichString* out);
|
||||
|
||||
int Signal_getSignalCount();
|
||||
|
||||
Signal** Signal_getSignalTable();
|
||||
|
@ -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;
|
||||
|
||||
int size = Panel_size(super);
|
||||
int size = Panel_getSize(super);
|
||||
|
||||
if (ch <= 255 && isdigit(ch)) {
|
||||
int signal = ch-48 + this->state;
|
||||
@ -44,34 +75,3 @@ static HandlerResult SignalsPanel_eventHandler(Panel* super, int ch) {
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -23,6 +23,10 @@ typedef struct SignalsPanel_ {
|
||||
|
||||
SignalsPanel* SignalsPanel_new(int x, int y, int w, int h);
|
||||
|
||||
void SignalsPanel_delete(Object* object);
|
||||
|
||||
void SignalsPanel_reset(SignalsPanel* this);
|
||||
|
||||
HandlerResult SignalsPanel_EventHandler(Panel* super, int ch);
|
||||
|
||||
#endif
|
||||
|
82
String.c
82
String.c
@ -18,6 +18,10 @@ in the source distribution for its full text.
|
||||
#define String_startsWith(s, match) (strstr((s), (match)) == (s))
|
||||
}*/
|
||||
|
||||
inline void String_delete(char* s) {
|
||||
free(s);
|
||||
}
|
||||
|
||||
inline char* String_copy(char* orig) {
|
||||
return strdup(orig);
|
||||
}
|
||||
@ -45,6 +49,53 @@ char* String_trim(char* in) {
|
||||
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) {
|
||||
if (s1 == NULL || s2 == NULL) {
|
||||
if (s1 == NULL && s2 == NULL)
|
||||
@ -93,6 +144,10 @@ void String_freeArray(char** 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 lens = strlen(s);
|
||||
int lenmatch = strlen(match);
|
||||
@ -103,30 +158,3 @@ int String_contains_i(char* s, char* match) {
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
22
String.h
22
String.h
@ -19,20 +19,34 @@ in the source distribution for its full text.
|
||||
|
||||
#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_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);
|
||||
|
||||
void String_freeArray(char** s);
|
||||
|
||||
int String_startsWith_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
|
||||
|
40
SwapMeter.c
40
SwapMeter.c
@ -23,26 +23,6 @@ int SwapMeter_attributes[] = {
|
||||
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 = {
|
||||
.setValues = SwapMeter_setValues,
|
||||
.display = SwapMeter_display,
|
||||
@ -54,3 +34,23 @@ MeterType SwapMeter = {
|
||||
.uiName = "Swap",
|
||||
.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);
|
||||
}
|
||||
|
@ -26,4 +26,8 @@ extern int SwapMeter_attributes[];
|
||||
|
||||
extern MeterType SwapMeter;
|
||||
|
||||
void SwapMeter_setValues(Meter* this, char* buffer, int len);
|
||||
|
||||
void SwapMeter_display(Object* cast, RichString* out);
|
||||
|
||||
#endif
|
||||
|
2
TODO
2
TODO
@ -5,8 +5,6 @@ BUGS:
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=375219
|
||||
* add swap column for swap usage in MB
|
||||
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:
|
||||
|
||||
|
36
TasksMeter.c
36
TasksMeter.c
@ -18,24 +18,6 @@ int TasksMeter_attributes[] = {
|
||||
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 = {
|
||||
.setValues = TasksMeter_setValues,
|
||||
.display = TasksMeter_display,
|
||||
@ -47,3 +29,21 @@ MeterType TasksMeter = {
|
||||
.uiName = "Task counter",
|
||||
.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");
|
||||
}
|
||||
|
@ -21,4 +21,8 @@ extern int TasksMeter_attributes[];
|
||||
|
||||
extern MeterType TasksMeter;
|
||||
|
||||
void TasksMeter_setValues(Meter* this, char* buffer, int len);
|
||||
|
||||
void TasksMeter_display(Object* cast, RichString* out);
|
||||
|
||||
#endif
|
||||
|
@ -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* this = (TraceScreen*) malloc(sizeof(TraceScreen));
|
||||
this->process = process;
|
||||
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;
|
||||
return this;
|
||||
}
|
||||
@ -53,7 +53,7 @@ void TraceScreen_delete(TraceScreen* this) {
|
||||
free(this);
|
||||
}
|
||||
|
||||
static void TraceScreen_draw(TraceScreen* this) {
|
||||
void TraceScreen_draw(TraceScreen* this) {
|
||||
attrset(CRT_colors[PANEL_HEADER_FOCUS]);
|
||||
mvhline(0, 0, ' ', COLS);
|
||||
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';
|
||||
if (contLine) {
|
||||
ListItem_append((ListItem*)Panel_get(panel,
|
||||
Panel_size(panel)-1), line);
|
||||
Panel_getSize(panel)-1), line);
|
||||
contLine = false;
|
||||
} else {
|
||||
Panel_add(panel, (Object*) ListItem_new(line, 0));
|
||||
@ -119,7 +119,7 @@ void TraceScreen_run(TraceScreen* this) {
|
||||
contLine = true;
|
||||
}
|
||||
if (follow)
|
||||
Panel_setSelected(panel, Panel_size(panel)-1);
|
||||
Panel_setSelected(panel, Panel_getSize(panel)-1);
|
||||
Panel_draw(panel, true);
|
||||
}
|
||||
int ch = getch();
|
||||
@ -146,7 +146,7 @@ void TraceScreen_run(TraceScreen* this) {
|
||||
case KEY_F(4):
|
||||
follow = !follow;
|
||||
if (follow)
|
||||
Panel_setSelected(panel, Panel_size(panel)-1);
|
||||
Panel_setSelected(panel, Panel_getSize(panel)-1);
|
||||
break;
|
||||
case 'q':
|
||||
case 27:
|
||||
|
@ -37,6 +37,8 @@ TraceScreen* TraceScreen_new(Process* process);
|
||||
|
||||
void TraceScreen_delete(TraceScreen* this);
|
||||
|
||||
void TraceScreen_draw(TraceScreen* this);
|
||||
|
||||
void TraceScreen_run(TraceScreen* this);
|
||||
|
||||
#endif
|
||||
|
@ -18,16 +18,28 @@ int UptimeMeter_attributes[] = {
|
||||
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;
|
||||
FILE* fd = fopen(PROCDIR "/uptime", "r");
|
||||
fscanf(fd, "%lf", &uptime);
|
||||
fclose(fd);
|
||||
int totalseconds = (int) ceil(uptime);
|
||||
int seconds = totalseconds % 60;
|
||||
int minutes = (totalseconds/60) % 60;
|
||||
int hours = (totalseconds/3600) % 24;
|
||||
int days = (totalseconds/86400);
|
||||
int minutes = (totalseconds-seconds) % 3600 / 60;
|
||||
int hours = (totalseconds-seconds-(minutes*60)) % 86400 / 3600;
|
||||
int days = (totalseconds-seconds-(minutes*60)-(hours*3600)) / 86400;
|
||||
this->values[0] = days;
|
||||
if (days > this->total) {
|
||||
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);
|
||||
}
|
||||
|
||||
MeterType UptimeMeter = {
|
||||
.setValues = UptimeMeter_setValues,
|
||||
.display = NULL,
|
||||
.mode = TEXT_METERMODE,
|
||||
.items = 1,
|
||||
.total = 100.0,
|
||||
.attributes = UptimeMeter_attributes,
|
||||
.name = "Uptime",
|
||||
.uiName = "Uptime",
|
||||
.caption = "Uptime: "
|
||||
};
|
||||
|
@ -21,4 +21,6 @@ extern int UptimeMeter_attributes[];
|
||||
|
||||
extern MeterType UptimeMeter;
|
||||
|
||||
void UptimeMeter_setValues(Meter* this, char* buffer, int len);
|
||||
|
||||
#endif
|
||||
|
@ -35,7 +35,7 @@ void UsersTable_delete(UsersTable* 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));
|
||||
if (name == NULL) {
|
||||
struct passwd* userData = getpwuid(uid);
|
||||
@ -47,6 +47,10 @@ char* UsersTable_getRef(UsersTable* this, unsigned int uid) {
|
||||
return name;
|
||||
}
|
||||
|
||||
inline int UsersTable_size(UsersTable* this) {
|
||||
return (Hashtable_size(this->users));
|
||||
}
|
||||
|
||||
inline void UsersTable_foreach(UsersTable* this, Hashtable_PairFunction f, void* userData) {
|
||||
Hashtable_foreach(this->users, f, userData);
|
||||
}
|
||||
|
@ -28,8 +28,10 @@ UsersTable* UsersTable_new();
|
||||
|
||||
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
|
||||
|
26
Vector.c
26
Vector.c
@ -63,7 +63,6 @@ void Vector_delete(Vector* this) {
|
||||
#ifdef DEBUG
|
||||
|
||||
static inline bool Vector_isConsistent(Vector* this) {
|
||||
assert(this->items <= this->arraySize);
|
||||
if (this->owner) {
|
||||
for (int i = 0; i < this->items; i++)
|
||||
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
|
||||
|
||||
void Vector_prune(Vector* this) {
|
||||
@ -218,9 +207,7 @@ inline int Vector_size(Vector* this) {
|
||||
return this->items;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
static void Vector_merge(Vector* this, Vector* v2) {
|
||||
void Vector_merge(Vector* this, Vector* v2) {
|
||||
int i;
|
||||
assert(Vector_isConsistent(this));
|
||||
|
||||
@ -231,15 +218,12 @@ static void Vector_merge(Vector* this, Vector* v2) {
|
||||
assert(Vector_isConsistent(this));
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void Vector_add(Vector* this, void* data_) {
|
||||
assert(data_ && ((Object*)data_)->class == this->vectorType);
|
||||
Object* data = data_;
|
||||
assert(Vector_isConsistent(this));
|
||||
int i = this->items;
|
||||
|
||||
Vector_set(this, this->items, data);
|
||||
assert(this->items == i+1); (void)(i);
|
||||
assert(Vector_isConsistent(this));
|
||||
}
|
||||
|
||||
@ -256,9 +240,7 @@ inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
static void Vector_foreach(Vector* this, Vector_procedure f) {
|
||||
void Vector_foreach(Vector* this, Vector_procedure f) {
|
||||
int i;
|
||||
assert(Vector_isConsistent(this));
|
||||
|
||||
@ -266,5 +248,3 @@ static void Vector_foreach(Vector* this, Vector_procedure f) {
|
||||
f(this->array[i]);
|
||||
assert(Vector_isConsistent(this));
|
||||
}
|
||||
|
||||
*/
|
||||
|
16
Vector.h
16
Vector.h
@ -41,8 +41,6 @@ void Vector_delete(Vector* this);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
int Vector_count(Vector* this);
|
||||
|
||||
#endif
|
||||
|
||||
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_);
|
||||
|
||||
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_);
|
||||
|
||||
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
|
||||
|
@ -1 +0,0 @@
|
||||
m4_include(plpa-1.1/plpa.m4)
|
@ -3,7 +3,6 @@
|
||||
aclocal
|
||||
autoconf
|
||||
autoheader
|
||||
libtoolize --copy
|
||||
automake --add-missing --copy
|
||||
|
||||
|
||||
|
51
configure.ac
51
configure.ac
@ -2,24 +2,20 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
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
|
||||
AC_CONFIG_SRCDIR([htop.c])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
AM_DISABLE_SHARED
|
||||
AM_ENABLE_STATIC
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([ncurses], [refresh], [], [missing_libraries="$missing_libraries libncurses"])
|
||||
AC_CHECK_LIB([m], [ceil], [], [missing_libraries="$missing_libraries libm"])
|
||||
|
||||
if test ! -z "$missing_libraries"; then
|
||||
AC_MSG_ERROR([missing libraries: $missing_libraries])
|
||||
AC_MSG_ERROR([missing libraries:$missing_headers])
|
||||
fi
|
||||
|
||||
# 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
|
||||
AC_MSG_ERROR([missing headers: $missing_headers])
|
||||
AC_MSG_ERROR([missing headers:$missing_headers])
|
||||
fi
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
@ -47,13 +43,11 @@ AC_TYPE_SIGNAL
|
||||
AC_FUNC_STAT
|
||||
AC_CHECK_FUNCS([memmove strncasecmp strstr strdup])
|
||||
|
||||
save_cflags="${CFLAGS}"
|
||||
CFLAGS="${CFLAGS} -std=c99"
|
||||
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_MSG_RESULT([yes]),
|
||||
AC_MSG_ERROR([htop is written in C99. A newer version of gcc is required.]))
|
||||
CFLAGS="$save_cflags"
|
||||
|
||||
PROCDIR=/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,
|
||||
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/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_OUTPUT
|
||||
|
24
htop.1
24
htop.1
@ -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"
|
||||
htop \- interactive process viewer
|
||||
.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
|
||||
entering their PIDs.
|
||||
.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"
|
||||
.LP
|
||||
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
|
||||
update of system calls issued by the process.
|
||||
.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
|
||||
Help screen
|
||||
.TP
|
||||
@ -96,9 +77,6 @@ If none is tagged, sends to the currently selected process.
|
||||
.B F10, q
|
||||
Quit
|
||||
.TP
|
||||
.B a (on multiprocessor machines)
|
||||
Set CPU affinity: mark which CPUs a process is allowed to use.
|
||||
.TP
|
||||
.B u
|
||||
Show only processes owned by a specified user.
|
||||
.TP
|
||||
|
312
htop.c
312
htop.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
htop - htop.c
|
||||
(C) 2004-2008 Hisham H. Muhammad
|
||||
(C) 2004-2006 Hisham H. Muhammad
|
||||
Released under the GNU GPL, see the COPYING file
|
||||
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 <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include "ProcessList.h"
|
||||
#include "CRT.h"
|
||||
@ -26,8 +25,6 @@ in the source distribution for its full text.
|
||||
#include "CategoriesPanel.h"
|
||||
#include "SignalsPanel.h"
|
||||
#include "TraceScreen.h"
|
||||
#include "OpenFilesScreen.h"
|
||||
#include "AffinityPanel.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
@ -36,16 +33,16 @@ in the source distribution for its full text.
|
||||
|
||||
#define INCSEARCH_MAX 40
|
||||
|
||||
static void printVersionFlag() {
|
||||
void printVersionFlag() {
|
||||
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");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void printHelpFlag() {
|
||||
void printHelpFlag() {
|
||||
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("-d DELAY Delay between updates, in tenths of seconds\n\n");
|
||||
printf("-u USERNAME Show only processes of a given user\n\n");
|
||||
@ -55,27 +52,23 @@ static void printHelpFlag() {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void showHelp(ProcessList* pl) {
|
||||
void showHelp(ProcessList* pl) {
|
||||
clear();
|
||||
attrset(CRT_colors[HELP_BOLD]);
|
||||
|
||||
for (int i = 0; i < LINES-1; i++)
|
||||
mvhline(i, 0, ' ', COLS);
|
||||
|
||||
mvaddstr(0, 0, "htop " VERSION " - (C) 2004-2008 Hisham Muhammad.");
|
||||
mvaddstr(0, 0, "htop " VERSION " - (C) 2004-2006 Hisham Muhammad.");
|
||||
mvaddstr(1, 0, "Released under the GNU GPL. See 'man' page for more info.");
|
||||
|
||||
attrset(CRT_colors[DEFAULT_COLOR]);
|
||||
mvaddstr(3, 0, "CPU usage bar: ");
|
||||
#define addattrstr(a,s) attrset(a);addstr(s)
|
||||
addattrstr(CRT_colors[BAR_BORDER], "[");
|
||||
if (pl->detailedCPUTime) {
|
||||
if (pl->expandSystemTime) {
|
||||
addattrstr(CRT_colors[CPU_NICE], "low"); addstr("/");
|
||||
addattrstr(CRT_colors[CPU_NORMAL], "normal"); 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_SOFTIRQ], "soft-irq"); addstr("/");
|
||||
addattrstr(CRT_colors[CPU_IOWAIT], "io-wait");
|
||||
addattrstr(CRT_colors[CPU_SOFTIRQ], "soft-irq");
|
||||
addattrstr(CRT_colors[BAR_SHADOW], " used%");
|
||||
} else {
|
||||
addattrstr(CRT_colors[CPU_NICE], "low-priority"); addstr("/");
|
||||
@ -100,47 +93,35 @@ static void showHelp(ProcessList* pl) {
|
||||
addattrstr(CRT_colors[BAR_BORDER], "]");
|
||||
attrset(CRT_colors[DEFAULT_COLOR]);
|
||||
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, " Status: R: running; S: sleeping; T: traced/stopped; Z: zombie; D: disk sleep");
|
||||
mvaddstr( 9, 0, " Arrows: scroll process list F5 t: tree view");
|
||||
mvaddstr(10, 0, " Digits: incremental PID search u: show processes of a single user");
|
||||
mvaddstr(11, 0, " F3 /: incremental name search H: hide/show user threads");
|
||||
mvaddstr(12, 0, " K: hide/show kernel threads");
|
||||
mvaddstr(13, 0, " Space: tag processes F: cursor follows process");
|
||||
mvaddstr(14, 0, " U: untag all processes");
|
||||
mvaddstr(15, 0, " F9 k: kill process/tagged processes P: sort by CPU%");
|
||||
mvaddstr(16, 0, " - ] F7: higher priority (root only) M: sort by MEM%");
|
||||
mvaddstr(17, 0, " + [ F8: lower priority (+ nice) T: sort by TIME");
|
||||
#ifdef HAVE_PLPA
|
||||
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");
|
||||
|
||||
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(10, 0, " F3 /: incremental name search H: hide/show user threads");
|
||||
mvaddstr(11, 0, " K: hide/show kernel threads");
|
||||
mvaddstr(12, 0, " Space: tag processes F: cursor follows process");
|
||||
mvaddstr(13, 0, " U: untag all processes");
|
||||
mvaddstr(14, 0, " F9 k: kill process/tagged processes P: sort by CPU%");
|
||||
mvaddstr(15, 0, " + [ F7: lower priority (+ nice) M: sort by MEM%");
|
||||
mvaddstr(16, 0, " - ] F8: higher priority (root only) T: sort by TIME");
|
||||
mvaddstr(17, 0, " F4 I: invert sort order");
|
||||
mvaddstr(18, 0, " F2 S: setup F6 >: select sort column");
|
||||
mvaddstr(19, 0, " F1 h: show this help screen");
|
||||
mvaddstr(20, 0, " F10 q: quit s: trace syscalls with strace");
|
||||
|
||||
attrset(CRT_colors[HELP_BOLD]);
|
||||
mvaddstr( 9, 0, " Arrows"); mvaddstr( 9,40, " F5 t");
|
||||
mvaddstr(10, 0, " Digits"); mvaddstr(10,40, " u");
|
||||
mvaddstr(11, 0, " F3 /"); mvaddstr(11,40, " H");
|
||||
mvaddstr(12,40, " K");
|
||||
mvaddstr(13, 0, " Space"); mvaddstr(13,40, " F");
|
||||
mvaddstr(14, 0, " U");
|
||||
mvaddstr(15, 0, " F9 k"); mvaddstr(15,40, " P");
|
||||
mvaddstr(16, 0, " + [ F7"); mvaddstr(16,40, " M");
|
||||
mvaddstr(17, 0, " - ] F8"); mvaddstr(17,40, " T");
|
||||
mvaddstr(18,40, " F4 I");
|
||||
#if HAVE_PLPA
|
||||
if (pl->processorCount > 1)
|
||||
mvaddstr(18, 0, " a:");
|
||||
#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");
|
||||
mvaddstr( 8, 0, " Arrows"); mvaddstr( 8,40, " F5 t");
|
||||
mvaddstr( 9, 0, " Digits"); mvaddstr( 9,40, " u");
|
||||
mvaddstr(10, 0, " F3 /"); mvaddstr(10,40, " H");
|
||||
mvaddstr(11,40, " K");
|
||||
mvaddstr(12, 0, " Space"); mvaddstr(12,40, " F");
|
||||
mvaddstr(13, 0, " U");
|
||||
mvaddstr(14, 0, " F9 k"); mvaddstr(14,40, " P");
|
||||
mvaddstr(15, 0, " + [ F7"); mvaddstr(15,40, " M");
|
||||
mvaddstr(16, 0, " - ] F8"); mvaddstr(16,40, " T");
|
||||
mvaddstr(17,40, " F4 I");
|
||||
mvaddstr(18, 0, " F2 S"); mvaddstr(18,40, " F6 >");
|
||||
mvaddstr(19, 0, " F1 h");
|
||||
mvaddstr(20, 0, " F10 q"); mvaddstr(20,40, " s");
|
||||
attrset(CRT_colors[DEFAULT_COLOR]);
|
||||
|
||||
attrset(CRT_colors[HELP_BOLD]);
|
||||
@ -151,12 +132,10 @@ static void showHelp(ProcessList* pl) {
|
||||
clear();
|
||||
}
|
||||
|
||||
static char* CategoriesFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
|
||||
|
||||
static void Setup_run(Settings* settings, int headerHeight) {
|
||||
ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true);
|
||||
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);
|
||||
Panel* panelFocus;
|
||||
int ch;
|
||||
@ -165,21 +144,18 @@ static void Setup_run(Settings* settings, int headerHeight) {
|
||||
}
|
||||
|
||||
static bool changePriority(Panel* panel, int delta) {
|
||||
bool ok = true;
|
||||
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);
|
||||
if (p->tag) {
|
||||
ok = Process_setPriority(p, p->nice + delta) && ok;
|
||||
Process_setPriority(p, p->nice + delta);
|
||||
anyTagged = true;
|
||||
}
|
||||
}
|
||||
if (!anyTagged) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -189,13 +165,13 @@ static HandlerResult pickWithEnter(Panel* panel, int ch) {
|
||||
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"};
|
||||
int fuEvents[2] = {13, 27};
|
||||
if (!list->eventHandler)
|
||||
if (!panel->eventHandler)
|
||||
Panel_setEventHandler(list, pickWithEnter);
|
||||
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);
|
||||
Panel* panelFocus;
|
||||
int ch;
|
||||
@ -210,13 +186,13 @@ static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, char** ke
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void addUserToVector(int key, void* userCast, void* panelCast) {
|
||||
void addUserToList(int key, void* userCast, void* panelCast) {
|
||||
char* user = (char*) userCast;
|
||||
Panel* panel = (Panel*) panelCast;
|
||||
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);
|
||||
if (user) {
|
||||
*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 delay = -1;
|
||||
@ -239,47 +207,32 @@ int main(int argc, char** argv) {
|
||||
uid_t userId = 0;
|
||||
int sortKey = 0;
|
||||
|
||||
char *lc_ctype = getenv("LC_CTYPE");
|
||||
if(lc_ctype != NULL)
|
||||
setlocale(LC_CTYPE, lc_ctype);
|
||||
else
|
||||
setlocale(LC_CTYPE, getenv("LC_ALL"));
|
||||
|
||||
int arg = 1;
|
||||
while (arg < argc) {
|
||||
if (String_eq(argv[arg], "--help")) {
|
||||
if (argc > 0) {
|
||||
if (String_eq(argv[1], "--help")) {
|
||||
printHelpFlag();
|
||||
} else if (String_eq(argv[arg], "--version")) {
|
||||
} else if (String_eq(argv[1], "--version")) {
|
||||
printVersionFlag();
|
||||
} else if (String_eq(argv[arg], "--sort-key")) {
|
||||
if (arg == argc - 1) printHelpFlag();
|
||||
arg++;
|
||||
char* field = argv[arg];
|
||||
if (String_eq(field, "help")) {
|
||||
} else if (String_eq(argv[1], "--sort-key")) {
|
||||
if (argc < 2) printHelpFlag();
|
||||
if (String_eq(argv[2], "help")) {
|
||||
for (int j = 1; j < LAST_PROCESSFIELD; j++)
|
||||
printf ("%s\n", Process_fieldNames[j]);
|
||||
exit(0);
|
||||
}
|
||||
sortKey = ColumnsPanel_fieldNameToIndex(field);
|
||||
sortKey = ColumnsPanel_fieldNameToIndex(argv[2]);
|
||||
if (sortKey == -1) {
|
||||
fprintf(stderr, "Error: invalid column \"%s\".\n", field);
|
||||
fprintf(stderr, "Error: invalid column \"%s\".\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
} else if (String_eq(argv[arg], "-d")) {
|
||||
if (arg == argc - 1) printHelpFlag();
|
||||
arg++;
|
||||
sscanf(argv[arg], "%d", &delay);
|
||||
} else if (String_eq(argv[1], "-d")) {
|
||||
if (argc < 2) printHelpFlag();
|
||||
sscanf(argv[2], "%d", &delay);
|
||||
if (delay < 1) delay = 1;
|
||||
if (delay > 100) delay = 100;
|
||||
} else if (String_eq(argv[arg], "-u")) {
|
||||
if (arg == argc - 1) printHelpFlag();
|
||||
arg++;
|
||||
setUserOnly(argv[arg], &userOnly, &userId);
|
||||
} else {
|
||||
fprintf(stderr, "Error: unknown flag: %s\n", argv[arg]);
|
||||
exit(1);
|
||||
} else if (String_eq(argv[1], "-u")) {
|
||||
if (argc < 2) printHelpFlag();
|
||||
setUserOnly(argv[2], &userOnly, &userId);
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
|
||||
if (access(PROCDIR, R_OK) != 0) {
|
||||
@ -292,7 +245,6 @@ int main(int argc, char** argv) {
|
||||
int refreshTimeout = 0;
|
||||
int resetRefreshTimeout = 5;
|
||||
bool doRefresh = true;
|
||||
bool doRecalculate = false;
|
||||
Settings* settings;
|
||||
|
||||
Panel* killPanel = NULL;
|
||||
@ -309,6 +261,10 @@ int main(int argc, char** argv) {
|
||||
|
||||
Header* header = Header_new(pl);
|
||||
settings = Settings_new(pl, header);
|
||||
if (sortKey > 0) {
|
||||
pl->sortKey = sortKey;
|
||||
pl->treeView = false;
|
||||
}
|
||||
int headerHeight = Header_calculateHeight(header);
|
||||
|
||||
// FIXME: move delay code to settings
|
||||
@ -318,21 +274,16 @@ int main(int argc, char** argv) {
|
||||
CRT_init(settings->delay, settings->colorScheme);
|
||||
|
||||
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));
|
||||
|
||||
char* searchFunctions[] = {"Next ", "Exit ", " Search: ", NULL};
|
||||
char* searchKeys[] = {"F3", "Esc", " "};
|
||||
int searchEvents[] = {KEY_F(3), 27, ERR};
|
||||
FunctionBar* searchBar = FunctionBar_new(searchFunctions, searchKeys, searchEvents);
|
||||
char* searchFunctions[3] = {"Next ", "Exit ", " Search: "};
|
||||
char* searchKeys[3] = {"F3", "Esc", " "};
|
||||
int searchEvents[3] = {KEY_F(3), 27, ERR};
|
||||
FunctionBar* searchBar = FunctionBar_new(3, searchFunctions, searchKeys, searchEvents);
|
||||
|
||||
char* defaultFunctions[] = {"Help ", "Setup ", "Search", "Invert", "Tree ",
|
||||
"SortBy", "Nice -", "Nice +", "Kill ", "Quit ", NULL};
|
||||
FunctionBar* defaultBar = FunctionBar_new(defaultFunctions, NULL, NULL);
|
||||
char* defaultFunctions[10] = {"Help ", "Setup ", "Search", "Invert", "Tree ",
|
||||
"SortBy", "Nice -", "Nice +", "Kill ", "Quit "};
|
||||
FunctionBar* defaultBar = FunctionBar_new(10, defaultFunctions, NULL, NULL);
|
||||
|
||||
ProcessList_scan(pl);
|
||||
usleep(75000);
|
||||
@ -357,15 +308,15 @@ int main(int argc, char** argv) {
|
||||
if (recalculate)
|
||||
oldTime = newTime;
|
||||
if (doRefresh) {
|
||||
incSearchIndex = 0;
|
||||
incSearchBuffer[0] = 0;
|
||||
int currPos = Panel_getSelectedIndex(panel);
|
||||
unsigned int currPid = 0;
|
||||
int currPid = 0;
|
||||
int currScrollV = panel->scrollV;
|
||||
if (follow)
|
||||
currPid = ProcessList_get(pl, currPos)->pid;
|
||||
if (recalculate || doRecalculate) {
|
||||
if (recalculate)
|
||||
ProcessList_scan(pl);
|
||||
doRecalculate = false;
|
||||
}
|
||||
if (refreshTimeout == 0) {
|
||||
ProcessList_sort(pl);
|
||||
refreshTimeout = 1;
|
||||
@ -431,6 +382,8 @@ int main(int argc, char** argv) {
|
||||
incSearchBuffer[incSearchIndex] = 0;
|
||||
} else {
|
||||
incSearchMode = false;
|
||||
incSearchIndex = 0;
|
||||
incSearchBuffer[0] = 0;
|
||||
FunctionBar_draw(defaultBar, NULL);
|
||||
continue;
|
||||
}
|
||||
@ -452,7 +405,7 @@ int main(int argc, char** argv) {
|
||||
continue;
|
||||
}
|
||||
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++)
|
||||
Panel_setSelected(panel, i);
|
||||
acc = pid * 10;
|
||||
@ -467,18 +420,7 @@ int main(int argc, char** argv) {
|
||||
MEVENT mevent;
|
||||
int ok = getmouse(&mevent);
|
||||
if (ok == OK) {
|
||||
if (mevent.y == panel->y) {
|
||||
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) {
|
||||
if (mevent.y >= panel->y + 1 && mevent.y < LINES - 1) {
|
||||
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
|
||||
doRefresh = false;
|
||||
refreshTimeout = resetRefreshTimeout;
|
||||
@ -505,18 +447,24 @@ int main(int argc, char** argv) {
|
||||
case 'M':
|
||||
{
|
||||
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;
|
||||
}
|
||||
case 'T':
|
||||
{
|
||||
refreshTimeout = 0;
|
||||
setSortKey(pl, TIME, panel, settings);
|
||||
pl->sortKey = TIME;
|
||||
pl->treeView = false;
|
||||
settings->changed = true;
|
||||
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
|
||||
break;
|
||||
}
|
||||
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);
|
||||
p->tag = false;
|
||||
}
|
||||
@ -526,7 +474,10 @@ int main(int argc, char** argv) {
|
||||
case 'P':
|
||||
{
|
||||
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;
|
||||
}
|
||||
case KEY_F(1):
|
||||
@ -562,17 +513,6 @@ int main(int argc, char** argv) {
|
||||
CRT_enableDelay();
|
||||
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 'C':
|
||||
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_setHeader(usersPanel, "Show processes of:");
|
||||
UsersTable_foreach(ut, addUserToVector, usersPanel);
|
||||
UsersTable_foreach(ut, addUserToList, usersPanel);
|
||||
Vector_sort(usersPanel->items);
|
||||
ListItem* allUsers = ListItem_new("All users", -1);
|
||||
Panel_insert(usersPanel, 0, (Object*) allUsers);
|
||||
char* fuFunctions[] = {"Show ", "Cancel ", NULL};
|
||||
ListItem* picked = (ListItem*) pickFromVector(panel, usersPanel, 20, headerHeight, fuFunctions, defaultBar);
|
||||
char* fuFunctions[2] = {"Show ", "Cancel "};
|
||||
ListItem* picked = (ListItem*) pickFromList(panel, usersPanel, 20, headerHeight, fuFunctions, defaultBar);
|
||||
if (picked) {
|
||||
if (picked == allUsers) {
|
||||
userOnly = false;
|
||||
@ -619,15 +559,15 @@ int main(int argc, char** argv) {
|
||||
killPanel = (Panel*) SignalsPanel_new(0, 0, 0, 0);
|
||||
}
|
||||
SignalsPanel_reset((SignalsPanel*) killPanel);
|
||||
char* fuFunctions[] = {"Send ", "Cancel ", NULL};
|
||||
Signal* signal = (Signal*) pickFromVector(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar);
|
||||
char* fuFunctions[2] = {"Send ", "Cancel "};
|
||||
Signal* signal = (Signal*) pickFromList(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar);
|
||||
if (signal) {
|
||||
if (signal->number != 0) {
|
||||
Panel_setHeader(panel, "Sending...");
|
||||
Panel_draw(panel, true);
|
||||
refresh();
|
||||
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);
|
||||
if (p->tag) {
|
||||
Process_sendSignal(p, signal->number);
|
||||
@ -645,43 +585,6 @@ int main(int argc, char** argv) {
|
||||
refreshTimeout = 0;
|
||||
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 'q':
|
||||
quit = 1;
|
||||
@ -698,20 +601,20 @@ int main(int argc, char** argv) {
|
||||
char* fuFunctions[2] = {"Sort ", "Cancel "};
|
||||
ProcessField* fields = pl->fields;
|
||||
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]));
|
||||
if (fields[i] == pl->sortKey)
|
||||
Panel_setSelected(sortPanel, i);
|
||||
free(name);
|
||||
}
|
||||
ListItem* field = (ListItem*) pickFromVector(panel, sortPanel, 15, headerHeight, fuFunctions, defaultBar);
|
||||
ListItem* field = (ListItem*) pickFromList(panel, sortPanel, 15, headerHeight, fuFunctions, defaultBar);
|
||||
if (field) {
|
||||
pl->treeView = false;
|
||||
settings->changed = true;
|
||||
setSortKey(pl, field->key, panel, settings);
|
||||
} else {
|
||||
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
|
||||
pl->sortKey = field->key;
|
||||
}
|
||||
((Object*)sortPanel)->delete((Object*)sortPanel);
|
||||
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
|
||||
refreshTimeout = 0;
|
||||
break;
|
||||
}
|
||||
@ -740,10 +643,8 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
case KEY_F(3):
|
||||
case '/':
|
||||
incSearchIndex = 0;
|
||||
incSearchBuffer[0] = 0;
|
||||
incSearchMode = true;
|
||||
FunctionBar_draw(searchBar, incSearchBuffer);
|
||||
incSearchMode = true;
|
||||
break;
|
||||
case 't':
|
||||
case KEY_F(5):
|
||||
@ -752,14 +653,11 @@ int main(int argc, char** argv) {
|
||||
settings->changed = true;
|
||||
break;
|
||||
case 'H':
|
||||
doRecalculate = true;
|
||||
refreshTimeout = 0;
|
||||
pl->hideUserlandThreads = !pl->hideUserlandThreads;
|
||||
pl->hideThreads = pl->hideUserlandThreads;
|
||||
pl->hideThreads = !pl->hideThreads;
|
||||
settings->changed = true;
|
||||
break;
|
||||
case 'K':
|
||||
doRecalculate = true;
|
||||
refreshTimeout = 0;
|
||||
pl->hideKernelThreads = !pl->hideKernelThreads;
|
||||
settings->changed = true;
|
||||
|
@ -1,10 +1,12 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Encoding=UTF-8
|
||||
Version=0.6.4
|
||||
Name=Htop
|
||||
Type=Application
|
||||
Comment=Show System Processes
|
||||
Terminal=true
|
||||
Exec=htop
|
||||
Path=
|
||||
Icon=htop
|
||||
Categories=ConsoleOnly;System;
|
||||
Categories=ConsoleOnly;System;Application;
|
||||
GenericName=Process Viewer
|
||||
|
15
htop.h
15
htop.h
@ -4,7 +4,7 @@
|
||||
#define HEADER_htop
|
||||
/*
|
||||
htop - htop.h
|
||||
(C) 2004-2008 Hisham H. Muhammad
|
||||
(C) 2004-2006 Hisham H. Muhammad
|
||||
Released under the GNU GPL, see the COPYING file
|
||||
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 <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include "ProcessList.h"
|
||||
#include "CRT.h"
|
||||
@ -30,8 +29,6 @@ in the source distribution for its full text.
|
||||
#include "CategoriesPanel.h"
|
||||
#include "SignalsPanel.h"
|
||||
#include "TraceScreen.h"
|
||||
#include "OpenFilesScreen.h"
|
||||
#include "AffinityPanel.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
@ -40,6 +37,16 @@ in the source distribution for its full text.
|
||||
|
||||
#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);
|
||||
|
||||
#endif
|
||||
|
@ -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)
|
@ -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.
|
@ -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
|
@ -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:
|
@ -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$
|
||||
|
||||
===========================================================================
|
@ -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
|
274
plpa-1.1/plpa.m4
274
plpa-1.1/plpa.m4
@ -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
|
@ -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)
|
@ -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:
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
Reference in New Issue
Block a user