40 Commits

Author SHA1 Message Date
dace850fa6 Bump version, changelog for minor htop-3.0.1 release 2020-09-03 13:23:43 +10:00
4f00a95364 Merge pull request #66 from ioquatix/patch-1
Fix image logo and titles.
2020-09-03 08:35:19 +10:00
0ab508e42b Merge pull request #57 from matthiasbeyer/patch-1
Do not link INSTALL file, because link target does not exist
2020-09-03 08:20:36 +10:00
f79591ef1b Merge branch 'eworm-de-unicode-runtime' 2020-09-02 15:09:58 +10:00
746a5f279a Fix image logo and titles. 2020-09-02 11:54:17 +12:00
8ee7d58cb0 Do not link INSTALL file, because link target does not exist 2020-09-01 14:47:00 +02:00
db5adbeae0 add option (-U, --no-unicode) to disable unicode at runtime 2020-09-01 10:09:00 +02:00
f5b3e8d2a3 Merge branch 'cgzones-oom2' 2020-09-01 15:17:32 +10:00
809e4db672 Merge branch 'oom2' of https://github.com/cgzones/htop into cgzones-oom2 2020-09-01 15:17:23 +10:00
e1e60f38dc CRT: note about possible use of replacement for + glyph in tree 2020-08-31 22:35:09 +02:00
19359cec5a affinity panel: use the tree collapsing as in the process list
With one exception, the root node does also have a `-`/`+` as a prefix.
2020-08-31 22:22:22 +02:00
b0f1336f79 affinity panel: show CPUs in the topology tree as CPU x
As it is in the non-topology list.
2020-08-31 22:18:18 +02:00
f861a2c616 Revert "Use UTF-8 for check buttons and tree open/closed"
This reverts commit 5d5913d355b3a9f03da589b3542b8f55467b4ed6.
2020-08-31 22:12:46 +02:00
e7f6d1ce5f Reduce oom cast from long to int
Oom values should never be greater then INT_MAX, they should be in the
range 0 - 1000.

Improves: d9a5dd4b91
2020-08-31 11:55:53 +02:00
47a7d0bd74 Merge branch 'configure' of https://github.com/cgzones/htop into cgzones-configure 2020-08-31 17:13:37 +10:00
b321177b08 Merge branch 'master' of github.com:htop-dev/htop 2020-08-31 16:57:46 +10:00
800d8c735d Merge branch 'cov_fixes' of https://github.com/cgzones/htop into cgzones-cov_fixes 2020-08-31 16:56:32 +10:00
f14173038e Merge branch 'oom' of https://github.com/cgzones/htop
Closes: #18, #22
2020-08-31 08:32:39 +02:00
fdf8a28e60 Merge branch 'Ckath-vim_mode_setting' 2020-08-31 16:14:48 +10:00
244630f67f Merge branch 'vim_mode_setting' of https://github.com/Ckath/htop into Ckath-vim_mode_setting 2020-08-31 16:14:40 +10:00
0a835e13bf Simplify the --version output, old dates are confusing people
Drop the copyright notice from the version output as a number
of people seem to be confused by what this means, and we can
do without all the (well intentioned) bug reports.
2020-08-31 16:14:23 +10:00
4bd0859b80 Add a badge/link to the released source tarballs 2020-08-31 16:12:44 +10:00
338bd829b0 add toggle for vim mode in options 2020-08-29 15:15:52 +02:00
5c99c6e942 Check btime sscanf parse from /proc/stat
Found by Coverity
2020-08-28 16:46:50 +02:00
a850d81bf5 Avoid use of uninitialized variables
Found by Coverity
2020-08-28 16:46:50 +02:00
05a5fdc47f Ignore sscanf return value of /proc/stat
Found by Coverity
2020-08-28 16:46:50 +02:00
af84d3dfa9 Fail on out-of-range CPU number
Found by Coverity
2020-08-28 16:46:50 +02:00
df41979afc Ignore wmove return value
Found by Coverity
2020-08-28 16:46:50 +02:00
d9a5dd4b91 Improve OOM output
* Fix sort by adding cast
* Shrink column size to 4
* Drop unnecessary maximum field width specifier in sscanf
2020-08-28 14:24:59 +02:00
a48ce9d103 Really tell gcc to ignore return value of fscanf 2020-08-28 13:10:41 +02:00
3f5784a3f0 Convert hwlock CI run to a full featured one 2020-08-28 13:10:41 +02:00
3b084db1c4 Print configured state 2020-08-28 13:10:41 +02:00
979d004214 Improve indent 2020-08-28 13:10:16 +02:00
5bee902665 Drop configure option --enable-proc
Move to HTOP_LINUX, as --enable-proc implies my_htop_platform=linux, and
the Linux features do not work without a proc fs.
2020-08-28 13:10:16 +02:00
2d14269bcd Merge pull request #14 from zdykstra/master
Normalize ZFS ARC caption
2020-08-28 16:58:06 +10:00
b992d52bcf Increae the size of sysfs power supply path buffers
Resolves https://github.com/htop-dev/htop/issues/15
2020-08-28 16:57:21 +10:00
f97fbd668a Normalize ZFS ARC caption
Other captions take the form of LABEL:<space>. This moves the
uncompressed ZFS ARC caption into the same style.
2020-08-28 00:02:35 -05:00
b5e6952cc6 Update link to Coverity project, still pending. 2020-08-27 10:42:40 +10:00
4a8ae4b5d4 Merge branch 'bertwesarg-affinity-fix-panel-width' 2020-08-27 09:36:56 +10:00
94b8c2e714 fix width of AffinitPanel
The panel size of 15 includes the gap to the next panel, thus use 14 as
the minimum size and let the caller of `AffinityPanel_new` handle the
gap.
2020-08-26 22:03:11 +02:00
17 changed files with 150 additions and 161 deletions

