Commit d6231bab authored by Hisham Muhammad's avatar Hisham Muhammad
Browse files

Initial import.

parents
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT([htop],[UNRELEASED-2006.01.12],[loderunner@users.sourceforge.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([htop.c])
AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
AC_CHECK_LIB([ncurses], [refresh])
AC_CHECK_LIB([m], [ceil])
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h curses.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_CONST
AC_TYPE_PID_T
AC_TYPE_UID_T
# Checks for library functions.
AC_FUNC_CLOSEDIR_VOID
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_TYPE_SIGNAL
AC_FUNC_STAT
AC_CHECK_FUNCS([memmove strncasecmp strstr strdup])
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.]))
PROCDIR=/proc
AC_ARG_WITH(proc, [ --with-proc=DIR Location of a Linux-compatible proc filesystem (default=/proc).],
if test -n "$withval"; then
AC_DEFINE_UNQUOTED(PROCDIR, "$withval", [Path of proc filesystem])
fi,
AC_DEFINE(PROCDIR, "/proc", [Path of proc filesystem]))
AC_CHECK_FILE(/proc/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(/proc/meminfo,,AC_MSG_ERROR(Cannot find /proc/meminfo. Make sure you have a Linux-compatible /proc filesystem mounted. See the file README for help.))
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
#ifdef DEBUG
#include "DebugMemory.h"
#define calloc(a, b) DebugMemory_calloc(a, b, __FILE__, __LINE__);
#define malloc(x) DebugMemory_malloc(x, __FILE__, __LINE__);
#define realloc(x,s) DebugMemory_realloc(x, s, __FILE__, __LINE__);
#define strdup(x) DebugMemory_strdup(x, __FILE__, __LINE__);
#define free(x) DebugMemory_free(x, __FILE__, __LINE__);
#define debug_done() DebugMemory_report();
#endif
#ifndef DEBUG
#define NDEBUG
#define debug_done() sleep(0)
#endif
.TH "htop" "1" "0.6" "Bartosz Fenski <fenio@o2.pl>" "Utils"
.SH "NAME"
htop \- interactive process viewer
.SH "SYNTAX"
.LP
.B htop
.SH "DESCRIPTION"
.LP
This program is a free (GPL) ncurses-based process viewer.
.LP
It is similar to top, but allows to scroll the list vertically and
horizontally to see all processes and their full command lines.
.LP
Tasks related to processes (killing, renicing) can be done without
entering their PIDs.
.br
.SH "INTERACTIVE COMMANDS"
.LP
The following commands are supported:
.LP
.TP 5
.B Arrows, PgUP, PgDn, Home, End
Scroll process list.
.TP
.B Space
"Tag": mark a process. Commands that can operate on multiple processes,
like "kill", will then apply over the list of tagged processes, instead
of the currently highlighted one.
.TP
.B U
"Untag" all processes (remove all tags added with the Space key).
.TP
.B s
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 F1, h
Help screen
.TP
.B F2, S
Setup screen. There you can configure meters displayed on the top side
of the screen, as well as set various display options, choose among
color schemes and select the layout of the displayed columns.
.TP
.B F3, /
Incremental process search: type in part of a process command line and
the selection highlight will be moved to it. While in search mode,
pressing this key will cycle through matching occurrences.
.TP
.B F4, I
Invert sort order: if sort order is increasing, switch to decreasing,
and vice-versa.
.TP
.B F5, t
Tree view: organize processes by parenthood, and layout the relations
between them as a tree. Toggling the key will switch between tree and
your previously selected sort view. Selecting a sort view will exit
tree view.
.TP
.B F6, >
Select field for sorting. The sort field is indicated by a
highlight in the header.
.TP
.B F7, ], -
Increase selected process priority (subtract from 'nice' value).
This can be done by the superuser only.
.TP
.B F8, [, +
Decrease selected process priority (add to 'nice' value)
.TP
.B F9, k
"Kill" process: sends a signal which is selected in a menu, to one or a group
of processes. If processes were tagged, sends the signal to all tagged processes.
If none is tagged, sends to the currently selected process.
.TP
.B F10, q
Quit
.TP
.B u
Show only processes owned by a specified user.
.TP
.B M
Sort by memory usage (top compatibility key).
.TP
.B P
Sort by processor usage (top compatibility key).
.TP
.B T
Sort by time (top compatibility key).
.TP
.B F
"Follow" process: if the sort order causes the currently selected process
to move in the list, make the selection bar follow it. This is useful for
monitoring a process: this way, you can keep a process always visible on
screen. When a movement key is used, "follow" loses effect.
.TP
.B K
Hide kernel threads: prevent the threads belonging the kernel to be
displayed in the process list. (This is a toggle key.)
.TP
.B H
Hide user threads: on systems that represent them differently than ordinary
processes (such as recent NPTL-based systems), this can hide threads from
userspace processes in the process list. (This is a toggle key.)
.TP
.B Ctrl-L
Refresh: redraw screen and recalculate values.
.TP
.B Numbers
PID search: type in process ID and the selection highlight will be moved to it.
.PD
.SH "AUTHORS"
.LP
htop is developed by Hisham Muhammad <lode@gobolinux.org>.
.br
This man page was written by Bartosz Fenski <fenio@o2.pl> for the
Debian GNU/Linux distribution (but it may be used by others), and
updated by Hisham Muhammad.
/*
htop - htop.c
(C) 2004,2005 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <math.h>
#include <sys/param.h>
#include <ctype.h>
#include <stdbool.h>
#include "ProcessList.h"
#include "CRT.h"
#include "ListBox.h"
#include "UsersTable.h"
#include "SignalItem.h"
#include "RichString.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "FunctionBar.h"
#include "ListItem.h"
#include "CategoriesListBox.h"
#include "SignalsListBox.h"
#include "TraceScreen.h"
#include "config.h"
#include "debug.h"
//#link m
#define INCSEARCH_MAX 40
/* private property */
char htop_barCharacters[] = "|#*@$%&";
void printVersionFlag() {
clear();
printf("htop " VERSION " - (C) 2004,2005 Hisham Muhammad.\n");
printf("Released under the GNU GPL.\n\n");
exit(0);
}
void printHelpFlag() {
clear();
printf("htop " VERSION " - (C) 2004,2005 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");
printf("Press F1 inside htop for online help.\n");
printf("See the man page for full information.\n\n");
exit(0);
}
void showHelp() {
clear();
attrset(CRT_colors[HELP_BOLD]);
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], "[");
addattrstr(CRT_colors[CPU_NICE], "low-priority"); addstr("/");
addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/");
addattrstr(CRT_colors[CPU_KERNEL], "kernel");
addattrstr(CRT_colors[BAR_SHADOW], " used%");
addattrstr(CRT_colors[BAR_BORDER], "]");
attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(4, 0, "Memory bar: ");
addattrstr(CRT_colors[BAR_BORDER], "[");
addattrstr(CRT_colors[MEMORY_USED], "used"); addstr("/");
addattrstr(CRT_colors[MEMORY_BUFFERS], "buffers"); addstr("/");
addattrstr(CRT_colors[MEMORY_CACHE], "cache");
addattrstr(CRT_colors[BAR_SHADOW], " used/total");
addattrstr(CRT_colors[BAR_BORDER], "]");
attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(5, 0, "Swap bar: ");
addattrstr(CRT_colors[BAR_BORDER], "[");
addattrstr(CRT_colors[SWAP], "used");
addattrstr(CRT_colors[BAR_SHADOW], " used/total");
addattrstr(CRT_colors[BAR_BORDER], "]");
attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(6,0, "Type and layout of header meters is configurable in the setup screen.");
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( 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]);
mvaddstr(23,0, "Press any key to return.");
attrset(CRT_colors[DEFAULT_COLOR]);
refresh();
CRT_readKey();
clear();
}
static void Setup_run(Settings* settings, int headerHeight) {
ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true);
CategoriesListBox* lbCategories = CategoriesListBox_new(settings, scr);
ScreenManager_add(scr, (ListBox*) lbCategories, NULL, 16);
CategoriesListBox_makeMetersPage(lbCategories);
ListBox* lbFocus;
int ch;
ScreenManager_run(scr, &lbFocus, &ch);
ScreenManager_delete(scr);
}
static bool changePriority(ListBox* lb, int delta) {
bool anyTagged = false;
for (int i = 0; i < ListBox_getSize(lb); i++) {
Process* p = (Process*) ListBox_get(lb, i);
if (p->tag) {
Process_setPriority(p, p->nice + delta);
anyTagged = true;
}
}
if (!anyTagged) {
Process* p = (Process*) ListBox_getSelected(lb);
Process_setPriority(p, p->nice + delta);
}
return anyTagged;
}
static HandlerResult pickWithEnter(ListBox* lb, int ch) {
if (ch == 13)
return BREAK_LOOP;
return IGNORED;
}
static Object* pickFromList(ListBox* lb, ListBox* list, int x, int y, char** keyLabels, FunctionBar* prevBar) {
char* fuKeys[2] = {"Enter", "Esc"};
int fuEvents[2] = {13, 27};
if (!lb->eventHandler)
ListBox_setEventHandler(list, pickWithEnter);
ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, false);
ScreenManager_add(scr, list, FunctionBar_new(2, keyLabels, fuKeys, fuEvents), x - 1);
ScreenManager_add(scr, lb, NULL, -1);
ListBox* lbFocus;
int ch;
ScreenManager_run(scr, &lbFocus, &ch);
ScreenManager_delete(scr);
ListBox_move(lb, 0, y);
ListBox_resize(lb, COLS, LINES-y-1);
FunctionBar_draw(prevBar, NULL);
if (lbFocus == list && ch == 13) {
return ListBox_getSelected(list);
}
return NULL;
}
void addUserToList(int key, void* userCast, void* lbCast) {
char* user = (char*) userCast;
ListBox* lb = (ListBox*) lbCast;
ListBox_add(lb, (Object*) ListItem_new(user, key));
}
void setUserOnly(const char* userName, bool* userOnly, uid_t* userId) {
struct passwd* user = getpwnam(userName);
if (user) {
*userOnly = true;
*userId = user->pw_uid;
}
}
int main(int argc, char** argv) {
int delay = -1;
bool userOnly = false;
uid_t userId = 0;
if (argc > 0) {
if (String_eq(argv[1], "--help")) {
printHelpFlag();
} else if (String_eq(argv[1], "--version")) {
printVersionFlag();
} 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[1], "-u")) {
if (argc < 2) printHelpFlag();
setUserOnly(argv[2], &userOnly, &userId);
}
}
ListBox* lb;
int quit = 0;
int refreshTimeout = 0;
int resetRefreshTimeout = 5;
bool doRefresh = true;
Settings* settings;
ListBox* lbk = NULL;
char incSearchBuffer[INCSEARCH_MAX];
int incSearchIndex = 0;
incSearchBuffer[0] = 0;
bool incSearchMode = false;
ProcessList* pl = NULL;
UsersTable* ut = UsersTable_new();
pl = ProcessList_new(ut);
Header* header = Header_new(pl);
settings = Settings_new(pl, header);
int headerHeight = Header_calculateHeight(header);
// FIXME: move delay code to settings
if (delay != -1)
settings->delay = delay;
CRT_init(settings->delay, settings->colorScheme);
lb = ListBox_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false);
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
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[10] = {"Help ", "Setup ", "Search", "Invert", "Tree ",
"SortBy", "Nice -", "Nice +", "Kill ", "Quit "};
FunctionBar* defaultBar = FunctionBar_new(10, defaultFunctions, NULL, NULL);
ProcessList_scan(pl);
usleep(75000);
FunctionBar_draw(defaultBar, NULL);
int acc = 0;
bool follow = false;
struct timeval tv;
double newTime = 0.0;
double oldTime = 0.0;
bool recalculate;
int ch = 0;
int closeTimeout = 0;
while (!quit) {
gettimeofday(&tv, NULL);
newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000);
recalculate = (newTime - oldTime > CRT_delay);
if (recalculate)
oldTime = newTime;
if (doRefresh) {
incSearchIndex = 0;
incSearchBuffer[0] = 0;
int currPos = ListBox_getSelectedIndex(lb);
int currPid = 0;
int currScrollV = lb->scrollV;
if (follow)
currPid = ProcessList_get(pl, currPos)->pid;
if (recalculate)
ProcessList_scan(pl);
if (refreshTimeout == 0) {
ProcessList_sort(pl);
refreshTimeout = 1;
}
ListBox_prune(lb);
int size = ProcessList_size(pl);
int lbi = 0;
for (int i = 0; i < size; i++) {
Process* p = ProcessList_get(pl, i);
if (!userOnly || (p->st_uid == userId)) {
ListBox_set(lb, lbi, (Object*)p);
if ((!follow && lbi == currPos) || (follow && p->pid == currPid)) {
ListBox_setSelected(lb, lbi);
lb->scrollV = currScrollV;
}
lbi++;
}
}
}
doRefresh = true;
Header_draw(header);
ListBox_draw(lb, true);
int prev = ch;
ch = getch();
if (ch == ERR) {
if (!incSearchMode)
refreshTimeout--;
if (prev == ch && !recalculate) {
closeTimeout++;
if (closeTimeout == 10)
break;
} else
closeTimeout = 0;
continue;
}
if (incSearchMode) {
doRefresh = false;
if (ch == KEY_F(3)) {
int here = ListBox_getSelectedIndex(lb);
int size = ProcessList_size(pl);
int i = here+1;
while (i != here) {
if (i == size)
i = 0;
Process* p = ProcessList_get(pl, i);
if (String_contains_i(p->comm, incSearchBuffer)) {
ListBox_setSelected(lb, i);
break;
}
i++;
}
continue;
} else if (isprint((char)ch) && (incSearchIndex < INCSEARCH_MAX)) {
incSearchBuffer[incSearchIndex] = ch;
incSearchIndex++;
incSearchBuffer[incSearchIndex] = 0;
} else if ((ch == KEY_BACKSPACE || ch == 127) && (incSearchIndex > 0)) {
incSearchIndex--;
incSearchBuffer[incSearchIndex] = 0;
} else {
incSearchMode = false;
incSearchIndex = 0;
incSearchBuffer[0] = 0;
FunctionBar_draw(defaultBar, NULL);
continue;
}
bool found = false;
for (int i = 0; i < ProcessList_size(pl); i++) {
Process* p = ProcessList_get(pl, i);
if (String_contains_i(p->comm, incSearchBuffer)) {
ListBox_setSelected(lb, i);
found = true;
break;
}
}
if (found)
FunctionBar_draw(searchBar, incSearchBuffer);
else
FunctionBar_drawAttr(searchBar, incSearchBuffer, CRT_colors[FAILED_SEARCH]);
continue;
}
if (isdigit((char)ch)) {
int pid = ch-48 + acc;
for (int i = 0; i < ProcessList_size(pl) && ((Process*) ListBox_getSelected(lb))->pid != pid; i++)
ListBox_setSelected(lb, i);
acc = pid * 10;
if (acc > 100000)
acc = 0;
continue;
} else {
acc = 0;
}
if (ch == KEY_MOUSE) {
MEVENT mevent;
int ok = getmouse(&mevent);
if (ok == OK) {
if (mevent.y >= lb->y + 1 && mevent.y < LINES - 1) {
ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV - 1);
doRefresh = false;
refreshTimeout = resetRefreshTimeout;
follow = true;
continue;
} if (mevent.y == LINES - 1) {
FunctionBar* bar;
if (incSearchMode) bar = searchBar;
else bar = defaultBar;
ch = FunctionBar_synthesizeEvent(bar, mevent.x);
}
}
}
switch (ch) {
case KEY_RESIZE:
ListBox_resize(lb, COLS, LINES-headerHeight-1);
if (incSearchMode)
FunctionBar_draw(searchBar, incSearchBuffer);
else
FunctionBar_draw(defaultBar, NULL);
break;
case 'M':
{
refreshTimeout = 0;
pl->sortKey = PERCENT_MEM;
pl->treeView = false;
settings->changed = true;
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
break;
}
case 'T':
{
refreshTimeout = 0;
pl->sortKey = TIME;
pl->treeView = false;
settings->changed = true;
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
break;
}
case 'U':
{
for (int i = 0; i < ListBox_getSize(lb); i++) {
Process* p = (Process*) ListBox_get(lb, i);
p->tag = false;
}
doRefresh = true;
break;
}
case 'P':
{
refreshTimeout = 0;
pl->sortKey = PERCENT_CPU;
pl->treeView = false;
settings->changed = true;
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
break;
}
case KEY_F(1):
case 'h':
{
showHelp();
FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0;
break;
}
case '\014': // Ctrl+L
{
clear();
FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0;
break;
}
case ' ':
{
Process* p = (Process*) ListBox_getSelected(lb);
Process_toggleTag(p);
ListBox_onKey(lb, KEY_DOWN);
break;
}
case 's':
{
TraceScreen* ts = TraceScreen_new((Process*) ListBox_getSelected(lb));
TraceScreen_run(ts);
TraceScreen_delete(ts);
clear();
FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0;
CRT_enableDelay();
break;
}
case 'S':
case 'C':
case KEY_F(2):
{
Setup_run(settings, headerHeight);
// TODO: shouldn't need this, colors should be dynamic
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
headerHeight = Header_calculateHeight(header);
ListBox_move(lb, 0, headerHeight);
ListBox_resize(lb, COLS, LINES-headerHeight-1);
FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0;
break;
}
case 'F':
{
follow = true;
continue;
}
case 'u':
{
ListBox* lbu = ListBox_new(0, 0, 0, 0, LISTITEM_CLASS, true);
ListBox_setHeader(lbu, "Show processes of:");
UsersTable_foreach(ut, addUserToList, lbu);
TypedVector_sort(lbu->items);
ListItem* allUsers = ListItem_new("All users", -1);
ListBox_insert(lbu, 0, (Object*) allUsers);
char* fuFunctions[2] = {"Show ", "Cancel "};
ListItem* picked = (ListItem*) pickFromList(lb, lbu, 20, headerHeight, fuFunctions, defaultBar);
if (picked) {
if (picked == allUsers) {
userOnly = false;
break;
} else {
setUserOnly(ListItem_getRef(picked), &userOnly, &userId);
}
}
break;
}
case KEY_F(9):
case 'k':
{
if (!lbk) {
lbk = (ListBox*) SignalsListBox_new(0, 0, 0, 0);
}
SignalsListBox_reset((SignalsListBox*) lbk);
char* fuFunctions[2] = {"Send ", "Cancel "};
Signal* signal = (Signal*) pickFromList(lb, lbk, 15, headerHeight, fuFunctions, defaultBar);
if (signal) {
if (signal->number != 0) {
ListBox_setHeader(lb, "Sending...");
ListBox_draw(lb, true);
refresh();
bool anyTagged = false;
for (int i = 0; i < ListBox_getSize(lb); i++) {
Process* p = (Process*) ListBox_get(lb, i);
if (p->tag) {
Process_sendSignal(p, signal->number);
Process_toggleTag(p);
anyTagged = true;
}
}
if (!anyTagged) {
Process* p = (Process*) ListBox_getSelected(lb);
Process_sendSignal(p, signal->number);
}
napms(500);
}
}
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
refreshTimeout = 0;
break;
}
case KEY_F(10):
case 'q':
quit = 1;
break;
case '<':
case ',':
case KEY_F(18):
case '>':
case '.':
case KEY_F(6):
{
ListBox* lbf = ListBox_new(0,0,0,0,LISTITEM_CLASS,true);
ListBox_setHeader(lbf, "Sort by");
char* fuFunctions[2] = {"Sort ", "Cancel "};
ProcessField* fields = pl->fields;
for (int i = 0; fields[i]; i++) {
char* name = String_trim(Process_printField(fields[i]));
ListBox_add(lbf, (Object*) ListItem_new(name, fields[i]));
if (fields[i] == pl->sortKey)
ListBox_setSelected(lbf, i);
free(name);
}
ListItem* field = (ListItem*) pickFromList(lb, lbf, 15, headerHeight, fuFunctions, defaultBar);
if (field) {
pl->treeView = false;
settings->changed = true;
pl->sortKey = field->key;
}
((Object*)lbf)->delete((Object*)lbf);
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
refreshTimeout = 0;
break;
}
case 'I':
case KEY_F(4):
{
refreshTimeout = 0;
settings->changed = true;
ProcessList_invertSortOrder(pl);
break;
}
case KEY_F(8):
case '[':
case '=':
case '+':
{
doRefresh = changePriority(lb, 1);
break;
}
case KEY_F(7):
case ']':
case '-':
{
doRefresh = changePriority(lb, -1);
break;
}
case KEY_F(3):
case '/':
FunctionBar_draw(searchBar, incSearchBuffer);
incSearchMode = true;
break;
case 't':
case KEY_F(5):
refreshTimeout = 0;
pl->treeView = !pl->treeView;
settings->changed = true;
break;
case 'H':
refreshTimeout = 0;
pl->hideThreads = !pl->hideThreads;
settings->changed = true;
break;
case 'K':
refreshTimeout = 0;
pl->hideKernelThreads = !pl->hideKernelThreads;
settings->changed = true;
break;
default:
doRefresh = false;
refreshTimeout = resetRefreshTimeout;
ListBox_onKey(lb, ch);
break;
}
follow = false;
}
attron(CRT_colors[RESET_COLOR]);
mvhline(LINES-1, 0, ' ', COLS);
attroff(CRT_colors[RESET_COLOR]);
refresh();
CRT_done();
if (settings->changed)
Settings_write(settings);
Header_delete(header);
ProcessList_delete(pl);
FunctionBar_delete((Object*)searchBar);
FunctionBar_delete((Object*)defaultBar);
((Object*)lb)->delete((Object*)lb);
if (lbk)
((Object*)lbk)->delete((Object*)lbk);
UsersTable_delete(ut);
Settings_delete(settings);
debug_done();
return 0;
}
[Desktop Entry]
Encoding=UTF-8
Version=0.6
Name=Htop
Type=Application
Comment=Show System Processes
Terminal=true
Exec=htop
Path=
Icon=htop
Categories=ConsoleOnly;System;
GenericName=Process Viewer
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_htop
#define HEADER_htop
/*
htop - htop.h
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "ProcessList.h"
#include "CRT.h"
#include "ListBox.h"
#include "UsersTable.h"
#include "SignalItem.h"
#include "RichString.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "FunctionBar.h"
#include "ListItem.h"
#include "CategoriesListBox.h"
#include "SignalsListBox.h"
#include "config.h"
#include "debug.h"
#include <unistd.h>
#include <math.h>
#include <sys/param.h>
#include <ctype.h>
#include <stdbool.h>
int usleep(int usec);
//#link m
#define INCSEARCH_MAX 40
void printVersionFlag();
void printHelpFlag();
void showHelp();
void showColumnConfig(ProcessList* pl);
void Setup_run(Settings* settings, int headerHeight);
int main(int argc, char** argv);
#endif
htop.png

169 Bytes

Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment