35 Commits

Author SHA1 Message Date
df7e4fcdc0 Update changelog with Berts latest addition 2020-08-26 10:44:22 +10:00
728b04bbb5 Merge branch 'ci-hwloc-job' of https://github.com/bertwesarg/htop into bertwesarg-ci-hwloc-job 2020-08-26 10:39:43 +10:00
d0f31ede56 Merge branch 'ci-hwloc-job' of https://github.com/bertwesarg/htop into bertwesarg-ci-hwloc-job 2020-08-26 10:15:00 +10:00
ba94e0dfda Merge branch 'ci2' of https://github.com/cgzones/htop into cgzones-ci2 2020-08-26 10:08:50 +10:00
fc4f74aa47 ci: add clang build 2020-08-25 12:01:56 +02:00
4e2b9f0965 Avoid shadowing warnings 2020-08-25 12:01:56 +02:00
b4ceb83d76 MakeHeader.py.in: remove unused import 2020-08-25 12:00:08 +02:00
1130ad8b73 MakeHeader.py.in: remove executable bit 2020-08-25 12:00:08 +02:00
11f558f934 Avoid discarding const qualifiers 2020-08-25 12:00:03 +02:00
7457bfe9f3 Avoid string overflow warning
Use xStrdup instead of xMallow and strncpy

    StringUtils.c: In function ‘String_split’:
    StringUtils.c:86:7: error: ‘strncpy’ specified bound depends on the length of the source argument [-Werror=stringop-overflow=]
       86 |       strncpy(token, s, size + 1);
          |       ^
    StringUtils.c:84:18: note: length computed here
       84 |       int size = strlen(s);
          |                  ^
2020-08-25 11:59:59 +02:00
21fb56e1e2 Avoid string overflow warning
Enough memory is allocated.

    Header.c: In function ‘Header_readMeterName’:
    Header.c:157:4: error: ‘strncpy’ specified bound depends on the length of the source argument [-Werror=stringop-overflow=]
      157 |    strncpy(name, Meter_name(meter), nameLen);
          |    ^
    Header.c:154:18: note: length computed here
      154 |    int nameLen = strlen(Meter_name(meter));
          |                  ^
2020-08-25 11:59:59 +02:00
6b11769448 Avoid conversion warning
linux/Platform.c:47:90: error: implicit conversion from ‘enum LinuxProcessFields’ to ‘enum ProcessFields’ [-Werror=enum-conversion]
       47 | ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
          |
2020-08-25 11:59:53 +02:00
d64a6a2453 CI: Add a HWLOC enabled job 2020-08-25 11:42:21 +02:00
345d415537 Do not include the generated config.h header into the package 2020-08-25 11:42:16 +02:00
054b7f2801 Fix out-of-tree builds 2020-08-25 10:36:27 +02:00
e172282002 Fix in AC_CONFIG_FILES, try #2 2020-08-24 21:37:28 +02:00
0bac7c9d94 Nope, configure works but make breaks.
This reverts commit dad62b6c9e.
2020-08-24 21:08:07 +02:00
dad62b6c9e Put Makeheader.py.in into AC_CONFIG_FILES 2020-08-24 21:01:50 +02:00
9eb9064fbd Cleanup unused CI build notes and whitespace 2020-08-24 10:22:44 +10:00
9e57b5c3f4 Generate an appropriate shebang line for MakeHeader script
Use configure.ac to handle platform differences where some
build hosts have only a python3, or only python, binary.

Related to https://github.com/htop-dev/htop/pull/6
2020-08-23 11:24:52 +10:00
b3aef4ea3a Revert "MakeHeader.py: use python3 shebang"
This reverts commit 40ac7a88af.
as it causes build failure on non-python3 platforms.
2020-08-23 09:42:11 +10:00
6900e57efd Updates to project URLs in docs and embedded in source code 2020-08-22 15:47:11 +10:00
5dad65ac2a Update header files to match whitespace changes in source files 2020-08-22 15:46:31 +10:00
6315f10725 Merge branch 'ginggs-patch-1' 2020-08-22 15:36:02 +10:00
45062b26d6 Merge branch 'patch-1' of https://github.com/ginggs/htop-1 into ginggs-patch-1 2020-08-22 15:35:55 +10:00
ada780c867 Merge branch 'cgzones-ci2' 2020-08-22 15:35:02 +10:00
6aed2be247 Fix build on FreeBSD 2020-08-21 16:49:28 +02:00
9fde0835ed Avoid empty translation unit warning
zfs/ZfsArcStats.c:22: error: ISO C forbids an empty translation unit [-Werror=pedantic]
       22 | }*/
          |
2020-08-21 10:38:44 +02:00
b92f62f912 Remove trailing whitespaces 2020-08-21 10:37:33 +02:00
3856bf574b Introduce xAsprintf as checked version of asprintf 2020-08-21 10:37:29 +02:00
40ac7a88af MakeHeader.py: use python3 shebang
Also drop unused import
2020-08-21 10:37:27 +02:00
d6adc2b681 github/ci: improve ci
- split steps for readability
- fail on compiler warnings
- add whitespace check
- run on all branches
- run `make distcheck`
2020-08-21 10:37:25 +02:00
57254cdd05 configure: add option --enable-werror
Adds the compiler flag -Werror to fail on warnings.
Useful for CI runs.
2020-08-21 10:37:20 +02:00
0b276f80f1 Mention change of maintainership in ChangeLog
Related to https://github.com/hishamhm/htop/issues/992
2020-08-21 16:42:16 +10:00
bba8c3bb2e Update the changelog to reflect content in the 3.0.0 release 2020-08-21 12:10:11 +10:00
66 changed files with 795 additions and 273 deletions

View File

@ -1,29 +1,63 @@
name: CI name: CI
on: on: [ push, pull_request ]
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs: jobs:
build-ubuntu-latest: build-ubuntu-latest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Install Dependencies
run: sudo apt-get install libncursesw5-dev
- name: Bootstrap
run: ./autogen.sh
- name: Configure
run: ./configure --enable-werror
- name: Build - name: Build
run: | run: make
sudo apt-get install libncursesw5-dev - name: Distcheck
./autogen.sh run: make distcheck DISTCHECK_CONFIGURE_FLAGS=--enable-werror
./configure
make
# build-macos-latest: build-ubuntu-clang-latest:
# runs-on: macos-latest runs-on: ubuntu-latest
# steps: env:
# - uses: actions/checkout@v2 CC: clang-10
# - name: make steps:
# run: | - uses: actions/checkout@v2
# ./autogen.sh - name: install clang repo
# ./configure run: |
# make wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key 2>/dev/null | sudo apt-key add -
sudo add-apt-repository 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main' -y
sudo apt-get update -q
- name: Install Dependencies
run: sudo apt-get install clang-10 libncursesw5-dev
- name: Bootstrap
run: ./autogen.sh
- name: Configure
run: ./configure --enable-werror
- name: Build
run: make
- name: Distcheck
run: make distcheck DISTCHECK_CONFIGURE_FLAGS=--enable-werror
build-ubuntu-latest-hwloc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: sudo apt-get install libncursesw5-dev libhwloc-dev
- name: Bootstrap
run: ./autogen.sh
- name: Configure
run: ./configure --enable-werror --enable-hwloc
- name: Build
run: make
- name: Distcheck
run: make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-werror --enable-hwloc'
whitespace_check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: check-whitespaces
run: git diff-tree --check $(git hash-object -t tree /dev/null) HEAD

1
.gitignore vendored
View File

@ -39,4 +39,5 @@ libtool
ltmain.sh ltmain.sh
m4/ m4/
missing missing
scripts/MakeHeader.py
stamp-h1 stamp-h1

View File

@ -316,17 +316,18 @@ static Htop_Reaction actionSetAffinity(State* st) {
Process* p = (Process*) Panel_getSelected(panel); Process* p = (Process*) Panel_getSelected(panel);
if (!p) return HTOP_OK; if (!p) return HTOP_OK;
Affinity* affinity = Affinity_get(p, st->pl); Affinity* affinity1 = Affinity_get(p, st->pl);
if (!affinity) return HTOP_OK; if (!affinity1) return HTOP_OK;
Panel* affinityPanel = AffinityPanel_new(st->pl, affinity); int width;
Affinity_delete(affinity); Panel* affinityPanel = AffinityPanel_new(st->pl, affinity1, &width);
Affinity_delete(affinity1);
void* set = Action_pickFromVector(st, affinityPanel, 15, true); void* set = Action_pickFromVector(st, affinityPanel, width, true);
if (set) { if (set) {
Affinity* affinity = AffinityPanel_getAffinity(affinityPanel, st->pl); Affinity* affinity2 = 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, (Arg){ .v = affinity2 }, NULL);
if (!ok) beep(); if (!ok) beep();
Affinity_delete(affinity); Affinity_delete(affinity2);
} }
Panel_delete((Object*)affinityPanel); Panel_delete((Object*)affinityPanel);
#endif #endif
@ -615,4 +616,3 @@ void Action_setBindings(Htop_Action* keys) {
keys['c'] = actionTagAllChildren; keys['c'] = actionTagAllChildren;
keys['e'] = actionShowEnvScreen; keys['e'] = actionShowEnvScreen;
} }

