From 59eeadec918a955b40427a1b012992161050c939 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Thu, 3 Sep 2020 12:34:39 +0200 Subject: New upstream version 3.0.1 --- .github/workflows/ci.yml | 8 ++--- AffinityPanel.c | 36 +++++++++++------------ CRT.c | 76 +++++++++++++++++------------------------------- CRT.h | 30 ++----------------- ChangeLog | 13 +++++++++ CheckItem.c | 7 +++-- DisplayOptionsPanel.c | 1 + InfoScreen.c | 2 +- README | 21 +++++++------ configure.ac | 37 ++++++++++++++--------- htop.1.in | 3 ++ htop.c | 39 ++++++++++++++----------- linux/Battery.c | 4 +-- linux/LinuxProcess.c | 7 ++--- linux/LinuxProcessList.c | 19 ++++++------ zfs/ZfsArcMeter.c | 3 +- 16 files changed, 146 insertions(+), 160 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b269bd..d95d0af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/AffinityPanel.c b/AffinityPanel.c index e95b381..1ffa900 100644 --- a/AffinityPanel.c +++ b/AffinityPanel.c @@ -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); @@ -260,7 +261,7 @@ static HandlerResult AffinityPanel_eventHandler(Panel* super, int ch) { static MaskItem *AffinityPanel_addObject(AffinityPanel* this, hwloc_obj_t obj, unsigned indent, MaskItem *parent) { const char* type_name = hwloc_obj_type_string(obj->type); - const char* index_prefix = " #"; + const char* index_prefix = "#"; unsigned depth = obj->depth; unsigned index = obj->logical_index; size_t off = 0, left = 10 * depth; @@ -279,14 +280,13 @@ 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; } - xSnprintf(buf, 64, "%s%s%u", type_name, index_prefix, index); + xSnprintf(buf, 64, "%s %s%u", type_name, index_prefix, index); MaskItem *item = MaskItem_newMask(buf, indent_buf, obj->complete_cpuset, false); if (parent) @@ -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; diff --git a/CRT.c b/CRT.c index 869573e..0d83bf4 100644 --- a/CRT.c +++ b/CRT.c @@ -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,13 +733,19 @@ 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); diff --git a/CRT.h b/CRT.h index 5fb2f09..7d5c8ad 100644 --- a/CRT.h +++ b/CRT.h @@ -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(); diff --git a/ChangeLog b/ChangeLog index e762491..a45b973 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/CheckItem.c b/CheckItem.c index a045d2f..910981e 100644 --- a/CheckItem.c +++ b/CheckItem.c @@ -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); } diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c index 1222d82..42375e6 100644 --- a/DisplayOptionsPanel.c +++ b/DisplayOptionsPanel.c @@ -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 diff --git a/InfoScreen.c b/InfoScreen.c index 9312000..5c586bd 100644 --- a/InfoScreen.c +++ b/InfoScreen.c @@ -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; diff --git a/README b/README index 5e65754..92bd285 100644 --- a/README +++ b/README @@ -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: - ./configure && make +~~~ shell +./configure && make +~~~ For compiling sources downloaded from the Git repository, run: - ./autogen.sh && ./configure && make +~~~ shell +./autogen.sh && ./configure && make +~~~ By default `make install` will install into `/usr/local`, for changing the path use `./configure --prefix=/some/path`. diff --git a/configure.ac b/configure.ac index 18291b9..f6498b7 100644 --- a/configure.ac +++ b/configure.ac @@ -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,20 +111,12 @@ 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" -fi, -AC_DEFINE(PROCDIR, "/proc", [Path of proc filesystem])) + if test -n "$withval"; then + AC_DEFINE_UNQUOTED(PROCDIR, "$withval", [Path of proc filesystem]) + PROCDIR="$withval" + fi, + AC_DEFINE(PROCDIR, "/proc", [Path of proc filesystem])) if test "x$cross_compiling" = xno; then if test "x$enable_proc" = xyes; then @@ -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 +]) diff --git a/htop.1.in b/htop.1.in index 9ef0761..c5b131b 100644 --- a/htop.1.in +++ b/htop.1.in @@ -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 diff --git a/htop.c b/htop.c index 7cdf4e4..bbf3a91 100644 --- a/htop.c +++ b/htop.c @@ -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,26 +77,28 @@ static CommandLineSettings parseArguments(int argc, char** argv) { .useColors = true, .enableMouse = true, .treeView = false, + .allowUnicode = true, }; static struct option long_opts[] = { - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'v'}, - {"delay", required_argument, 0, 'd'}, - {"sort-key", required_argument, 0, 's'}, - {"user", optional_argument, 0, 'u'}, - {"no-color", no_argument, 0, 'C'}, - {"no-colour",no_argument, 0, 'C'}, - {"no-mouse", no_argument, 0, 'm'}, - {"tree", no_argument, 0, 't'}, - {"pid", required_argument, 0, 'p'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {"delay", required_argument, 0, 'd'}, + {"sort-key", required_argument, 0, 's'}, + {"user", optional_argument, 0, 'u'}, + {"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} }; 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); diff --git a/linux/Battery.c b/linux/Battery.c index 4014a50..a8784da 100644 --- a/linux/Battery.c +++ b/linux/Battery.c @@ -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); diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c index 3a15049..5970c93 100644 --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -241,7 +241,7 @@ ProcessFieldData Process_fields[] = { #ifdef HAVE_CGROUP [CGROUP] = { .name = "CGROUP", .title = " CGROUP ", .description = "Which cgroup the process is in", .flags = PROCESS_FLAG_LINUX_CGROUP, }, #endif - [OOM] = { .name = "OOM", .title = " OOM ", .description = "OOM (Out-of-Memory) killer score", .flags = PROCESS_FLAG_LINUX_OOM, }, + [OOM] = { .name = "OOM", .title = " OOM ", .description = "OOM (Out-of-Memory) killer score", .flags = PROCESS_FLAG_LINUX_OOM, }, [IO_PRIORITY] = { .name = "IO_PRIORITY", .title = "IO ", .description = "I/O priority", .flags = PROCESS_FLAG_LINUX_IOPRIO, }, #ifdef HAVE_DELAYACCT [PERCENT_CPU_DELAY] = { .name = "PERCENT_CPU_DELAY", .title = "CPUD% ", .description = "CPU delay %", .flags = 0, }, @@ -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); diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 6d3d034..732a86b 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -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"); } diff --git a/zfs/ZfsArcMeter.c b/zfs/ZfsArcMeter.c index 8042555..8bd0f5d 100644 --- a/zfs/ZfsArcMeter.c +++ b/zfs/ZfsArcMeter.c @@ -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: " }; -- cgit v1.2.3