15 Commits

35 changed files with 112 additions and 503 deletions

View File

@ -115,7 +115,7 @@ static void Action_runSetup(Settings* settings, const Header* header, ProcessLis
static bool changePriority(MainPanel* panel, int delta) {
bool anyTagged;
bool ok = MainPanel_foreachProcess(panel, (MainPanel_ForeachProcessFn) Process_changePriorityBy, (Arg){ .i = delta }, &anyTagged);
bool ok = MainPanel_foreachProcess(panel, (MainPanel_ForeachProcessFn) Process_changePriorityBy, delta, &anyTagged);
if (!ok)
beep();
return anyTagged;
@ -187,7 +187,6 @@ static Htop_Reaction sortBy(State* st) {
// ----------------------------------------
static Htop_Reaction actionResize(State* st) {
clear();
Panel_resize(st->panel, COLS, LINES-(st->panel->y)-1);
return HTOP_REDRAW_BAR;
}
@ -298,7 +297,7 @@ static Htop_Reaction actionSetAffinity(State* st) {
void* set = Action_pickFromVector(st, affinityPanel, 15);
if (set) {
Affinity* affinity = AffinityPanel_getAffinity(affinityPanel, st->pl);
bool ok = MainPanel_foreachProcess((MainPanel*)panel, (MainPanel_ForeachProcessFn) Affinity_set, (Arg){ .v = affinity }, NULL);
bool ok = MainPanel_foreachProcess((MainPanel*)panel, (MainPanel_ForeachProcessFn) Affinity_set, (size_t) affinity, NULL);
if (!ok) beep();
Affinity_delete(affinity);
}
@ -315,7 +314,7 @@ static Htop_Reaction actionKill(State* st) {
Panel_setHeader(st->panel, "Sending...");
Panel_draw(st->panel, true);
refresh();
MainPanel_foreachProcess((MainPanel*)st->panel, (MainPanel_ForeachProcessFn) Process_sendSignal, (Arg){ .i = sgn->key }, NULL);
MainPanel_foreachProcess((MainPanel*)st->panel, (MainPanel_ForeachProcessFn) Process_sendSignal, (size_t) sgn->key, NULL);
napms(500);
}
}

View File

@ -1,56 +0,0 @@
Contributing Guide
==================
Hello, and thank you so much for taking your time to contribute in any way to
htop! There are many ways to contribute, and I'll try to list them below. The
support from the free software community has been amazing over the years and
it is the number one thing that keeps me going, maintaining and improving
something that started as a tiny pet project back in 2004 and that nowadays is
a piece of software used all over the world, in both reality [and
fiction!](http://hisham.hm/htop/index.php?page=sightings). Cheers!
-- Hisham Muhammad
Bug Reports
-----------
Bug reports should be posted in the [Github issue
tracker](http://github.com/hishamhm/htop/issues). (I reply to them all, but I
usually do it in batches! :) ) Bug reports are extremely important since it's
impossible for me to test htop in every possible system, distribution and
scenario. Your feedback is what keeps the tool stable and always improving!
Thank you!
Pull Requests
-------------
Code contributions are most welcome! Just [fork the
repo](http://github.com/hishamhm/htop) and send a [pull
request](https://github.com/hishamhm/htop/pulls). Help is especially
appreciated for support of platforms other than Linux. If proposing new
features, please be mindful that htop is a system tool that needs to keep a
small footprint and perform well on systems under stress -- so unfortunately I
can't accept every new feature proposed, as I need to keep the tool slim and
maintainable. Great ideas backed by a PR are always carefully considered for
inclusion, though! Also, PRs containing bug fixes and portability tweaks are a
no-brainer, please send those in!
Feature Requests
----------------
Back when htop was hosted in SourceForge, there used to be separate Bug
Tracker and Feature Request pages. These go all lumped together under "Issues"
in Github, which is a bit confusing. For this reason, I close Feature Requests
and file them with the [`feature
request`](https://github.com/hishamhm/htop/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22feature+request%22+)
label, where they remain accessible, but not mixed with actual bug reports.
This doesn't mean I'm dismissing or ignoring feature requests right away! It's
just an organizational issue (with Github, really!).
Donations
---------
If you like htop, feel free to [buy the author a
beer](http://hisham.hm/htop/index.php?page=donate). :-)

32
CRT.c
View File

@ -37,7 +37,6 @@ in the source distribution for its full text.
#define White COLOR_WHITE
#define ColorPairGrayBlack ColorPair(Magenta,Magenta)
#define ColorIndexGrayBlack ColorIndex(Magenta,Magenta)
#define KEY_WHEELUP KEY_F(20)
#define KEY_WHEELDOWN KEY_F(21)
@ -719,23 +718,22 @@ void CRT_enableDelay() {
void CRT_setColors(int colorScheme) {
CRT_colorScheme = colorScheme;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (ColorIndex(i,j) != ColorPairGrayBlack) {
int bg = (colorScheme != COLORSCHEME_BLACKNIGHT)
? (j==0 ? -1 : j)
: j;
init_pair(ColorIndex(i,j), i, bg);
if (colorScheme == COLORSCHEME_BLACKNIGHT) {
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++) {
if (ColorIndex(i,j) != ColorIndex(Magenta,Magenta)) {
init_pair(ColorIndex(i,j), i, j);
}
}
}
init_pair(ColorIndex(Magenta,Magenta), 8, 0);
} else {
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++) {
if (ColorIndex(i,j) != ColorIndex(Magenta,Magenta)) {
init_pair(ColorIndex(i,j), i, (j==0?-1:j));
}
}
init_pair(ColorIndex(Magenta,Magenta), 8, -1);
}
int grayBlackFg = COLORS > 8 ? 8 : 0;
int grayBlackBg = (colorScheme != COLORSCHEME_BLACKNIGHT)
? -1
: 0;
init_pair(ColorIndexGrayBlack, grayBlackFg, grayBlackBg);
CRT_colors = CRT_colorSchemes[colorScheme];
}

1
CRT.h
View File

@ -26,7 +26,6 @@ in the source distribution for its full text.
#define White COLOR_WHITE
#define ColorPairGrayBlack ColorPair(Magenta,Magenta)
#define ColorIndexGrayBlack ColorIndex(Magenta,Magenta)
#define KEY_WHEELUP KEY_F(20)
#define KEY_WHEELDOWN KEY_F(21)

View File

@ -1,51 +1,3 @@
What's new in version 2.1.1
* Check for pkg-config when building with --enable-delayacct
(thanks to @florian2833z for the report)
* Use CFLAGS from ncurses*-config if present
(thanks to Michael Klein)
* Fix build failure in Glibc 2.28
(thanks to Kang-Che Sung)
* BUGFIX: fix behavior of SYSCR column
(thanks to Marc Kleine-Budde)
* BUGFIX: preserve LDFLAGS when building
(thanks to Lance Frederickson for the report)
* BUGFIX: fix issue with small terminals
(thanks to Daniel Elf for the report)
* BUGFIX: fix crash with particular keycodes
(thanks to Wellington Torrejais da Silva for the report)
* BUGFIX: fix terminal color issues
(thanks to Kang-Che Sung for the report)
What's new in version 2.1.0
* Linux: Delay accounting metrics
(thanks to André Carvalho)
* DragonFlyBSD support
(thanks to Diederik de Groot)
* Support for real-time signals
(thanks to Kang-Che Sung)
* 'c' key now works with threads as well
* Session column renamed from SESN to SID
(thanks to Kamyar Rasta)
* Improved UI for meter style selection
(thanks to Kang-Che Sung)
* Improved code for constructing process tree
(thanks to wangqr)
* Compile-time option to disable setuid
* Error checking of various standard library operations
* Replacement of sprintf with snprintf
(thanks to Tomasz Kramkowski)
* Linux: performance improvements in battery meter
* Linux: update process TTY device
* Linux: add support for sorting TASK_IDLE
(thanks to Vladimir Panteleev)
* Linux: add upper-bound to running process counter
(thanks to Lucas Correia Villa Real)
* BUGFIX: avoid crash when battery is removed
(thanks to Jan Chren)
* BUGFIX: macOS: fix infinite loop in tree view
(thanks to Wataru Ashihara)
What's new in version 2.0.2

View File

@ -78,7 +78,6 @@ static HandlerResult ColorsPanel_eventHandler(Panel* super, int ch) {
this->settings->changed = true;
const Header* header = this->scr->header;
CRT_setColors(mark);
clear();
Panel* menu = (Panel*) Vector_get(this->scr->panels, 0);
Header_draw(header);
RichString_setAttr(&(super->header), CRT_colors[PANEL_HEADER_FOCUS]);

View File

@ -25,12 +25,7 @@ typedef struct MainPanel_ {
pid_t pidSearch;
} MainPanel;
typedef union {
int i;
void* v;
} Arg;
typedef bool(*MainPanel_ForeachProcessFn)(Process*, Arg);
typedef bool(*MainPanel_ForeachProcessFn)(Process*, size_t);
#define MainPanel_getFunctionBar(this_) (((Panel*)(this_))->defaultBar)
@ -155,7 +150,7 @@ const char* MainPanel_getValue(MainPanel* this, int i) {
return "";
}
bool MainPanel_foreachProcess(MainPanel* this, MainPanel_ForeachProcessFn fn, Arg arg, bool* wasAnyTagged) {
bool MainPanel_foreachProcess(MainPanel* this, MainPanel_ForeachProcessFn fn, size_t arg, bool* wasAnyTagged) {
Panel* super = (Panel*) this;
bool ok = true;
bool anyTagged = false;

View File

@ -21,12 +21,7 @@ typedef struct MainPanel_ {
pid_t pidSearch;
} MainPanel;
typedef union {
int i;
void* v;
} Arg;
typedef bool(*MainPanel_ForeachProcessFn)(Process*, Arg);
typedef bool(*MainPanel_ForeachProcessFn)(Process*, size_t);
#define MainPanel_getFunctionBar(this_) (((Panel*)(this_))->defaultBar)
@ -39,7 +34,7 @@ int MainPanel_selectedPid(MainPanel* this);
const char* MainPanel_getValue(MainPanel* this, int i);
bool MainPanel_foreachProcess(MainPanel* this, MainPanel_ForeachProcessFn fn, Arg arg, bool* wasAnyTagged);
bool MainPanel_foreachProcess(MainPanel* this, MainPanel_ForeachProcessFn fn, size_t arg, bool* wasAnyTagged);
extern PanelClass MainPanel_class;

View File

@ -152,7 +152,7 @@ int Meter_humanUnit(char* buffer, unsigned long int value, int size) {
if (value / 1024 < powi)
break;
if (prefix[1] == '\0')
if (prefix[1] == 0)
break;
powi *= 1024;
@ -287,7 +287,7 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
int blockSizes[10];
xSnprintf(bar, w + 1, "%*.*s", w, w, buffer);
xSnprintf(bar, w + 1, "%*s", w, buffer);
// First draw in the bar[] buffer...
int offset = 0;
@ -359,7 +359,7 @@ static int GraphMeterMode_pixPerRow;
static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
if (!this->drawData) this->drawData = xCalloc(1, sizeof(GraphData));
GraphData* data = (GraphData*) this->drawData;
GraphData* data = (GraphData*) this->drawData;
const int nValues = METER_BUFFER_LEN;
#ifdef HAVE_LIBNCURSESW
@ -404,7 +404,7 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
k = -i/2;
i = 0;
}
for (; i < nValues - 1; i+=2, k++) {
for (; i < nValues; i+=2, k++) {
int pix = GraphMeterMode_pixPerRow * GRAPH_HEIGHT;
int v1 = CLAMP((int) lround(data->values[i] * pix), 1, pix);
int v2 = CLAMP((int) lround(data->values[i+1] * pix), 1, pix);

View File

@ -130,7 +130,7 @@ void OpenFilesScreen_scan(InfoScreen* this) {
char** data = fdata->data.data;
int lenN = data['n'] ? strlen(data['n']) : 0;
int sizeEntry = 5 + 7 + 10 + 10 + 10 + lenN + 5 /*spaces*/ + 1 /*null*/;
char entry[sizeEntry];
char* entry = xMalloc(sizeEntry);
xSnprintf(entry, sizeEntry, "%5.5s %7.7s %10.10s %10.10s %10.10s %s",
data['f'] ? data['f'] : "",
data['t'] ? data['t'] : "",

View File

@ -477,7 +477,7 @@ HandlerResult Panel_selectByTyping(Panel* this, int ch) {
this->eventHandlerState = xCalloc(100, sizeof(char));
char* buffer = this->eventHandlerState;
if (ch > 0 && ch < 255 && isalnum(ch)) {
if (ch < 255 && isalnum(ch)) {
int len = strlen(buffer);
if (len < 99) {
buffer[len] = ch;

View File

@ -28,12 +28,7 @@ in the source distribution for its full text.
#include <time.h>
#include <assert.h>
#include <math.h>
#ifdef MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#elif defined(MAJOR_IN_SYSMACROS) || \
(defined(HAVE_SYS_SYSMACROS_H) && HAVE_SYS_SYSMACROS_H)
#include <sys/sysmacros.h>
#endif
#include <inttypes.h>
#ifdef __ANDROID__
#define SYS_ioprio_get __NR_ioprio_get
@ -51,7 +46,6 @@ in the source distribution for its full text.
#include "Object.h"
#include <sys/types.h>
#include <inttypes.h>
#define PROCESS_FLAG_IO 0x0001
@ -181,8 +175,6 @@ typedef struct ProcessClass_ {
#define Process_isChildOf(process_, pid_) (process_->tgid == pid_ || (process_->tgid == process_->pid && process_->ppid == pid_))
#define Process_sortState(state) ((state) == 'I' ? 0x100 : (state))
}*/
static int Process_getuid = -1;
@ -543,11 +535,11 @@ bool Process_setPriority(Process* this, int priority) {
return (err == 0);
}
bool Process_changePriorityBy(Process* this, int delta) {
bool Process_changePriorityBy(Process* this, size_t delta) {
return Process_setPriority(this, this->nice + delta);
}
void Process_sendSignal(Process* this, int sgn) {
void Process_sendSignal(Process* this, size_t sgn) {
CRT_dropPrivileges();
kill(this->pid, (int) sgn);
CRT_restorePrivileges();
@ -608,7 +600,7 @@ long Process_compare(const void* v1, const void* v2) {
return (p1->starttime_ctime - p2->starttime_ctime);
}
case STATE:
return (Process_sortState(p1->state) - Process_sortState(p2->state));
return (p1->state - p2->state);
case ST_UID:
return (p1->st_uid - p2->st_uid);
case TIME:

View File

@ -9,11 +9,6 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#ifdef MAJOR_IN_MKDEV
#elif defined(MAJOR_IN_SYSMACROS) || \
(defined(HAVE_SYS_SYSMACROS_H) && HAVE_SYS_SYSMACROS_H)
#endif
#ifdef __ANDROID__
#define SYS_ioprio_get __NR_ioprio_get
#define SYS_ioprio_set __NR_ioprio_set
@ -29,7 +24,6 @@ in the source distribution for its full text.
#include "Object.h"
#include <sys/types.h>
#include <inttypes.h>
#define PROCESS_FLAG_IO 0x0001
@ -159,8 +153,6 @@ typedef struct ProcessClass_ {
#define Process_isChildOf(process_, pid_) (process_->tgid == pid_ || (process_->tgid == process_->pid && process_->ppid == pid_))
#define Process_sortState(state) ((state) == 'I' ? 0x100 : (state))
#define ONE_K 1024L
#define ONE_M (ONE_K * ONE_K)
@ -198,9 +190,9 @@ void Process_toggleTag(Process* this);
bool Process_setPriority(Process* this, int priority);
bool Process_changePriorityBy(Process* this, int delta);
bool Process_changePriorityBy(Process* this, size_t delta);
void Process_sendSignal(Process* this, int sgn);
void Process_sendSignal(Process* this, size_t sgn);
long Process_pidCompare(const void* v1, const void* v2);

View File

@ -232,11 +232,6 @@ void ProcessList_sort(ProcessList* this) {
pid_t ppid = process->tgid == process->pid ? process->ppid : process->tgid;
// Bisect the process vector to find parent
int l = 0, r = size;
// If PID corresponds with PPID (e.g. "kernel_task" (PID:0, PPID:0)
// on Mac OS X 10.11.6) cancel bisecting and regard this process as
// root.
if (process->pid == ppid)
r = 0;
while (l < r) {
int c = (l + r) / 2;
pid_t pid = ((Process*)(Vector_get(this->processes, c)))->pid;

View File

@ -63,10 +63,6 @@ typedef struct RichString_ {
}*/
#ifndef CLAMP
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
#endif
#define charBytes(n) (sizeof(CharType) * (n))
static void RichString_extendLen(RichString* this, int len) {
@ -107,7 +103,6 @@ static inline void RichString_writeFrom(RichString* this, int attrs, const char*
inline void RichString_setAttrn(RichString* this, int attrs, int start, int finish) {
cchar_t* ch = this->chptr + start;
finish = CLAMP(finish, 0, this->chlen - 1);
for (int i = start; i <= finish; i++) {
ch->attr = attrs;
ch++;
@ -137,7 +132,6 @@ static inline void RichString_writeFrom(RichString* this, int attrs, const char*
void RichString_setAttrn(RichString* this, int attrs, int start, int finish) {
chtype* ch = this->chptr + start;
finish = CLAMP(finish, 0, this->chlen - 1);
for (int i = start; i <= finish; i++) {
*ch = (*ch & 0xff) | attrs;
ch++;

View File

@ -59,10 +59,6 @@ typedef struct RichString_ {
} RichString;
#ifndef CLAMP
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
#endif
#define charBytes(n) (sizeof(CharType) * (n))
#define RichString_setLen(this, len) do{ if(len < RICHSTRING_MAXLEN && this->chlen < RICHSTRING_MAXLEN) { RichString_setChar(this,len,0); this->chlen=len; } else RichString_extendLen(this,len); }while(0)

View File

@ -285,8 +285,7 @@ static bool Settings_read(Settings* this, const char* fileName) {
if (!fd)
return false;
bool didReadMeters = false;
bool didReadFields = false;
bool readMeters = false;
ProcessField* legacyFields = xCalloc(Platform_numberOfFields+1, sizeof(ProcessField));
int legacyFlags;
bool legacyFieldsRead = false;
@ -343,16 +342,16 @@ static bool Settings_read(Settings* this, const char* fileName) {
if (this->colorScheme < 0 || this->colorScheme >= LAST_COLORSCHEME) this->colorScheme = 0;
} else if (String_eq(option[0], "left_meters")) {
Settings_readMeters(this, option[1], 0);
didReadMeters = true;
readMeters = true;
} else if (String_eq(option[0], "right_meters")) {
Settings_readMeters(this, option[1], 1);
didReadMeters = true;
readMeters = true;
} else if (String_eq(option[0], "left_meter_modes")) {
Settings_readMeterModes(this, option[1], 0);
didReadMeters = true;
readMeters = true;
} else if (String_eq(option[0], "right_meter_modes")) {
Settings_readMeterModes(this, option[1], 1);
didReadMeters = true;
readMeters = true;
} else if (strncmp(option[0], "screen:", 7) == 0) {
Settings_newScreen(this, option[0] + 7, option[1]);
} else if (String_eq(option[0], ".tree_view")) {
@ -379,10 +378,10 @@ static bool Settings_read(Settings* this, const char* fileName) {
this->screens[0]->flags = legacyFlags;
}
}
if (!didReadMeters) {
if (!readMeters) {
Settings_defaultMeters(this);
}
return didReadFields;
return true;
}
static void writeFields(FILE* fd, ProcessField* fields, bool byName) {
@ -514,8 +513,10 @@ Settings* Settings_new(int cpuCount) {
free(htopDir);
free(configDir);
struct stat st;
int err = lstat(legacyDotfile, &st);
if (err || S_ISLNK(st.st_mode)) {
if (lstat(legacyDotfile, &st) != 0) {
st.st_mode = 0;
}
if (access(legacyDotfile, R_OK) != 0 || S_ISLNK(st.st_mode)) {
free(legacyDotfile);
legacyDotfile = NULL;
}
@ -524,38 +525,33 @@ Settings* Settings_new(int cpuCount) {
this->colorScheme = 0;
this->changed = false;
this->delay = DEFAULT_DELAY;
bool ok = false;
if (legacyDotfile) {
ok = Settings_read(this, legacyDotfile);
if (ok) {
bool ok = Settings_read(this, legacyDotfile ? legacyDotfile : this->filename);
if (ok) {
if (legacyDotfile) {
// Transition to new location and delete old configuration file
if (Settings_write(this))
unlink(legacyDotfile);
}
free(legacyDotfile);
}
if (!ok) {
ok = Settings_read(this, this->filename);
}
if (!ok) {
} else {
this->changed = true;
// TODO: how to get SYSCONFDIR correctly through Autoconf?
char* systemSettings = String_cat(SYSCONFDIR, "/htoprc");
ok = Settings_read(this, systemSettings);
free(systemSettings);
}
if (!ok) {
Settings_defaultMeters(this);
Settings_defaultScreens(this);
this->hideKernelThreads = true;
this->highlightMegabytes = true;
this->highlightThreads = true;
this->headerMargin = true;
if (!ok) {
Settings_defaultMeters(this);
Settings_defaultScreens(this);
this->hideKernelThreads = true;
this->highlightMegabytes = true;
this->highlightThreads = true;
this->headerMargin = true;
}
}
this->ssIndex = 0;
this->ss = this->screens[this->ssIndex];
free(legacyDotfile);
return this;
}

View File

@ -9,7 +9,6 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define DEFAULT_DELAY 15
#include "Process.h"
#include <stdbool.h>

View File

@ -108,8 +108,7 @@ bool TraceScreen_forkTracer(TraceScreen* this) {
(void) written;
exit(1);
}
int ok = fcntl(this->fdpair[0], F_SETFL, O_NONBLOCK);
if (ok == -1) return false;
fcntl(this->fdpair[0], F_SETFL, O_NONBLOCK);
this->strace = fdopen(this->fdpair[0], "r");
this->fd_strace = fileno(this->strace);
return true;

View File

@ -284,19 +284,11 @@ inline Object* Vector_get(Vector* this, int idx) {
#endif
#ifdef DEBUG
inline int Vector_size(Vector* this) {
assert(Vector_isConsistent(this));
return this->items;
}
#else
#define Vector_size(v_) ((v_)->items)
#endif
/*
static void Vector_merge(Vector* this, Vector* v2) {

View File

@ -70,16 +70,8 @@ extern Object* Vector_get(Vector* this, int idx);
#endif
#ifdef DEBUG
extern int Vector_size(Vector* this);
#else
#define Vector_size(v_) ((v_)->items)
#endif
/*
*/

View File

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.65)
AC_INIT([htop],[3.0.0beta3],[hisham@gobolinux.org])
AC_INIT([htop],[2.0.2],[hisham@gobolinux.org])
SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(date +%s)}"
year=$(date -u -d "@$SOURCE_DATE_EPOCH" "+%Y" 2>/dev/null || date -u -r "$SOURCE_DATE_EPOCH" "+%Y" 2>/dev/null || date -u "+%Y")
@ -61,16 +61,6 @@ AC_CHECK_HEADERS([stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h],[
])
AC_CHECK_HEADERS([execinfo.h],[:],[:])
AC_HEADER_MAJOR
dnl glibc 2.25 deprecates 'major' and 'minor' in <sys/types.h> and requires to
dnl include <sys/sysmacros.h>. However the logic in AC_HEADER_MAJOR has not yet
dnl been updated in Autoconf 2.69, so use a workaround:
m4_version_prereq([2.70], [],
[if test "x$ac_cv_header_sys_mkdev_h" = xno; then
AC_CHECK_HEADER(sys/sysmacros.h, [AC_DEFINE(MAJOR_IN_SYSMACROS, 1,
[Define to 1 if `major', `minor', and `makedev' are declared in <sys/sysmacros.h>.])])
fi])
# Checks for typedefs, structures, and compiler characteristics.
# ----------------------------------------------------------------------
AC_HEADER_STDBOOL
@ -164,26 +154,20 @@ m4_define([HTOP_CHECK_SCRIPT],
[
if test ! -z "m4_toupper($HTOP_[$1]_CONFIG_SCRIPT)"; then
# to be used to set the path to ncurses*-config when cross-compiling
htop_config_script_libs=$(m4_toupper($HTOP_[$1]_CONFIG_SCRIPT) --libs 2> /dev/null)
htop_config_script_cflags=$(m4_toupper($HTOP_[$1]_CONFIG_SCRIPT) --cflags 2> /dev/null)
htop_config_script=$(m4_toupper($HTOP_[$1]_CONFIG_SCRIPT) --libs 2> /dev/null)
else
htop_config_script_libs=$([$4] --libs 2> /dev/null)
htop_config_script_cflags=$([$4] --cflags 2> /dev/null)
htop_config_script=$([$4] --libs 2> /dev/null)
fi
htop_script_success=no
htop_save_LDFLAGS="$LDFLAGS"
htop_save_CFLAGS="$CFLAGS"
if test ! "x$htop_config_script_libs" = x; then
LDFLAGS="$htop_config_script_libs $LDFLAGS"
CFLAGS="$htop_config_script_cflags $CFLAGS"
if test ! "x$htop_config_script" = x; then
LDFLAGS="$htop_config_script $LDFLAGS"
AC_CHECK_LIB([$1], [$2], [
AC_DEFINE([$3], 1, [The library is present.])
LIBS="$htop_config_script_libs $LIBS "
LIBS="$htop_config_script $LIBS "
htop_script_success=yes
], [
CFLAGS="$htop_save_CFLAGS"
])
LDFLAGS="$htop_save_LDFLAGS"
], [])
LDFLAGS="$save_LDFLAGS"
fi
if test "x$htop_script_success" = xno; then
[$5]
@ -321,11 +305,10 @@ fi
AC_ARG_ENABLE(delayacct, [AS_HELP_STRING([--enable-delayacct], [enable linux delay accounting])],, enable_delayacct="no")
if test "x$enable_delayacct" = xyes
then
PKG_PROG_PKG_CONFIG()
PKG_CHECK_MODULES(LIBNL3, libnl-3.0, [], [missing_libraries="$missing_libraries libnl-3"])
PKG_CHECK_MODULES(LIBNL3GENL, libnl-genl-3.0, [], [missing_libraries="$missing_libraries libnl-genl-3"])
CFLAGS="$CFLAGS $LIBNL3_CFLAGS $LIBNL3GENL_CFLAGS"
LIBS="$LIBS $LIBNL3_LIBS $LIBNL3GENL_LIBS"
CFLAGS+=" $LIBNL3_CFLAGS $LIBNL3GENL_CFLAGS"
LIBS+=" $LIBNL3_LIBS $LIBNL3GENL_LIBS"
AC_DEFINE(HAVE_DELAYACCT, 1, [Define if delay accounting support should be enabled.])
fi

View File

@ -171,8 +171,7 @@ void ProcessList_goThroughEntries(ProcessList* super) {
DarwinProcess_setFromKInfoProc(&proc->super, &ps[i], tv.tv_sec, preExisting);
DarwinProcess_setFromLibprocPidinfo(proc, dpl);
// Disabled due to bug in macOS High Sierra
// DarwinProcess_scanThreads(proc);
DarwinProcess_scanThreads(proc);
super->totalTasks += 1;

View File

@ -25,11 +25,6 @@ in the source distribution for its full text.
#include "CPUMeter.h"
#include "BatteryMeter.h"
#include "DarwinProcess.h"
typedef enum DarwinProcessFields {
LAST_PROCESSFIELD = 100,
} DarwinProcessField;
}*/
#ifndef CLAMP
@ -102,7 +97,7 @@ ProcessFieldData Process_fields[] = {
[TIME] = { .name = "TIME", .title = " TIME+ ", .description = "Total time the process has spent in user and system time", .flags = 0, },
[NLWP] = { .name = "NLWP", .title = "NLWP ", .description = "Number of threads in the process", .flags = 0, },
[TGID] = { .name = "TGID", .title = " TGID ", .description = "Thread group ID (i.e. process ID)", .flags = 0, },
[LAST_PROCESSFIELD] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, },
[100] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, },
};
MeterClass* Platform_meterTypes[] = {

View File

@ -16,10 +16,6 @@ in the source distribution for its full text.
#include "BatteryMeter.h"
#include "DarwinProcess.h"
typedef enum DarwinProcessFields {
LAST_PROCESSFIELD = 100,
} DarwinProcessField;
#ifndef CLAMP
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
#endif

View File

@ -49,11 +49,11 @@ The following commands are supported while in htop:
.LP
.TP 5
.B Up, Alt-k
Select (highlight) the previous process in the process list. Scroll the list
Select (hightlight) the previous process in the process list. Scroll the list
if necessary.
.TP
.B Down, Alt-j
Select (highlight) the next process in the process list. Scroll the list if
Select (hightlight) the next process in the process list. Scroll the list if
necessary.
.TP
.B Left, Alt-h

View File

@ -72,8 +72,6 @@ static unsigned long int parseBatInfo(const char *fileName, const unsigned short
fclose(file);
if (!line) break;
char *foundNumStr = String_getToken(line, wordNum);
const unsigned long int foundNum = atoi(foundNumStr);
free(foundNumStr);
@ -110,14 +108,17 @@ static ACPresence procAcpiCheck() {
char statePath[50];
xSnprintf((char *) statePath, sizeof statePath, "%s/%s/state", power_supplyPath, entryName);
FILE* file = fopen(statePath, "r");
if (!file) {
isOn = AC_ERROR;
continue;
}
char* line = String_readLine(file);
fclose(file);
if (!line) continue;
fclose(file);
const char *isOnline = String_getToken(line, 2);
free(line);

View File

@ -198,7 +198,7 @@ ProcessFieldData Process_fields[] = {
[0] = { .name = "", .title = NULL, .description = NULL, .flags = 0, },
[PID] = { .name = "PID", .title = " PID ", .description = "Process/thread ID", .flags = 0, },
[COMM] = { .name = "Command", .title = "Command ", .description = "Command line", .flags = 0, },
[STATE] = { .name = "STATE", .title = "S ", .description = "Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging, I idle)", .flags = 0, },
[STATE] = { .name = "STATE", .title = "S ", .description = "Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging)", .flags = 0, },
[PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
[PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group ID", .flags = 0, },
[SESSION] = { .name = "SESSION", .title = " SID ", .description = "Process's session ID", .flags = 0, },

View File

@ -26,12 +26,6 @@ in the source distribution for its full text.
#include <assert.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#elif defined(MAJOR_IN_SYSMACROS) || \
(defined(HAVE_SYS_SYSMACROS_H) && HAVE_SYS_SYSMACROS_H)
#include <sys/sysmacros.h>
#endif
#ifdef HAVE_DELAYACCT
#include <netlink/attr.h>
@ -442,7 +436,7 @@ static void LinuxProcessList_readIoFile(LinuxProcess* process, const char* dirna
}
break;
case 's':
if (line[4] == 'r' && strncmp(line+1, "yscr: ", 6) == 0) {
if (line[5] == 'r' && strncmp(line+1, "yscr: ", 6) == 0) {
process->io_syscr = strtoull(line+7, NULL, 10);
} else if (strncmp(line+1, "yscw: ", 6) == 0) {
process->io_syscw = strtoull(line+7, NULL, 10);
@ -601,36 +595,36 @@ static void LinuxProcessList_readOomData(LinuxProcess* process, const char* dirn
static int handleNetlinkMsg(struct nl_msg *nlmsg, void *linuxProcess) {
struct nlmsghdr *nlhdr;
struct nlattr *nlattrs[TASKSTATS_TYPE_MAX + 1];
struct nlattr *nlattr;
struct taskstats *stats;
int rem;
unsigned long long int timeDelta;
LinuxProcess* lp = (LinuxProcess*) linuxProcess;
struct nlattr *nlattrs[TASKSTATS_TYPE_MAX + 1];
struct nlattr *nlattr;
struct taskstats *stats;
int rem;
unsigned long long int timeDelta;
LinuxProcess* lp = (LinuxProcess*) linuxProcess;
nlhdr = nlmsg_hdr(nlmsg);
nlhdr = nlmsg_hdr(nlmsg);
if (genlmsg_parse(nlhdr, 0, nlattrs, TASKSTATS_TYPE_MAX, NULL) < 0) {
return NL_SKIP;
}
}
if ((nlattr = nlattrs[TASKSTATS_TYPE_AGGR_PID]) || (nlattr = nlattrs[TASKSTATS_TYPE_NULL])) {
stats = nla_data(nla_next(nla_data(nlattr), &rem));
assert(lp->super.pid == stats->ac_pid);
timeDelta = (stats->ac_etime*1000 - lp->delay_read_time);
#define BOUNDS(x) isnan(x) ? 0.0 : (x > 100) ? 100.0 : x;
#define DELTAPERC(x,y) BOUNDS((float) (x - y) / timeDelta * 100);
lp->cpu_delay_percent = DELTAPERC(stats->cpu_delay_total, lp->cpu_delay_total);
lp->blkio_delay_percent = DELTAPERC(stats->blkio_delay_total, lp->blkio_delay_total);
lp->swapin_delay_percent = DELTAPERC(stats->swapin_delay_total, lp->swapin_delay_total);
#undef DELTAPERC
#undef BOUNDS
lp->swapin_delay_total = stats->swapin_delay_total;
lp->blkio_delay_total = stats->blkio_delay_total;
lp->cpu_delay_total = stats->cpu_delay_total;
lp->delay_read_time = stats->ac_etime*1000;
}
return NL_OK;
if ((nlattr = nlattrs[TASKSTATS_TYPE_AGGR_PID]) || (nlattr = nlattrs[TASKSTATS_TYPE_NULL])) {
stats = nla_data(nla_next(nla_data(nlattr), &rem));
assert(lp->super.pid == stats->ac_pid);
timeDelta = (stats->ac_etime*1000 - lp->delay_read_time);
#define BOUNDS(x) isnan(x) ? 0.0 : (x > 100) ? 100.0 : x;
#define DELTAPERC(x,y) BOUNDS((float) (x - y) / timeDelta * 100);
lp->cpu_delay_percent = DELTAPERC(stats->cpu_delay_total, lp->cpu_delay_total);
lp->blkio_delay_percent = DELTAPERC(stats->blkio_delay_total, lp->blkio_delay_total);
lp->swapin_delay_percent = DELTAPERC(stats->swapin_delay_total, lp->swapin_delay_total);
#undef DELTAPERC
#undef BOUNDS
lp->swapin_delay_total = stats->swapin_delay_total;
lp->blkio_delay_total = stats->blkio_delay_total;
lp->cpu_delay_total = stats->cpu_delay_total;
lp->delay_read_time = stats->ac_etime*1000;
}
return NL_OK;
}
static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProcess* process) {

View File

@ -9,11 +9,6 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#ifdef MAJOR_IN_MKDEV
#elif defined(MAJOR_IN_SYSMACROS) || \
(defined(HAVE_SYS_SYSMACROS_H) && HAVE_SYS_SYSMACROS_H)
#endif
#ifdef HAVE_DELAYACCT
#endif

View File

@ -1,135 +0,0 @@
/*
* This file is based on tiptop.
* by Erven ROHOU
* Copyright (c) 2011, 2012, 2014 Inria
* License: GNU General Public License version 2.
*/
#include "PerfCounter.h"
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include "XAlloc.h"
/*{
#include <config.h>
#include <sys/types.h>
#include <unistd.h>
#include <asm/unistd.h>
#include <inttypes.h>
#include <stdbool.h>
// The sys_perf_counter_open syscall and header files changed names
// between Linux 2.6.31 and 2.6.32. Do the mangling here.
#ifdef HAVE_LINUX_PERF_COUNTER_H
#include <linux/perf_counter.h>
#define STRUCT_NAME perf_counter_attr
#define SYSCALL_NUM __NR_perf_counter_open
#elif HAVE_LINUX_PERF_EVENT_H
#include <linux/perf_event.h>
#define STRUCT_NAME perf_event_attr
#define SYSCALL_NUM __NR_perf_event_open
#else
#error Sorry, performance counters not supported on this system.
#endif
typedef struct PerfCounter_ {
struct STRUCT_NAME events;
pid_t pid;
int fd;
uint64_t prevValue;
uint64_t value;
} PerfCounter;
#define PerfCounter_delta(pc_) ((pc_)->value - (pc_)->prevValue)
}*/
int PerfCounter_openFds = 0;
static int PerfCounter_fdLimit = -1;
static void PerfCounter_initFdLimit() {
char name[100] = { 0 }; /* needs to fit the name /proc/xxxx/limits */
snprintf(name, sizeof(name) - 1, "/proc/%d/limits", getpid());
FILE* f = fopen(name, "r");
if (f) {
char line[100];
while (fgets(line, 100, f)) {
int n = sscanf(line, "Max open files %d", &PerfCounter_fdLimit);
if (n) {
break;
}
}
fclose(f);
}
PerfCounter_fdLimit -= 20; /* keep some slack */
if (PerfCounter_fdLimit == 0) { /* something went wrong */
PerfCounter_fdLimit = 200; /* reasonable default? */
}
}
static long perf_event_open(struct STRUCT_NAME *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags) {
int ret = syscall(SYSCALL_NUM, hw_event, pid, cpu, group_fd, flags);
#if defined(__x86_64__) || defined(__i386__)
if (ret < 0 && ret > -4096) {
errno = -ret;
ret = -1;
}
#endif
return ret;
}
PerfCounter* PerfCounter_new(pid_t pid, uint32_t type, uint64_t config) {
if (PerfCounter_fdLimit == -1) {
PerfCounter_initFdLimit();
}
PerfCounter* this = xCalloc(sizeof(PerfCounter), 1);
this->pid = pid;
this->events.disabled = 0;
this->events.pinned = 1;
this->events.exclude_hv = 1;
this->events.exclude_kernel = 1;
this->events.type = type;
this->events.config = config;
if (PerfCounter_openFds < PerfCounter_fdLimit) {
this->fd = perf_event_open(&this->events, pid, -1, -1, 0);
} else {
this->fd = -1;
}
if (this->fd != -1) {
PerfCounter_openFds++;
}
return this;
}
void PerfCounter_delete(PerfCounter* this) {
if (!this) {
return;
}
if (this->fd != -1) {
PerfCounter_openFds--;
}
close(this->fd);
free(this);
}
bool PerfCounter_read(PerfCounter* this) {
if (this->fd == -1) {
return false;
}
uint64_t value;
int r = read(this->fd, &value, sizeof(value));
if (r != sizeof(value)) {
close(this->fd);
this->fd = perf_event_open(&this->events, this->pid, -1, -1, 0);
return false;
}
this->prevValue = this->value;
this->value = value;
return true;
}

View File

@ -1,54 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_PerfCounter
#define HEADER_PerfCounter
/*
* This file is based on tiptop.
* by Erven ROHOU
* Copyright (c) 2011, 2012, 2014 Inria
* License: GNU General Public License version 2.
*/
#include <config.h>
#include <sys/types.h>
#include <unistd.h>
#include <asm/unistd.h>
#include <inttypes.h>
#include <stdbool.h>
// The sys_perf_counter_open syscall and header files changed names
// between Linux 2.6.31 and 2.6.32. Do the mangling here.
#ifdef HAVE_LINUX_PERF_COUNTER_H
#include <linux/perf_counter.h>
#define STRUCT_NAME perf_counter_attr
#define SYSCALL_NUM __NR_perf_counter_open
#elif HAVE_LINUX_PERF_EVENT_H
#include <linux/perf_event.h>
#define STRUCT_NAME perf_event_attr
#define SYSCALL_NUM __NR_perf_event_open
#else
#error Sorry, performance counters not supported on this system.
#endif
typedef struct PerfCounter_ {
struct STRUCT_NAME events;
pid_t pid;
int fd;
uint64_t prevValue;
uint64_t value;
} PerfCounter;
#define PerfCounter_delta(pc_) ((pc_)->value - (pc_)->prevValue)
extern int PerfCounter_openFds;
PerfCounter* PerfCounter_new(pid_t pid, uint32_t type, uint64_t config);
void PerfCounter_delete(PerfCounter* this);
bool PerfCounter_read(PerfCounter* this);
#endif

View File

@ -97,7 +97,7 @@ static Htop_Reaction Platform_actionSetIOPriority(State* st) {
void* set = Action_pickFromVector(st, ioprioPanel, 21);
if (set) {
IOPriority ioprio = IOPriorityPanel_getIOPriority(ioprioPanel);
bool ok = MainPanel_foreachProcess((MainPanel*)panel, (MainPanel_ForeachProcessFn) LinuxProcess_setIOPriority, (Arg){ .i = ioprio }, NULL);
bool ok = MainPanel_foreachProcess((MainPanel*)panel, (MainPanel_ForeachProcessFn) LinuxProcess_setIOPriority, (size_t) ioprio, NULL);
if (!ok)
beep();
}

View File

@ -68,3 +68,8 @@ void ProcessList_goThroughEntries(ProcessList* super) {
proc->minflt = 20;
proc->majflt = 20;
}
void UnsupportedProcessList_scan(ProcessList* this) {
(void) this;
// stub!
}

View File

@ -17,4 +17,6 @@ void ProcessList_delete(ProcessList* this);
void ProcessList_goThroughEntries(ProcessList* super);
void UnsupportedProcessList_scan(ProcessList* this);
#endif