View File

@ -54,5 +54,4 @@ extern Htop_Reaction Action_follow(State* st);
extern void Action_setBindings(Htop_Action* keys); extern void Action_setBindings(Htop_Action* keys);
#endif #endif

View File

@ -8,69 +8,416 @@ in the source distribution for its full text.
#include "AffinityPanel.h" #include "AffinityPanel.h"
#include "CRT.h" #include "CRT.h"
#include "CheckItem.h" #include "Vector.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#ifdef HAVE_LIBHWLOC
#include <hwloc.h>
#endif
/*{ /*{
#include "Panel.h" #include "Panel.h"
#include "Affinity.h" #include "Affinity.h"
#include "ProcessList.h" #include "ProcessList.h"
#include "ListItem.h"
}*/ }*/
static HandlerResult AffinityPanel_eventHandler(Panel* this, int ch) { typedef struct MaskItem_ {
CheckItem* selected = (CheckItem*) Panel_getSelected(this); Object super;
const char* text;
const char* indent;
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;
#ifdef HAVE_LIBHWLOC
bool ownCpuset;
hwloc_bitmap_t cpuset;
#else
int cpu;
#endif
} MaskItem;
static void MaskItem_delete(Object* cast) {
MaskItem* this = (MaskItem*) cast;
free((void*)this->text);
if (this->indent)
free((void*)this->indent);
Vector_delete(this->children);
#ifdef HAVE_LIBHWLOC
if (this->ownCpuset)
hwloc_bitmap_free(this->cpuset);
#endif
free(this);
}
static void MaskItem_display(Object* cast, RichString* out) {
MaskItem* this = (MaskItem*)cast;
assert (this != NULL);
if (this->value == 2)
RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_FULL]);
else if (this->value == 1)
RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_PARTIAL]);
else
RichString_append(out, CRT_colors[CHECK_MARK], CRT_checkStr[CHECK_STR_NONE]);
RichString_append(out, CRT_colors[CHECK_TEXT], " ");
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]);
RichString_append(out, CRT_colors[CHECK_TEXT], " ");
}
RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
}
static ObjectClass MaskItem_class = {
.display = MaskItem_display,
.delete = MaskItem_delete
};
#ifdef HAVE_LIBHWLOC
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->value = 0;
this->ownCpuset = owner;
this->cpuset = cpuset;
this->sub_tree = hwloc_bitmap_weight(cpuset) > 1 ? 1 : 0;
this->children = Vector_new(Class(MaskItem), true, DEFAULT_SIZE);
return this;
}
#endif
static MaskItem* MaskItem_newSingleton(const char* text, int cpu, bool isSet) {
MaskItem* this = AllocThis(MaskItem);
this->text = xStrdup(text);
this->indent = NULL;
this->sub_tree = 0;
this->children = Vector_new(Class(MaskItem), true, DEFAULT_SIZE);
#ifdef HAVE_LIBHWLOC
this->ownCpuset = true;
this->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_set(this->cpuset, cpu);
(void)isSet;
#else
this->cpu = cpu;
#endif
this->value = 2 * isSet;
return this;
}
typedef struct AffinityPanel_ {
Panel super;
ProcessList* pl;
bool topoView;
Vector *cpuids;
unsigned width;
#ifdef HAVE_LIBHWLOC
MaskItem *topoRoot;
hwloc_const_cpuset_t allCpuset;
hwloc_bitmap_t workCpuset;
#endif
} AffinityPanel;
static void AffinityPanel_delete(Object* cast) {
AffinityPanel* this = (AffinityPanel*) cast;
Panel* super = (Panel*) this;
Panel_done(super);
Vector_delete(this->cpuids);
#ifdef HAVE_LIBHWLOC
hwloc_bitmap_free(this->workCpuset);
MaskItem_delete((Object*) this->topoRoot);
#endif
free(this);
}
#ifdef HAVE_LIBHWLOC
static void AffinityPanel_updateItem(AffinityPanel* this, MaskItem* item) {
Panel* super = (Panel*) this;
item->value = hwloc_bitmap_isincluded(item->cpuset, this->workCpuset) ? 2 :
hwloc_bitmap_intersects(item->cpuset, this->workCpuset) ? 1 : 0;
Panel_add(super, (Object*) item);
}
static void AffinityPanel_updateTopo(AffinityPanel* this, MaskItem* item) {
AffinityPanel_updateItem(this, item);
if (item->sub_tree == 2)
return;
for (int i = 0; i < Vector_size(item->children); i++)
AffinityPanel_updateTopo(this, (MaskItem*) Vector_get(item->children, i));
}
#endif
static void AffinityPanel_update(AffinityPanel* this, bool keepSelected) {
Panel* super = (Panel*) this;
FunctionBar_setLabel(super->currentBar, KEY_F(3), this->topoView ? "Collapse/Expand" : "");
FunctionBar_draw(super->currentBar, NULL);
int oldSelected = Panel_getSelectedIndex(super);
Panel_prune(super);
#ifdef HAVE_LIBHWLOC
if (this->topoView)
AffinityPanel_updateTopo(this, this->topoRoot);
else {
for (int i = 0; i < Vector_size(this->cpuids); i++)
AffinityPanel_updateItem(this, (MaskItem*) Vector_get(this->cpuids, i));
}
#else
Panel_splice(super, this->cpuids);
#endif
if (keepSelected)
Panel_setSelected(super, oldSelected);
super->needsRedraw = true;
}
static HandlerResult AffinityPanel_eventHandler(Panel* super, int ch) {
AffinityPanel* this = (AffinityPanel*) super;
HandlerResult result = IGNORED;
MaskItem* selected = (MaskItem*) Panel_getSelected(super);
bool keepSelected = true;
switch(ch) { switch(ch) {
case KEY_MOUSE: case KEY_MOUSE:
case KEY_RECLICK: case KEY_RECLICK:
case ' ': case ' ':
CheckItem_set(selected, ! (CheckItem_get(selected)) ); #ifdef HAVE_LIBHWLOC
return HANDLED; if (selected->value == 2) {
/* Item was selected, so remove this mask from the top cpuset. */
hwloc_bitmap_andnot(this->workCpuset, this->workCpuset, selected->cpuset);
selected->value = 0;
} else {
/* Item was not or only partial selected, so set all bits from this object
in the top cpuset. */
hwloc_bitmap_or(this->workCpuset, this->workCpuset, selected->cpuset);
selected->value = 2;
}
#else
selected->value = 2 * !selected->value; /* toggle between 0 and 2 */
#endif
result = HANDLED;
break;
#ifdef HAVE_LIBHWLOC
case KEY_F(1):
hwloc_bitmap_copy(this->workCpuset, this->allCpuset);
result = HANDLED;
break;
case KEY_F(2):
this->topoView = !this->topoView;
keepSelected = false;
result = HANDLED;
break;
case KEY_F(3):
case '-':
case '+':
if (selected->sub_tree)
selected->sub_tree = 1 + !(selected->sub_tree - 1); /* toggle between 1 and 2 */
result = HANDLED;
break;
#endif
case 0x0a: case 0x0a:
case 0x0d: case 0x0d:
case KEY_ENTER: case KEY_ENTER:
return BREAK_LOOP; result = BREAK_LOOP;
break;
} }
return IGNORED;
if (HANDLED == result)
AffinityPanel_update(this, keepSelected);
return result;
} }
#ifdef HAVE_LIBHWLOC
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 = " #";
unsigned depth = obj->depth;
unsigned index = obj->logical_index;
size_t off = 0, left = 10 * depth;
char buf[64], indent_buf[left + 1];
if (obj->type == HWLOC_OBJ_PU) {
index = Settings_cpuId(this->pl->settings, obj->os_index);
type_name = "CPU";
index_prefix = "";
}
indent_buf[0] = '\0';
if (depth > 0) {
for (unsigned i = 1; i < depth; i++) {
xSnprintf(&indent_buf[off], left, "%s ", (indent & (1u << i)) ? CRT_treeStr[TREE_STR_VERT] : " ");
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]);
size_t len = strlen(&indent_buf[off]);
off += len, left -= len;
}
xSnprintf(buf, 64, "%s%s%u", type_name, index_prefix, index);
MaskItem *item = MaskItem_newMask(buf, indent_buf, obj->complete_cpuset, false);
if (parent)
Vector_add(parent->children, item);
if (item->sub_tree && parent && parent->sub_tree == 1) {
/* if obj is fully included or fully excluded, collapse the item */
hwloc_bitmap_t result = hwloc_bitmap_alloc();
hwloc_bitmap_and(result, obj->complete_cpuset, this->workCpuset);
int weight = hwloc_bitmap_weight(result);
hwloc_bitmap_free(result);
if (weight == 0 || weight == (hwloc_bitmap_weight(this->workCpuset) + hwloc_bitmap_weight(obj->complete_cpuset)))
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);
if (width > this->width)
this->width = width;
return item;
}
static MaskItem *AffinityPanel_buildTopology(AffinityPanel* this, hwloc_obj_t obj, unsigned indent, MaskItem *parent) {
MaskItem *item = AffinityPanel_addObject(this, obj, indent, parent);
if (obj->next_sibling) {
indent |= (1u << obj->depth);
} else {
indent &= ~(1u << obj->depth);
}
for (unsigned i = 0; i < obj->arity; i++)
AffinityPanel_buildTopology(this, obj->children[i], indent, item);
return parent == NULL ? item : NULL;
}
#endif
PanelClass AffinityPanel_class = { PanelClass AffinityPanel_class = {
.super = { .super = {
.extends = Class(Panel), .extends = Class(Panel),
.delete = Panel_delete .delete = AffinityPanel_delete
}, },
.eventHandler = AffinityPanel_eventHandler .eventHandler = AffinityPanel_eventHandler
}; };
Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) { static const char* const AffinityPanelFunctions[] = {
Panel* this = Panel_new(1, 1, 1, 1, true, Class(CheckItem), FunctionBar_newEnterEsc("Set ", "Cancel ")); "Set ",
Object_setClass(this, Class(AffinityPanel)); "Cancel ",
#ifdef HAVE_LIBHWLOC
"All",
"Topology",
" ",
#endif
NULL
};
static const char* const AffinityPanelKeys[] = {"Enter", "Esc", "F1", "F2", "F3"};
static const int AffinityPanelEvents[] = {13, 27, KEY_F(1), KEY_F(2), KEY_F(3)};
Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity, int* width) {
AffinityPanel* this = AllocThis(AffinityPanel);
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, Class(MaskItem), false, FunctionBar_new(AffinityPanelFunctions, AffinityPanelKeys, AffinityPanelEvents));
this->pl = pl;
this->width = 15;
this->cpuids = Vector_new(Class(MaskItem), true, DEFAULT_SIZE);
#ifdef HAVE_LIBHWLOC
this->topoView = pl->settings->topologyAffinity;
#else
this->topoView = false;
#endif
#ifdef HAVE_LIBHWLOC
this->allCpuset = hwloc_topology_get_complete_cpuset(pl->topology);
this->workCpuset = hwloc_bitmap_alloc();
#endif
Panel_setHeader(super, "Use CPUs:");
Panel_setHeader(this, "Use CPUs:");
int curCpu = 0; int curCpu = 0;
for (int i = 0; i < pl->cpuCount; i++) { for (int i = 0; i < pl->cpuCount; i++) {
char number[10]; char number[16];
xSnprintf(number, 9, "%d", Settings_cpuId(pl->settings, i)); xSnprintf(number, 9, "CPU %d", Settings_cpuId(pl->settings, i));
bool mode; unsigned width = 4 + strlen(number);
if (width > this->width)
this->width = width;
bool isSet = false;
if (curCpu < affinity->used && affinity->cpus[curCpu] == i) { if (curCpu < affinity->used && affinity->cpus[curCpu] == i) {
mode = true; #ifdef HAVE_LIBHWLOC
hwloc_bitmap_set(this->workCpuset, i);
#endif
isSet = true;
curCpu++; curCpu++;
} else {
mode = false;
} }
Panel_add(this, (Object*) CheckItem_newByVal(xStrdup(number), mode));
MaskItem* cpuItem = MaskItem_newSingleton(number, i, isSet);
Vector_add(this->cpuids, (Object*) cpuItem);
} }
return this;
#ifdef HAVE_LIBHWLOC
this->topoRoot = AffinityPanel_buildTopology(this, hwloc_get_root_obj(pl->topology), 0, NULL);
#endif
if (width)
*width = this->width;
AffinityPanel_update(this, false);
return super;
} }
Affinity* AffinityPanel_getAffinity(Panel* this, ProcessList* pl) { Affinity* AffinityPanel_getAffinity(Panel* super, ProcessList* pl) {
AffinityPanel* this = (AffinityPanel*) super;
Affinity* affinity = Affinity_new(pl); Affinity* affinity = Affinity_new(pl);
int size = Panel_size(this);
for (int i = 0; i < size; i++) { #ifdef HAVE_LIBHWLOC
if (CheckItem_get((CheckItem*)Panel_get(this, i))) int i;
Affinity_add(affinity, i); hwloc_bitmap_foreach_begin(i, this->workCpuset)
Affinity_add(affinity, i);
hwloc_bitmap_foreach_end();
#else
for (int i = 0; i < this->pl->cpuCount; i++) {
MaskItem* item = (MaskItem*)Vector_get(this->cpuids, i);
if (item->value)
Affinity_add(affinity, item->cpu);
} }
#endif
return affinity; return affinity;
} }

