mirror of
https://github.com/xzeldon/htop.git
synced 2025-07-15 21:44:36 +03:00
Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
29983ff83a | |||
36b7f57200 | |||
c5fe142256 | |||
691b7dd5af | |||
ad0f9c58bf | |||
a8d0f2a7fe | |||
e6596cbd69 | |||
40c9f89971 | |||
09ad8067f4 | |||
bda3ee2b81 | |||
bdb015ffa3 | |||
80a515abcc | |||
5000cefc13 | |||
bf7d98e7ac | |||
c096712b8d | |||
be82448bd5 | |||
68c00b9cdb | |||
3c8d586a1c | |||
3869c43393 | |||
fcca4c2f2d | |||
dd88510dcd | |||
43ffdb0eda | |||
bf395e10c5 | |||
8f259bc5e1 | |||
38e6136b82 | |||
589b0733d9 | |||
c9b58c7fbe | |||
ca06e68037 | |||
3f805cf347 |
11
CPUMeter.c
11
CPUMeter.c
@ -381,6 +381,7 @@ const MeterClass AllCPUs2Meter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "AllCPUs2",
|
||||
@ -401,6 +402,7 @@ const MeterClass LeftCPUsMeter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "LeftCPUs",
|
||||
@ -421,6 +423,7 @@ const MeterClass RightCPUsMeter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "RightCPUs",
|
||||
@ -441,6 +444,7 @@ const MeterClass LeftCPUs2Meter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "LeftCPUs2",
|
||||
@ -461,6 +465,7 @@ const MeterClass RightCPUs2Meter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "RightCPUs2",
|
||||
@ -481,6 +486,7 @@ const MeterClass AllCPUs4Meter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "AllCPUs4",
|
||||
@ -501,6 +507,7 @@ const MeterClass LeftCPUs4Meter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "LeftCPUs4",
|
||||
@ -521,6 +528,7 @@ const MeterClass RightCPUs4Meter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "RightCPUs4",
|
||||
@ -541,6 +549,7 @@ const MeterClass AllCPUs8Meter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "AllCPUs8",
|
||||
@ -561,6 +570,7 @@ const MeterClass LeftCPUs8Meter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "LeftCPUs8",
|
||||
@ -581,6 +591,7 @@ const MeterClass RightCPUs8Meter_class = {
|
||||
},
|
||||
.updateValues = AllCPUsMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "RightCPUs8",
|
||||
|
2
CRT.c
2
CRT.c
@ -772,6 +772,8 @@ static void dumpStderr(void) {
|
||||
|
||||
fsync(STDERR_FILENO);
|
||||
dup2(stderrRedirectBackupFd, STDERR_FILENO);
|
||||
close(stderrRedirectBackupFd);
|
||||
stderrRedirectBackupFd = -1;
|
||||
lseek(stderrRedirectNewFd, 0, SEEK_SET);
|
||||
|
||||
bool header = false;
|
||||
|
5
Header.c
5
Header.c
@ -212,7 +212,10 @@ void Header_draw(const Header* this) {
|
||||
Meter* meter = (Meter*) Vector_get(meters, i);
|
||||
|
||||
float actualWidth = colWidth;
|
||||
if (meter->mode == TEXT_METERMODE) {
|
||||
|
||||
/* Let meters in text mode expand to the right on empty neighbors;
|
||||
except for multi column meters. */
|
||||
if (meter->mode == TEXT_METERMODE && !Meter_isMultiColumn(meter)) {
|
||||
for (int j = 1; j < meter->columnWidthCount; j++) {
|
||||
actualWidth += (float)width * HeaderLayout_layouts[this->headerLayout].widths[col + j] / 100.0F;
|
||||
}
|
||||
|
2
Header.h
2
Header.h
@ -23,7 +23,7 @@ typedef struct Header_ {
|
||||
int height;
|
||||
} Header;
|
||||
|
||||
#define Header_forEachColumn(this_, i_) for (size_t (i_)=0; (i_) < HeaderLayout_getColumns((this_)->headerLayout); ++(i_))
|
||||
#define Header_forEachColumn(this_, i_) for (size_t (i_)=0, H_fEC_numColumns_ = HeaderLayout_getColumns((this_)->headerLayout); (i_) < H_fEC_numColumns_; ++(i_))
|
||||
|
||||
Header* Header_new(ProcessList* pl, Settings* settings, HeaderLayout hLayout);
|
||||
|
||||
|
@ -82,6 +82,6 @@ HeaderOptionsPanel* HeaderOptionsPanel_new(Settings* settings, ScreenManager* sc
|
||||
for (int i = 0; i < LAST_HEADER_LAYOUT; i++) {
|
||||
Panel_add(super, (Object*) CheckItem_newByVal(HeaderLayout_layouts[i].description, false));
|
||||
}
|
||||
CheckItem_set((CheckItem*)Panel_get(super, settings->hLayout), true);
|
||||
CheckItem_set((CheckItem*)Panel_get(super, scr->header->headerLayout), true);
|
||||
return this;
|
||||
}
|
||||
|
@ -61,8 +61,8 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) {
|
||||
if (ch == KEY_RESIZE)
|
||||
return IGNORED;
|
||||
|
||||
/* reset on every normal key */
|
||||
if (ch != ERR)
|
||||
/* reset on every normal key, except mouse events while mouse support is disabled */
|
||||
if (ch != ERR && (ch != KEY_MOUSE || this->state->settings->enableMouse))
|
||||
this->state->hideProcessSelection = false;
|
||||
|
||||
if (EVENT_IS_HEADER_CLICK(ch)) {
|
||||
|
@ -33,10 +33,14 @@ static void MemorySwapMeter_updateValues(Meter* this) {
|
||||
static void MemorySwapMeter_draw(Meter* this, int x, int y, int w) {
|
||||
MemorySwapMeterData* data = this->meterData;
|
||||
|
||||
/* Use the same width for each sub meter to align with CPU meter */
|
||||
const int colwidth = w / 2;
|
||||
const int diff = w - colwidth * 2;
|
||||
|
||||
assert(data->memoryMeter->draw);
|
||||
data->memoryMeter->draw(data->memoryMeter, x, y, w / 2);
|
||||
data->memoryMeter->draw(data->memoryMeter, x, y, colwidth);
|
||||
assert(data->swapMeter->draw);
|
||||
data->swapMeter->draw(data->swapMeter, x + w / 2, y, w - w / 2);
|
||||
data->swapMeter->draw(data->swapMeter, x + colwidth + diff, y, colwidth);
|
||||
}
|
||||
|
||||
static void MemorySwapMeter_init(Meter* this) {
|
||||
@ -91,6 +95,7 @@ const MeterClass MemorySwapMeter_class = {
|
||||
},
|
||||
.updateValues = MemorySwapMeter_updateValues,
|
||||
.defaultMode = CUSTOM_METERMODE,
|
||||
.isMultiColumn = true,
|
||||
.name = "MemorySwap",
|
||||
.uiName = "Memory & Swap",
|
||||
.description = "Combined memory and swap usage",
|
||||
|
2
Meter.h
2
Meter.h
@ -73,6 +73,7 @@ typedef struct MeterClass_ {
|
||||
const char* const caption; /* prefix in the actual header */
|
||||
const char* const description; /* optional meter description in header setup menu */
|
||||
const uint8_t maxItems;
|
||||
const bool isMultiColumn; /* whether the meter draws multiple sub-columns (defaults to false) */
|
||||
} MeterClass;
|
||||
|
||||
#define As_Meter(this_) ((const MeterClass*)((this_)->super.klass))
|
||||
@ -92,6 +93,7 @@ typedef struct MeterClass_ {
|
||||
#define Meter_attributes(this_) As_Meter(this_)->attributes
|
||||
#define Meter_name(this_) As_Meter(this_)->name
|
||||
#define Meter_uiName(this_) As_Meter(this_)->uiName
|
||||
#define Meter_isMultiColumn(this_) As_Meter(this_)->isMultiColumn
|
||||
|
||||
typedef struct GraphData_ {
|
||||
struct timeval time;
|
||||
|
@ -715,8 +715,10 @@ void Process_printPercentage(float val, char* buffer, int n, int* attr) {
|
||||
}
|
||||
xSnprintf(buffer, n, "%4.1f ", val);
|
||||
} else if (val < 999) {
|
||||
*attr = CRT_colors[PROCESS_MEGABYTES];
|
||||
xSnprintf(buffer, n, "%3d. ", (int)val);
|
||||
} else {
|
||||
*attr = CRT_colors[PROCESS_MEGABYTES];
|
||||
xSnprintf(buffer, n, "%4d ", (int)val);
|
||||
}
|
||||
} else {
|
||||
|
110
README
110
README
@ -1,10 +1,12 @@
|
||||
# [](https://htop.dev)
|
||||
# [](https://htop.dev)
|
||||
|
||||
[](https://github.com/htop-dev/htop/actions)
|
||||
[](https://scan.coverity.com/projects/21665)
|
||||
[](https://groups.io/g/htop)
|
||||
[](https://web.libera.chat/#htop)
|
||||
[](https://github.com/htop-dev/htop/releases/latest)
|
||||
[](https://github.com/htop-dev/htop/releases/latest)
|
||||
[](https://repology.org/project/htop/versions)
|
||||
[](COPYING?raw=true)
|
||||
|
||||

|
||||
|
||||
@ -13,26 +15,30 @@
|
||||
`htop` is a cross-platform interactive process viewer.
|
||||
|
||||
`htop` allows scrolling the list of processes vertically and horizontally to see their full command lines and related information like memory and CPU consumption.
|
||||
Also system wide information, like load average or swap usage, is shown.
|
||||
|
||||
The information displayed is configurable through a graphical setup and can be sorted and filtered interactively.
|
||||
|
||||
Tasks related to processes (e.g. killing and renicing) can be done without entering their PIDs.
|
||||
|
||||
Running `htop` requires `ncurses` libraries (typically named libncursesw*).
|
||||
Running `htop` requires `ncurses` libraries, typically named libncurses(w).
|
||||
|
||||
For more information and details on how to contribute to `htop` visit [htop.dev](https://htop.dev).
|
||||
`htop` is written in C.
|
||||
|
||||
For more information and details visit [htop.dev](https://htop.dev).
|
||||
|
||||
## Build instructions
|
||||
|
||||
### Prerequisite
|
||||
List of build-time dependencies:
|
||||
* `build-essential` standard GNU autotools-based
|
||||
* `autoconf`
|
||||
* `autotools`
|
||||
* `ncurses`
|
||||
* standard GNU autotools-based C toolchain
|
||||
- C99 compliant compiler
|
||||
- `autoconf`
|
||||
- `autotools`
|
||||
* `ncurses`
|
||||
|
||||
**Note about `ncurses`:**
|
||||
> htop requires ncurses 6.0. Be aware the appropriate package is sometimes still called libncurses5 (on Debian/Ubuntu). Also ncurses usually comes in two flavours:
|
||||
> `htop` requires `ncurses` 6.0. Be aware the appropriate package is sometimes still called libncurses5 (on Debian/Ubuntu). Also `ncurses` usually comes in two flavours:
|
||||
>* With Unicode support.
|
||||
>* Without Unicode support.
|
||||
>
|
||||
@ -42,27 +48,26 @@ List of additional build-time dependencies (based on feature flags):
|
||||
* `sensors`
|
||||
* `hwloc`
|
||||
* `libcap`
|
||||
* `libnl-3`
|
||||
|
||||
Compiling `htop` requires the header files for `ncurses` . Install these and other required packages for C development from your package manager.
|
||||
Install these and other required packages for C development from your package manager.
|
||||
|
||||
**Debian/Ubuntu**
|
||||
~~~ shell
|
||||
sudo apt install libncursesw5-dev autotools-dev autoconf
|
||||
sudo apt install libncursesw5-dev autotools-dev autoconf build-essential
|
||||
~~~
|
||||
|
||||
**Fedora/RHEL**
|
||||
~~~ shell
|
||||
sudo dnf install ncurses-devel automake autoconf
|
||||
sudo dnf install ncurses-devel automake autoconf gcc
|
||||
~~~
|
||||
|
||||
### Compiling from source:
|
||||
To compile from sources downloaded from the Git repository (`git clone` or downloads from [Github releases](https://github.com/htop-dev/htop/releases/)), then run:
|
||||
### Compile from source:
|
||||
To compile from source, download from the Git repository (`git clone` or downloads from [GitHub releases](https://github.com/htop-dev/htop/releases/)), then run:
|
||||
~~~ shell
|
||||
./autogen.sh && ./configure && make
|
||||
~~~
|
||||
|
||||
By default `make install` will install into `/usr/local`, for changing the path use `./configure --prefix=/some/path`.
|
||||
|
||||
### Install
|
||||
To install on the local system run `make install`. By default `make install` installs into `/usr/local`. To change this path use `./configure --prefix=/some/path`.
|
||||
|
||||
@ -74,52 +79,55 @@ To install on the local system run `make install`. By default `make install` ins
|
||||
|
||||
* `--enable-unicode`:
|
||||
enable Unicode support
|
||||
dependency: *libncursesw*
|
||||
default: *yes*
|
||||
* `--enable-pcp`:
|
||||
enable Performance Co-Pilot support via a new pcp-htop utility
|
||||
dependency: *libpcp*
|
||||
default: *no*
|
||||
- dependency: *libncursesw*
|
||||
- default: *yes*
|
||||
* `--enable-affinity`:
|
||||
enable `sched_setaffinity(2)` and `sched_getaffinity(2)` for affinity support; conflicts with hwloc
|
||||
default: *check*
|
||||
- default: *check*
|
||||
* `--enable-hwloc`:
|
||||
enable hwloc support for CPU affinity; disables affinity support
|
||||
dependency: *libhwloc*
|
||||
default: *no*
|
||||
- dependency: *libhwloc*
|
||||
- default: *no*
|
||||
* `--enable-static`:
|
||||
build a static htop binary; hwloc and delay accounting are not supported
|
||||
default: *no*
|
||||
- default: *no*
|
||||
* `--enable-debug`:
|
||||
Enable asserts and internal sanity checks; implies a performance penalty
|
||||
default: *no*
|
||||
- default: *no*
|
||||
|
||||
#### Performance Co-Pilot
|
||||
|
||||
* `--enable-pcp`:
|
||||
enable Performance Co-Pilot support via a new pcp-htop utility
|
||||
- dependency: *libpcp*
|
||||
- default: *no*
|
||||
|
||||
#### Linux
|
||||
|
||||
* `--enable-sensors`:
|
||||
enable libsensors(3) support for reading temperature data
|
||||
dependencies: *libsensors-dev*(build-time), at runtime *libsensors* is loaded via `dlopen(3)` if available
|
||||
default: *check*
|
||||
- dependencies: *libsensors-dev*(build-time), at runtime *libsensors* is loaded via `dlopen(3)` if available
|
||||
- default: *check*
|
||||
* `--enable-capabilities`:
|
||||
enable Linux capabilities support
|
||||
dependency: *libcap*
|
||||
default: *check*
|
||||
- dependency: *libcap*
|
||||
- default: *check*
|
||||
* `--with-proc`:
|
||||
location of a Linux-compatible proc filesystem
|
||||
default: */proc*
|
||||
- default: */proc*
|
||||
* `--enable-openvz`:
|
||||
enable OpenVZ support
|
||||
default: *no*
|
||||
- default: *no*
|
||||
* `--enable-vserver`:
|
||||
enable VServer support
|
||||
default: *no*
|
||||
- default: *no*
|
||||
* `--enable-ancient-vserver`:
|
||||
enable ancient VServer support (implies `--enable-vserver`)
|
||||
default: *no*
|
||||
- default: *no*
|
||||
* `--enable-delayacct`:
|
||||
enable Linux delay accounting support
|
||||
dependencies: *pkg-config*(build-time), *libnl-3* and *libnl-genl-3*
|
||||
default: *check*
|
||||
- dependencies: *pkg-config*(build-time), *libnl-3* and *libnl-genl-3*
|
||||
- default: *check*
|
||||
|
||||
|
||||
## Runtime dependencies:
|
||||
@ -128,37 +136,39 @@ To install on the local system run `make install`. By default `make install` ins
|
||||
|
||||
### Runtime optional dependencies:
|
||||
`htop` has a set of fixed optional dependencies, depending on build/configure option used:
|
||||
* `libdl`, if not building static and support for some of the optional libraries is enabled, is always required when support for to optionally load dependencies (i.e. `libsensors`, `systemd`) is present.
|
||||
* `libcap`, user-space interfaces to the POSIX 1003.1e, is always required when `--enable-capabilities` was used to configure `htop`.
|
||||
|
||||
#### Linux
|
||||
* `libdl`, if not building a static binary, is always required when support for optional dependencies (i.e. `libsensors`, `libsystemd`) is present.
|
||||
* `libcap`, user-space interfaces to POSIX 1003.1e capabilities, is always required when `--enable-capabilities` was used to configure `htop`.
|
||||
* `libsensors`, readout of temperatures and CPU speeds, is optional even when `--enable-sensors` was used to configure `htop`.
|
||||
* `systemd` is optional when `--enable-static` was not used to configure `htop` (Linux only). If building statically and `libsystemd` is not found by `configure` support for the SystemD meter is disabled entirely.
|
||||
* `libsystemd` is optional when `--enable-static` was not used to configure `htop`. If building statically and `libsystemd` is not found by `configure`, support for the systemd meter is disabled entirely.
|
||||
|
||||
`htop` checks for the availability of the actual runtime lib as `htop` runs.
|
||||
`htop` checks for the availability of the actual runtime libraries as `htop` runs.
|
||||
|
||||
**BSD**
|
||||
On most *BSD systems you also have `kvm` as a static requirement to read all the kernel information.
|
||||
#### BSD
|
||||
On most BSD systems `kvm` is a requirement to read kernel information.
|
||||
|
||||
More information on required and optional dependencies can be found in [configure.ac](configure.ac).
|
||||
|
||||
## Usage
|
||||
See the manual page (`man htop`) or the on-line help ('F1' or 'h' inside `htop`) for a list of supported key commands.
|
||||
See the manual page (`man htop`) or the help menu (**F1** or **h** inside `htop`) for a list of supported key commands.
|
||||
|
||||
## Support
|
||||
|
||||
If you have trouble running `htop` please consult your Operating System / Linux distribution documentation for getting support and filing bugs.
|
||||
If you have trouble running `htop` please consult your operating system / Linux distribution documentation for getting support and filing bugs.
|
||||
|
||||
## Bugs, development feedback
|
||||
|
||||
We have a [development mailing list](https://htop.dev/mailinglist.html). Feel free to subscribe for release announcements or asking questions on the development of htop.
|
||||
We have a [development mailing list](https://htop.dev/mailinglist.html). Feel free to subscribe for release announcements or asking questions on the development of `htop`.
|
||||
|
||||
You can also join our IRC channel #htop on Libera.Chat and talk to the developers there.
|
||||
You can also join our IRC channel [#htop on Libera.Chat](https://web.libera.chat/#htop) and talk to the developers there.
|
||||
|
||||
If you have found an issue with the source of htop, please check whether this has already been reported in our [Github issue tracker](https://github.com/htop-dev/htop/issues).
|
||||
If not, please file a new issue describing the problem you have found, the location in the source code you are referring to and a possible fix.
|
||||
If you have found an issue within the source of `htop`, please check whether this has already been reported in our [GitHub issue tracker](https://github.com/htop-dev/htop/issues).
|
||||
If not, please file a new issue describing the problem you have found, the potential location in the source code you are referring to and a possible fix if available.
|
||||
|
||||
## History
|
||||
|
||||
`htop` was invented, developed and maintained by Hisham Muhammad from 2004 to 2019. His [legacy repository](https://github.com/hishamhm/htop/) has been archived to preserve the history.
|
||||
`htop` was invented, developed and maintained by [Hisham Muhammad](https://hisham.hm/) from 2004 to 2019. His [legacy repository](https://github.com/hishamhm/htop/) has been archived to preserve the history.
|
||||
|
||||
In 2020 a [team](https://github.com/orgs/htop-dev/people) took over the development amicably and continues to maintain `htop` collaboratively.
|
||||
|
||||
|
@ -181,7 +181,7 @@ static bool Settings_read(Settings* this, const char* fileName, unsigned int ini
|
||||
this->config_version = atoi(option[1]);
|
||||
if (this->config_version > CONFIG_READER_MIN_VERSION) {
|
||||
// the version of the config file on disk is newer than what we can read
|
||||
fprintf(stderr, "WARNING: %s specifies configuration format version v%d, but this %s binary supports up to v%d.", fileName, this->config_version, PACKAGE, CONFIG_READER_MIN_VERSION);
|
||||
fprintf(stderr, "WARNING: %s specifies configuration format version v%d, but this %s binary supports up to v%d\n.", fileName, this->config_version, PACKAGE, CONFIG_READER_MIN_VERSION);
|
||||
fprintf(stderr, " The configuration version will be downgraded to v%d when %s exits.\n", CONFIG_READER_MIN_VERSION, PACKAGE);
|
||||
String_freeArray(option);
|
||||
fclose(fd);
|
||||
@ -542,7 +542,7 @@ Settings* Settings_new(unsigned int initialCpuCount, Hashtable* dynamicColumns)
|
||||
}
|
||||
if (!ok) {
|
||||
this->changed = true;
|
||||
Settings_read(this, SYSCONFDIR "/htoprc", initialCpuCount);
|
||||
ok = Settings_read(this, SYSCONFDIR "/htoprc", initialCpuCount);
|
||||
}
|
||||
if (!ok) {
|
||||
Settings_defaultMeters(this, initialCpuCount);
|
||||
|
16
XUtils.c
16
XUtils.c
@ -78,6 +78,22 @@ void* xReallocArray(void* ptr, size_t nmemb, size_t size) {
|
||||
return xRealloc(ptr, nmemb * size);
|
||||
}
|
||||
|
||||
void* xReallocArrayZero(void* ptr, size_t prevmemb, size_t newmemb, size_t size) {
|
||||
assert((ptr == NULL) == (prevmemb == 0));
|
||||
|
||||
if (prevmemb == newmemb) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* ret = xReallocArray(ptr, newmemb, size);
|
||||
|
||||
if (newmemb > prevmemb) {
|
||||
memset((unsigned char*)ret + prevmemb * size, '\0', (newmemb - prevmemb) * size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool String_contains_i(const char* s1, const char* s2) {
|
||||
return strcasestr(s1, s2) != NULL;
|
||||
}
|
||||
|
2
XUtils.h
2
XUtils.h
@ -30,6 +30,8 @@ void* xRealloc(void* ptr, size_t size) ATTR_ALLOC_SIZE1(2);
|
||||
|
||||
void* xReallocArray(void* ptr, size_t nmemb, size_t size) ATTR_ALLOC_SIZE2(2, 3);
|
||||
|
||||
void* xReallocArrayZero(void* ptr, size_t prevmemb, size_t newmemb, size_t size) ATTR_ALLOC_SIZE2(3, 4);
|
||||
|
||||
/*
|
||||
* String_startsWith gives better performance if strlen(match) can be computed
|
||||
* at compile time (e.g. when they are immutable string literals). :)
|
||||
|
@ -6,7 +6,7 @@
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
AC_INIT([htop], [3.1.0-rc2], [htop@groups.io], [], [https://htop.dev/])
|
||||
AC_INIT([htop], [3.1.0], [htop@groups.io], [], [https://htop.dev/])
|
||||
|
||||
AC_CONFIG_SRCDIR([htop.c])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
@ -367,7 +367,7 @@ if test "$enable_static" = yes; then
|
||||
fi
|
||||
if test "$my_htop_platform" = "solaris"; then
|
||||
# On OmniOS /usr/include/sys/regset.h redefines ERR to 13 - \r, breaking the Enter key.
|
||||
# Since ncruses macros use the ERR macro, we can not use another name.
|
||||
# Since ncurses macros use the ERR macro, we can not use another name.
|
||||
AC_DEFINE([ERR], [(-1)], [Predefine ncurses macro.])
|
||||
fi
|
||||
AC_CHECK_FUNCS( [set_escdelay] )
|
||||
|
@ -269,7 +269,7 @@ ERROR_A:
|
||||
Process_updateCmdline(proc, k->kp_proc.p_comm, 0, strlen(k->kp_proc.p_comm));
|
||||
}
|
||||
|
||||
// Converts nanoseconds to hundreths of a second (centiseconds) as needed by the "time" field of the Process struct.
|
||||
// Converts nanoseconds to hundredths of a second (centiseconds) as needed by the "time" field of the Process struct.
|
||||
static long long int nanosecondsToCentiseconds(uint64_t nanoseconds) {
|
||||
const uint64_t centiseconds_per_second = 100;
|
||||
const uint64_t nanoseconds_per_second = 1e9;
|
||||
|
@ -432,7 +432,8 @@ void Platform_gettime_monotonic(uint64_t* msec) {
|
||||
|
||||
#else
|
||||
|
||||
Generic_gettime_monotomic(msec);
|
||||
Generic_gettime_monotonic(msec);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -167,11 +167,11 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super) {
|
||||
|
||||
DIR* dir = opendir("/sys/devices/system/cpu");
|
||||
if (!dir) {
|
||||
super->activeCPUs = 1;
|
||||
super->existingCPUs = 1;
|
||||
this->cpuData = xReallocArray(this->cpuData, 2, sizeof(CPUData));
|
||||
this->cpuData = xReallocArrayZero(this->cpuData, super->existingCPUs ? (super->existingCPUs + 1) : 0, 2, sizeof(CPUData));
|
||||
this->cpuData[0].online = true; /* average is always "online" */
|
||||
this->cpuData[1].online = true;
|
||||
super->activeCPUs = 1;
|
||||
super->existingCPUs = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -204,10 +204,7 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super) {
|
||||
/* readdir() iterates with no specific order */
|
||||
unsigned int max = MAXIMUM(existing, id + 1);
|
||||
if (max > currExisting) {
|
||||
this->cpuData = xReallocArray(this->cpuData, max + /* aggregate */ 1, sizeof(CPUData));
|
||||
for (unsigned int j = currExisting; j < max; j++) {
|
||||
this->cpuData[j].online = false;
|
||||
}
|
||||
this->cpuData = xReallocArrayZero(this->cpuData, currExisting ? (currExisting + 1) : 0, max + /* aggregate */ 1, sizeof(CPUData));
|
||||
this->cpuData[0].online = true; /* average is always "online" */
|
||||
currExisting = max;
|
||||
}
|
||||
@ -1426,7 +1423,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||
{
|
||||
bool prev = proc->usesDeletedLib;
|
||||
|
||||
if ((lp->m_lrs == 0 && (settings->flags & PROCESS_FLAG_LINUX_LRS_FIX)) ||
|
||||
if ((settings->flags & PROCESS_FLAG_LINUX_LRS_FIX) ||
|
||||
(settings->highlightDeletedExe && !proc->procExeDeleted && !proc->isKernelThread && !proc->isUserlandThread)) {
|
||||
// Check if we really should recalculate the M_LRS value for this process
|
||||
uint64_t passedTimeInMs = pl->realtimeMs - lp->last_mlrs_calctime;
|
||||
|
@ -1,63 +1,47 @@
|
||||
{
|
||||
<ncurses internal memory allocated at startup>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
fun:CRT_init
|
||||
fun:main
|
||||
}
|
||||
|
||||
{
|
||||
<ncurses internal memory allocated at startup>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
fun:CRT_init
|
||||
}
|
||||
|
||||
{
|
||||
<ncurses internal memory>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
fun:wgetch
|
||||
fun:ScreenManager_run
|
||||
fun:Action_runSetup
|
||||
fun:actionSetup
|
||||
fun:MainPanel_eventHandler
|
||||
fun:ScreenManager_run
|
||||
fun:main
|
||||
}
|
||||
|
||||
{
|
||||
<ncurses internal memory>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
fun:wgetch
|
||||
fun:ScreenManager_run
|
||||
fun:main
|
||||
}
|
||||
|
||||
{
|
||||
<ncurses internal memory>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
fun:wrefresh
|
||||
fun:main
|
||||
}
|
||||
|
||||
{
|
||||
<ncurses internal memory>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:realloc
|
||||
fun:_nc_doalloc
|
||||
fun:_nc_tparm_analyze
|
||||
fun:tparm
|
||||
match-leak-kinds: possible,reachable
|
||||
...
|
||||
fun:doupdate_sp
|
||||
fun:wrefresh
|
||||
obj:*
|
||||
}
|
||||
|
||||
{
|
||||
<ncurses internal memory>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: possible,reachable
|
||||
...
|
||||
fun:newterm_sp
|
||||
fun:newterm
|
||||
fun:initscr
|
||||
fun:CRT_init
|
||||
}
|
||||
|
||||
{
|
||||
<ncurses internal memory>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
obj:*/libtinfo*
|
||||
fun:CRT_init
|
||||
}
|
||||
|
||||
{
|
||||
<ncurses internal memory>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
obj:*/libncurses*
|
||||
fun:CRT_init
|
||||
}
|
||||
|
||||
{
|
||||
<ncurses internal memory>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: possible,reachable
|
||||
...
|
||||
obj:*/libncurses*
|
||||
fun:CRT_setColors
|
||||
fun:CRT_init
|
||||
}
|
||||
|
@ -3,4 +3,4 @@
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
SCRIPTDIR=$(dirname "$SCRIPT")
|
||||
|
||||
valgrind --leak-check=full --show-reachable=yes --show-leak-kinds=all --track-fds=yes --errors-for-leak-kinds=all --suppressions="${SCRIPTDIR}/htop_suppressions.valgrind" "${SCRIPTDIR}/../htop"
|
||||
valgrind --leak-check=full --show-reachable=yes --show-leak-kinds=all --track-fds=yes --errors-for-leak-kinds=all --track-origins=yes --suppressions="${SCRIPTDIR}/htop_suppressions.valgrind" "${SCRIPTDIR}/../htop"
|
||||
|
Reference in New Issue
Block a user