1 Commits
0.8.2 ... 0.8

Author SHA1 Message Date
33fee7963a Tag release 0.8 in revision history. 2008-05-07 23:06:27 +00:00
37 changed files with 160 additions and 1063 deletions

View File

@ -39,7 +39,7 @@ Panel* AffinityPanel_new(int processorCount, unsigned long mask) {
} }
unsigned long AffinityPanel_getAffinity(Panel* this) { unsigned long AffinityPanel_getAffinity(Panel* this) {
int size = Panel_size(this); int size = Panel_getSize(this);
unsigned long mask = 0; unsigned long mask = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (CheckItem_get((CheckItem*)Panel_get(this, i))) if (CheckItem_get((CheckItem*)Panel_get(this, i)))

View File

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

View File

@ -43,10 +43,6 @@ static void CPUMeter_init(Meter* this) {
static void CPUMeter_setValues(Meter* this, char* buffer, int size) { static void CPUMeter_setValues(Meter* this, char* buffer, int size) {
ProcessList* pl = this->pl; ProcessList* pl = this->pl;
int processor = this->param; int processor = this->param;
if (processor > this->pl->processorCount) {
snprintf(buffer, size, "absent");
return;
}
double total = (double) pl->totalPeriod[processor]; double total = (double) pl->totalPeriod[processor];
double cpu; double cpu;
this->values[0] = pl->nicePeriod[processor] / total * 100.0; this->values[0] = pl->nicePeriod[processor] / total * 100.0;
@ -71,10 +67,6 @@ static void CPUMeter_display(Object* cast, RichString* out) {
char buffer[50]; char buffer[50];
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
RichString_init(out); 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]); sprintf(buffer, "%5.1f%% ", this->values[1]);
RichString_append(out, CRT_colors[METER_TEXT], ":"); RichString_append(out, CRT_colors[METER_TEXT], ":");
RichString_append(out, CRT_colors[CPU_NORMAL], buffer); RichString_append(out, CRT_colors[CPU_NORMAL], buffer);

14
CRT.c
View File

@ -56,7 +56,6 @@ typedef enum ColorElements_ {
METER_VALUE, METER_VALUE,
LED_COLOR, LED_COLOR,
UPTIME, UPTIME,
BATTERY,
TASKS_TOTAL, TASKS_TOTAL,
TASKS_RUNNING, TASKS_RUNNING,
SWAP, SWAP,
@ -100,7 +99,6 @@ typedef enum ColorElements_ {
CPU_IOWAIT, CPU_IOWAIT,
CPU_IRQ, CPU_IRQ,
CPU_SOFTIRQ, CPU_SOFTIRQ,
HOSTNAME,
LAST_COLORELEMENT LAST_COLORELEMENT
} ColorElements; } ColorElements;
@ -218,7 +216,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD; CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD;
CRT_colors[FAILED_SEARCH] = A_REVERSE | A_BOLD; CRT_colors[FAILED_SEARCH] = A_REVERSE | A_BOLD;
CRT_colors[UPTIME] = A_BOLD; CRT_colors[UPTIME] = A_BOLD;
CRT_colors[BATTERY] = A_BOLD;
CRT_colors[LARGE_NUMBER] = A_BOLD; CRT_colors[LARGE_NUMBER] = A_BOLD;
CRT_colors[METER_TEXT] = A_NORMAL; CRT_colors[METER_TEXT] = A_NORMAL;
CRT_colors[METER_VALUE] = A_BOLD; CRT_colors[METER_VALUE] = A_BOLD;
@ -265,7 +262,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CPU_IOWAIT] = A_NORMAL; CRT_colors[CPU_IOWAIT] = A_NORMAL;
CRT_colors[CPU_IRQ] = A_BOLD; CRT_colors[CPU_IRQ] = A_BOLD;
CRT_colors[CPU_SOFTIRQ] = A_BOLD; CRT_colors[CPU_SOFTIRQ] = A_BOLD;
CRT_colors[HOSTNAME] = A_BOLD;
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE) { } else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE) {
CRT_colors[RESET_COLOR] = ColorPair(Black,White); CRT_colors[RESET_COLOR] = ColorPair(Black,White);
CRT_colors[DEFAULT_COLOR] = ColorPair(Black,White); CRT_colors[DEFAULT_COLOR] = ColorPair(Black,White);
@ -277,7 +273,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,White); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,White);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = ColorPair(Yellow,White); CRT_colors[UPTIME] = ColorPair(Yellow,White);
CRT_colors[BATTERY] = ColorPair(Yellow,White);
CRT_colors[LARGE_NUMBER] = ColorPair(Red,White); CRT_colors[LARGE_NUMBER] = ColorPair(Red,White);
CRT_colors[METER_TEXT] = ColorPair(Blue,White); CRT_colors[METER_TEXT] = ColorPair(Blue,White);
CRT_colors[METER_VALUE] = ColorPair(Black,White); CRT_colors[METER_VALUE] = ColorPair(Black,White);
@ -324,7 +319,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black); CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black);
CRT_colors[CPU_IRQ] = ColorPair(Blue,White); CRT_colors[CPU_IRQ] = ColorPair(Blue,White);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,White); CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,White);
CRT_colors[HOSTNAME] = ColorPair(Black,White);
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE2) { } else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE2) {
CRT_colors[RESET_COLOR] = ColorPair(Black,Black); CRT_colors[RESET_COLOR] = ColorPair(Black,Black);
CRT_colors[DEFAULT_COLOR] = ColorPair(Black,Black); CRT_colors[DEFAULT_COLOR] = ColorPair(Black,Black);
@ -336,7 +330,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,Black); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,Black);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = ColorPair(Yellow,Black); CRT_colors[UPTIME] = ColorPair(Yellow,Black);
CRT_colors[BATTERY] = ColorPair(Yellow,Black);
CRT_colors[LARGE_NUMBER] = ColorPair(Red,Black); CRT_colors[LARGE_NUMBER] = ColorPair(Red,Black);
CRT_colors[METER_TEXT] = ColorPair(Blue,Black); CRT_colors[METER_TEXT] = ColorPair(Blue,Black);
CRT_colors[METER_VALUE] = ColorPair(Black,Black); CRT_colors[METER_VALUE] = ColorPair(Black,Black);
@ -383,7 +376,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black); CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black); CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black); CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black);
CRT_colors[HOSTNAME] = ColorPair(White,Black);
} else if (CRT_colorScheme == COLORSCHEME_MIDNIGHT) { } else if (CRT_colorScheme == COLORSCHEME_MIDNIGHT) {
CRT_colors[RESET_COLOR] = ColorPair(White,Blue); CRT_colors[RESET_COLOR] = ColorPair(White,Blue);
CRT_colors[DEFAULT_COLOR] = ColorPair(White,Blue); CRT_colors[DEFAULT_COLOR] = ColorPair(White,Blue);
@ -395,7 +387,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD | ColorPair(Yellow,Blue); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = A_BOLD | ColorPair(Yellow,Blue); CRT_colors[UPTIME] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[BATTERY] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Blue); CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Blue);
CRT_colors[METER_TEXT] = ColorPair(Cyan,Blue); CRT_colors[METER_TEXT] = ColorPair(Cyan,Blue);
CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Blue); CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Blue);
@ -442,7 +433,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Blue); CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Blue);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Black,Blue); CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Black,Blue);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Black,Blue); CRT_colors[CPU_SOFTIRQ] = ColorPair(Black,Blue);
CRT_colors[HOSTNAME] = ColorPair(White,Blue);
} else if (CRT_colorScheme == COLORSCHEME_BLACKNIGHT) { } else if (CRT_colorScheme == COLORSCHEME_BLACKNIGHT) {
CRT_colors[RESET_COLOR] = ColorPair(Cyan,Black); CRT_colors[RESET_COLOR] = ColorPair(Cyan,Black);
CRT_colors[DEFAULT_COLOR] = ColorPair(Cyan,Black); CRT_colors[DEFAULT_COLOR] = ColorPair(Cyan,Black);
@ -454,7 +444,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = ColorPair(Green,Black); CRT_colors[UPTIME] = ColorPair(Green,Black);
CRT_colors[BATTERY] = ColorPair(Green,Black);
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black); CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black);
CRT_colors[METER_TEXT] = ColorPair(Cyan,Black); CRT_colors[METER_TEXT] = ColorPair(Cyan,Black);
CRT_colors[METER_VALUE] = ColorPair(Green,Black); CRT_colors[METER_VALUE] = ColorPair(Green,Black);
@ -501,7 +490,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black); CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black); CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black); CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black);
CRT_colors[HOSTNAME] = ColorPair(Green,Black);
} else { } else {
/* Default */ /* Default */
CRT_colors[RESET_COLOR] = ColorPair(White,Black); CRT_colors[RESET_COLOR] = ColorPair(White,Black);
@ -514,7 +502,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White); CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan); CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = A_BOLD | ColorPair(Cyan,Black); CRT_colors[UPTIME] = A_BOLD | ColorPair(Cyan,Black);
CRT_colors[BATTERY] = A_BOLD | ColorPair(Cyan,Black);
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black); CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black);
CRT_colors[METER_TEXT] = ColorPair(Cyan,Black); CRT_colors[METER_TEXT] = ColorPair(Cyan,Black);
CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Black); CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Black);
@ -561,6 +548,5 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black); CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black);
CRT_colors[CPU_IRQ] = ColorPair(Yellow,Black); CRT_colors[CPU_IRQ] = ColorPair(Yellow,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Magenta,Black); CRT_colors[CPU_SOFTIRQ] = ColorPair(Magenta,Black);
CRT_colors[HOSTNAME] = A_BOLD;
} }
} }