View File

@ -9,15 +9,32 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#ifdef HAVE_LIBHWLOC
#endif
#include "Panel.h" #include "Panel.h"
#include "Affinity.h" #include "Affinity.h"
#include "ProcessList.h" #include "ProcessList.h"
#include "ListItem.h"
#ifdef HAVE_LIBHWLOC
#endif
#ifdef HAVE_LIBHWLOC
#endif
#ifdef HAVE_LIBHWLOC
#endif
extern PanelClass AffinityPanel_class; extern PanelClass AffinityPanel_class;
extern Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity); extern Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity, int* width);
extern Affinity* AffinityPanel_getAffinity(Panel* this, ProcessList* pl); extern Affinity* AffinityPanel_getAffinity(Panel* super, ProcessList* pl);
#endif #endif

View File

@ -1,56 +1,34 @@
Contributing Guide Contributing Guide
================== ==================
Hello, and thank you so much for taking your time to contribute in any way to Thank you so much for taking the time to contribute in to htop!
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
----------- -----------
Bug reports should be posted in the [Github issue Bug reports should be posted in the [Github issue
tracker](http://github.com/hishamhm/htop/issues). (I reply to them all, but I tracker](https://github.com/htop-dev/htop/issues).
usually do it in batches! :) ) Bug reports are extremely important since it's Bug reports are extremely important since it's impossible for us to test
impossible for me to test htop in every possible system, distribution and htop in every possible system, distribution and scenario. Your feedback
scenario. Your feedback is what keeps the tool stable and always improving! is what keeps the tool stable and always improving! Thank you!
Thank you!
Pull Requests Pull Requests
------------- -------------
Code contributions are most welcome! Just [fork the Code contributions are most welcome! Just [fork the
repo](http://github.com/hishamhm/htop) and send a [pull repo](https://github.com/htop-dev/htop) and send a [pull
request](https://github.com/hishamhm/htop/pulls). Help is especially request](https://github.com/htop-dev/htop/pulls). Help is especially
appreciated for support of platforms other than Linux. If proposing new 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 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 small footprint and perform well on systems under stress -- so unfortunately
can't accept every new feature proposed, as I need to keep the tool slim and we can't accept every new feature proposed, as we need to keep the tool slim
maintainable. Great ideas backed by a PR are always carefully considered for and maintainable. Great ideas backed by a PR are always carefully considered
inclusion, though! Also, PRs containing bug fixes and portability tweaks are a for inclusion though! Also, PRs containing bug fixes and portability tweaks
no-brainer, please send those in! are always included, please send those in!
Feature Requests Feature Requests
---------------- ----------------
Back when htop was hosted in SourceForge, there used to be separate Bug Please label Github issues that are feature requests with the [`feature
Tracker and Feature Request pages. These go all lumped together under "Issues" request`](https://github.com/htop-dev/htop/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22feature+request%22+)
in Github, which is a bit confusing. For this reason, I close Feature Requests label.
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). :-)

View File

@ -353,4 +353,3 @@ Public License instead of this License.
applicable licenses of the version of PLPA used in your combined work, applicable licenses of the version of PLPA used in your combined work,
provided that you include the source code of such version of PLPA when provided that you include the source code of such version of PLPA when
and as the GNU GPL requires distribution of source code. and as the GNU GPL requires distribution of source code.

68
CRT.c
View File

@ -59,6 +59,19 @@ typedef enum TreeStr_ {
TREE_STR_COUNT TREE_STR_COUNT
} TreeStr; } 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_ { typedef enum ColorSchemes_ {
COLORSCHEME_DEFAULT = 0, COLORSCHEME_DEFAULT = 0,
COLORSCHEME_MONOCHROME = 1, COLORSCHEME_MONOCHROME = 1,
@ -113,7 +126,6 @@ typedef enum ColorElements_ {
LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIFTEEN,
LOAD_AVERAGE_FIVE, LOAD_AVERAGE_FIVE,
LOAD_AVERAGE_ONE, LOAD_AVERAGE_ONE,
CHECK_BOX,
CHECK_MARK, CHECK_MARK,
CHECK_TEXT, CHECK_TEXT,
CLOCK, CLOCK,
@ -159,6 +171,17 @@ const char *CRT_treeStrAscii[TREE_STR_COUNT] = {
"-", // TREE_STR_SHUT "-", // 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 #ifdef HAVE_LIBNCURSESW
const char *CRT_treeStrUtf8[TREE_STR_COUNT] = { const char *CRT_treeStrUtf8[TREE_STR_COUNT] = {
@ -171,12 +194,27 @@ const char *CRT_treeStrUtf8[TREE_STR_COUNT] = {
"\xe2\x94\x80", // TREE_STR_SHUT ─ "\xe2\x94\x80", // TREE_STR_SHUT ─
}; };
bool CRT_utf8 = false; 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 ⊞
};
#endif #endif
bool CRT_utf8 = false;
const char **CRT_treeStr = CRT_treeStrAscii; const char **CRT_treeStr = CRT_treeStrAscii;
const char **CRT_checkStr = CRT_checkStrAscii;
const char **CRT_collapStr = CRT_collapStrAscii;
static bool CRT_hasColors; static bool CRT_hasColors;
int CRT_delay = 0; int CRT_delay = 0;
@ -229,8 +267,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD, [LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black), [HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black),
[CLOCK] = A_BOLD, [CLOCK] = A_BOLD,
[CHECK_BOX] = ColorPair(Cyan,Black), [CHECK_MARK] = A_BOLD | ColorPair(Cyan,Black),
[CHECK_MARK] = A_BOLD,
[CHECK_TEXT] = A_NORMAL, [CHECK_TEXT] = A_NORMAL,
[HOSTNAME] = A_BOLD, [HOSTNAME] = A_BOLD,
[CPU_NICE] = ColorPair(Blue,Black), [CPU_NICE] = ColorPair(Blue,Black),
@ -298,8 +335,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD, [LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD, [HELP_BOLD] = A_BOLD,
[CLOCK] = A_BOLD, [CLOCK] = A_BOLD,
[CHECK_BOX] = A_BOLD, [CHECK_MARK] = A_BOLD,
[CHECK_MARK] = A_NORMAL,
[CHECK_TEXT] = A_NORMAL, [CHECK_TEXT] = A_NORMAL,
[HOSTNAME] = A_BOLD, [HOSTNAME] = A_BOLD,
[CPU_NICE] = A_NORMAL, [CPU_NICE] = A_NORMAL,
@ -367,7 +403,6 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = ColorPair(Black,White), [LOAD] = ColorPair(Black,White),
[HELP_BOLD] = ColorPair(Blue,White), [HELP_BOLD] = ColorPair(Blue,White),
[CLOCK] = ColorPair(Black,White), [CLOCK] = ColorPair(Black,White),
[CHECK_BOX] = ColorPair(Blue,White),
[CHECK_MARK] = ColorPair(Black,White), [CHECK_MARK] = ColorPair(Black,White),
[CHECK_TEXT] = ColorPair(Black,White), [CHECK_TEXT] = ColorPair(Black,White),
[HOSTNAME] = ColorPair(Black,White), [HOSTNAME] = ColorPair(Black,White),
@ -436,7 +471,6 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = ColorPair(White,Black), [LOAD] = ColorPair(White,Black),
[HELP_BOLD] = ColorPair(Blue,Black), [HELP_BOLD] = ColorPair(Blue,Black),
[CLOCK] = ColorPair(White,Black), [CLOCK] = ColorPair(White,Black),
[CHECK_BOX] = ColorPair(Blue,Black),
[CHECK_MARK] = ColorPair(Black,Black), [CHECK_MARK] = ColorPair(Black,Black),
[CHECK_TEXT] = ColorPair(Black,Black), [CHECK_TEXT] = ColorPair(Black,Black),
[HOSTNAME] = ColorPair(White,Black), [HOSTNAME] = ColorPair(White,Black),
@ -505,8 +539,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD | ColorPair(White,Blue), [LOAD] = A_BOLD | ColorPair(White,Blue),
[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Blue), [HELP_BOLD] = A_BOLD | ColorPair(Cyan,Blue),
[CLOCK] = ColorPair(White,Blue), [CLOCK] = ColorPair(White,Blue),
[CHECK_BOX] = ColorPair(Cyan,Blue), [CHECK_MARK] = A_BOLD | ColorPair(Cyan,Blue),
[CHECK_MARK] = A_BOLD | ColorPair(White,Blue),
[CHECK_TEXT] = A_NORMAL | ColorPair(White,Blue), [CHECK_TEXT] = A_NORMAL | ColorPair(White,Blue),
[HOSTNAME] = ColorPair(White,Blue), [HOSTNAME] = ColorPair(White,Blue),
[CPU_NICE] = A_BOLD | ColorPair(Cyan,Blue), [CPU_NICE] = A_BOLD | ColorPair(Cyan,Blue),
@ -574,7 +607,6 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[LOAD] = A_BOLD, [LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black), [HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black),
[CLOCK] = ColorPair(Green,Black), [CLOCK] = ColorPair(Green,Black),
[CHECK_BOX] = ColorPair(Green,Black),
[CHECK_MARK] = A_BOLD | ColorPair(Green,Black), [CHECK_MARK] = A_BOLD | ColorPair(Green,Black),
[CHECK_TEXT] = ColorPair(Cyan,Black), [CHECK_TEXT] = ColorPair(Cyan,Black),
[HOSTNAME] = ColorPair(Green,Black), [HOSTNAME] = ColorPair(Green,Black),
@ -731,18 +763,14 @@ void CRT_init(int delay, int colorScheme) {
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
#ifdef HAVE_LIBNCURSESW #ifdef HAVE_LIBNCURSESW
if(strcmp(nl_langinfo(CODESET), "UTF-8") == 0) if(strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
CRT_utf8 = true; CRT_utf8 = true;
else CRT_treeStr = CRT_treeStrUtf8;
CRT_utf8 = false; CRT_checkStr = CRT_checkStrUtf8;
CRT_collapStr = CRT_collapStrUtf8;
}
#endif #endif
CRT_treeStr =
#ifdef HAVE_LIBNCURSESW
CRT_utf8 ? CRT_treeStrUtf8 :
#endif
CRT_treeStrAscii;
#if NCURSES_MOUSE_VERSION > 1 #if NCURSES_MOUSE_VERSION > 1
mousemask(BUTTON1_RELEASED | BUTTON4_PRESSED | BUTTON5_PRESSED, NULL); mousemask(BUTTON1_RELEASED | BUTTON4_PRESSED | BUTTON5_PRESSED, NULL);
#else #else

28
CRT.h
View File

@ -47,6 +47,19 @@ typedef enum TreeStr_ {
TREE_STR_COUNT TREE_STR_COUNT
} TreeStr; } 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_ { typedef enum ColorSchemes_ {
COLORSCHEME_DEFAULT = 0, COLORSCHEME_DEFAULT = 0,
COLORSCHEME_MONOCHROME = 1, COLORSCHEME_MONOCHROME = 1,
@ -101,7 +114,6 @@ typedef enum ColorElements_ {
LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIFTEEN,
LOAD_AVERAGE_FIVE, LOAD_AVERAGE_FIVE,
LOAD_AVERAGE_ONE, LOAD_AVERAGE_ONE,
CHECK_BOX,
CHECK_MARK, CHECK_MARK,
CHECK_TEXT, CHECK_TEXT,
CLOCK, CLOCK,
@ -138,16 +150,28 @@ extern void CRT_handleSIGSEGV(int sgn);
extern const char *CRT_treeStrAscii[TREE_STR_COUNT]; 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 #ifdef HAVE_LIBNCURSESW
extern const char *CRT_treeStrUtf8[TREE_STR_COUNT]; extern const char *CRT_treeStrUtf8[TREE_STR_COUNT];
extern bool CRT_utf8; extern const char *CRT_checkStrUtf8[CHECK_STR_COUNT];
extern const char *CRT_collapStrUtf8[COLLAP_STR_COUNT];
#endif #endif
extern bool CRT_utf8;
extern const char **CRT_treeStr; extern const char **CRT_treeStr;
extern const char **CRT_checkStr;
extern const char **CRT_collapStr;
extern int CRT_delay; extern int CRT_delay;
extern int* CRT_colors; extern int* CRT_colors;

View File

@ -1,3 +1,66 @@
What's new in version 3.0.0
* New maintainers - after a prolonged period of inactivity
from Hisham, the creator and original maintainer, a team
of community maintainers have volunteered to take over a
fork at https://htop.dev and https://github.com/htop-dev
to keep the project going.
* Support ZFS ARC statistics
(thanks to Ross Williams)
* Support more than 2 smaller CPU meter columns
(thanks to Christoph Budziszewski)
* Support Linux proportional set size metrics
(thanks to @linvinus, @ntninja and @himikof)
* Support Linux pressure stall information metrics
(thanks to Ran Benita)
* New display option to show CPU frequency in CPU meters
(thanks to Arnav Singh)
* Update Linux sysfs battery discovery for recent kernels
(thanks to @smattie)
* Add hardware topology information in the affinity panel
(thanks to Bert Wesarg)
* Add timestamp reporting to the strace screen
(thanks to Mario Harjac)
* Add simple, optional vim key mapping mode
(thanks to Daniel Flanagan)
* Added an option to disable the mouse
(thanks to MartinJM)
* Add Solaris11 compatibility
(thanks to Jan Senolt)
* Without an argument -u uses $USER value automatically
(thanks to @solanav)
* Support less(1) search navigation shortcuts
(thanks to @syrrim)
* Update the FreeBSD maximum PID to match FreeBSD change
(thanks to @multiplexd)
* Report values larger than 100 terabytes
(thanks to @adrien1018)
* Widen ST_UID (UID) column to allow for UIDs > 9999
(thanks to DLange)
* BUGFIX: fix makefiles for building with clang
(thanks to Jorge Pereira)
* BUGFIX: fix <sys/sysmacros.h> major() usage
(thanks to @wataash and Kang-Che Sung)
* BUGFIX: fix the STARTTIME column on FreeBSD
(thanks to Rob Crowston)
* BUGFIX: truncate overwide jail names on FreeBSD
(thanks to Rob Crowston)
* BUGFIX: fix reported memory values on FreeBSD
(thanks to Tobias Kortkamp)
* BUGFIX: fix reported CPU meter values on OpenBSD
(thanks to @motet-a)
* BUGFIX: correctly identify other types of zombie process
(thanks to @joder)
* BUGFIX: improve follow-process handling in some situations
(thanks to @wangqr)
* BUGFIX: fix custom meters reverting to unexpected setting
(thanks to @wangqr)
* BUGFIX: close pipe after running lsof(1)
(thanks to Jesin)
* BUGFIX: meters honour setting of counting CPUs from 0/1
(thanks to @rnsanchez)
What's new in version 2.2.0 What's new in version 2.2.0
* Solaris/Illumos/OpenIndiana support * Solaris/Illumos/OpenIndiana support

View File

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

View File

@ -164,4 +164,3 @@ void ColumnsPanel_update(Panel* super) {
} }
this->settings->fields[size] = 0; this->settings->fields[size] = 0;
} }

View File

@ -28,5 +28,4 @@ extern int ColumnsPanel_fieldNameToIndex(const char* name);
extern void ColumnsPanel_update(Panel* super); extern void ColumnsPanel_update(Panel* super);
#endif #endif

View File

@ -100,5 +100,8 @@ 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 percentage numerically"), &(settings->showCPUUsage)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU frequency"), &(settings->showCPUFrequency))); 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 the mouse"), &(settings->enableMouse)));
#ifdef HAVE_LIBHWLOC
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Show topology when selecting affinity by default"), &(settings->topologyAffinity)));
#endif
return this; return this;
} }