View File

@ -40,20 +40,20 @@ jobs:
- name: Distcheck
run: make distcheck DISTCHECK_CONFIGURE_FLAGS=--enable-werror
build-ubuntu-latest-hwloc:
build-ubuntu-latest-full-featured:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: sudo apt-get install libncursesw5-dev libhwloc-dev
run: sudo apt-get install libncursesw5-dev libhwloc-dev libnl-3-dev libnl-genl-3-dev
- name: Bootstrap
run: ./autogen.sh
- name: Configure
run: ./configure --enable-werror --enable-hwloc
run: ./configure --enable-werror --enable-openvz --enable-cgroup --enable-vserver --enable-ancient-vserver --enable-taskstats --enable-unicode --enable-linux-affinity --enable-hwloc --enable-setuid --enable-delayacct
- name: Build
run: make
- name: Distcheck
run: make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-werror --enable-hwloc'
run: make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-werror --enable-openvz --enable-cgroup --enable-vserver --enable-ancient-vserver --enable-taskstats --enable-unicode --enable-linux-affinity --enable-hwloc --enable-setuid --enable-delayacct'
whitespace_check:
runs-on: ubuntu-latest

View File

@ -320,6 +320,7 @@ static Htop_Reaction actionSetAffinity(State* st) {
if (!affinity1) return HTOP_OK;
int width;
Panel* affinityPanel = AffinityPanel_new(st->pl, affinity1, &width);
width += 1; /* we add a gap between the panels */
Affinity_delete(affinity1);
void* set = Action_pickFromVector(st, affinityPanel, width, true);

View File

@ -27,7 +27,7 @@ in the source distribution for its full text.
typedef struct MaskItem_ {
Object super;
const char* text;
const char* indent;
const char* indent; /* used also as an condition whether this is a tree node */
int value; /* tri-state: 0 - off, 1 - some set, 2 - all set */
int sub_tree; /* tri-state: 0 - no sub-tree, 1 - open sub-tree, 2 - closed sub-tree */
Vector *children;
@ -55,20 +55,21 @@ static void MaskItem_delete(Object* cast) {
static void MaskItem_display(Object* cast, RichString* out) {
MaskItem* this = (MaskItem*)cast;
assert (this != NULL);
RichString_append(out, CRT_colors[CHECK_BOX], "[");
if (this->value == 2)
RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_FULL]);
RichString_append(out, CRT_colors[CHECK_MARK], "x");
else if (this->value == 1)
RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_PARTIAL]);
RichString_append(out, CRT_colors[CHECK_MARK], "o");
else
RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_NONE]);
RichString_append(out, CRT_colors[CHECK_MARK], " ");
RichString_append(out, CRT_colors[CHECK_BOX], "]");
RichString_append(out, CRT_colors[CHECK_TEXT], " ");
if (this->indent)
if (this->indent) {
RichString_append(out, CRT_colors[PROCESS_TREE], this->indent);
if (this->sub_tree) {
RichString_append(out, CRT_colors[PROCESS_TREE],
this->sub_tree == 1
? CRT_collapStr[COLLAP_STR_OPEN]
: CRT_collapStr[COLLAP_STR_CLOSED]);
this->sub_tree == 2
? CRT_treeStr[TREE_STR_OPEN]
: CRT_treeStr[TREE_STR_SHUT]);
RichString_append(out, CRT_colors[CHECK_TEXT], " ");
}
RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
@ -84,7 +85,7 @@ static ObjectClass MaskItem_class = {
static MaskItem* MaskItem_newMask(const char* text, const char* indent, hwloc_bitmap_t cpuset, bool owner) {
MaskItem* this = AllocThis(MaskItem);
this->text = xStrdup(text);
this->indent = xStrdup(indent);
this->indent = xStrdup(indent); /* nonnull for tree node */
this->value = 0;
this->ownCpuset = owner;
this->cpuset = cpuset;
@ -98,7 +99,7 @@ static MaskItem* MaskItem_newMask(const char* text, const char* indent, hwloc_bi
static MaskItem* MaskItem_newSingleton(const char* text, int cpu, bool isSet) {
MaskItem* this = AllocThis(MaskItem);
this->text = xStrdup(text);
this->indent = NULL;
this->indent = NULL; /* not a tree node */
this->sub_tree = 0;
this->children = Vector_new(Class(MaskItem), true, DEFAULT_SIZE);
@ -279,9 +280,8 @@ static MaskItem *AffinityPanel_addObject(AffinityPanel* this, hwloc_obj_t obj, u
size_t len = strlen(&indent_buf[off]);
off += len, left -= len;
}
xSnprintf(&indent_buf[off], left, "%s%s ",
obj->next_sibling ? CRT_treeStr[TREE_STR_RTEE] : CRT_treeStr[TREE_STR_BEND],
CRT_treeStr[TREE_STR_HORZ]);
xSnprintf(&indent_buf[off], left, "%s",
obj->next_sibling ? CRT_treeStr[TREE_STR_RTEE] : CRT_treeStr[TREE_STR_BEND]);
size_t len = strlen(&indent_buf[off]);
off += len, left -= len;
}
@ -302,8 +302,8 @@ static MaskItem *AffinityPanel_addObject(AffinityPanel* this, hwloc_obj_t obj, u
item->sub_tree = 2;
}
/* "[x] " + "|- " * depth + ("[+] ")? + name */
unsigned width = (CRT_utf8 ? 2 : 4) + 3 * depth + (item->sub_tree ? (CRT_utf8 ? 2 : 4) : 0) + strlen(buf);
/* "[x] " + "|- " * depth + ("- ")?(if root node) + name */
unsigned width = 4 + 3 * depth + (2 * !depth) + strlen(buf);
if (width > this->width)
this->width = width;
@ -352,7 +352,9 @@ Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity, int* width) {
Panel_init(super, 1, 1, 1, 1, Class(MaskItem), false, FunctionBar_new(AffinityPanelFunctions, AffinityPanelKeys, AffinityPanelEvents));
this->pl = pl;
this->width = 15;
/* defaults to 15, this also includes the gap between the panels,
* but this will be added by the caller */
this->width = 14;
this->cpuids = Vector_new(Class(MaskItem), true, DEFAULT_SIZE);

76
CRT.c
View File

@ -59,19 +59,6 @@ typedef enum TreeStr_ {
TREE_STR_COUNT
} TreeStr;
typedef enum CheckStr_ {
CHECK_STR_NONE,
CHECK_STR_PARTIAL,
CHECK_STR_FULL,
CHECK_STR_COUNT
} CheckStr;
typedef enum CollapStr_ {
COLLAP_STR_OPEN,
COLLAP_STR_CLOSED,
COLLAP_STR_COUNT
} CollapStr;
typedef enum ColorSchemes_ {
COLORSCHEME_DEFAULT = 0,
COLORSCHEME_MONOCHROME = 1,
@ -126,6 +113,7 @@ typedef enum ColorElements_ {
LOAD_AVERAGE_FIFTEEN,
LOAD_AVERAGE_FIVE,
LOAD_AVERAGE_ONE,
CHECK_BOX,
CHECK_MARK,
CHECK_TEXT,
CLOCK,
@ -171,17 +159,6 @@ const char *CRT_treeStrAscii[TREE_STR_COUNT] = {
"-", // TREE_STR_SHUT
};
const char *CRT_checkStrAscii[CHECK_STR_COUNT] = {
"[ ]", // CHECK_STR_NONE
"[o]", // CHECK_STR_PARTIAL
"[x]", // CHECK_STR_FULL
};
const char *CRT_collapStrAscii[COLLAP_STR_COUNT] = {
"[-]", // COLLAP_STR_OPEN
"[+]", // COLLAP_STR_CLOSED
};
#ifdef HAVE_LIBNCURSESW
const char *CRT_treeStrUtf8[TREE_STR_COUNT] = {
@ -190,31 +167,18 @@ const char *CRT_treeStrUtf8[TREE_STR_COUNT] = {
"\xe2\x94\x9c", // TREE_STR_RTEE ├
"\xe2\x94\x94", // TREE_STR_BEND └
"\xe2\x94\x8c", // TREE_STR_TEND ┌
"+", // TREE_STR_OPEN +
"+", // TREE_STR_OPEN +, TODO use 🮯 'BOX DRAWINGS LIGHT HORIZONTAL
// WITH VERTICAL STROKE' (U+1FBAF, "\xf0\x9f\xae\xaf") when
// Unicode 13 is common
"\xe2\x94\x80", // TREE_STR_SHUT ─
};
const char *CRT_checkStrUtf8[CHECK_STR_COUNT] = {
"\xe2\x98\x90", // CHECK_STR_NONE ☐
"\xe2\x98\x92", // CHECK_STR_PARTIAL ☒
"\xe2\x98\x91", // CHECK_STR_FULL ☑
};
const char *CRT_collapStrUtf8[COLLAP_STR_COUNT] = {
"\xe2\x8a\x9f", // COLLAP_STR_OPEN ⊟
"\xe2\x8a\x9e", // COLLAP_STR_CLOSED ⊞
};
bool CRT_utf8 = false;
#endif
bool CRT_utf8 = false;
const char **CRT_treeStr = CRT_treeStrAscii;
const char **CRT_checkStr = CRT_checkStrAscii;
const char **CRT_collapStr = CRT_collapStrAscii;
static bool CRT_hasColors;
int CRT_delay = 0;
@ -267,7 +231,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black),
[CLOCK] = A_BOLD,
[CHECK_MARK] = A_BOLD | ColorPair(Cyan,Black),
[CHECK_BOX] = ColorPair(Cyan,Black),
[CHECK_MARK] = A_BOLD,
[CHECK_TEXT] = A_NORMAL,
[HOSTNAME] = A_BOLD,
[CPU_NICE] = ColorPair(Blue,Black),
@ -335,7 +300,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD,
[CLOCK] = A_BOLD,
[CHECK_MARK] = A_BOLD,
[CHECK_BOX] = A_BOLD,
[CHECK_MARK] = A_NORMAL,
[CHECK_TEXT] = A_NORMAL,
[HOSTNAME] = A_BOLD,
[CPU_NICE] = A_NORMAL,
@ -403,6 +369,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = ColorPair(Black,White),
[HELP_BOLD] = ColorPair(Blue,White),
[CLOCK] = ColorPair(Black,White),
[CHECK_BOX] = ColorPair(Blue,White),
[CHECK_MARK] = ColorPair(Black,White),
[CHECK_TEXT] = ColorPair(Black,White),
[HOSTNAME] = ColorPair(Black,White),
@ -471,6 +438,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = ColorPair(White,Black),
[HELP_BOLD] = ColorPair(Blue,Black),
[CLOCK] = ColorPair(White,Black),
[CHECK_BOX] = ColorPair(Blue,Black),
[CHECK_MARK] = ColorPair(Black,Black),
[CHECK_TEXT] = ColorPair(Black,Black),
[HOSTNAME] = ColorPair(White,Black),
@ -539,7 +507,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD | ColorPair(White,Blue),
[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Blue),
[CLOCK] = ColorPair(White,Blue),
[CHECK_MARK] = A_BOLD | ColorPair(Cyan,Blue),
[CHECK_BOX] = ColorPair(Cyan,Blue),
[CHECK_MARK] = A_BOLD | ColorPair(White,Blue),
[CHECK_TEXT] = A_NORMAL | ColorPair(White,Blue),
[HOSTNAME] = ColorPair(White,Blue),
[CPU_NICE] = A_BOLD | ColorPair(Cyan,Blue),
@ -607,6 +576,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black),
[CLOCK] = ColorPair(Green,Black),
[CHECK_BOX] = ColorPair(Green,Black),
[CHECK_MARK] = A_BOLD | ColorPair(Green,Black),
[CHECK_TEXT] = ColorPair(Cyan,Black),
[HOSTNAME] = ColorPair(Green,Black),
@ -697,7 +667,7 @@ void CRT_restorePrivileges() {
// TODO: pass an instance of Settings instead.
void CRT_init(int delay, int colorScheme) {
void CRT_init(int delay, int colorScheme, bool allowUnicode) {
initscr();
noecho();
CRT_delay = delay;
@ -763,14 +733,20 @@ void CRT_init(int delay, int colorScheme) {
setlocale(LC_CTYPE, "");
#ifdef HAVE_LIBNCURSESW
if(strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
if (allowUnicode && strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
CRT_utf8 = true;
CRT_treeStr = CRT_treeStrUtf8;
CRT_checkStr = CRT_checkStrUtf8;
CRT_collapStr = CRT_collapStrUtf8;
}
else
CRT_utf8 = false;
#else
(void) allowUnicode;
#endif
CRT_treeStr =
#ifdef HAVE_LIBNCURSESW
CRT_utf8 ? CRT_treeStrUtf8 :
#endif
CRT_treeStrAscii;
#if NCURSES_MOUSE_VERSION > 1
mousemask(BUTTON1_RELEASED | BUTTON4_PRESSED | BUTTON5_PRESSED, NULL);
#else

30
CRT.h
View File

@ -47,19 +47,6 @@ typedef enum TreeStr_ {
TREE_STR_COUNT
} TreeStr;
typedef enum CheckStr_ {
CHECK_STR_NONE,
CHECK_STR_PARTIAL,
CHECK_STR_FULL,
CHECK_STR_COUNT
} CheckStr;
typedef enum CollapStr_ {
COLLAP_STR_OPEN,
COLLAP_STR_CLOSED,
COLLAP_STR_COUNT
} CollapStr;
typedef enum ColorSchemes_ {
COLORSCHEME_DEFAULT = 0,
COLORSCHEME_MONOCHROME = 1,
@ -114,6 +101,7 @@ typedef enum ColorElements_ {
LOAD_AVERAGE_FIFTEEN,
LOAD_AVERAGE_FIVE,
LOAD_AVERAGE_ONE,
CHECK_BOX,
CHECK_MARK,
CHECK_TEXT,
CLOCK,
@ -150,28 +138,16 @@ extern void CRT_handleSIGSEGV(int sgn);
extern const char *CRT_treeStrAscii[TREE_STR_COUNT];
extern const char *CRT_checkStrAscii[CHECK_STR_COUNT];
extern const char *CRT_collapStrAscii[COLLAP_STR_COUNT];
#ifdef HAVE_LIBNCURSESW
extern const char *CRT_treeStrUtf8[TREE_STR_COUNT];
extern const char *CRT_checkStrUtf8[CHECK_STR_COUNT];
extern const char *CRT_collapStrUtf8[COLLAP_STR_COUNT];
extern bool CRT_utf8;
#endif
extern bool CRT_utf8;
extern const char **CRT_treeStr;
extern const char **CRT_checkStr;
extern const char **CRT_collapStr;
extern int CRT_delay;
extern int* CRT_colors;
@ -213,7 +189,7 @@ extern void CRT_restorePrivileges();
// TODO: pass an instance of Settings instead.
extern void CRT_init(int delay, int colorScheme);
extern void CRT_init(int delay, int colorScheme, bool allowUnicode);
extern void CRT_done();

View File

@ -1,3 +1,16 @@
What's new in version 3.0.1
* Coverity fixes, CI improvements, documentation updates
* BUGFIX: Fix early exit with longer sysfs battery paths
* BUGFIX: Improve OOM output, fix sorting
(thanks to Christian Göttsche)
* Rework check buttons and tree open/closed
(thanks to Bert Wesarg)
* Add -U/--no-unicode option to disable unicode
(thanks to Christian Hesse)
* Improvements to the affinity panel
(thanks to Bert Wesarg)
What's new in version 3.0.0
* New maintainers - after a prolonged period of inactivity

View File

@ -35,11 +35,12 @@ static void CheckItem_delete(Object* cast) {
static void CheckItem_display(Object* cast, RichString* out) {
CheckItem* this = (CheckItem*)cast;
assert (this != NULL);
RichString_write(out, CRT_colors[CHECK_BOX], "[");
if (CheckItem_get(this))
RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_FULL]);
RichString_append(out, CRT_colors[CHECK_MARK], "x");
else
RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_NONE]);
RichString_append(out, CRT_colors[CHECK_TEXT], " ");
RichString_append(out, CRT_colors[CHECK_MARK], " ");
RichString_append(out, CRT_colors[CHECK_BOX], "] ");
RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
}

View File

@ -100,6 +100,7 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU percentage numerically"), &(settings->showCPUUsage)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU frequency"), &(settings->showCPUFrequency)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Enable the mouse"), &(settings->enableMouse)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Enable vim mode"), &(settings->vimMode)));
#ifdef HAVE_LIBHWLOC
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Show topology when selecting affinity by default"), &(settings->topologyAffinity)));
#endif

View File

@ -80,7 +80,7 @@ void InfoScreen_drawTitled(InfoScreen* this, const char* fmt, ...) {
va_start(ap, fmt);
attrset(CRT_colors[METER_TEXT]);
mvhline(0, 0, ' ', COLS);
wmove(stdscr, 0, 0);
(void) wmove(stdscr, 0, 0);
vw_printw(stdscr, fmt, ap);
attrset(CRT_colors[DEFAULT_COLOR]);
this->display->needsRedraw = true;

17
README
View File

@ -1,13 +1,13 @@
![htop](https://htop.dev)
# [![htop](htop.png)](https://htop.dev)
[![CI](https://github.com/htop-dev/htop/workflows/CI/badge.svg)](https://github.com/htop-dev/htop/actions)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/21617/badge.svg)](https://scan.coverity.com/projects/21617)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/21665/badge.svg)](https://scan.coverity.com/projects/21665)
[![Mailing List](https://img.shields.io/badge/Mailing%20List-htop-blue.svg)](https://groups.io/g/htop)
[![IRC #htop](https://img.shields.io/badge/IRC-htop-blue.svg)](https://webchat.freenode.net/#htop)
[![Github Release](https://img.shields.io/github/release/htop-dev/htop.svg)](https://github.com/htop-dev/htop/releases/latest)
[![Download](https://api.bintray.com/packages/htop/source/htop/images/download.svg)](https://bintray.com/htop/source/htop/_latestVersion)
Introduction
------------
## Introduction
`htop` is a cross-platform interactive process viewer.
It requires `ncurses`.
@ -15,20 +15,23 @@ It requires `ncurses`.
For more information and details on how to contribute to `htop`
visit [htop.dev](https://htop.dev).
Build instructions
------------------
## Build instructions
This program is distributed as a standard autotools-based package.
For detailed instructions see the [INSTALL](/INSTALL) file, which
For detailed instructions see the `INSTALL` file, which
is created after `./autogen.sh` is run.
When compiling from a [release tarball](https://github.com/htop-dev/htop/releases/), run:
~~~ shell
./configure && make
~~~
For compiling sources downloaded from the Git repository, run:
~~~ shell
./autogen.sh && ./configure && make
~~~
By default `make install` will install into `/usr/local`, for changing
the path use `./configure --prefix=/some/path`.

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.0],[htop@groups.io])
AC_INIT([htop],[3.0.1],[htop@groups.io])
AC_CONFIG_SRCDIR([htop.c])
AC_CONFIG_AUX_DIR([.])
@ -111,15 +111,7 @@ AC_SUBST(wextra_flag)
# ----------------------------------------------------------------------
PROCDIR=/proc
AC_ARG_ENABLE(proc, [AS_HELP_STRING([--enable-proc], [use Linux-compatible proc filesystem])], enable_proc="yes", enable_proc="no")
if test "x$enable_proc" = xyes; then
# An enabled proc assumes we're emulating Linux.
my_htop_platform=linux
AC_DEFINE(HAVE_PROC, 1, [Define if using a Linux-compatible proc filesystem.])
fi
AC_ARG_WITH(proc, [AS_HELP_STRING([--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])
PROCDIR="$withval"
@ -340,3 +332,20 @@ then
echo "****************************************************************"
echo ""
fi
AC_MSG_RESULT([
${PACKAGE_NAME} ${VERSION}
platform: $my_htop_platform
proc directory: $PROCDIR
openvz: $enable_openvz
cgroup: $enable_cgroup
vserver: $enable_vserver
ancient vserver: $enable_ancient_vserver
taskstats: $enable_taskstats
unicode: $enable_unicode
linux affinity: $enable_linux_affinity
hwlock: $enable_hwloc
setuid: $enable_setuid
linux delay accounting: $enable_delayacct
])

View File

@ -48,6 +48,9 @@ Sort by this column (use \-\-sort\-key help for a column list)
\fB\-u \-\-user=USERNAME\fR
Show only the processes of a given user
.TP
\fB\-U \-\-no-unicode\fR
Do not use unicode but ASCII characters for graph meters
.TP
\fB\-v \-\-version
Output version information and exit
.TP

19
htop.c
View File

@ -29,14 +29,12 @@ in the source distribution for its full text.
//#link m
static void printVersionFlag() {
fputs("htop " VERSION " - " COPYRIGHT "\n"
"Released under the GNU GPL.\n\n",
stdout);
fputs("htop " VERSION "\n", stdout);
exit(0);
}
static void printHelpFlag() {
fputs("htop " VERSION " - " COPYRIGHT "\n"
fputs("htop " VERSION "\n"
"Released under the GNU GPL.\n\n"
"-C --no-color Use a monochrome color scheme\n"
"-m --no-mouse Disable the mouse\n"
@ -45,6 +43,7 @@ static void printHelpFlag() {
"-s --sort-key=COLUMN Sort by COLUMN (try --sort-key=help for a list)\n"
"-t --tree Show the tree view by default\n"
"-u --user[=USERNAME] Show only processes for a given user (or $USER)\n"
"-U --no-unicode Do not use unicode but plain ASCII\n"
"-p --pid=PID,[,PID,PID...] Show only the given PIDs\n"
"-v --version Print version info\n"
"\n"
@ -65,6 +64,7 @@ typedef struct CommandLineSettings_ {
bool useColors;
bool enableMouse;
bool treeView;
bool allowUnicode;
} CommandLineSettings;
static CommandLineSettings parseArguments(int argc, char** argv) {
@ -77,6 +77,7 @@ static CommandLineSettings parseArguments(int argc, char** argv) {
.useColors = true,
.enableMouse = true,
.treeView = false,
.allowUnicode = true,
};
static struct option long_opts[] =
@ -89,6 +90,7 @@ static CommandLineSettings parseArguments(int argc, char** argv) {
{"no-color", no_argument, 0, 'C'},
{"no-colour", no_argument, 0, 'C'},
{"no-mouse", no_argument, 0, 'm'},
{"no-unicode", no_argument, 0, 'U'},
{"tree", no_argument, 0, 't'},
{"pid", required_argument, 0, 'p'},
{0,0,0,0}
@ -96,7 +98,7 @@ static CommandLineSettings parseArguments(int argc, char** argv) {
int opt, opti=0;
/* Parse arguments */
while ((opt = getopt_long(argc, argv, "hvmCs:td:u::p:", long_opts, &opti))) {
while ((opt = getopt_long(argc, argv, "hvmCs:td:u:Up:", long_opts, &opti))) {
if (opt == EOF) break;
switch (opt) {
case 'h':
@ -150,6 +152,9 @@ static CommandLineSettings parseArguments(int argc, char** argv) {
case 'm':
flags.enableMouse = false;
break;
case 'U':
flags.allowUnicode = false;
break;
case 't':
flags.treeView = true;
break;
@ -200,7 +205,7 @@ int main(int argc, char** argv) {
CommandLineSettings flags = parseArguments(argc, argv); // may exit()
#ifdef HAVE_PROC
#ifdef HTOP_LINUX
if (access(PROCDIR, R_OK) != 0) {
fprintf(stderr, "Error: could not read procfs (compiled to look in %s).\n", PROCDIR);
exit(1);
@ -228,7 +233,7 @@ int main(int argc, char** argv) {
if (flags.treeView)
settings->treeView = true;
CRT_init(settings->delay, settings->colorScheme);
CRT_init(settings->delay, settings->colorScheme, flags.allowUnicode);
MainPanel* panel = MainPanel_new();
ProcessList_setPanel(pl, (Panel*) panel);

View File

@ -107,7 +107,7 @@ static ACPresence procAcpiCheck() {
if (entryName[0] != 'A')
continue;
char statePath[50];
char statePath[256];
xSnprintf((char *) statePath, sizeof statePath, "%s/%s/state", power_supplyPath, entryName);
FILE* file = fopen(statePath, "r");
if (!file) {
@ -191,7 +191,7 @@ static void Battery_getSysData(double* level, ACPresence* isOnAC) {
if (!dirEntry)
break;
char* entryName = (char *) dirEntry->d_name;
const char filePath[50];
const char filePath[256];
xSnprintf((char *) filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/type", entryName);
int fd1 = open(filePath, O_RDONLY);

View File

@ -264,7 +264,6 @@ ProcessPidColumn Process_pidColumns[] = {
{ .id = TGID, .label = "TGID" },
{ .id = PGRP, .label = "PGRP" },
{ .id = SESSION, .label = "SID" },
{ .id = OOM, .label = "OOM" },
{ .id = 0, .label = NULL },
};
@ -397,7 +396,7 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
#ifdef HAVE_CGROUP
case CGROUP: xSnprintf(buffer, n, "%-10s ", lp->cgroup); break;
#endif
case OOM: xSnprintf(buffer, n, Process_pidFormat, lp->oom); break;
case OOM: xSnprintf(buffer, n, "%4u ", lp->oom); break;
case IO_PRIORITY: {
int klass = IOPriority_class(lp->ioPriority);
if (klass == IOPRIO_CLASS_NONE) {
@ -493,7 +492,7 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
return strcmp(p1->cgroup ? p1->cgroup : "", p2->cgroup ? p2->cgroup : "");
#endif
case OOM:
return (p2->oom - p1->oom);
return ((int)p2->oom - (int)p1->oom);
#ifdef HAVE_DELAYACCT
case PERCENT_CPU_DELAY:
return (p2->cpu_delay_percent > p1->cpu_delay_percent ? 1 : -1);

View File

@ -275,7 +275,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
} else if (String_startsWith(buffer, "cpu")) {
cpus++;
} else if (String_startsWith(buffer, "btime ")) {
sscanf(buffer, "btime %lld\n", &btime);
if (sscanf(buffer, "btime %lld\n", &btime) != 1)
CRT_fatalError("Failed to parse btime from " PROCSTATFILE);
break;
}
} while(true);
@ -577,7 +578,7 @@ static void LinuxProcessList_readOpenVZData(LinuxProcess* process, const char* d
FILE* file = fopen(filename, "r");
if (!file)
return;
(void) fscanf(file,
(void)! fscanf(file,
"%*32u %*32s %*1c %*32u %*32u %*32u %*32u %*32u %*32u %*32u "
"%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u "
"%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u "
@ -670,7 +671,7 @@ static void LinuxProcessList_readOomData(LinuxProcess* process, const char* dirn
char buffer[PROC_LINE_LENGTH + 1];
if (fgets(buffer, PROC_LINE_LENGTH, file)) {
unsigned int oom;
int ok = sscanf(buffer, "%32u", &oom);
int ok = sscanf(buffer, "%u", &oom);
if (ok >= 1) {
process->oom = oom;
}
@ -1062,9 +1063,9 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) {
}
static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) {
unsigned long long int dbufSize;
unsigned long long int dnodeSize;
unsigned long long int bonusSize;
unsigned long long int dbufSize = 0;
unsigned long long int dnodeSize = 0;
unsigned long long int bonusSize = 0;
FILE* file = fopen(PROCARCSTATSFILE, "r");
if (file == NULL) {
@ -1142,10 +1143,10 @@ static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) {
char* ok = fgets(buffer, PROC_LINE_LENGTH, file);
if (!ok) buffer[0] = '\0';
if (i == 0)
sscanf(buffer, "cpu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
(void) sscanf(buffer, "cpu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
else {
int cpuid;
sscanf(buffer, "cpu%4d %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
(void) sscanf(buffer, "cpu%4d %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
assert(cpuid == i - 1);
}
// Guest time is already accounted in usertime
@ -1235,7 +1236,7 @@ static inline double LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) {
(sscanf(buffer, "cpu MHz : %lf", &frequency) == 1) ||
(sscanf(buffer, "cpu MHz: %lf", &frequency) == 1)
) {
if (cpuid < 0) {
if (cpuid < 0 || cpuid > (cpus - 1)) {
CRT_fatalError(PROCCPUINFOFILE " is malformed: cpu MHz line without corresponding processor line");
}

View File

@ -60,7 +60,6 @@ static void ZfsArcMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
if (this->values[5] > 0) {
RichString_write(out, CRT_colors[METER_TEXT], ":");
Meter_humanUnit(buffer, this->total, 50);
RichString_append(out, CRT_colors[METER_VALUE], buffer);
Meter_humanUnit(buffer, this->values[5], 50);
@ -100,5 +99,5 @@ MeterClass ZfsArcMeter_class = {
.attributes = ZfsArcMeter_attributes,
.name = "ZFSARC",
.uiName = "ZFS ARC",
.caption = "ARC"
.caption = "ARC: "
};