2
CRT.h
View File

@ -58,7 +58,6 @@ typedef enum ColorElements_ {
METER_VALUE, METER_VALUE,
LED_COLOR, LED_COLOR,
UPTIME, UPTIME,
BATTERY,
TASKS_TOTAL, TASKS_TOTAL,
TASKS_RUNNING, TASKS_RUNNING,
SWAP, SWAP,
@ -102,7 +101,6 @@ typedef enum ColorElements_ {
CPU_IOWAIT, CPU_IOWAIT,
CPU_IRQ, CPU_IRQ,
CPU_SOFTIRQ, CPU_SOFTIRQ,
HOSTNAME,
LAST_COLORELEMENT LAST_COLORELEMENT
} ColorElements; } ColorElements;

View File

@ -23,17 +23,17 @@ typedef struct CategoriesPanel_ {
}*/ }*/
static char* MetersFunctions[] = {" ", " ", " ", "Type ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done ", NULL}; static char* MetersFunctions[10] = {" ", " ", " ", "Type ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done "};
static char* AvailableMetersFunctions[] = {" ", " ", " ", " ", "Add L ", "Add R ", " ", " ", " ", "Done ", NULL}; static char* AvailableMetersFunctions[10] = {" ", " ", " ", " ", "Add L ", "Add R ", " ", " ", " ", "Done "};
static char* DisplayOptionsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL}; static char* DisplayOptionsFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
static char* ColumnsFunctions[] = {" ", " ", " ", " ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done ", NULL}; static char* ColumnsFunctions[10] = {" ", " ", " ", " ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done "};
static char* ColorsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL}; static char* ColorsFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
static char* AvailableColumnsFunctions[] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done ", NULL}; static char* AvailableColumnsFunctions[10] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done "};
static void CategoriesPanel_delete(Object* object) { static void CategoriesPanel_delete(Object* object) {
Panel* super = (Panel*) object; Panel* super = (Panel*) object;
@ -46,26 +46,26 @@ void CategoriesPanel_makeMetersPage(CategoriesPanel* this) {
Panel* leftMeters = (Panel*) MetersPanel_new(this->settings, "Left column", this->settings->header->leftMeters, this->scr); 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* 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); 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, leftMeters, FunctionBar_new(10, MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, rightMeters, FunctionBar_new(MetersFunctions, NULL, NULL), 20); ScreenManager_add(this->scr, rightMeters, FunctionBar_new(10, MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableMeters, FunctionBar_new(AvailableMetersFunctions, NULL, NULL), -1); ScreenManager_add(this->scr, availableMeters, FunctionBar_new(10, AvailableMetersFunctions, NULL, NULL), -1);
} }
static void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this) { static void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this) {
Panel* displayOptions = (Panel*) DisplayOptionsPanel_new(this->settings, this->scr); Panel* displayOptions = (Panel*) DisplayOptionsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, displayOptions, FunctionBar_new(DisplayOptionsFunctions, NULL, NULL), -1); ScreenManager_add(this->scr, displayOptions, FunctionBar_new(10, DisplayOptionsFunctions, NULL, NULL), -1);
} }
static void CategoriesPanel_makeColorsPage(CategoriesPanel* this) { static void CategoriesPanel_makeColorsPage(CategoriesPanel* this) {
Panel* colors = (Panel*) ColorsPanel_new(this->settings, this->scr); Panel* colors = (Panel*) ColorsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, colors, FunctionBar_new(ColorsFunctions, NULL, NULL), -1); ScreenManager_add(this->scr, colors, FunctionBar_new(10, ColorsFunctions, NULL, NULL), -1);
} }
static void CategoriesPanel_makeColumnsPage(CategoriesPanel* this) { static void CategoriesPanel_makeColumnsPage(CategoriesPanel* this) {
Panel* columns = (Panel*) ColumnsPanel_new(this->settings, this->scr); Panel* columns = (Panel*) ColumnsPanel_new(this->settings, this->scr);
Panel* availableColumns = (Panel*) AvailableColumnsPanel_new(this->settings, columns, 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, columns, FunctionBar_new(10, ColumnsFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableColumns, FunctionBar_new(AvailableColumnsFunctions, NULL, NULL), -1); ScreenManager_add(this->scr, availableColumns, FunctionBar_new(10, AvailableColumnsFunctions, NULL, NULL), -1);
} }
static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) { static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {

View File

@ -1,34 +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 What's new in version 0.8
* Ability to change sort column with the mouse by * Ability to change sort column with the mouse by

View File

@ -30,7 +30,7 @@ static HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch) {
int selected = Panel_getSelectedIndex(super); int selected = Panel_getSelectedIndex(super);
HandlerResult result = IGNORED; HandlerResult result = IGNORED;
int size = Panel_size(super); int size = Panel_getSize(super);
switch(ch) { switch(ch) {
case KEY_F(7): case KEY_F(7):
@ -95,7 +95,7 @@ int ColumnsPanel_fieldNameToIndex(const char* name) {
void ColumnsPanel_update(Panel* super) { void ColumnsPanel_update(Panel* super) {
ColumnsPanel* this = (ColumnsPanel*) super; ColumnsPanel* this = (ColumnsPanel*) super;
int size = Panel_size(super); int size = Panel_getSize(super);
this->settings->changed = true; this->settings->changed = true;
// FIXME: this is crappily inefficient // FIXME: this is crappily inefficient
free(this->settings->pl->fields); free(this->settings->pl->fields);

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,5 @@
if HAVE_PLPA
SUBDIRS = plpa-1.1 SUBDIRS = plpa-1.1
endif
bin_PROGRAMS = htop bin_PROGRAMS = htop
dist_man_MANS = htop.1 dist_man_MANS = htop.1
@ -19,27 +17,24 @@ myhtopsources = AvailableMetersPanel.c CategoriesPanel.c CheckItem.c \
ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c DebugMemory.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 \ DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c \
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.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 \ Process.c ProcessList.c RichString.c ScreenManager.c Settings.c \
SignalItem.c SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \ SignalItem.c SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \
UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c \ UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c
HostnameMeter.c OpenFilesScreen.c
myhtopheaders = AvailableColumnsPanel.h AvailableMetersPanel.h \ myhtopheaders = AvailableColumnsPanel.h AvailableMetersPanel.h \
CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h \ CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h \
CPUMeter.h CRT.h DebugMemory.h DisplayOptionsPanel.h FunctionBar.h \ CPUMeter.h CRT.h DebugMemory.h DisplayOptionsPanel.h FunctionBar.h \
Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.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 \ Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h \
ScreenManager.h Settings.h SignalItem.h SignalsPanel.h String.h \ ScreenManager.h Settings.h SignalItem.h SignalsPanel.h String.h \
SwapMeter.h TasksMeter.h TraceScreen.h UptimeMeter.h UsersTable.h Vector.h \ SwapMeter.h TasksMeter.h TraceScreen.h UptimeMeter.h UsersTable.h Vector.h \
Process.h AffinityPanel.h HostnameMeter.h OpenFilesScreen.h Process.h AffinityPanel.h
SUFFIXES = .h SUFFIXES = .h
BUILT_SOURCES = $(myhtopheaders) BUILT_SOURCES = $(myhtopheaders)
htop_SOURCES = $(myhtopheaders) $(myhtopsources) config.h debug.h htop_SOURCES = $(myhtopheaders) $(myhtopsources) config.h debug.h
if HAVE_PLPA
htop_LDADD = $(top_builddir)/plpa-1.1/src/libplpa_included.la htop_LDADD = $(top_builddir)/plpa-1.1/src/libplpa_included.la
endif
profile: profile:
$(MAKE) all CFLAGS="-pg -O2" $(MAKE) all CFLAGS="-pg -O2"

22
Meter.c
View File

@ -6,18 +6,19 @@ in the source distribution for its full text.
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include "RichString.h" #include <math.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <stdarg.h>
#include "Meter.h" #include "Meter.h"
#include "Object.h" #include "Object.h"
#include "CRT.h" #include "CRT.h"
#include "ListItem.h" #include "ListItem.h"
#include "String.h" #include "String.h"
#include "ProcessList.h" #include "ProcessList.h"
#include "RichString.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
@ -95,10 +96,7 @@ typedef enum {
#include "TasksMeter.h" #include "TasksMeter.h"
#include "LoadAverageMeter.h" #include "LoadAverageMeter.h"
#include "UptimeMeter.h" #include "UptimeMeter.h"
#include "BatteryMeter.h"
#include "ClockMeter.h" #include "ClockMeter.h"
#include "HostnameMeter.h"
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
@ -122,9 +120,7 @@ MeterType* Meter_types[] = {
&SwapMeter, &SwapMeter,
&TasksMeter, &TasksMeter,
&UptimeMeter, &UptimeMeter,
&BatteryMeter,
&AllCPUsMeter, &AllCPUsMeter,
&HostnameMeter,
NULL NULL
}; };
@ -246,8 +242,8 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
w -= 2; w -= 2;
attrset(CRT_colors[METER_TEXT]); attrset(CRT_colors[METER_TEXT]);
int captionLen = 3; mvaddstr(y, x, this->caption);
mvaddnstr(y, x, this->caption, captionLen); int captionLen = strlen(this->caption);
x += captionLen; x += captionLen;
w -= captionLen; w -= captionLen;
attrset(CRT_colors[BAR_BORDER]); attrset(CRT_colors[BAR_BORDER]);

16
Meter.h
View File

@ -10,17 +10,18 @@ in the source distribution for its full text.
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include "RichString.h" #include <math.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <stdarg.h>
#include "Object.h" #include "Object.h"
#include "CRT.h" #include "CRT.h"
#include "ListItem.h" #include "ListItem.h"
#include "String.h" #include "String.h"
#include "ProcessList.h" #include "ProcessList.h"
#include "RichString.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
@ -96,10 +97,7 @@ typedef enum {
#include "TasksMeter.h" #include "TasksMeter.h"
#include "LoadAverageMeter.h" #include "LoadAverageMeter.h"
#include "UptimeMeter.h" #include "UptimeMeter.h"
#include "BatteryMeter.h"
#include "ClockMeter.h" #include "ClockMeter.h"
#include "HostnameMeter.h"
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))

View File

@ -79,7 +79,6 @@ static HandlerResult MetersPanel_EventHandler(Panel* super, int ch) {
} }
if (result == HANDLED) { if (result == HANDLED) {
Header* header = this->settings->header; Header* header = this->settings->header;
this->settings->changed = true;
Header_calculateHeight(header); Header_calculateHeight(header);
Header_draw(header); Header_draw(header);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2); ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);

View File

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

View File

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

63
Panel.c
View File

@ -94,9 +94,9 @@ void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner)
this->selected = 0; this->selected = 0;
this->oldSelected = 0; this->oldSelected = 0;
this->needsRedraw = true; this->needsRedraw = true;
RichString_prune(&(this->header)); this->header.len = 0;
if (String_eq(CRT_termType, "linux")) if (String_eq(CRT_termType, "linux"))
this->scrollHAmount = 20; this->scrollHAmount = 40;
else else
this->scrollHAmount = 5; this->scrollHAmount = 5;
} }
@ -213,7 +213,7 @@ int Panel_getSelectedIndex(Panel* this) {
return this->selected; return this->selected;
} }
int Panel_size(Panel* this) { int Panel_getSize(Panel* this) {
assert (this != NULL); assert (this != NULL);
return Vector_size(this->items); return Vector_size(this->items);
@ -326,74 +326,43 @@ void Panel_draw(Panel* this, bool focus) {
move(0, 0); move(0, 0);
} }
bool Panel_onKey(Panel* this, int key) { void Panel_onKey(Panel* this, int key) {
assert (this != NULL); assert (this != NULL);
switch (key) { switch (key) {
case KEY_DOWN: case KEY_DOWN:
if (this->selected + 1 < Vector_size(this->items)) if (this->selected + 1 < Vector_size(this->items))
this->selected++; this->selected++;
return true; break;
case KEY_UP: case KEY_UP:
if (this->selected > 0) if (this->selected > 0)
this->selected--; this->selected--;
return true; break;
#ifdef KEY_C_DOWN
case KEY_C_DOWN:
if (this->selected + 1 < Vector_size(this->items)) {
this->selected++;
if (this->scrollV < Vector_size(this->items) - this->h) {
this->scrollV++;
this->needsRedraw = true;
}
}
return true;
#endif
#ifdef KEY_C_UP
case KEY_C_UP:
if (this->selected > 0) {
this->selected--;
if (this->scrollV > 0) {
this->scrollV--;
this->needsRedraw = true;
}
}
return true;
#endif
case KEY_LEFT: case KEY_LEFT:
if (this->scrollH > 0) { if (this->scrollH > 0) {
this->scrollH -= 5; this->scrollH -= this->scrollHAmount;
this->needsRedraw = true; this->needsRedraw = true;
} }
return true; break;
case KEY_RIGHT: case KEY_RIGHT:
this->scrollH += 5; this->scrollH += this->scrollHAmount;
this->needsRedraw = true; this->needsRedraw = true;
return true; break;
case KEY_PPAGE: case KEY_PPAGE:
this->selected -= (this->h - 1); this->selected -= this->h;
this->scrollV -= (this->h - 1);
if (this->selected < 0) if (this->selected < 0)
this->selected = 0; this->selected = 0;
if (this->scrollV < 0) break;
this->scrollV = 0;
this->needsRedraw = true;
return true;
case KEY_NPAGE: case KEY_NPAGE:
this->selected += (this->h - 1); this->selected += this->h;
int size = Vector_size(this->items); int size = Vector_size(this->items);
if (this->selected >= size) if (this->selected >= size)
this->selected = size - 1; this->selected = size - 1;
this->scrollV += (this->h - 1); break;
if (this->scrollV >= MAX(0, size - this->h))
this->scrollV = MAX(0, size - this->h - 1);
this->needsRedraw = true;
return true;
case KEY_HOME: case KEY_HOME:
this->selected = 0; this->selected = 0;
return true; break;
case KEY_END: case KEY_END:
this->selected = Vector_size(this->items) - 1; this->selected = Vector_size(this->items) - 1;
return true; break;
} }
return false;
} }

View File

@ -104,12 +104,12 @@ void Panel_moveSelectedDown(Panel* this);
int Panel_getSelectedIndex(Panel* this); int Panel_getSelectedIndex(Panel* this);
int Panel_size(Panel* this); int Panel_getSize(Panel* this);
void Panel_setSelected(Panel* this, int selected); void Panel_setSelected(Panel* this, int selected);
void Panel_draw(Panel* this, bool focus); void Panel_draw(Panel* this, bool focus);
bool Panel_onKey(Panel* this, int key); void Panel_onKey(Panel* this, int key);
#endif #endif

View File

@ -28,16 +28,13 @@ in the source distribution for its full text.
#include <pwd.h> #include <pwd.h>
#include <sched.h> #include <sched.h>
#ifdef HAVE_PLPA
#include <plpa.h> #include <plpa.h>
#endif
// This works only with glibc 2.1+. On earlier versions // This works only with glibc 2.1+. On earlier versions
// the behavior is similar to have a hardcoded page size. // the behavior is similar to have a hardcoded page size.
#ifndef PAGE_SIZE #ifndef PAGE_SIZE
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) ) #define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
#endif #endif
#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )
#define PROCESS_COMM_LEN 300 #define PROCESS_COMM_LEN 300
@ -50,10 +47,7 @@ typedef enum ProcessField_ {
PROCESSOR, M_SIZE, M_RESIDENT, M_SHARE, M_TRS, M_DRS, M_LRS, M_DT, ST_UID, PERCENT_CPU, PERCENT_MEM, PROCESSOR, M_SIZE, M_RESIDENT, M_SHARE, M_TRS, M_DRS, M_LRS, M_DT, ST_UID, PERCENT_CPU, PERCENT_MEM,
USER, TIME, NLWP, TGID, USER, TIME, NLWP, TGID,
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
CTID, VPID, VEID, VPID,
#endif
#ifdef HAVE_VSERVER
VXID,
#endif #endif
#ifdef HAVE_TASKSTATS #ifdef HAVE_TASKSTATS
RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE, RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
@ -127,12 +121,9 @@ typedef struct Process_ {
float percent_mem; float percent_mem;
char* user; char* user;
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
unsigned int ctid; unsigned int veid;
unsigned int vpid; unsigned int vpid;
#endif #endif
#ifdef HAVE_VSERVER
unsigned int vxid;
#endif
#ifdef HAVE_TASKSTATS #ifdef HAVE_TASKSTATS
unsigned long long io_rchar; unsigned long long io_rchar;
unsigned long long io_wchar; unsigned long long io_wchar;
@ -166,10 +157,7 @@ char *Process_fieldNames[] = {
"M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM", "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM",
"USER", "TIME", "NLWP", "TGID", "USER", "TIME", "NLWP", "TGID",
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
"CTID", "VPID", "VEID", "VPID",
#endif
#ifdef HAVE_VSERVER
"VXID",
#endif #endif
#ifdef HAVE_TASKSTATS #ifdef HAVE_TASKSTATS
"RCHAR", "WCHAR", "SYSCR", "SYSCW", "RBYTES", "WBYTES", "CNCLWB", "RCHAR", "WCHAR", "SYSCR", "SYSCW", "RBYTES", "WBYTES", "CNCLWB",
@ -188,10 +176,7 @@ char *Process_fieldTitles[] = {
" CODE ", " DATA ", " LIB ", " DIRTY ", " UID ", "CPU% ", "MEM% ", " CODE ", " DATA ", " LIB ", " DIRTY ", " UID ", "CPU% ", "MEM% ",
"USER ", " TIME+ ", "NLWP ", " TGID ", "USER ", " TIME+ ", "NLWP ", " TGID ",
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
" CTID ", " VPID ", " VEID ", " VPID ",
#endif
#ifdef HAVE_VSERVER
" VXID ",
#endif #endif
#ifdef HAVE_TASKSTATS #ifdef HAVE_TASKSTATS
" RD_CHAR ", " WR_CHAR ", " RD_SYSC ", " WR_SYSC ", " IO_RD ", " IO_WR ", " IO_CANCEL ", " RD_CHAR ", " WR_CHAR ", " RD_SYSC ", " WR_SYSC ", " IO_RD ", " IO_WR ", " IO_CANCEL ",
@ -208,8 +193,8 @@ static int Process_getuid = -1;
static void Process_printLargeNumber(Process* this, RichString *str, unsigned long number) { static void Process_printLargeNumber(Process* this, RichString *str, unsigned long number) {
char buffer[11]; char buffer[11];
int len; int len;
if(number >= (10 * ONE_M)) { if(number >= (1000 * ONE_M)) {
len = snprintf(buffer, 10, "%3.1fG ", (float)number / ONE_M); len = snprintf(buffer, 10, "%4.2fG ", (float)number / ONE_M);
RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len); RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len);
} else if(number >= (100000)) { } else if(number >= (100000)) {
len = snprintf(buffer, 10, "%4ldM ", number / ONE_K); len = snprintf(buffer, 10, "%4ldM ", number / ONE_K);
@ -354,13 +339,13 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
: attr; : attr;
break; break;
} }
case M_DRS: Process_printLargeNumber(this, str, this->m_drs * PAGE_SIZE_KB); return; case M_DRS: Process_printLargeNumber(this, str, this->m_drs * PAGE_SIZE); return;
case M_DT: Process_printLargeNumber(this, str, this->m_dt * PAGE_SIZE_KB); return; case M_DT: Process_printLargeNumber(this, str, this->m_dt * PAGE_SIZE); return;
case M_LRS: Process_printLargeNumber(this, str, this->m_lrs * PAGE_SIZE_KB); return; case M_LRS: Process_printLargeNumber(this, str, this->m_lrs * PAGE_SIZE); return;
case M_TRS: Process_printLargeNumber(this, str, this->m_trs * PAGE_SIZE_KB); return; case M_TRS: Process_printLargeNumber(this, str, this->m_trs * PAGE_SIZE); return;
case M_SIZE: Process_printLargeNumber(this, str, this->m_size * 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_KB); 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_KB); 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 ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break;
case USER: { case USER: {
if (Process_getuid != this->st_uid) if (Process_getuid != this->st_uid)
@ -400,12 +385,9 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
break; break;
} }
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
case CTID: snprintf(buffer, n, "%5u ", this->ctid); break; case VEID: snprintf(buffer, n, "%5u ", this->veid); break;
case VPID: snprintf(buffer, n, "%5u ", this->vpid); break; case VPID: snprintf(buffer, n, "%5u ", this->vpid); break;
#endif #endif
#ifdef HAVE_VSERVER
case VXID: snprintf(buffer, n, "%5u ", this->vxid); break;
#endif
#ifdef HAVE_TASKSTATS #ifdef HAVE_TASKSTATS
case RCHAR: snprintf(buffer, n, "%10llu ", this->io_rchar); break; case RCHAR: snprintf(buffer, n, "%10llu ", this->io_rchar); break;
case WCHAR: snprintf(buffer, n, "%10llu ", this->io_wchar); break; case WCHAR: snprintf(buffer, n, "%10llu ", this->io_wchar); break;
@ -496,7 +478,6 @@ bool Process_setPriority(Process* this, int priority) {
return (err == 0); return (err == 0);
} }
#ifdef HAVE_PLPA
unsigned long Process_getAffinity(Process* this) { unsigned long Process_getAffinity(Process* this) {
unsigned long mask = 0; unsigned long mask = 0;
plpa_sched_getaffinity(this->pid, sizeof(unsigned long), (plpa_cpu_set_t*) &mask); plpa_sched_getaffinity(this->pid, sizeof(unsigned long), (plpa_cpu_set_t*) &mask);
@ -506,7 +487,6 @@ unsigned long Process_getAffinity(Process* this) {
bool Process_setAffinity(Process* this, unsigned long mask) { bool Process_setAffinity(Process* this, unsigned long mask) {
return (plpa_sched_setaffinity(this->pid, sizeof(unsigned long), (plpa_cpu_set_t*) &mask) == 0); return (plpa_sched_setaffinity(this->pid, sizeof(unsigned long), (plpa_cpu_set_t*) &mask) == 0);
} }
#endif
void Process_sendSignal(Process* this, int signal) { void Process_sendSignal(Process* this, int signal) {
kill(this->pid, signal); kill(this->pid, signal);
@ -535,13 +515,9 @@ int Process_compare(const void* v1, const void* v2) {
case PPID: case PPID:
return (p1->ppid - p2->ppid); return (p1->ppid - p2->ppid);
case USER: case USER:
return strcmp(p1->user ? p1->user : "", p2->user ? p2->user : ""); return strcmp(p1->user, p2->user);
case PRIORITY: case PRIORITY:
return (p1->priority - p2->priority); return (p1->priority - p2->priority);
case PROCESSOR:
return (p1->processor - p2->processor);
case SESSION:
return (p1->session - p2->session);
case STATE: case STATE:
return (p1->state - p2->state); return (p1->state - p2->state);
case NICE: case NICE:
@ -575,15 +551,11 @@ int Process_compare(const void* v1, const void* v2) {
case NLWP: case NLWP:
return (p1->nlwp - p2->nlwp); return (p1->nlwp - p2->nlwp);
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
case CTID: case VEID:
return (p1->ctid - p2->ctid); return (p1->veid - p2->veid);
case VPID: case VPID:
return (p1->vpid - p2->vpid); return (p1->vpid - p2->vpid);
#endif #endif
#ifdef HAVE_VSERVER
case VXID:
return (p1->vxid - p2->vxid);
#endif
#ifdef HAVE_TASKSTATS #ifdef HAVE_TASKSTATS
case RCHAR: diff = p2->io_rchar - p1->io_rchar; goto test_diff; 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 WCHAR: diff = p2->io_wchar - p1->io_wchar; goto test_diff;

View File

@ -31,16 +31,13 @@ in the source distribution for its full text.
#include <pwd.h> #include <pwd.h>
#include <sched.h> #include <sched.h>
#ifdef HAVE_PLPA
#include <plpa.h> #include <plpa.h>
#endif
// This works only with glibc 2.1+. On earlier versions // This works only with glibc 2.1+. On earlier versions
// the behavior is similar to have a hardcoded page size. // the behavior is similar to have a hardcoded page size.
#ifndef PAGE_SIZE #ifndef PAGE_SIZE
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) ) #define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
#endif #endif
#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )
#define PROCESS_COMM_LEN 300 #define PROCESS_COMM_LEN 300
@ -52,10 +49,7 @@ typedef enum ProcessField_ {
PROCESSOR, M_SIZE, M_RESIDENT, M_SHARE, M_TRS, M_DRS, M_LRS, M_DT, ST_UID, PERCENT_CPU, PERCENT_MEM, PROCESSOR, M_SIZE, M_RESIDENT, M_SHARE, M_TRS, M_DRS, M_LRS, M_DT, ST_UID, PERCENT_CPU, PERCENT_MEM,
USER, TIME, NLWP, TGID, USER, TIME, NLWP, TGID,
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
CTID, VPID, VEID, VPID,
#endif
#ifdef HAVE_VSERVER
VXID,
#endif #endif
#ifdef HAVE_TASKSTATS #ifdef HAVE_TASKSTATS
RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE, RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
@ -129,12 +123,9 @@ typedef struct Process_ {
float percent_mem; float percent_mem;
char* user; char* user;
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
unsigned int ctid; unsigned int veid;
unsigned int vpid; unsigned int vpid;
#endif #endif
#ifdef HAVE_VSERVER
unsigned int vxid;
#endif
#ifdef HAVE_TASKSTATS #ifdef HAVE_TASKSTATS
unsigned long long io_rchar; unsigned long long io_rchar;
unsigned long long io_wchar; unsigned long long io_wchar;
@ -175,11 +166,9 @@ void Process_toggleTag(Process* this);
bool Process_setPriority(Process* this, int priority); bool Process_setPriority(Process* this, int priority);
#ifdef HAVE_PLPA
unsigned long Process_getAffinity(Process* this); unsigned long Process_getAffinity(Process* this);
bool Process_setAffinity(Process* this, unsigned long mask); bool Process_setAffinity(Process* this, unsigned long mask);
#endif
void Process_sendSignal(Process* this, int signal); void Process_sendSignal(Process* this, int signal);

View File

@ -371,9 +371,7 @@ void ProcessList_sort(ProcessList* this) {
// Take PID 1 as root and add to the new listing // Take PID 1 as root and add to the new listing
int vsize = Vector_size(this->processes); int vsize = Vector_size(this->processes);
Process* init = (Process*) (Vector_take(this->processes, 0)); Process* init = (Process*) (Vector_take(this->processes, 0));
// This assertion crashes on hardened kernels. assert(init->pid == 1);
// I wonder how well tree view works on those systems.
// assert(init->pid == 1);
init->indent = 0; init->indent = 0;
Vector_add(this->processes2, init); Vector_add(this->processes2, init);
// Recursively empty list // Recursively empty list
@ -563,7 +561,13 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
process->pid = pid; process->pid = pid;
} }
} }
process->tgid = parent ? parent->pid : pid; if (parent) {
process->tgid = parent->pid;
}
#ifdef HAVE_TASKSTATS
ProcessList_readIoFile(this, process, dirname, name);
#endif
if (showUserlandThreads && (!parent || pid != parent->pid)) { if (showUserlandThreads && (!parent || pid != parent->pid)) {
char subdirname[MAX_NAME+1]; char subdirname[MAX_NAME+1];
@ -573,10 +577,6 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
continue; continue;
} }
#ifdef HAVE_TASKSTATS
ProcessList_readIoFile(this, process, dirname, name);
#endif
process->updated = true; process->updated = true;
if (!existingProcess) if (!existingProcess)
@ -621,7 +621,7 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
if (access("/proc/vz", R_OK) != 0) { if (access("/proc/vz", R_OK) != 0) {
process->vpid = process->pid; process->vpid = process->pid;
process->ctid = 0; process->veid = 0;
} else { } else {
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name); snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r"); status = ProcessList_fopen(this, statusfilename, "r");
@ -634,42 +634,8 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
"%*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", "%u %u",
&process->vpid, &process->ctid); &process->vpid, &process->veid);
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); fclose(status);
} }
#endif #endif
@ -696,7 +662,7 @@ static bool ProcessList_processEntries(ProcessList* this, char* dirname, Process
period * 100.0; period * 100.0;
process->percent_cpu = MAX(MIN(percent_cpu, processors*100.0), 0.0); process->percent_cpu = MAX(MIN(percent_cpu, processors*100.0), 0.0);
process->percent_mem = (process->m_resident * PAGE_SIZE_KB) / process->percent_mem = (process->m_resident * PAGE_SIZE) /
(float)(this->totalMem) * (float)(this->totalMem) *
100.0; 100.0;

2
README
View File

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

View File

@ -8,14 +8,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <curses.h>
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
#ifdef HAVE_LIBNCURSESW #ifdef HAVE_LIBNCURSESW
#include <curses.h> #include <wchar.h>
#else
#include <ncursesw/curses.h>
#endif #endif
#define RICHSTRING_MAXLEN 300 #define RICHSTRING_MAXLEN 300
@ -91,8 +89,7 @@ int RichString_findChar(RichString *this, char c, int start) {
inline void RichString_appendn(RichString* this, int attrs, char* data_c, int len) { inline void RichString_appendn(RichString* this, int attrs, char* data_c, int len) {
int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len); int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
for (int i = this->len, j = 0; i < last; i++, j++) for (int i = this->len, j = 0; i < last; i++, j++)
this->chstr[i] = (isprint(data_c[j]) ? data_c[j] : '?') | attrs; this->chstr[i] = data_c[j] | attrs;
this->chstr[last] = 0; this->chstr[last] = 0;
this->len = last; this->len = last;
} }
@ -117,10 +114,6 @@ int RichString_findChar(RichString *this, char c, int start) {
#endif #endif
void RichString_prune(RichString* this) {
this->len = 0;
}
void RichString_setAttr(RichString *this, int attrs) { void RichString_setAttr(RichString *this, int attrs) {
RichString_setAttrn(this, attrs, 0, this->len - 1); RichString_setAttrn(this, attrs, 0, this->len - 1);
} }

View File

@ -11,14 +11,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <curses.h>
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
#ifdef HAVE_LIBNCURSESW #ifdef HAVE_LIBNCURSESW
#include <curses.h> #include <wchar.h>
#else
#include <ncursesw/curses.h>
#endif #endif
#define RICHSTRING_MAXLEN 300 #define RICHSTRING_MAXLEN 300
@ -69,8 +67,6 @@ int RichString_findChar(RichString *this, char c, int start);
#endif #endif
void RichString_prune(RichString* this);
void RichString_setAttr(RichString *this, int attrs); void RichString_setAttr(RichString *this, int attrs);
extern void RichString_append(RichString* this, int attrs, char* data); extern void RichString_append(RichString* this, int attrs, char* data);

View File

@ -83,7 +83,7 @@ void ScreenManager_add(ScreenManager* this, Panel* item, FunctionBar* fuBar, int
if (fuBar) if (fuBar)
Vector_add(this->fuBars, fuBar); Vector_add(this->fuBars, fuBar);
else else
Vector_add(this->fuBars, FunctionBar_new(NULL, NULL, NULL)); Vector_add(this->fuBars, FunctionBar_new(0, NULL, NULL, NULL));
if (!this->fuBar && fuBar) this->fuBar = fuBar; if (!this->fuBar && fuBar) this->fuBar = fuBar;
item->needsRedraw = true; item->needsRedraw = true;
this->itemCount++; this->itemCount++;
@ -188,7 +188,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
if (focus > 0) if (focus > 0)
focus--; focus--;
panelFocus = (Panel*) Vector_get(this->items, focus); panelFocus = (Panel*) Vector_get(this->items, focus);
if (Panel_size(panelFocus) == 0 && focus > 0) if (Panel_getSize(panelFocus) == 0 && focus > 0)
goto tryLeft; goto tryLeft;
break; break;
case KEY_RIGHT: case KEY_RIGHT:
@ -197,7 +197,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
if (focus < this->itemCount - 1) if (focus < this->itemCount - 1)
focus++; focus++;
panelFocus = (Panel*) Vector_get(this->items, focus); panelFocus = (Panel*) Vector_get(this->items, focus);
if (Panel_size(panelFocus) == 0 && focus < this->itemCount - 1) if (Panel_getSize(panelFocus) == 0 && focus < this->itemCount - 1)
goto tryRight; goto tryRight;
break; break;
case KEY_F(10): case KEY_F(10):

View File

@ -23,7 +23,7 @@ typedef struct SignalsPanel_ {
static HandlerResult SignalsPanel_eventHandler(Panel* super, int ch) { static HandlerResult SignalsPanel_eventHandler(Panel* super, int ch) {
SignalsPanel* this = (SignalsPanel*) super; SignalsPanel* this = (SignalsPanel*) super;
int size = Panel_size(super); int size = Panel_getSize(super);
if (ch <= 255 && isdigit(ch)) { if (ch <= 255 && isdigit(ch)) {
int signal = ch-48 + this->state; int signal = ch-48 + this->state;

View File

@ -103,30 +103,3 @@ int String_contains_i(char* s, char* match) {
} }
return 0; return 0;
} }
char* String_getToken(const char* line, const unsigned short int numMatch) {
const unsigned short int len = strlen(line);
char inWord = 0;
unsigned short int count = 0;
char match[50];
unsigned short int foundCount = 0;
for (unsigned short int i = 0; i < len; i++) {
char lastState = inWord;
inWord = line[i] == ' ' ? 0:1;
if (lastState == 0 && inWord == 1)
count++;
if(inWord == 1){
if (count == numMatch && line[i] != ' ' && line[i] != '\0' && line[i] != '\n' && line[i] != EOF) {
match[foundCount] = line[i];
foundCount++;
}
}
}
match[foundCount] = '\0';
return((char*)strdup(match));
}

View File

@ -33,6 +33,4 @@ void String_freeArray(char** s);
int String_contains_i(char* s, char* match); int String_contains_i(char* s, char* match);
char* String_getToken(const char* line, const unsigned short int numMatch);
#endif #endif

View File

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

View File

@ -25,9 +25,9 @@ static void UptimeMeter_setValues(Meter* this, char* buffer, int len) {
fclose(fd); fclose(fd);
int totalseconds = (int) ceil(uptime); int totalseconds = (int) ceil(uptime);
int seconds = totalseconds % 60; int seconds = totalseconds % 60;
int minutes = (totalseconds/60) % 60; int minutes = (totalseconds-seconds) % 3600 / 60;
int hours = (totalseconds/3600) % 24; int hours = (totalseconds-seconds-(minutes*60)) % 86400 / 3600;
int days = (totalseconds/86400); int days = (totalseconds-seconds-(minutes*60)-(hours*3600)) / 86400;
this->values[0] = days; this->values[0] = days;
if (days > this->total) { if (days > this->total) {
this->total = days; this->total = days;

View File

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57) AC_PREREQ(2.57)
AC_INIT([htop],[0.8.2],[loderunner@users.sourceforge.net]) AC_INIT([htop],[0.8],[loderunner@users.sourceforge.net])
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([htop.c]) AC_CONFIG_SRCDIR([htop.c])
AC_CONFIG_HEADER([config.h]) AC_CONFIG_HEADER([config.h])
@ -69,17 +69,6 @@ if test "x$enable_openvz" = xyes; then
AC_DEFINE(HAVE_OPENVZ, 1, [Define if openvz support enabled.]) AC_DEFINE(HAVE_OPENVZ, 1, [Define if openvz support enabled.])
fi 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") 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 if test "x$enable_taskstats" = xyes; then
AC_DEFINE(HAVE_TASKSTATS, 1, [Define if taskstats support enabled.]) AC_DEFINE(HAVE_TASKSTATS, 1, [Define if taskstats support enabled.])
@ -88,10 +77,8 @@ fi
AC_ARG_ENABLE(unicode, [AC_HELP_STRING([--enable-unicode], [enable Unicode support])], ,enable_unicode="no") AC_ARG_ENABLE(unicode, [AC_HELP_STRING([--enable-unicode], [enable Unicode support])], ,enable_unicode="no")
if test "x$enable_unicode" = xyes; then if test "x$enable_unicode" = xyes; then
AC_CHECK_LIB([ncursesw], [refresh], [], [missing_libraries="$missing_libraries libncursesw"]) AC_CHECK_LIB([ncursesw], [refresh], [], [missing_libraries="$missing_libraries libncursesw"])
AC_CHECK_HEADERS([ncursesw/curses.h],[:],[missing_headers="$missing_headers $ac_header"])
else else
AC_CHECK_LIB([ncurses], [refresh], [], [missing_libraries="$missing_libraries libncurses"]) AC_CHECK_LIB([ncurses], [refresh], [], [missing_libraries="$missing_libraries libncurses"])
AC_CHECK_HEADERS([curses.h],[:],[missing_headers="$missing_headers $ac_header"])
fi fi
AC_CHECK_FILE($PROCDIR/stat,,AC_MSG_ERROR(Cannot find /proc/stat. Make sure you have a Linux-compatible /proc filesystem mounted. See the file README for help.)) AC_CHECK_FILE($PROCDIR/stat,,AC_MSG_ERROR(Cannot find /proc/stat. Make sure you have a Linux-compatible /proc filesystem mounted. See the file README for help.))
@ -99,9 +86,8 @@ AC_CHECK_FILE($PROCDIR/meminfo,,AC_MSG_ERROR(Cannot find /proc/meminfo. Make sur
PLPA_INCLUDED(plpa-1.1) PLPA_INCLUDED(plpa-1.1)
PLPA_INIT(plpa_happy=yes, plpa_happy=no) PLPA_INIT(plpa_happy=yes, plpa_happy=no)
AM_CONDITIONAL([HAVE_PLPA], [test "$plpa_happy" = "yes"]) if test "x$plpa_happy" = xno; then
if test "$plpa_happy" = "yes"; then AC_MSG_ERROR([Failed to initialize PLPA.])
AC_DEFINE([HAVE_PLPA], [1], [Have plpa])
fi fi
AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([Makefile])

21
htop.1
View File

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

94
htop.c
View File

@ -26,7 +26,6 @@ in the source distribution for its full text.
#include "CategoriesPanel.h" #include "CategoriesPanel.h"
#include "SignalsPanel.h" #include "SignalsPanel.h"
#include "TraceScreen.h" #include "TraceScreen.h"
#include "OpenFilesScreen.h"
#include "AffinityPanel.h" #include "AffinityPanel.h"
#include "config.h" #include "config.h"
@ -100,10 +99,8 @@ static void showHelp(ProcessList* pl) {
addattrstr(CRT_colors[BAR_BORDER], "]"); addattrstr(CRT_colors[BAR_BORDER], "]");
attrset(CRT_colors[DEFAULT_COLOR]); attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(6,0, "Type and layout of header meters are configurable in the setup screen."); mvaddstr(6,0, "Type and layout of header meters are configurable in the setup screen.");
if (CRT_colorScheme == COLORSCHEME_MONOCHROME) { mvaddstr(7, 0, "Status: R: running; S: sleeping; T: traced/stopped; Z: zombie; D: disk sleep");
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( 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(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(11, 0, " F3 /: incremental name search H: hide/show user threads");
@ -111,16 +108,14 @@ static void showHelp(ProcessList* pl) {
mvaddstr(13, 0, " Space: tag processes F: cursor follows process"); mvaddstr(13, 0, " Space: tag processes F: cursor follows process");
mvaddstr(14, 0, " U: untag all processes"); mvaddstr(14, 0, " U: untag all processes");
mvaddstr(15, 0, " F9 k: kill process/tagged processes P: sort by CPU%"); 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(16, 0, " + [ F7: lower priority (+ nice) M: sort by MEM%");
mvaddstr(17, 0, " + [ F8: lower priority (+ nice) T: sort by TIME"); mvaddstr(17, 0, " - ] F8: higher priority (root only) T: sort by TIME");
#ifdef HAVE_PLPA
if (pl->processorCount > 1) if (pl->processorCount > 1)
mvaddstr(18, 0, " a: set CPU affinity F4 I: invert sort order"); mvaddstr(18, 0, " a: set CPU affinity F4 I: invert sort order");
else else
#endif
mvaddstr(18, 0, " F4 I: invert sort order"); mvaddstr(18, 0, " F4 I: invert sort order");
mvaddstr(19, 0, " F2 S: setup F6 >: select sort column"); 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(20, 0, " F1 h: show this help screen");
mvaddstr(21, 0, " F10 q: quit s: trace syscalls with strace"); mvaddstr(21, 0, " F10 q: quit s: trace syscalls with strace");
attrset(CRT_colors[HELP_BOLD]); attrset(CRT_colors[HELP_BOLD]);
@ -134,12 +129,10 @@ static void showHelp(ProcessList* pl) {
mvaddstr(16, 0, " + [ F7"); mvaddstr(16,40, " M"); mvaddstr(16, 0, " + [ F7"); mvaddstr(16,40, " M");
mvaddstr(17, 0, " - ] F8"); mvaddstr(17,40, " T"); mvaddstr(17, 0, " - ] F8"); mvaddstr(17,40, " T");
mvaddstr(18,40, " F4 I"); mvaddstr(18,40, " F4 I");
#if HAVE_PLPA
if (pl->processorCount > 1) if (pl->processorCount > 1)
mvaddstr(18, 0, " a:"); mvaddstr(18, 0, " a:");
#endif
mvaddstr(19, 0, " F2 S"); mvaddstr(19,40, " F6 >"); mvaddstr(19, 0, " F2 S"); mvaddstr(19,40, " F6 >");
mvaddstr(20, 0, " F1 h"); mvaddstr(20,40, " l"); mvaddstr(20, 0, " F1 h");
mvaddstr(21, 0, " F10 q"); mvaddstr(21,40, " s"); mvaddstr(21, 0, " F10 q"); mvaddstr(21,40, " s");
attrset(CRT_colors[DEFAULT_COLOR]); attrset(CRT_colors[DEFAULT_COLOR]);
@ -156,7 +149,7 @@ static char* CategoriesFunctions[10] = {" ", " ", " ", " ",
static void Setup_run(Settings* settings, int headerHeight) { static void Setup_run(Settings* settings, int headerHeight) {
ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true); ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true);
CategoriesPanel* panelCategories = CategoriesPanel_new(settings, scr); CategoriesPanel* panelCategories = CategoriesPanel_new(settings, scr);
ScreenManager_add(scr, (Panel*) panelCategories, FunctionBar_new(CategoriesFunctions, NULL, NULL), 16); ScreenManager_add(scr, (Panel*) panelCategories, FunctionBar_new(10, CategoriesFunctions, NULL, NULL), 16);
CategoriesPanel_makeMetersPage(panelCategories); CategoriesPanel_makeMetersPage(panelCategories);
Panel* panelFocus; Panel* panelFocus;
int ch; int ch;
@ -167,7 +160,7 @@ static void Setup_run(Settings* settings, int headerHeight) {
static bool changePriority(Panel* panel, int delta) { static bool changePriority(Panel* panel, int delta) {
bool ok = true; bool ok = true;
bool anyTagged = false; bool anyTagged = false;
for (int i = 0; i < Panel_size(panel); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i); Process* p = (Process*) Panel_get(panel, i);
if (p->tag) { if (p->tag) {
ok = Process_setPriority(p, p->nice + delta) && ok; ok = Process_setPriority(p, p->nice + delta) && ok;
@ -189,13 +182,13 @@ static HandlerResult pickWithEnter(Panel* panel, int ch) {
return IGNORED; return IGNORED;
} }
static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, char** keyLabels, FunctionBar* prevBar) { static Object* pickFromList(Panel* panel, Panel* list, int x, int y, char** keyLabels, FunctionBar* prevBar) {
char* fuKeys[2] = {"Enter", "Esc"}; char* fuKeys[2] = {"Enter", "Esc"};
int fuEvents[2] = {13, 27}; int fuEvents[2] = {13, 27};
if (!list->eventHandler) if (!list->eventHandler)
Panel_setEventHandler(list, pickWithEnter); Panel_setEventHandler(list, pickWithEnter);
ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, false); ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, false);
ScreenManager_add(scr, list, FunctionBar_new(keyLabels, fuKeys, fuEvents), x - 1); ScreenManager_add(scr, list, FunctionBar_new(2, keyLabels, fuKeys, fuEvents), x - 1);
ScreenManager_add(scr, panel, NULL, -1); ScreenManager_add(scr, panel, NULL, -1);
Panel* panelFocus; Panel* panelFocus;
int ch; int ch;
@ -210,7 +203,7 @@ static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, char** ke
return NULL; return NULL;
} }
static void addUserToVector(int key, void* userCast, void* panelCast) { static void addUserToList(int key, void* userCast, void* panelCast) {
char* user = (char*) userCast; char* user = (char*) userCast;
Panel* panel = (Panel*) panelCast; Panel* panel = (Panel*) panelCast;
Panel_add(panel, (Object*) ListItem_new(user, key)); Panel_add(panel, (Object*) ListItem_new(user, key));
@ -275,9 +268,6 @@ int main(int argc, char** argv) {
if (arg == argc - 1) printHelpFlag(); if (arg == argc - 1) printHelpFlag();
arg++; arg++;
setUserOnly(argv[arg], &userOnly, &userId); setUserOnly(argv[arg], &userOnly, &userId);
} else {
fprintf(stderr, "Error: unknown flag: %s\n", argv[arg]);
exit(1);
} }
arg++; arg++;
} }
@ -292,7 +282,6 @@ int main(int argc, char** argv) {
int refreshTimeout = 0; int refreshTimeout = 0;
int resetRefreshTimeout = 5; int resetRefreshTimeout = 5;
bool doRefresh = true; bool doRefresh = true;
bool doRecalculate = false;
Settings* settings; Settings* settings;
Panel* killPanel = NULL; Panel* killPanel = NULL;
@ -325,14 +314,14 @@ int main(int argc, char** argv) {
} }
Panel_setRichHeader(panel, ProcessList_printHeader(pl)); Panel_setRichHeader(panel, ProcessList_printHeader(pl));
char* searchFunctions[] = {"Next ", "Exit ", " Search: ", NULL}; char* searchFunctions[3] = {"Next ", "Exit ", " Search: "};
char* searchKeys[] = {"F3", "Esc", " "}; char* searchKeys[3] = {"F3", "Esc", " "};
int searchEvents[] = {KEY_F(3), 27, ERR}; int searchEvents[3] = {KEY_F(3), 27, ERR};
FunctionBar* searchBar = FunctionBar_new(searchFunctions, searchKeys, searchEvents); FunctionBar* searchBar = FunctionBar_new(3, searchFunctions, searchKeys, searchEvents);
char* defaultFunctions[] = {"Help ", "Setup ", "Search", "Invert", "Tree ", char* defaultFunctions[10] = {"Help ", "Setup ", "Search", "Invert", "Tree ",
"SortBy", "Nice -", "Nice +", "Kill ", "Quit ", NULL}; "SortBy", "Nice -", "Nice +", "Kill ", "Quit "};
FunctionBar* defaultBar = FunctionBar_new(defaultFunctions, NULL, NULL); FunctionBar* defaultBar = FunctionBar_new(10, defaultFunctions, NULL, NULL);
ProcessList_scan(pl); ProcessList_scan(pl);
usleep(75000); usleep(75000);
@ -357,15 +346,15 @@ int main(int argc, char** argv) {
if (recalculate) if (recalculate)
oldTime = newTime; oldTime = newTime;
if (doRefresh) { if (doRefresh) {
incSearchIndex = 0;
incSearchBuffer[0] = 0;
int currPos = Panel_getSelectedIndex(panel); int currPos = Panel_getSelectedIndex(panel);
unsigned int currPid = 0; unsigned int currPid = 0;
int currScrollV = panel->scrollV; int currScrollV = panel->scrollV;
if (follow) if (follow)
currPid = ProcessList_get(pl, currPos)->pid; currPid = ProcessList_get(pl, currPos)->pid;
if (recalculate || doRecalculate) { if (recalculate)
ProcessList_scan(pl); ProcessList_scan(pl);
doRecalculate = false;
}
if (refreshTimeout == 0) { if (refreshTimeout == 0) {
ProcessList_sort(pl); ProcessList_sort(pl);
refreshTimeout = 1; refreshTimeout = 1;
@ -431,6 +420,8 @@ int main(int argc, char** argv) {
incSearchBuffer[incSearchIndex] = 0; incSearchBuffer[incSearchIndex] = 0;
} else { } else {
incSearchMode = false; incSearchMode = false;
incSearchIndex = 0;
incSearchBuffer[0] = 0;
FunctionBar_draw(defaultBar, NULL); FunctionBar_draw(defaultBar, NULL);
continue; continue;
} }
@ -516,7 +507,7 @@ int main(int argc, char** argv) {
} }
case 'U': case 'U':
{ {
for (int i = 0; i < Panel_size(panel); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i); Process* p = (Process*) Panel_get(panel, i);
p->tag = false; p->tag = false;
} }
@ -562,17 +553,6 @@ int main(int argc, char** argv) {
CRT_enableDelay(); CRT_enableDelay();
break; break;
} }
case 'l':
{
OpenFilesScreen* ts = OpenFilesScreen_new((Process*) Panel_getSelected(panel));
OpenFilesScreen_run(ts);
OpenFilesScreen_delete(ts);
clear();
FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0;
CRT_enableDelay();
break;
}
case 'S': case 'S':
case 'C': case 'C':
case KEY_F(2): case KEY_F(2):
@ -596,12 +576,12 @@ int main(int argc, char** argv) {
{ {
Panel* usersPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare); Panel* usersPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare);
Panel_setHeader(usersPanel, "Show processes of:"); Panel_setHeader(usersPanel, "Show processes of:");
UsersTable_foreach(ut, addUserToVector, usersPanel); UsersTable_foreach(ut, addUserToList, usersPanel);
Vector_sort(usersPanel->items); Vector_sort(usersPanel->items);
ListItem* allUsers = ListItem_new("All users", -1); ListItem* allUsers = ListItem_new("All users", -1);
Panel_insert(usersPanel, 0, (Object*) allUsers); Panel_insert(usersPanel, 0, (Object*) allUsers);
char* fuFunctions[] = {"Show ", "Cancel ", NULL}; char* fuFunctions[2] = {"Show ", "Cancel "};
ListItem* picked = (ListItem*) pickFromVector(panel, usersPanel, 20, headerHeight, fuFunctions, defaultBar); ListItem* picked = (ListItem*) pickFromList(panel, usersPanel, 20, headerHeight, fuFunctions, defaultBar);
if (picked) { if (picked) {
if (picked == allUsers) { if (picked == allUsers) {
userOnly = false; userOnly = false;
@ -619,15 +599,15 @@ int main(int argc, char** argv) {
killPanel = (Panel*) SignalsPanel_new(0, 0, 0, 0); killPanel = (Panel*) SignalsPanel_new(0, 0, 0, 0);
} }
SignalsPanel_reset((SignalsPanel*) killPanel); SignalsPanel_reset((SignalsPanel*) killPanel);
char* fuFunctions[] = {"Send ", "Cancel ", NULL}; char* fuFunctions[2] = {"Send ", "Cancel "};
Signal* signal = (Signal*) pickFromVector(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar); Signal* signal = (Signal*) pickFromList(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar);
if (signal) { if (signal) {
if (signal->number != 0) { if (signal->number != 0) {
Panel_setHeader(panel, "Sending..."); Panel_setHeader(panel, "Sending...");
Panel_draw(panel, true); Panel_draw(panel, true);
refresh(); refresh();
bool anyTagged = false; bool anyTagged = false;
for (int i = 0; i < Panel_size(panel); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i); Process* p = (Process*) Panel_get(panel, i);
if (p->tag) { if (p->tag) {
Process_sendSignal(p, signal->number); Process_sendSignal(p, signal->number);
@ -645,7 +625,6 @@ int main(int argc, char** argv) {
refreshTimeout = 0; refreshTimeout = 0;
break; break;
} }
#ifdef HAVE_PLPA
case 'a': case 'a':
{ {
if (pl->processorCount == 1) if (pl->processorCount == 1)
@ -657,12 +636,12 @@ int main(int argc, char** argv) {
Panel* affinityPanel = AffinityPanel_new(pl->processorCount, curr); Panel* affinityPanel = AffinityPanel_new(pl->processorCount, curr);
char* fuFunctions[2] = {"Set ", "Cancel "}; char* fuFunctions[2] = {"Set ", "Cancel "};
void* set = pickFromVector(panel, affinityPanel, 15, headerHeight, fuFunctions, defaultBar); void* set = pickFromList(panel, affinityPanel, 15, headerHeight, fuFunctions, defaultBar);
if (set) { if (set) {
unsigned long new = AffinityPanel_getAffinity(affinityPanel); unsigned long new = AffinityPanel_getAffinity(affinityPanel);
bool anyTagged = false; bool anyTagged = false;
bool ok = true; bool ok = true;
for (int i = 0; i < Panel_size(panel); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i); Process* p = (Process*) Panel_get(panel, i);
if (p->tag) { if (p->tag) {
ok = Process_setAffinity(p, new) && ok; ok = Process_setAffinity(p, new) && ok;
@ -681,7 +660,6 @@ int main(int argc, char** argv) {
refreshTimeout = 0; refreshTimeout = 0;
break; break;
} }
#endif
case KEY_F(10): case KEY_F(10):
case 'q': case 'q':
quit = 1; quit = 1;
@ -704,7 +682,7 @@ int main(int argc, char** argv) {
Panel_setSelected(sortPanel, i); Panel_setSelected(sortPanel, i);
free(name); free(name);
} }
ListItem* field = (ListItem*) pickFromVector(panel, sortPanel, 15, headerHeight, fuFunctions, defaultBar); ListItem* field = (ListItem*) pickFromList(panel, sortPanel, 15, headerHeight, fuFunctions, defaultBar);
if (field) { if (field) {
settings->changed = true; settings->changed = true;
setSortKey(pl, field->key, panel, settings); setSortKey(pl, field->key, panel, settings);
@ -740,10 +718,8 @@ int main(int argc, char** argv) {
} }
case KEY_F(3): case KEY_F(3):
case '/': case '/':
incSearchIndex = 0;
incSearchBuffer[0] = 0;
incSearchMode = true;
FunctionBar_draw(searchBar, incSearchBuffer); FunctionBar_draw(searchBar, incSearchBuffer);
incSearchMode = true;
break; break;
case 't': case 't':
case KEY_F(5): case KEY_F(5):
@ -752,14 +728,12 @@ int main(int argc, char** argv) {
settings->changed = true; settings->changed = true;
break; break;
case 'H': case 'H':
doRecalculate = true;
refreshTimeout = 0; refreshTimeout = 0;
pl->hideUserlandThreads = !pl->hideUserlandThreads; pl->hideUserlandThreads = !pl->hideUserlandThreads;
pl->hideThreads = pl->hideUserlandThreads; pl->hideThreads = pl->hideUserlandThreads;
settings->changed = true; settings->changed = true;
break; break;
case 'K': case 'K':
doRecalculate = true;
refreshTimeout = 0; refreshTimeout = 0;
pl->hideKernelThreads = !pl->hideKernelThreads; pl->hideKernelThreads = !pl->hideKernelThreads;
settings->changed = true; settings->changed = true;

View File

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

1
htop.h
View File

@ -30,7 +30,6 @@ in the source distribution for its full text.
#include "CategoriesPanel.h" #include "CategoriesPanel.h"
#include "SignalsPanel.h" #include "SignalsPanel.h"
#include "TraceScreen.h" #include "TraceScreen.h"
#include "OpenFilesScreen.h"
#include "AffinityPanel.h" #include "AffinityPanel.h"
#include "config.h" #include "config.h"