View File

@ -154,7 +154,7 @@ char* Header_readMeterName(Header* this, int i, int column) {
int nameLen = strlen(Meter_name(meter)); int nameLen = strlen(Meter_name(meter));
int len = nameLen + 100; int len = nameLen + 100;
char* name = xMalloc(len); char* name = xMalloc(len);
strncpy(name, Meter_name(meter), nameLen); memcpy(name, Meter_name(meter), nameLen);
name[nameLen] = '\0'; name[nameLen] = '\0';
if (meter->param) if (meter->param)
xSnprintf(name + nameLen, len - nameLen, "(%d)", meter->param); xSnprintf(name + nameLen, len - nameLen, "(%d)", meter->param);

View File

@ -56,7 +56,7 @@ static const char* const InfoScreenKeys[] = {"F3", "F4", "F5", "Esc"};
static int InfoScreenEvents[] = {KEY_F(3), KEY_F(4), KEY_F(5), 27}; static int InfoScreenEvents[] = {KEY_F(3), KEY_F(4), KEY_F(5), 27};
InfoScreen* InfoScreen_init(InfoScreen* this, Process* process, FunctionBar* bar, int height, char* panelHeader) { InfoScreen* InfoScreen_init(InfoScreen* this, Process* process, FunctionBar* bar, int height, const char* panelHeader) {
this->process = process; this->process = process;
if (!bar) { if (!bar) {
bar = FunctionBar_new(InfoScreenFunctions, InfoScreenKeys, InfoScreenEvents); bar = FunctionBar_new(InfoScreenFunctions, InfoScreenKeys, InfoScreenEvents);
@ -75,7 +75,7 @@ InfoScreen* InfoScreen_done(InfoScreen* this) {
return this; return this;
} }
void InfoScreen_drawTitled(InfoScreen* this, char* fmt, ...) { void InfoScreen_drawTitled(InfoScreen* this, const char* fmt, ...) {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
attrset(CRT_colors[METER_TEXT]); attrset(CRT_colors[METER_TEXT]);

View File

@ -38,11 +38,11 @@ struct InfoScreen_ {
Vector* lines; Vector* lines;
}; };
extern InfoScreen* InfoScreen_init(InfoScreen* this, Process* process, FunctionBar* bar, int height, char* panelHeader); extern InfoScreen* InfoScreen_init(InfoScreen* this, Process* process, FunctionBar* bar, int height, const char* panelHeader);
extern InfoScreen* InfoScreen_done(InfoScreen* this); extern InfoScreen* InfoScreen_done(InfoScreen* this);
extern void InfoScreen_drawTitled(InfoScreen* this, char* fmt, ...); extern void InfoScreen_drawTitled(InfoScreen* this, const char* fmt, ...);
extern void InfoScreen_addLine(InfoScreen* this, const char* line); extern void InfoScreen_addLine(InfoScreen* this, const char* line);

View File

@ -85,4 +85,3 @@ long ListItem_compare(const void* cast1, const void* cast2) {
ListItem* obj2 = (ListItem*) cast2; ListItem* obj2 = (ListItem*) cast2;
return strcmp(obj1->value, obj2->value); return strcmp(obj1->value, obj2->value);
} }

View File

@ -29,5 +29,4 @@ extern const char* ListItem_getRef(ListItem* this);
extern long ListItem_compare(const void* cast1, const void* cast2); extern long ListItem_compare(const void* cast1, const void* cast2);
#endif #endif

View File

@ -12,7 +12,7 @@ applications_DATA = htop.desktop
pixmapdir = $(datadir)/pixmaps pixmapdir = $(datadir)/pixmaps
pixmap_DATA = htop.png pixmap_DATA = htop.png
AM_CFLAGS = -pedantic -Wall $(wextra_flag) -std=c99 -D_XOPEN_SOURCE_EXTENDED -DSYSCONFDIR=\"$(sysconfdir)\" -I"$(top_srcdir)/$(my_htop_platform)" AM_CFLAGS += -pedantic -Wall $(wextra_flag) -std=c99 -D_XOPEN_SOURCE_EXTENDED -DSYSCONFDIR=\"$(sysconfdir)\" -I"$(top_srcdir)/$(my_htop_platform)"
AM_LDFLAGS = AM_LDFLAGS =
AM_CPPFLAGS = -DNDEBUG AM_CPPFLAGS = -DNDEBUG
@ -203,7 +203,8 @@ endif
SUFFIXES = .h SUFFIXES = .h
BUILT_SOURCES = $(myhtopheaders) $(myhtopplatheaders) BUILT_SOURCES = $(myhtopheaders) $(myhtopplatheaders)
htop_SOURCES = $(myhtopheaders) $(myhtopplatheaders) $(myhtopsources) $(myhtopplatsources) config.h htop_SOURCES = $(myhtopheaders) $(myhtopplatheaders) $(myhtopsources) $(myhtopplatsources)
nodist_htop_SOURCES = config.h
.PHONY: htop-headers clean-htop-headers .PHONY: htop-headers clean-htop-headers
@ -225,7 +226,7 @@ coverage:
$(MAKE) all CFLAGS="" AM_CPPFLAGS="-fprofile-arcs -ftest-coverage -DDEBUG" LDFLAGS="-lgcov" $(MAKE) all CFLAGS="" AM_CPPFLAGS="-fprofile-arcs -ftest-coverage -DDEBUG" LDFLAGS="-lgcov"
.c.h: .c.h:
@srcdir@/scripts/MakeHeader.py $< ./scripts/MakeHeader.py $<
cppcheck: cppcheck:
cppcheck -q -v . --enable=all -DHAVE_CGROUP -DHAVE_OPENVZ -DHAVE_TASKSTATS cppcheck -q -v . --enable=all -DHAVE_CGROUP -DHAVE_OPENVZ -DHAVE_TASKSTATS

1
NEWS
View File

@ -2,4 +2,3 @@
See the commit history for news of the past. See the commit history for news of the past.
See the bug tracker for news of the future. See the bug tracker for news of the future.
Run the program for news of the present. Run the program for news of the present.

View File

@ -264,6 +264,14 @@ void Panel_setSelected(Panel* this, int selected) {
} }
} }
void Panel_splice(Panel *this, Vector* from) {
assert (this != NULL);
assert (from != NULL);
Vector_splice(this->items, from);
this->needsRedraw = true;
}
void Panel_draw(Panel* this, bool focus) { void Panel_draw(Panel* this, bool focus) {
assert (this != NULL); assert (this != NULL);

View File

@ -119,6 +119,8 @@ extern void Panel_setSelected(Panel* this, int selected);
extern void Panel_draw(Panel* this, bool focus); extern void Panel_draw(Panel* this, bool focus);
extern void Panel_splice(Panel *this, Vector* from);
extern bool Panel_onKey(Panel* this, int key); extern bool Panel_onKey(Panel* this, int key);
extern HandlerResult Panel_selectByTyping(Panel* this, int ch); extern HandlerResult Panel_selectByTyping(Panel* this, int ch);

View File

@ -85,7 +85,7 @@ typedef enum ProcessFields {
typedef struct ProcessPidColumn_ { typedef struct ProcessPidColumn_ {
int id; int id;
char* label; const char* label;
} ProcessPidColumn; } ProcessPidColumn;
typedef struct Process_ { typedef struct Process_ {

View File

@ -61,7 +61,7 @@ typedef enum ProcessFields {
typedef struct ProcessPidColumn_ { typedef struct ProcessPidColumn_ {
int id; int id;
char* label; const char* label;
} ProcessPidColumn; } ProcessPidColumn;
typedef struct Process_ { typedef struct Process_ {

View File

@ -93,12 +93,19 @@ ProcessList* ProcessList_init(ProcessList* this, ObjectClass* klass, UsersTable*
#ifdef HAVE_LIBHWLOC #ifdef HAVE_LIBHWLOC
this->topologyOk = false; this->topologyOk = false;
int topoErr = hwloc_topology_init(&this->topology); if (hwloc_topology_init(&this->topology) == 0) {
if (topoErr == 0) { this->topologyOk =
topoErr = hwloc_topology_load(this->topology); #if HWLOC_API_VERSION < 0x00020000
} /* try to ignore the top-level machine object type */
if (topoErr == 0) { 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_MACHINE) &&
this->topologyOk = true; /* ignore caches, which don't add structure */
0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CORE) &&
0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CACHE) &&
0 == hwloc_topology_set_flags(this->topology, HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) &&
#else
0 == hwloc_topology_set_all_types_filter(this->topology, HWLOC_TYPE_FILTER_KEEP_STRUCTURE) &&
#endif
0 == hwloc_topology_load(this->topology);
} }
#endif #endif

View File

@ -62,6 +62,9 @@ typedef struct Settings_ {
bool headerMargin; bool headerMargin;
bool enableMouse; bool enableMouse;
bool vimMode; bool vimMode;
#ifdef HAVE_LIBHWLOC
bool topologyAffinity;
#endif
bool changed; bool changed;
} Settings; } Settings;
@ -256,6 +259,10 @@ static bool Settings_read(Settings* this, const char* fileName) {
didReadMeters = true; didReadMeters = true;
} else if (String_eq(option[0], "vim_mode")) { } else if (String_eq(option[0], "vim_mode")) {
this->vimMode = atoi(option[1]); this->vimMode = atoi(option[1]);
#ifdef HAVE_LIBHWLOC
} else if (String_eq(option[0], "topology_affinity")) {
this->topologyAffinity = !!atoi(option[1]);
#endif
} }
String_freeArray(option); String_freeArray(option);
} }
@ -336,6 +343,9 @@ bool Settings_write(Settings* this) {
fprintf(fd, "right_meters="); writeMeters(this, fd, 1); fprintf(fd, "right_meters="); writeMeters(this, fd, 1);
fprintf(fd, "right_meter_modes="); writeMeterModes(this, fd, 1); fprintf(fd, "right_meter_modes="); writeMeterModes(this, fd, 1);
fprintf(fd, "vim_mode=%d\n", (int) this->vimMode); fprintf(fd, "vim_mode=%d\n", (int) this->vimMode);
#ifdef HAVE_LIBHWLOC
fprintf(fd, "topology_affinity=%d\n", (int) this->topologyAffinity);
#endif
fclose(fd); fclose(fd);
return true; return true;
} }
@ -362,6 +372,9 @@ Settings* Settings_new(int cpuCount) {
this->cpuCount = cpuCount; this->cpuCount = cpuCount;
this->showProgramPath = true; this->showProgramPath = true;
this->highlightThreads = true; this->highlightThreads = true;
#ifdef HAVE_LIBHWLOC
this->topologyAffinity = false;
#endif
this->fields = xCalloc(Platform_numberOfFields+1, sizeof(ProcessField)); this->fields = xCalloc(Platform_numberOfFields+1, sizeof(ProcessField));
// TODO: turn 'fields' into a Vector, // TODO: turn 'fields' into a Vector,

View File

@ -53,6 +53,9 @@ typedef struct Settings_ {
bool headerMargin; bool headerMargin;
bool enableMouse; bool enableMouse;
bool vimMode; bool vimMode;
#ifdef HAVE_LIBHWLOC
bool topologyAffinity;
#endif
bool changed; bool changed;
} Settings; } Settings;

View File

@ -81,10 +81,7 @@ char** String_split(const char* s, char sep, int* n) {
s += size + 1; s += size + 1;
} }
if (s[0] != '\0') { if (s[0] != '\0') {
int size = strlen(s); out[ctr] = xStrdup(s);
char* token = xMalloc(size + 1);
strncpy(token, s, size + 1);
out[ctr] = token;
ctr++; ctr++;
} }
out = xRealloc(out, sizeof(char*) * (ctr + 1)); out = xRealloc(out, sizeof(char*) * (ctr + 1));

View File

@ -152,4 +152,3 @@ STrace screen:
LSOF screen: LSOF screen:
TODO TODO

View File

@ -335,3 +335,15 @@ inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) {
} }
return -1; return -1;
} }
void Vector_splice(Vector* this, Vector* from) {
assert(Vector_isConsistent(this));
assert(Vector_isConsistent(from));
assert(!(this->owner && from->owner));
int olditmes = this->items;
this->items += from->items;
Vector_checkArraySize(this);
for (int j = 0; j < from->items; j++)
this->array[olditmes + j] = from->array[j];
}

View File

@ -88,4 +88,6 @@ extern void Vector_add(Vector* this, void* data_);
extern int Vector_indexOf(Vector* this, void* search_, Object_Compare compare); extern int Vector_indexOf(Vector* this, void* search_, Object_Compare compare);
void Vector_splice(Vector* this, Vector* from);
#endif #endif

View File

@ -14,7 +14,7 @@
#include <stdlib.h> #include <stdlib.h>
}*/ }*/
static inline void fail() { void fail() {
curs_set(1); curs_set(1);
endwin(); endwin();
err(1, NULL); err(1, NULL);
@ -44,6 +44,10 @@ void* xRealloc(void* ptr, size_t size) {
return data; return data;
} }
#undef xAsprintf
#define xAsprintf(strp, fmt, ...) do { int _r=asprintf(strp, fmt, __VA_ARGS__); if (_r < 0) { fail(); } } while(0)
#define xSnprintf(fmt, len, ...) do { int _l=len; int _n=snprintf(fmt, _l, __VA_ARGS__); if (!(_n > -1 && _n < _l)) { curs_set(1); endwin(); err(1, NULL); } } while(0) #define xSnprintf(fmt, len, ...) do { int _l=len; int _n=snprintf(fmt, _l, __VA_ARGS__); if (!(_n > -1 && _n < _l)) { curs_set(1); endwin(); err(1, NULL); } } while(0)
#undef xStrdup #undef xStrdup

View File

@ -11,12 +11,18 @@
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
extern void fail(void);
extern void* xMalloc(size_t size); extern void* xMalloc(size_t size);
extern void* xCalloc(size_t nmemb, size_t size); extern void* xCalloc(size_t nmemb, size_t size);
extern void* xRealloc(void* ptr, size_t size); extern void* xRealloc(void* ptr, size_t size);
#undef xAsprintf
#define xAsprintf(strp, fmt, ...) do { int _r=asprintf(strp, fmt, __VA_ARGS__); if (_r < 0) { fail(); } } while(0)
#define xSnprintf(fmt, len, ...) do { int _l=len; int _n=snprintf(fmt, _l, __VA_ARGS__); if (!(_n > -1 && _n < _l)) { curs_set(1); endwin(); err(1, NULL); } } while(0) #define xSnprintf(fmt, len, ...) do { int _l=len; int _n=snprintf(fmt, _l, __VA_ARGS__); if (!(_n > -1 && _n < _l)) { curs_set(1); endwin(); err(1, NULL); } } while(0)
#undef xStrdup #undef xStrdup

View File

@ -295,6 +295,12 @@ then
]) ])
fi fi
AC_ARG_ENABLE([werror], [AS_HELP_STRING([--enable-werror], [Treat warnings as errors (default: warnings are not errors)])], [enable_werror="$enableval"], [enable_werror=no])
AS_IF([test "x$enable_werror" = "xyes"], [AM_CFLAGS="$AM_CFLAGS -Werror"])
AC_SUBST([AM_CFLAGS])
AC_CHECK_PROGS(PYTHON, [python python3 python2])
AC_SUBST(PYTHON)
# Bail out on errors. # Bail out on errors.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
@ -318,6 +324,7 @@ AM_CONDITIONAL([HTOP_SOLARIS], [test "$my_htop_platform" = solaris])
AM_CONDITIONAL([HTOP_UNSUPPORTED], [test "$my_htop_platform" = unsupported]) AM_CONDITIONAL([HTOP_UNSUPPORTED], [test "$my_htop_platform" = unsupported])
AC_SUBST(my_htop_platform) AC_SUBST(my_htop_platform)
AC_CONFIG_FILES([Makefile htop.1]) AC_CONFIG_FILES([Makefile htop.1])
AC_CONFIG_FILES([scripts/MakeHeader.py], [chmod +x scripts/MakeHeader.py])
AC_OUTPUT AC_OUTPUT
if test "$my_htop_platform" = "unsupported" if test "$my_htop_platform" = "unsupported"

View File

@ -72,4 +72,3 @@ void Battery_getData(double* level, ACPresence* isOnAC) {
CFRelease(power_sources); CFRelease(power_sources);
} }
} }

View File

@ -15,7 +15,7 @@ void CRT_handleSIGSEGV(int sgn) {
(void) sgn; (void) sgn;
CRT_done(); CRT_done();
#ifdef __APPLE__ #ifdef __APPLE__
fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at http://hisham.hm/htop\n"); fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at https://htop.dev\n");
#ifdef HAVE_EXECINFO_H #ifdef HAVE_EXECINFO_H
size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *)); size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *));
fprintf(stderr, "\n Please include in your report the following backtrace: \n"); fprintf(stderr, "\n Please include in your report the following backtrace: \n");
@ -32,4 +32,3 @@ void CRT_handleSIGSEGV(int sgn) {
#endif #endif
abort(); abort();
} }

View File

@ -17,7 +17,7 @@ in the source distribution for its full text.
void CRT_handleSIGSEGV(int sgn) { void CRT_handleSIGSEGV(int sgn) {
(void) sgn; (void) sgn;
CRT_done(); CRT_done();
fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at http://hisham.hm/htop\n"); fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at https://htop.dev\n");
#ifdef HAVE_EXECINFO_H #ifdef HAVE_EXECINFO_H
size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *)); size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *));
fprintf(stderr, "\n Please include in your report the following backtrace: \n"); fprintf(stderr, "\n Please include in your report the following backtrace: \n");
@ -32,4 +32,3 @@ void CRT_handleSIGSEGV(int sgn) {
#endif #endif
abort(); abort();
} }

View File

@ -18,4 +18,3 @@ void CRT_handleSIGSEGV(int sgn) {
fprintf(stderr, "\nPlease contact your platform package maintainer!\n\n"); fprintf(stderr, "\nPlease contact your platform package maintainer!\n\n");
abort(); abort();
} }

View File

@ -325,17 +325,6 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
cachedMem *= pageSizeKb; cachedMem *= pageSizeKb;
pl->cachedMem = cachedMem; pl->cachedMem = cachedMem;
if (fpl->zfsArcEnabled) {
len = sizeof(memZfsArc);
sysctl(MIB_kstat_zfs_misc_arcstats_size, 5, &(memZfsArc), &len , NULL, 0);
memZfsArc /= 1024;
fpl->memZfsArc = memZfsArc;
fpl->memWire -= fpl->memZfsArc;
pl->cachedMem += fpl->memZfsArc;
// maybe when we learn how to make custom memory meter
// we could do custom arc breakdown?
}
if (fpl->zfs.enabled) { if (fpl->zfs.enabled) {
fpl->memWire -= fpl->zfs.size; fpl->memWire -= fpl->zfs.size;
pl->cachedMem += fpl->zfs.size; pl->cachedMem += fpl->zfs.size;

View File

@ -64,7 +64,7 @@ static unsigned long int parseBatInfo(const char *fileName, const unsigned short
} }
char* line = NULL; char* line = NULL;
for (unsigned short int i = 0; i < lineNum; i++) { for (unsigned short int j = 0; j < lineNum; j++) {
free(line); free(line);
line = String_readLine(file); line = String_readLine(file);
if (!line) break; if (!line) break;
@ -194,26 +194,26 @@ static void Battery_getSysData(double* level, ACPresence* isOnAC) {
const char filePath[50]; const char filePath[50];
xSnprintf((char *) filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/type", entryName); xSnprintf((char *) filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/type", entryName);
int fd = open(filePath, O_RDONLY); int fd1 = open(filePath, O_RDONLY);
if (fd == -1) if (fd1 == -1)
continue; continue;
char type[8]; char type[8];
ssize_t typelen = xread(fd, type, 7); ssize_t typelen = xread(fd1, type, 7);
close(fd); close(fd1);
if (typelen < 1) if (typelen < 1)
continue; continue;
if (type[0] == 'B' && type[1] == 'a' && type[2] == 't') { if (type[0] == 'B' && type[1] == 'a' && type[2] == 't') {
xSnprintf((char *) filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/uevent", entryName); xSnprintf((char *) filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/uevent", entryName);
int fd = open(filePath, O_RDONLY); int fd2 = open(filePath, O_RDONLY);
if (fd == -1) { if (fd2 == -1) {
closedir(dir); closedir(dir);
return; return;
} }
char buffer[1024]; char buffer[1024];
ssize_t buflen = xread(fd, buffer, 1023); ssize_t buflen = xread(fd2, buffer, 1023);
close(fd); close(fd2);
if (buflen < 1) { if (buflen < 1) {
closedir(dir); closedir(dir);
return; return;
@ -259,18 +259,18 @@ static void Battery_getSysData(double* level, ACPresence* isOnAC) {
} }
xSnprintf((char *) filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/online", entryName); xSnprintf((char *) filePath, sizeof filePath, SYS_POWERSUPPLY_DIR "/%s/online", entryName);
int fd = open(filePath, O_RDONLY); int fd3 = open(filePath, O_RDONLY);
if (fd == -1) { if (fd3 == -1) {
closedir(dir); closedir(dir);
return; return;
} }
char buffer[2] = ""; char buffer[2] = "";
for(;;) { for(;;) {
ssize_t res = read(fd, buffer, 1); ssize_t res = read(fd3, buffer, 1);
if (res == -1 && errno == EINTR) continue; if (res == -1 && errno == EINTR) continue;
break; break;
} }
close(fd); close(fd3);
if (buffer[0] == '0') { if (buffer[0] == '0') {
*isOnAC = AC_ABSENT; *isOnAC = AC_ABSENT;
} else if (buffer[0] == '1') { } else if (buffer[0] == '1') {

View File

@ -38,4 +38,3 @@ typedef int IOPriority;
#define IOPriority_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 7) #define IOPriority_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 7)
}*/ }*/

View File

@ -39,5 +39,4 @@ typedef int IOPriority;
#define IOPriority_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 7) #define IOPriority_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 7)
#endif #endif

View File

@ -41,4 +41,3 @@ Panel* IOPriorityPanel_new(IOPriority currPrio) {
IOPriority IOPriorityPanel_getIOPriority(Panel* this) { IOPriority IOPriorityPanel_getIOPriority(Panel* this) {
return (IOPriority) ( ((ListItem*) Panel_getSelected(this))->key ); return (IOPriority) ( ((ListItem*) Panel_getSelected(this))->key );
} }

View File

@ -17,5 +17,4 @@ extern Panel* IOPriorityPanel_new(IOPriority currPrio);
extern IOPriority IOPriorityPanel_getIOPriority(Panel* this); extern IOPriority IOPriorityPanel_getIOPriority(Panel* this);
#endif #endif

View File

@ -17,7 +17,7 @@ void CRT_handleSIGSEGV(int sgn) {
(void) sgn; (void) sgn;
CRT_done(); CRT_done();
#ifdef __linux #ifdef __linux
fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at http://hisham.hm/htop\n"); fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at https://htop.dev\n");
#ifdef HAVE_EXECINFO_H #ifdef HAVE_EXECINFO_H
size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *)); size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *));
fprintf(stderr, "\n Please include in your report the following backtrace: \n"); fprintf(stderr, "\n Please include in your report the following backtrace: \n");

View File

@ -514,4 +514,3 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
bool Process_isThread(Process* this) { bool Process_isThread(Process* this) {
return (Process_isUserlandThread(this) || Process_isKernelThread(this)); return (Process_isUserlandThread(this) || Process_isKernelThread(this));
} }

View File

@ -189,5 +189,4 @@ extern long LinuxProcess_compare(const void* v1, const void* v2);
extern bool Process_isThread(Process* this); extern bool Process_isThread(Process* this);
#endif #endif

View File

@ -822,11 +822,11 @@ static char* LinuxProcessList_updateTtyDevice(TtyDriver* ttyDrivers, unsigned in
struct stat sstat; struct stat sstat;
char* fullPath; char* fullPath;
for(;;) { for(;;) {
asprintf(&fullPath, "%s/%d", ttyDrivers[i].path, idx); xAsprintf(&fullPath, "%s/%d", ttyDrivers[i].path, idx);
int err = stat(fullPath, &sstat); int err = stat(fullPath, &sstat);
if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) return fullPath; if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) return fullPath;
free(fullPath); free(fullPath);
asprintf(&fullPath, "%s%d", ttyDrivers[i].path, idx); xAsprintf(&fullPath, "%s%d", ttyDrivers[i].path, idx);
err = stat(fullPath, &sstat); err = stat(fullPath, &sstat);
if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) return fullPath; if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) return fullPath;
free(fullPath); free(fullPath);
@ -837,7 +837,7 @@ static char* LinuxProcessList_updateTtyDevice(TtyDriver* ttyDrivers, unsigned in
if (err == 0 && tty_nr == sstat.st_rdev) return strdup(ttyDrivers[i].path); if (err == 0 && tty_nr == sstat.st_rdev) return strdup(ttyDrivers[i].path);
} }
char* out; char* out;
asprintf(&out, "/dev/%u:%u", maj, min); xAsprintf(&out, "/dev/%u:%u", maj, min);
return out; return out;
} }
@ -1227,9 +1227,9 @@ static inline double LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) {
(sscanf(buffer, "processor: %d", &cpuid) == 1) (sscanf(buffer, "processor: %d", &cpuid) == 1)
) { ) {
if (cpuid < 0 || cpuid > (cpus - 1)) { if (cpuid < 0 || cpuid > (cpus - 1)) {
char buffer[64]; char tmpbuffer[64];
xSnprintf(buffer, sizeof(buffer), PROCCPUINFOFILE " contains out-of-range CPU number %d", cpuid); xSnprintf(tmpbuffer, sizeof(tmpbuffer), PROCCPUINFOFILE " contains out-of-range CPU number %d", cpuid);
CRT_fatalError(buffer); CRT_fatalError(tmpbuffer);
} }
} else if ( } else if (
(sscanf(buffer, "cpu MHz : %lf", &frequency) == 1) || (sscanf(buffer, "cpu MHz : %lf", &frequency) == 1) ||

View File

@ -44,7 +44,7 @@ in the source distribution for its full text.
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x))) #define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
#endif #endif
ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 }; ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, (int)M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
//static ProcessField defaultIoFields[] = { PID, IO_PRIORITY, USER, IO_READ_RATE, IO_WRITE_RATE, IO_RATE, COMM, 0 }; //static ProcessField defaultIoFields[] = { PID, IO_PRIORITY, USER, IO_READ_RATE, IO_WRITE_RATE, IO_RATE, COMM, 0 };
@ -94,12 +94,12 @@ static Htop_Reaction Platform_actionSetIOPriority(State* st) {
LinuxProcess* p = (LinuxProcess*) Panel_getSelected(panel); LinuxProcess* p = (LinuxProcess*) Panel_getSelected(panel);
if (!p) return HTOP_OK; if (!p) return HTOP_OK;
IOPriority ioprio = p->ioPriority; IOPriority ioprio1 = p->ioPriority;
Panel* ioprioPanel = IOPriorityPanel_new(ioprio); Panel* ioprioPanel = IOPriorityPanel_new(ioprio1);
void* set = Action_pickFromVector(st, ioprioPanel, 21, true); void* set = Action_pickFromVector(st, ioprioPanel, 21, true);
if (set) { if (set) {
IOPriority ioprio = IOPriorityPanel_getIOPriority(ioprioPanel); IOPriority ioprio2 = 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, (Arg){ .i = ioprio2 }, NULL);
if (!ok) if (!ok)
beep(); beep();
} }

View File

@ -19,4 +19,3 @@ void CRT_handleSIGSEGV(int sgn) {
fprintf(stderr, "\nPlease contact your platform package maintainer!\n\n"); fprintf(stderr, "\nPlease contact your platform package maintainer!\n\n");
abort(); abort();
} }

View File

@ -400,4 +400,3 @@ void ProcessList_goThroughEntries(ProcessList* this) {
OpenBSDProcessList_scanProcs(opl); OpenBSDProcessList_scanProcs(opl);
OpenBSDProcessList_scanCPUTime(opl); OpenBSDProcessList_scanCPUTime(opl);
} }

4
scripts/MakeHeader.py → scripts/MakeHeader.py.in Executable file → Normal file
View File

@ -1,5 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env @PYTHON@
import os, sys, string, io import os, sys, io
try: try:
from StringIO import StringIO from StringIO import StringIO
except ImportError: except ImportError:

View File

@ -5,4 +5,3 @@ void Battery_getData(double* level, ACPresence* isOnAC) {
*level = -1; *level = -1;
*isOnAC = AC_ERROR; *isOnAC = AC_ERROR;
} }

View File

@ -17,7 +17,7 @@ in the source distribution for its full text.
void CRT_handleSIGSEGV(int sgn) { void CRT_handleSIGSEGV(int sgn) {
(void) sgn; (void) sgn;
CRT_done(); CRT_done();
fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at http://hisham.hm/htop\n"); fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at https://htop.dev\n");
#ifdef HAVE_EXECINFO_H #ifdef HAVE_EXECINFO_H
size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *)); size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *));
fprintf(stderr, "\n Please include in your report the following backtrace: \n"); fprintf(stderr, "\n Please include in your report the following backtrace: \n");

View File

@ -419,4 +419,3 @@ void ProcessList_goThroughEntries(ProcessList* this) {
this->kernelThreads = 1; this->kernelThreads = 1;
proc_walk(&SolarisProcessList_walkproc, this, PR_WALK_LWP); proc_walk(&SolarisProcessList_walkproc, this, PR_WALK_LWP);
} }

View File

@ -685,4 +685,3 @@ describe("htop test suite", function()
os.execute("make lcov && xdg-open lcov/index.html") os.execute("make lcov && xdg-open lcov/index.html")
end) end)
end) end)

View File

@ -5,4 +5,3 @@ void Battery_getData(double* level, ACPresence* isOnAC) {
*level = -1; *level = -1;
*isOnAC = AC_ERROR; *isOnAC = AC_ERROR;
} }

View File

@ -18,4 +18,3 @@ void CRT_handleSIGSEGV(int sgn) {
fprintf(stderr, "\nPlease contact your platform package maintainer!\n\n"); fprintf(stderr, "\nPlease contact your platform package maintainer!\n\n");
abort(); abort();
} }

View File

@ -30,4 +30,3 @@ void UnsupportedProcess_delete(Object* cast) {
// free platform-specific fields here // free platform-specific fields here
free(this); free(this);
} }

View File

@ -15,7 +15,7 @@ in the source distribution for its full text.
extern int ZfsArcMeter_attributes[]; extern int ZfsArcMeter_attributes[];
void ZfsArcMeter_readStats(Meter* this, ZfsArcStats* stats); extern void ZfsArcMeter_readStats(Meter* this, ZfsArcStats* stats);
extern MeterClass ZfsArcMeter_class; extern MeterClass ZfsArcMeter_class;

View File

@ -20,3 +20,5 @@ typedef struct ZfsArcStats_ {
unsigned long long int uncompressed; unsigned long long int uncompressed;
} ZfsArcStats; } ZfsArcStats;
}*/ }*/
static int make_iso_compilers_happy __attribute__((unused));

View File

@ -23,4 +23,5 @@ typedef struct ZfsArcStats_ {
unsigned long long int uncompressed; unsigned long long int uncompressed;
} ZfsArcStats; } ZfsArcStats;
#endif #endif