24 Commits

Author SHA1 Message Date
ad8aa2ce77 Bump version number for 3.0.3 release 2020-12-07 11:49:14 +11:00
b92cfa7d7a Merge branch 'conversion' of https://github.com/cgzones/htop into cgzones-conversion 2020-12-07 11:41:22 +11:00
57d9ecc551 OpenBSD update
- compilation failures like `return &this->this;` -> `return &this->super;`
- iwyu update
- misc cleanup
2020-12-06 16:20:55 +01:00
ad764ff972 Introduce METER_BUFFER_CHECK and METER_BUFFER_APPEND_CHR to cleanup writing to bar buffers
Closes: #294
2020-12-06 16:03:44 +01:00
77ec86aff4 Use size_t as type for buffer length in Process 2020-12-06 16:03:44 +01:00
e1ce141bc3 Use size_t as len type for Meter_UpdateValues
Most of the time the parameter is passed to snprintf type functions
2020-12-06 16:03:44 +01:00
d9224c66a4 Use size_t as len type for xSnprintf
Like the C snprintf function
2020-12-06 16:03:44 +01:00
3d15ba5197 Remove unused function Header_readMeterName 2020-12-06 16:03:25 +01:00
7ba25aa3c4 IWYU update 2020-12-06 15:32:16 +01:00
22f8f8000c Initialize buffer for retrieved path
This avoids a warning on GCC 11.

Fixes #369
2020-12-06 11:51:03 +01:00
4c4ba9d949 DragonFlyBSDProcessList: fix missing type 2020-12-06 00:43:41 +01:00
8d1595a20e FreeBSD: fix crash on empty environment
e.g. on kernel threads
2020-12-05 20:34:23 +01:00
876194492f LinuxProcessList: add underscore suffix for raw struct name
Fit the general coding style
2020-12-05 20:25:54 +01:00
5f528b7455 Meter: fix bar coloring without wide ncurses support
attrset() seems to not work with mvaddchnstr()
2020-12-05 20:01:10 +01:00
641fd2c4ad RichString: avoid signed integer misuse 2020-12-05 20:01:10 +01:00
f913680020 Hide degree character without wide ncurses support 2020-12-05 20:01:10 +01:00
f0a9dfc37e Resolve conversion from int to char 2020-12-05 19:58:32 +01:00
1e9b184367 Resolve conversion from int to unsigned and back 2020-12-05 19:58:32 +01:00
ba1549f99b Resolve conversion from int to short 2020-12-05 19:58:32 +01:00
f61e74a4af Resolve conversion from ssize_t to int for readlink return value 2020-12-05 19:58:32 +01:00
8029e9af04 Update htop logo, provide .svg file as well 2020-12-05 13:46:34 +01:00
ef0fc7129e Update AUTHORS file with htop-dev team 2020-12-05 11:07:32 +01:00
bc16fa037f Convert personal copyright authorship to team 2020-12-04 13:55:55 +01:00
cc7f16bb8f Some minor additions to the changelog 2020-12-04 07:51:33 +01:00
59 changed files with 419 additions and 335 deletions

12
AUTHORS
View File

@ -1 +1,11 @@
Hisham H. Muhammad Originally authored by:
Hisham H. Muhammad
Currently maintained by the htop dev team:
Benny Baumann
Christian Göttsche
Daniel Lange
Nathan Scott
For the full list of contributors see:
git log --format="%aN" | sort -u

View File

@ -21,7 +21,7 @@ static const int BatteryMeter_attributes[] = {
BATTERY BATTERY
}; };
static void BatteryMeter_updateValues(Meter* this, char* buffer, int len) { static void BatteryMeter_updateValues(Meter* this, char* buffer, size_t len) {
ACPresence isOnAC; ACPresence isOnAC;
double percent; double percent;

View File

@ -50,7 +50,7 @@ static void CPUMeter_init(Meter* this) {
Meter_setCaption(this, "Avg"); Meter_setCaption(this, "Avg");
} }
static void CPUMeter_updateValues(Meter* this, char* buffer, int size) { static void CPUMeter_updateValues(Meter* this, char* buffer, size_t size) {
int cpu = this->param; int cpu = this->param;
if (cpu > this->pl->cpuCount) { if (cpu > this->pl->cpuCount) {
xSnprintf(buffer, size, "absent"); xSnprintf(buffer, size, "absent");

15
CRT.c
View File

@ -11,7 +11,6 @@ in the source distribution for its full text.
#include <errno.h> #include <errno.h>
#include <langinfo.h> #include <langinfo.h>
#include <locale.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -80,13 +79,13 @@ static const char* initDegreeSign(void) {
#ifdef HAVE_LIBNCURSESW #ifdef HAVE_LIBNCURSESW
if (CRT_utf8) if (CRT_utf8)
return "\xc2\xb0"; return "\xc2\xb0";
#endif
static char buffer[4]; static char buffer[4];
// this might fail if the current locale does not support wide characters // this might fail if the current locale does not support wide characters
int r = snprintf(buffer, sizeof(buffer), "%lc", 176); int r = snprintf(buffer, sizeof(buffer), "%lc", 176);
if (r > 0) if (r > 0)
return buffer; return buffer;
#endif
return ""; return "";
} }
@ -789,10 +788,10 @@ void CRT_enableDelay() {
void CRT_setColors(int colorScheme) { void CRT_setColors(int colorScheme) {
CRT_colorScheme = colorScheme; CRT_colorScheme = colorScheme;
for (int i = 0; i < 8; i++) { for (short int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) { for (short int j = 0; j < 8; j++) {
if (ColorIndex(i, j) != ColorIndexGrayBlack) { if (ColorIndex(i, j) != ColorIndexGrayBlack) {
int bg = (colorScheme != COLORSCHEME_BLACKNIGHT) short int bg = (colorScheme != COLORSCHEME_BLACKNIGHT)
? (j == 0 ? -1 : j) ? (j == 0 ? -1 : j)
: j; : j;
init_pair(ColorIndex(i, j), i, bg); init_pair(ColorIndex(i, j), i, bg);
@ -800,10 +799,8 @@ void CRT_setColors(int colorScheme) {
} }
} }
int grayBlackFg = COLORS > 8 ? 8 : 0; short int grayBlackFg = COLORS > 8 ? 8 : 0;
int grayBlackBg = (colorScheme != COLORSCHEME_BLACKNIGHT) short int grayBlackBg = (colorScheme != COLORSCHEME_BLACKNIGHT) ? -1 : 0;
? -1
: 0;
init_pair(ColorIndexGrayBlack, grayBlackFg, grayBlackBg); init_pair(ColorIndexGrayBlack, grayBlackFg, grayBlackBg);
CRT_colors = CRT_colorSchemes[colorScheme]; CRT_colors = CRT_colorSchemes[colorScheme];

View File

@ -5,8 +5,9 @@ What's new in version 3.0.3
* Improved command display/sort functionality * Improved command display/sort functionality
(thanks to Narendran Gopalakrishnan) (thanks to Narendran Gopalakrishnan)
* Add screen for active file locks * Add screen for active file locks
(thanks to Fynn J. Wulf)
* Calculate library size (M_LRS column) from maps file * Calculate library size (M_LRS column) from maps file
(thanks to Fynn Wulf) (thanks to Fynn J. Wulf)
* Add a Zram meter * Add a Zram meter
(thanks to Murloc Knight) (thanks to Murloc Knight)
* Add Linux cwd process column * Add Linux cwd process column
@ -49,8 +50,10 @@ What's new in version 3.0.3
* Avoid expensive build of process tree when not using it * Avoid expensive build of process tree when not using it
* Include documentation for COMM and EXE * Include documentation for COMM and EXE
* Distinguish display of no permissions for reading M_LRS * Distinguish display of no permissions for reading M_LRS
* Only calculate M_LRS size every 5 seconds * Only calculate M_LRS size every 2 seconds
* Improvements to comm / cmdline display functionality * Improvements to comm / cmdline display functionality
* Merged view for COMM, EXE and cmdline
(thanks to Narendran Gopalakrishnan and Benny Baumann)
* Consistent kernel thread display for COMM/EXE columns * Consistent kernel thread display for COMM/EXE columns
* Central fault handling for all platforms * Central fault handling for all platforms
* Handle parsing envID & VPid from process status file * Handle parsing envID & VPid from process status file

View File

@ -19,7 +19,7 @@ static const int ClockMeter_attributes[] = {
CLOCK CLOCK
}; };
static void ClockMeter_updateValues(Meter* this, char* buffer, int size) { static void ClockMeter_updateValues(Meter* this, char* buffer, size_t size) {
time_t t = time(NULL); time_t t = time(NULL);
struct tm result; struct tm result;
struct tm* lt = localtime_r(&t, &result); struct tm* lt = localtime_r(&t, &result);

View File

@ -18,7 +18,6 @@ in the source distribution for its full text.
#include "ProvideCurses.h" #include "ProvideCurses.h"
#include "RichString.h" #include "RichString.h"
#include "Vector.h" #include "Vector.h"
#include "XUtils.h"
// TO ADD A NEW SCHEME: // TO ADD A NEW SCHEME:

View File

@ -1,6 +1,6 @@
/* /*
htop - Compat.c htop - Compat.c
(C) 2020 Christian Göttsche (C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
@ -94,11 +94,11 @@ int Compat_openat(const char* dirpath,
#endif /* !HAVE_OPENAT */ #endif /* !HAVE_OPENAT */
int Compat_readlinkat(int dirfd, ssize_t Compat_readlinkat(int dirfd,
const char* dirpath, const char* dirpath,
const char* pathname, const char* pathname,
char* buf, char* buf,
size_t bufsize) { size_t bufsize) {
#ifdef HAVE_READLINKAT #ifdef HAVE_READLINKAT

View File

@ -2,7 +2,7 @@
#define HEADER_Compat #define HEADER_Compat
/* /*
htop - Compat.h htop - Compat.h
(C) 2020 Christian Göttsche (C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
@ -12,7 +12,7 @@ in the source distribution for its full text.
#include <fcntl.h> #include <fcntl.h>
#include <stddef.h> #include <stddef.h>
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h> // IWYU pragma: keep
int Compat_faccessat(int dirfd, int Compat_faccessat(int dirfd,
@ -50,10 +50,10 @@ int Compat_openat(openat_arg_t dirpath, const char* pathname, int flags);
#endif /* HAVE_OPENAT */ #endif /* HAVE_OPENAT */
int Compat_readlinkat(int dirfd, ssize_t Compat_readlinkat(int dirfd,
const char* dirpath, const char* dirpath,
const char* pathname, const char* pathname,
char* buf, char* buf,
size_t bufsize); size_t bufsize);
#endif /* HEADER_Compat */ #endif /* HEADER_Compat */

View File

@ -19,7 +19,7 @@ static const int DateMeter_attributes[] = {
DATE DATE
}; };
static void DateMeter_updateValues(Meter* this, char* buffer, int size) { static void DateMeter_updateValues(Meter* this, char* buffer, size_t size) {
time_t t = time(NULL); time_t t = time(NULL);
struct tm result; struct tm result;
struct tm* lt = localtime_r(&t, &result); struct tm* lt = localtime_r(&t, &result);

View File

@ -19,7 +19,7 @@ static const int DateTimeMeter_attributes[] = {
DATETIME DATETIME
}; };
static void DateTimeMeter_updateValues(Meter* this, char* buffer, int size) { static void DateTimeMeter_updateValues(Meter* this, char* buffer, size_t size) {
time_t t = time(NULL); time_t t = time(NULL);
struct tm result; struct tm result;
struct tm* lt = localtime_r(&t, &result); struct tm* lt = localtime_r(&t, &result);

View File

@ -1,6 +1,6 @@
/* /*
htop - DiskIOMeter.c htop - DiskIOMeter.c
(C) 2020 Christian Göttsche (C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
@ -30,7 +30,7 @@ static unsigned long int cached_read_diff = 0;
static unsigned long int cached_write_diff = 0; static unsigned long int cached_write_diff = 0;
static double cached_utilisation_diff = 0.0; static double cached_utilisation_diff = 0.0;
static void DiskIOMeter_updateValues(Meter* this, char* buffer, int len) { static void DiskIOMeter_updateValues(Meter* this, char* buffer, size_t len) {
static unsigned long long int cached_last_update = 0; static unsigned long long int cached_last_update = 0;
struct timeval tv; struct timeval tv;

View File

@ -1,8 +1,8 @@
#ifndef HEADER_DiskIOMeter #ifndef HEADER_DiskIOMeter
#define HEADER_DiskIOMeter #define HEADER_DiskIOMeter
/* /*
h top - DiskIOMeter*.h htop - DiskIOMeter.h
(C) 2020 Christian Göttsche (C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */

View File

@ -18,7 +18,6 @@ in the source distribution for its full text.
#include "Object.h" #include "Object.h"
#include "OptionItem.h" #include "OptionItem.h"
#include "ProvideCurses.h" #include "ProvideCurses.h"
#include "XUtils.h"
static const char* const DisplayOptionsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL}; static const char* const DisplayOptionsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL};

View File

@ -13,6 +13,7 @@ in the source distribution for its full text.
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "Macros.h" #include "Macros.h"
#include "XUtils.h" #include "XUtils.h"

View File

@ -131,21 +131,6 @@ int Header_size(Header* this, int column) {
return Vector_size(meters); return Vector_size(meters);
} }
char* Header_readMeterName(Header* this, int i, int column) {
Vector* meters = this->columns[column];
Meter* meter = (Meter*) Vector_get(meters, i);
int nameLen = strlen(Meter_name(meter));
int len = nameLen + 100;
char* name = xMalloc(len);
memcpy(name, Meter_name(meter), nameLen);
name[nameLen] = '\0';
if (meter->param)
xSnprintf(name + nameLen, len - nameLen, "(%d)", meter->param);
return name;
}
MeterModeId Header_readMeterMode(Header* this, int i, int column) { MeterModeId Header_readMeterMode(Header* this, int i, int column) {
Vector* meters = this->columns[column]; Vector* meters = this->columns[column];

View File

@ -39,8 +39,6 @@ Meter* Header_addMeterByClass(Header* this, const MeterClass* type, int param, i
int Header_size(Header* this, int column); int Header_size(Header* this, int column);
char* Header_readMeterName(Header* this, int i, int column);
MeterModeId Header_readMeterMode(Header* this, int i, int column); MeterModeId Header_readMeterMode(Header* this, int i, int column);
void Header_reinit(Header* this); void Header_reinit(Header* this);

View File

@ -19,7 +19,7 @@ static const int HostnameMeter_attributes[] = {
HOSTNAME HOSTNAME
}; };
static void HostnameMeter_updateValues(Meter* this, char* buffer, int size) { static void HostnameMeter_updateValues(Meter* this, char* buffer, size_t size) {
(void) this; (void) this;
gethostname(buffer, size - 1); gethostname(buffer, size - 1);
} }

View File

@ -24,7 +24,7 @@ static const int LoadMeter_attributes[] = {
LOAD LOAD
}; };
static void LoadAverageMeter_updateValues(Meter* this, char* buffer, int size) { static void LoadAverageMeter_updateValues(Meter* this, char* buffer, size_t size) {
Platform_getLoadAverage(&this->values[0], &this->values[1], &this->values[2]); Platform_getLoadAverage(&this->values[0], &this->values[1], &this->values[2]);
xSnprintf(buffer, size, "%.2f/%.2f/%.2f", this->values[0], this->values[1], this->values[2]); xSnprintf(buffer, size, "%.2f/%.2f/%.2f", this->values[0], this->values[1], this->values[2]);
} }
@ -40,7 +40,7 @@ static void LoadAverageMeter_display(const Object* cast, RichString* out) {
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer); RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
} }
static void LoadMeter_updateValues(Meter* this, char* buffer, int size) { static void LoadMeter_updateValues(Meter* this, char* buffer, size_t size) {
double five, fifteen; double five, fifteen;
Platform_getLoadAverage(&this->values[0], &five, &fifteen); Platform_getLoadAverage(&this->values[0], &five, &fifteen);
if (this->values[0] > this->total) { if (this->values[0] > this->total) {

View File

@ -3,12 +3,14 @@ AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS = htop bin_PROGRAMS = htop
dist_man_MANS = htop.1 dist_man_MANS = htop.1
EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png \ EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png htop.svg \
install-sh autogen.sh missing install-sh autogen.sh missing
applicationsdir = $(datadir)/applications applicationsdir = $(datadir)/applications
applications_DATA = htop.desktop applications_DATA = htop.desktop
pixmapdir = $(datadir)/pixmaps pixmapdir = $(datadir)/pixmaps
pixmap_DATA = htop.png pixmap_DATA = htop.png
appicondir = $(datadir)/icons/hicolor/scalable/apps
appicon_DATA = htop.svg
AM_CFLAGS += -pedantic -std=c99 -D_XOPEN_SOURCE_EXTENDED -DSYSCONFDIR=\"$(sysconfdir)\" -I"$(top_srcdir)/$(my_htop_platform)" AM_CFLAGS += -pedantic -std=c99 -D_XOPEN_SOURCE_EXTENDED -DSYSCONFDIR=\"$(sysconfdir)\" -I"$(top_srcdir)/$(my_htop_platform)"
AM_LDFLAGS = AM_LDFLAGS =

View File

@ -19,17 +19,16 @@ static const int MemoryMeter_attributes[] = {
MEMORY_CACHE MEMORY_CACHE
}; };
static void MemoryMeter_updateValues(Meter* this, char* buffer, int size) { static void MemoryMeter_updateValues(Meter* this, char* buffer, size_t size) {
int written; int written;
Platform_setMemoryValues(this); Platform_setMemoryValues(this);
written = Meter_humanUnit(buffer, this->values[0], size); written = Meter_humanUnit(buffer, this->values[0], size);
buffer += written; METER_BUFFER_CHECK(buffer, size, written);
if ((size -= written) > 0) {
*buffer++ = '/'; METER_BUFFER_APPEND_CHR(buffer, size, '/');
size--;
Meter_humanUnit(buffer, this->total, size); Meter_humanUnit(buffer, this->total, size);
}
} }
static void MemoryMeter_display(const Object* cast, RichString* out) { static void MemoryMeter_display(const Object* cast, RichString* out) {

36
Meter.c
View File

@ -20,6 +20,7 @@ in the source distribution for its full text.
#include "Object.h" #include "Object.h"
#include "ProvideCurses.h" #include "ProvideCurses.h"
#include "RichString.h" #include "RichString.h"
#include "Settings.h"
#include "XUtils.h" #include "XUtils.h"
@ -48,10 +49,10 @@ Meter* Meter_new(const struct ProcessList_* pl, int param, const MeterClass* typ
return this; return this;
} }
int Meter_humanUnit(char* buffer, unsigned long int value, int size) { int Meter_humanUnit(char* buffer, unsigned long int value, size_t size) {
const char* prefix = "KMGTPEZY"; const char* prefix = "KMGTPEZY";
unsigned long int powi = 1; unsigned long int powi = 1;
unsigned int written, powj = 1, precision = 2; unsigned int powj = 1, precision = 2;
for (;;) { for (;;) {
if (value / 1024 < powi) if (value / 1024 < powi)
@ -73,10 +74,7 @@ int Meter_humanUnit(char* buffer, unsigned long int value, int size) {
break; break;
} }
written = snprintf(buffer, size, "%.*f%c", return snprintf(buffer, size, "%.*f%c", precision, (double) value / powi, *prefix);
precision, (double) value / powi, *prefix);
return written;
} }
void Meter_delete(Object* cast) { void Meter_delete(Object* cast) {
@ -157,7 +155,7 @@ ListItem* Meter_toListItem(Meter* this, bool moving) {
static void TextMeterMode_draw(Meter* this, int x, int y, int w) { static void TextMeterMode_draw(Meter* this, int x, int y, int w) {
char buffer[METER_BUFFER_LEN]; char buffer[METER_BUFFER_LEN];
Meter_updateValues(this, buffer, METER_BUFFER_LEN - 1); Meter_updateValues(this, buffer, sizeof(buffer));
(void) w; (void) w;
attrset(CRT_colors[METER_TEXT]); attrset(CRT_colors[METER_TEXT]);
@ -177,7 +175,7 @@ static const char BarMeterMode_characters[] = "|#*@$%&.";
static void BarMeterMode_draw(Meter* this, int x, int y, int w) { static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
char buffer[METER_BUFFER_LEN]; char buffer[METER_BUFFER_LEN];
Meter_updateValues(this, buffer, METER_BUFFER_LEN - 1); Meter_updateValues(this, buffer, sizeof(buffer));
w -= 2; w -= 2;
attrset(CRT_colors[METER_TEXT]); attrset(CRT_colors[METER_TEXT]);
@ -188,19 +186,18 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
attrset(CRT_colors[BAR_BORDER]); attrset(CRT_colors[BAR_BORDER]);
mvaddch(y, x, '['); mvaddch(y, x, '[');
mvaddch(y, x + w, ']'); mvaddch(y, x + w, ']');
attrset(CRT_colors[RESET_COLOR]);
w--; w--;
x++; x++;
if (w < 1) { if (w < 1)
attrset(CRT_colors[RESET_COLOR]);
return; return;
}
// The text in the bar is right aligned; // The text in the bar is right aligned;
// calculate needed padding and generate leading spaces // calculate needed padding and generate leading spaces
const int textLen = mbstowcs(NULL, buffer, 0); const int textLen = mbstowcs(NULL, buffer, 0);
const int padding = MAXIMUM(w - textLen, 0); const int padding = CLAMP(w - textLen, 0, w);
RichString_begin(bar); RichString_begin(bar);
RichString_appendChr(&bar, ' ', padding); RichString_appendChr(&bar, ' ', padding);
@ -236,13 +233,13 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
// ...then print the buffer. // ...then print the buffer.
offset = 0; offset = 0;
for (uint8_t i = 0; i < this->curItems; i++) { for (uint8_t i = 0; i < this->curItems; i++) {
attrset(CRT_colors[Meter_attributes(this)[i]]); RichString_setAttrn(&bar, CRT_colors[Meter_attributes(this)[i]], offset, offset + blockSizes[i] - 1);
RichString_printoffnVal(bar, y, x + offset, offset, blockSizes[i]); RichString_printoffnVal(bar, y, x + offset, offset, blockSizes[i]);
offset += blockSizes[i]; offset += blockSizes[i];
offset = CLAMP(offset, 0, w); offset = CLAMP(offset, 0, w);
} }
if (offset < w) { if (offset < w) {
attrset(CRT_colors[BAR_SHADOW]); RichString_setAttrn(&bar, CRT_colors[BAR_SHADOW], offset, w - 1);
RichString_printoffnVal(bar, y, x + offset, offset, w - offset); RichString_printoffnVal(bar, y, x + offset, offset, w - offset);
} }
@ -312,8 +309,8 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
for (int i = 0; i < nValues - 1; i++) for (int i = 0; i < nValues - 1; i++)
data->values[i] = data->values[i + 1]; data->values[i] = data->values[i + 1];
char buffer[nValues]; char buffer[METER_BUFFER_LEN];
Meter_updateValues(this, buffer, nValues - 1); Meter_updateValues(this, buffer, sizeof(buffer));
double value = 0.0; double value = 0.0;
for (uint8_t i = 0; i < this->curItems; i++) for (uint8_t i = 0; i < this->curItems; i++)
@ -381,7 +378,7 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
LEDMeterMode_digits = LEDMeterMode_digitsAscii; LEDMeterMode_digits = LEDMeterMode_digitsAscii;
char buffer[METER_BUFFER_LEN]; char buffer[METER_BUFFER_LEN];
Meter_updateValues(this, buffer, METER_BUFFER_LEN - 1); Meter_updateValues(this, buffer, sizeof(buffer));
RichString_begin(out); RichString_begin(out);
Meter_displayBuffer(this, buffer, &out); Meter_displayBuffer(this, buffer, &out);
@ -396,7 +393,7 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
int xx = x + strlen(this->caption); int xx = x + strlen(this->caption);
int len = RichString_sizeVal(out); int len = RichString_sizeVal(out);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
char c = RichString_getCharVal(out, i); int c = RichString_getCharVal(out, i);
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
LEDMeterMode_drawDigit(xx, y, c - 48); LEDMeterMode_drawDigit(xx, y, c - 48);
xx += 4; xx += 4;
@ -444,8 +441,7 @@ const MeterMode* const Meter_modes[] = {
/* Blank meter */ /* Blank meter */
static void BlankMeter_updateValues(Meter* this, char* buffer, int size) { static void BlankMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, size_t size) {
(void) this; (void) buffer; (void) size;
if (size > 0) { if (size > 0) {
*buffer = 0; *buffer = 0;
} }

27
Meter.h
View File

@ -20,13 +20,36 @@ in the source distribution for its full text.
#define METER_BUFFER_LEN 256 #define METER_BUFFER_LEN 256
#define METER_BUFFER_CHECK(buffer, size, written) \
do { \
if ((written) < 0 || (size_t)(written) >= (size)) { \
return; \
} \
(buffer) += (written); \
(size) -= (size_t)(written); \
} while (0)
#define METER_BUFFER_APPEND_CHR(buffer, size, c) \
do { \
if ((size) < 2) { \
return; \
} \
*(buffer)++ = c; \
*(buffer) = '\0'; \
(size)--; \
if ((size) == 0) { \
return; \
} \
} while (0)
struct Meter_; struct Meter_;
typedef struct Meter_ Meter; typedef struct Meter_ Meter;
typedef void(*Meter_Init)(Meter*); typedef void(*Meter_Init)(Meter*);
typedef void(*Meter_Done)(Meter*); typedef void(*Meter_Done)(Meter*);
typedef void(*Meter_UpdateMode)(Meter*, int); typedef void(*Meter_UpdateMode)(Meter*, int);
typedef void(*Meter_UpdateValues)(Meter*, char*, int); typedef void(*Meter_UpdateValues)(Meter*, char*, size_t);
typedef void(*Meter_Draw)(Meter*, int, int, int); typedef void(*Meter_Draw)(Meter*, int, int, int);
typedef struct MeterClass_ { typedef struct MeterClass_ {
@ -101,7 +124,7 @@ extern const MeterClass Meter_class;
Meter* Meter_new(const ProcessList* pl, int param, const MeterClass* type); Meter* Meter_new(const ProcessList* pl, int param, const MeterClass* type);
int Meter_humanUnit(char* buffer, unsigned long int value, int size); int Meter_humanUnit(char* buffer, unsigned long int value, size_t size);
void Meter_delete(Object* cast); void Meter_delete(Object* cast);

View File

@ -24,7 +24,7 @@ static unsigned long int cached_rxp_diff = 0;
static unsigned long int cached_txb_diff = 0; static unsigned long int cached_txb_diff = 0;
static unsigned long int cached_txp_diff = 0; static unsigned long int cached_txp_diff = 0;
static void NetworkIOMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, int len) { static void NetworkIOMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, size_t len) {
static unsigned long long int cached_last_update = 0; static unsigned long long int cached_last_update = 0;
struct timeval tv; struct timeval tv;

View File

@ -12,7 +12,9 @@ in the source distribution for its full text.
#include <stdlib.h> #include <stdlib.h>
#include "CRT.h" #include "CRT.h"
#include "Macros.h"
#include "RichString.h" #include "RichString.h"
#include "XUtils.h"
static void OptionItem_delete(Object* cast) { static void OptionItem_delete(Object* cast) {

View File

@ -223,7 +223,7 @@ static inline void Process_writeCommand(const Process* this, int attr, int basea
} }
} }
void Process_outputRate(RichString* str, char* buffer, int n, double rate, int coloring) { void Process_outputRate(RichString* str, char* buffer, size_t n, double rate, int coloring) {
int largeNumberColor = CRT_colors[LARGE_NUMBER]; int largeNumberColor = CRT_colors[LARGE_NUMBER];
int processMegabytesColor = CRT_colors[PROCESS_MEGABYTES]; int processMegabytesColor = CRT_colors[PROCESS_MEGABYTES];
int processColor = CRT_colors[PROCESS]; int processColor = CRT_colors[PROCESS];
@ -258,7 +258,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
char buffer[256]; buffer[255] = '\0'; char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR]; int attr = CRT_colors[DEFAULT_COLOR];
int baseattr = CRT_colors[PROCESS_BASENAME]; int baseattr = CRT_colors[PROCESS_BASENAME];
int n = sizeof(buffer) - 1; size_t n = sizeof(buffer) - 1;
bool coloring = this->settings->highlightMegabytes; bool coloring = this->settings->highlightMegabytes;
switch (field) { switch (field) {
@ -312,7 +312,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
} else { } else {
ret = snprintf(buf, n, " "); ret = snprintf(buf, n, " ");
} }
if (ret < 0 || ret >= n) { if (ret < 0 || (size_t)ret >= n) {
written = n; written = n;
} else { } else {
written = ret; written = ret;

View File

@ -10,7 +10,6 @@ in the source distribution for its full text.
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include "Object.h" #include "Object.h"
@ -177,7 +176,7 @@ void Process_printTime(RichString* str, unsigned long long totalHundredths);
void Process_fillStarttimeBuffer(Process* this); void Process_fillStarttimeBuffer(Process* this);
void Process_outputRate(RichString* str, char* buffer, int n, double rate, int coloring); void Process_outputRate(RichString* str, char* buffer, size_t n, double rate, int coloring);
void Process_display(const Object* cast, RichString* out); void Process_display(const Object* cast, RichString* out);

View File

@ -14,6 +14,7 @@ in the source distribution for its full text.
#include "CRT.h" #include "CRT.h"
#include "Hashtable.h" #include "Hashtable.h"
#include "Macros.h"
#include "Vector.h" #include "Vector.h"
#include "XUtils.h" #include "XUtils.h"

View File

@ -86,7 +86,7 @@ static inline void RichString_writeFrom(RichString* this, int attrs, const char*
int newLen = from + len; int newLen = from + len;
RichString_setLen(this, newLen); RichString_setLen(this, newLen);
for (int i = from, j = 0; i < newLen; i++, j++) { for (int i = from, j = 0; i < newLen; i++, j++) {
this->chptr[i] = (data_c[j] >= 32 ? data_c[j] : '?') | attrs; this->chptr[i] = (((unsigned char)data_c[j]) >= 32 ? ((unsigned char)data_c[j]) : '?') | attrs;
} }
this->chptr[newLen] = 0; this->chptr[newLen] = 0;
} }

View File

@ -10,6 +10,7 @@ in the source distribution for its full text.
#include "config.h" // IWYU pragma: keep #include "config.h" // IWYU pragma: keep
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include "Process.h" #include "Process.h"

View File

@ -17,17 +17,16 @@ static const int SwapMeter_attributes[] = {
SWAP SWAP
}; };
static void SwapMeter_updateValues(Meter* this, char* buffer, int size) { static void SwapMeter_updateValues(Meter* this, char* buffer, size_t size) {
int written; int written;
Platform_setSwapValues(this); Platform_setSwapValues(this);
written = Meter_humanUnit(buffer, this->values[0], size); written = Meter_humanUnit(buffer, this->values[0], size);
buffer += written; METER_BUFFER_CHECK(buffer, size, written);
if ((size -= written) > 0) {
*buffer++ = '/'; METER_BUFFER_APPEND_CHR(buffer, size, '/');
size--;
Meter_humanUnit(buffer, this->total, size); Meter_humanUnit(buffer, this->total, size);
}
} }
static void SwapMeter_display(const Object* cast, RichString* out) { static void SwapMeter_display(const Object* cast, RichString* out) {

View File

@ -23,7 +23,7 @@ static const int TasksMeter_attributes[] = {
TASKS_RUNNING TASKS_RUNNING
}; };
static void TasksMeter_updateValues(Meter* this, char* buffer, int len) { static void TasksMeter_updateValues(Meter* this, char* buffer, size_t len) {
const ProcessList* pl = this->pl; const ProcessList* pl = this->pl;
this->values[0] = pl->kernelThreads; this->values[0] = pl->kernelThreads;
this->values[1] = pl->userlandThreads; this->values[1] = pl->userlandThreads;

View File

@ -17,7 +17,7 @@ static const int UptimeMeter_attributes[] = {
UPTIME UPTIME
}; };
static void UptimeMeter_updateValues(Meter* this, char* buffer, int len) { static void UptimeMeter_updateValues(Meter* this, char* buffer, size_t len) {
int totalseconds = Platform_getUptime(); int totalseconds = Platform_getUptime();
if (totalseconds == -1) { if (totalseconds == -1) {
xSnprintf(buffer, len, "(unknown)"); xSnprintf(buffer, len, "(unknown)");

View File

@ -11,6 +11,7 @@ in the source distribution for its full text.
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -183,13 +184,13 @@ int xAsprintf(char** strp, const char* fmt, ...) {
return r; return r;
} }
int xSnprintf(char* buf, int len, const char* fmt, ...) { int xSnprintf(char* buf, size_t len, const char* fmt, ...) {
va_list vl; va_list vl;
va_start(vl, fmt); va_start(vl, fmt);
int n = vsnprintf(buf, len, fmt, vl); int n = vsnprintf(buf, len, fmt, vl);
va_end(vl); va_end(vl);
if (n < 0 || n >= len) { if (n < 0 || (size_t)n >= len) {
fail(); fail();
} }

View File

@ -13,6 +13,7 @@ in the source distribution for its full text.
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> // IWYU pragma: keep #include <stdlib.h> // IWYU pragma: keep
#include <string.h> // IWYU pragma: keep #include <string.h> // IWYU pragma: keep
#include <sys/types.h>
#include "Compat.h" #include "Compat.h"
#include "Macros.h" #include "Macros.h"
@ -58,7 +59,7 @@ ATTR_FORMAT(printf, 2, 3)
int xAsprintf(char** strp, const char* fmt, ...); int xAsprintf(char** strp, const char* fmt, ...);
ATTR_FORMAT(printf, 3, 4) ATTR_FORMAT(printf, 3, 4)
int xSnprintf(char* buf, int len, const char* fmt, ...); int xSnprintf(char* buf, size_t len, const char* fmt, ...);
char* xStrdup(const char* str) ATTR_NONNULL; char* xStrdup(const char* str) ATTR_NONNULL;

View File

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_PREREQ(2.65) AC_PREREQ(2.65)
AC_INIT([htop],[3.0.3-rc1],[htop@groups.io]) AC_INIT([htop],[3.0.3],[htop@groups.io])
AC_CONFIG_SRCDIR([htop.c]) AC_CONFIG_SRCDIR([htop.c])
AC_CONFIG_AUX_DIR([.]) AC_CONFIG_AUX_DIR([.])

View File

@ -59,6 +59,6 @@ char* DragonFlyBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kpro
char* DragonFlyBSDProcessList_readJailName(DragonFlyBSDProcessList* dfpl, int jailid); char* DragonFlyBSDProcessList_readJailName(DragonFlyBSDProcessList* dfpl, int jailid);
void ProcessList_goThroughEntries(ProcessList* super, pauseProcessUpdate); void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate);
#endif #endif

View File

@ -248,7 +248,7 @@ char* Platform_getProcessEnv(pid_t pid) {
char* env = xMalloc(capacity); char* env = xMalloc(capacity);
int err = sysctl(mib, 4, env, &capacity, NULL, 0); int err = sysctl(mib, 4, env, &capacity, NULL, 0);
if (err) { if (err || capacity == 0) {
free(env); free(env);
return NULL; return NULL;
} }

BIN
htop.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

112
htop.svg Normal file
View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="30.398mm" height="30.399mm" version="1.1" viewBox="0 0 30.398 30.399" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="aj" x1="42.304" x2="42.245" y1="57.522" y2="50.607" gradientTransform="translate(41.404 221.45)" gradientUnits="userSpaceOnUse" xlink:href="#c"/>
<linearGradient id="c">
<stop stop-color="#363d36" offset="0"/>
<stop stop-color="#565d56" offset=".2"/>
<stop stop-color="#6c766c" offset=".8"/>
<stop stop-color="#8c968c" offset="1"/>
</linearGradient>
<filter id="f" x="-.063963" y="-.025049" width="1.1279" height="1.0501" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.072789412"/>
</filter>
<linearGradient id="ai" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(41.508 221.43)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<linearGradient id="a">
<stop stop-color="#8bf18b" offset="0"/>
<stop stop-color="#5bc15b" offset=".2"/>
<stop stop-color="#47a347" offset=".8"/>
<stop stop-color="#177317" offset="1"/>
</linearGradient>
<filter id="l" x="-.08928" y="-.022545" width="1.1786" height="1.0451" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.065909587"/>
</filter>
<linearGradient id="d" x1="42.304" x2="42.245" y1="57.522" y2="50.607" gradientTransform="translate(24.234,-9.2667)" gradientUnits="userSpaceOnUse" xlink:href="#c"/>
<filter id="e" x="-.063963" y="-.025049" width="1.1279" height="1.0501" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.072789412"/>
</filter>
<linearGradient id="ah" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(44.242 221.43)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<filter id="k" x="-.08928" y="-.022545" width="1.1786" height="1.0451" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.065909587"/>
</filter>
<linearGradient id="ag" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(46.976 221.43)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<filter id="j" x="-.08928" y="-.022545" width="1.1786" height="1.0451" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.065909587"/>
</filter>
<linearGradient id="af" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(49.709 221.43)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<filter id="am" x="-.08928" y="-.022545" width="1.1786" height="1.0451" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.065909587"/>
</filter>
<linearGradient id="ae" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(52.443 221.43)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<filter id="al" x="-.08928" y="-.022545" width="1.1786" height="1.0451" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.065909587"/>
</filter>
<linearGradient id="ad" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(55.177 221.43)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<filter id="ak" x="-.08928" y="-.022545" width="1.1786" height="1.0451" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.065909587"/>
</filter>
<linearGradient id="ac" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(57.91 221.43)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<filter id="i" x="-.08928" y="-.022545" width="1.1786" height="1.0451" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.065909587"/>
</filter>
<linearGradient id="ab" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(60.644 221.43)" gradientUnits="userSpaceOnUse" xlink:href="#b"/>
<linearGradient id="b">
<stop stop-color="#fe7f7f" offset="0"/>
<stop stop-color="#ce4f4f" offset=".2"/>
<stop stop-color="#b23030" offset=".8"/>
<stop stop-color="#920000" offset="1"/>
</linearGradient>
<filter id="h" x="-.08928" y="-.022545" width="1.1786" height="1.0451" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.065909587"/>
</filter>
<linearGradient id="aa" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(63.376 221.43)" gradientUnits="userSpaceOnUse" xlink:href="#b"/>
<filter id="g" x="-.08928" y="-.022545" width="1.1786" height="1.0451" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="0.065909587"/>
</filter>
<linearGradient id="z" x1="42.304" x2="42.245" y1="57.522" y2="50.607" gradientTransform="translate(41.404 210.02)" gradientUnits="userSpaceOnUse" xlink:href="#c"/>
<linearGradient id="y" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(41.508 210)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<linearGradient id="x" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(44.242 210)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<linearGradient id="w" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(46.976 210)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<linearGradient id="v" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(57.91 210)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<linearGradient id="u" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(63.376 210)" gradientUnits="userSpaceOnUse" xlink:href="#b"/>
<linearGradient id="t" x1="42.304" x2="42.245" y1="57.522" y2="50.607" gradientTransform="translate(41.404 232.87)" gradientUnits="userSpaceOnUse" xlink:href="#c"/>
<linearGradient id="s" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(41.508 232.85)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<linearGradient id="r" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(44.242 232.85)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<linearGradient id="q" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(46.976 232.85)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
<linearGradient id="p" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(60.644 232.85)" gradientUnits="userSpaceOnUse" xlink:href="#b"/>
<linearGradient id="o" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(63.376 232.85)" gradientUnits="userSpaceOnUse" xlink:href="#b"/>
<linearGradient id="n" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(57.91 232.85)" gradientUnits="userSpaceOnUse" xlink:href="#b"/>
<linearGradient id="m" x1="44.761" x2="44.761" y1="50.493" y2="57.517" gradientTransform="translate(60.644 210)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
</defs>
<g transform="translate(.08011 -.58599)">
<g transform="matrix(.98769 0 0 .99741 -80.905 -258.93)" fill-rule="evenodd">
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m82.188 271.97 0.0251 6.963 2.7061-8e-3v-1.2194h-1.0357v-4.602h1.019v-1.1442z" fill="url(#aj)" filter="url(#f)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m85.401 271.95v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#ai)" filter="url(#l)"/>
<path transform="matrix(-.99856 0 0 1.2772 177.16 218.32)" d="m65.017 41.255 0.02508 6.963 2.7061-0.0084v-1.2194h-1.0357v-4.602h1.019v-1.1442z" fill="url(#d)" filter="url(#e)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m88.135 271.95v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#ah)" filter="url(#k)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m90.868 271.95v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#ag)" filter="url(#j)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m93.602 271.95v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#af)" filter="url(#am)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m96.335 271.95v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#ae)" filter="url(#al)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m99.069 271.95v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#ad)" filter="url(#ak)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m101.8 271.95v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#ac)" filter="url(#i)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m104.54 271.95v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#ab)" filter="url(#h)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -76.353)" d="m107.27 271.95v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#aa)" filter="url(#g)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -72.134)" d="m82.188 260.54 0.0251 6.963 2.7061-8e-3v-1.2194h-1.0357v-4.602h1.019v-1.1442z" fill="url(#z)" filter="url(#f)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -72.134)" d="m85.401 260.52v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#y)" filter="url(#l)"/>
<path transform="matrix(-.99856 0 0 1.2772 177.16 207.94)" d="m65.017 41.255 0.02508 6.963 2.7061-0.0084v-1.2194h-1.0357v-4.602h1.019v-1.1442z" fill="url(#d)" filter="url(#e)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -72.134)" d="m88.135 260.52v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#x)" filter="url(#k)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -72.134)" d="m90.868 260.52v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#w)" filter="url(#j)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -72.134)" d="m101.8 260.52v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#v)" filter="url(#i)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -72.134)" d="m107.27 260.52v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#u)" filter="url(#g)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -80.616)" d="m82.188 283.39 0.0251 6.963 2.7061-8e-3v-1.2194h-1.0357v-4.602h1.019v-1.1442z" fill="url(#t)" filter="url(#f)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -80.616)" d="m85.401 283.37v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#s)" filter="url(#l)"/>
<path transform="matrix(-.99856 0 0 1.2772 177.16 228.65)" d="m65.017 41.255 0.02508 6.963 2.7061-0.0084v-1.2194h-1.0357v-4.602h1.019v-1.1442z" fill="url(#d)" filter="url(#e)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -80.616)" d="m88.135 283.37v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#r)" filter="url(#k)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -80.616)" d="m90.868 283.37v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#q)" filter="url(#j)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -80.616)" d="m104.54 283.37v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#p)" filter="url(#h)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -80.616)" d="m107.27 283.37v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#o)" filter="url(#g)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -80.616)" d="m101.8 283.37v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#n)" filter="url(#h)"/>
<path transform="matrix(.99856 0 0 1.2772 .14037 -72.134)" d="m104.54 260.52v7.0132h1.7718v-7.0162h-1.7718z" fill="url(#m)" filter="url(#i)"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -4,7 +4,6 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <errno.h> #include <errno.h>
#include <limits.h>
#include <sensors/sensors.h> #include <sensors/sensors.h>
#include "XUtils.h" #include "XUtils.h"

View File

@ -11,6 +11,7 @@ in the source distribution for its full text.
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <syscall.h> #include <syscall.h>
#include <unistd.h> #include <unistd.h>
@ -617,7 +618,7 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
bool coloring = this->settings->highlightMegabytes; bool coloring = this->settings->highlightMegabytes;
char buffer[256]; buffer[255] = '\0'; char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR]; int attr = CRT_colors[DEFAULT_COLOR];
int n = sizeof(buffer) - 1; size_t n = sizeof(buffer) - 1;
switch ((int)field) { switch ((int)field) {
case TTY_NR: { case TTY_NR: {
if (lp->ttyDevice) { if (lp->ttyDevice) {

View File

@ -8,10 +8,9 @@ Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#include "config.h" #include "config.h" // IWYU pragma: keep
#include <stdbool.h> #include <stdbool.h>
#include <sys/types.h>
#include "IOPriority.h" #include "IOPriority.h"
#include "Object.h" #include "Object.h"

View File

@ -13,18 +13,17 @@ in the source distribution for its full text.
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <limits.h>
#include <math.h> #include <math.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <strings.h>
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/utsname.h>
#ifdef HAVE_DELAYACCT #ifdef HAVE_DELAYACCT
#include <linux/netlink.h> #include <linux/netlink.h>
@ -437,7 +436,7 @@ static void LinuxProcessList_readIoFile(LinuxProcess* process, openat_arg_t proc
} }
} }
typedef struct LibraryData { typedef struct LibraryData_ {
uint64_t size; uint64_t size;
bool exec; bool exec;
} LibraryData; } LibraryData;
@ -883,7 +882,7 @@ static void LinuxProcessList_readSecattrData(LinuxProcess* process, openat_arg_t
} }
static void LinuxProcessList_readCwd(LinuxProcess* process, openat_arg_t procFd) { static void LinuxProcessList_readCwd(LinuxProcess* process, openat_arg_t procFd) {
char pathBuffer[PATH_MAX + 1]; char pathBuffer[PATH_MAX + 1] = {0};
#if defined(HAVE_READLINKAT) && defined(HAVE_OPENAT) #if defined(HAVE_READLINKAT) && defined(HAVE_OPENAT)
ssize_t r = readlinkat(procFd, "cwd", pathBuffer, sizeof(pathBuffer) - 1); ssize_t r = readlinkat(procFd, "cwd", pathBuffer, sizeof(pathBuffer) - 1);
@ -892,6 +891,7 @@ static void LinuxProcessList_readCwd(LinuxProcess* process, openat_arg_t procFd)
xSnprintf(filename, sizeof(filename), "%s/cwd", procFd); xSnprintf(filename, sizeof(filename), "%s/cwd", procFd);
ssize_t r = readlink(filename, pathBuffer, sizeof(pathBuffer) - 1); ssize_t r = readlink(filename, pathBuffer, sizeof(pathBuffer) - 1);
#endif #endif
if (r < 0) { if (r < 0) {
free(process->cwd); free(process->cwd);
process->cwd = NULL; process->cwd = NULL;

View File

@ -12,7 +12,6 @@ in the source distribution for its full text.
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#include <limits.h> #include <limits.h>
@ -371,7 +370,7 @@ char* Platform_getInodeFilename(pid_t pid, ino_t inode) {
struct stat sb; struct stat sb;
struct dirent *de; struct dirent *de;
DIR *dirp; DIR *dirp;
size_t len; ssize_t len;
int fd; int fd;
char path[PATH_MAX]; char path[PATH_MAX];

View File

@ -25,7 +25,7 @@ static const int PressureStallMeter_attributes[] = {
PRESSURE_STALL_THREEHUNDRED PRESSURE_STALL_THREEHUNDRED
}; };
static void PressureStallMeter_updateValues(Meter* this, char* buffer, int len) { static void PressureStallMeter_updateValues(Meter* this, char* buffer, size_t len) {
const char* file; const char* file;
if (strstr(Meter_name(this), "CPU")) { if (strstr(Meter_name(this), "CPU")) {
file = "cpu"; file = "cpu";

View File

@ -1,6 +1,6 @@
/* /*
htop - SELinuxMeter.c htop - SELinuxMeter.c
(C) 2020 Christian Goettsche (C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
@ -9,7 +9,6 @@ in the source distribution for its full text.
#include "CRT.h" #include "CRT.h"
#include <fcntl.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@ -71,7 +70,7 @@ static bool isSelinuxEnforcing(void) {
return !!enforce; return !!enforce;
} }
static void SELinuxMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, int len) { static void SELinuxMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, size_t len) {
enabled = isSelinuxEnabled(); enabled = isSelinuxEnabled();
enforcing = isSelinuxEnforcing(); enforcing = isSelinuxEnforcing();

View File

@ -2,7 +2,7 @@
#define HEADER_SELinuxMeter #define HEADER_SELinuxMeter
/* /*
htop - SELinuxMeter.h htop - SELinuxMeter.h
(C) 2020 Christian Goettsche (C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */

View File

@ -1,6 +1,6 @@
/* /*
htop - SystemdMeter.c htop - SystemdMeter.c
(C) 2020 Christian Göttsche (C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
@ -229,7 +229,7 @@ static void updateViaExec(void) {
fclose(commandOutput); fclose(commandOutput);
} }
static void SystemdMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, int size) { static void SystemdMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, size_t size) {
free(systemState); free(systemState);
systemState = NULL; systemState = NULL;
nFailedUnits = nInstalledJobs = nNames = nJobs = INVALID_VALUE; nFailedUnits = nInstalledJobs = nNames = nJobs = INVALID_VALUE;

View File

@ -3,7 +3,7 @@
/* /*
htop - SystemdMeter.h htop - SystemdMeter.h
(C) 2020 Christian Göttsche (C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */

View File

@ -11,7 +11,7 @@ static const int ZramMeter_attributes[] = {
ZRAM ZRAM
}; };
static void ZramMeter_updateValues(Meter* this, char* buffer, int size) { static void ZramMeter_updateValues(Meter* this, char* buffer, size_t size) {
int written; int written;
Platform_setZramValues(this); Platform_setZramValues(this);
@ -20,29 +20,18 @@ static void ZramMeter_updateValues(Meter* this, char* buffer, int size) {
this->curItems = 1; this->curItems = 1;
written = Meter_humanUnit(buffer, this->values[0], size); written = Meter_humanUnit(buffer, this->values[0], size);
buffer += written; METER_BUFFER_CHECK(buffer, size, written);
size -= written;
if (size <= 0) { METER_BUFFER_APPEND_CHR(buffer, size, '(');
return;
}
*buffer++ = '(';
size--;
if (size <= 0) {
return;
}
written = Meter_humanUnit(buffer, this->values[1], size); written = Meter_humanUnit(buffer, this->values[1], size);
buffer += written; METER_BUFFER_CHECK(buffer, size, written);
size -= written;
if (size <= 0) { METER_BUFFER_APPEND_CHR(buffer, size, ')');
return;
} METER_BUFFER_APPEND_CHR(buffer, size, '/');
*buffer++ = ')';
size--; Meter_humanUnit(buffer, this->total, size);
if ((size -= written) > 0) {
*buffer++ = '/';
size--;
Meter_humanUnit(buffer, this->total, size);
}
} }
static void ZramMeter_display(const Object* cast, RichString* out) { static void ZramMeter_display(const Object* cast, RichString* out) {

View File

@ -6,26 +6,15 @@ Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#include "Process.h"
#include "ProcessList.h"
#include "OpenBSDProcess.h" #include "OpenBSDProcess.h"
#include "Platform.h"
#include "CRT.h"
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "CRT.h"
#include "Process.h"
#include "RichString.h"
#include "XUtils.h"
const ProcessClass OpenBSDProcess_class = {
.super = {
.extends = Class(Process),
.display = Process_display,
.delete = Process_delete,
.compare = OpenBSDProcess_compare
},
.writeField = OpenBSDProcess_writeField,
};
ProcessFieldData Process_fields[] = { ProcessFieldData Process_fields[] = {
[0] = { [0] = {
@ -200,7 +189,7 @@ Process* OpenBSDProcess_new(const Settings* settings) {
OpenBSDProcess* this = xCalloc(sizeof(OpenBSDProcess), 1); OpenBSDProcess* this = xCalloc(sizeof(OpenBSDProcess), 1);
Object_setClass(this, Class(OpenBSDProcess)); Object_setClass(this, Class(OpenBSDProcess));
Process_init(&this->super, settings); Process_init(&this->super, settings);
return &this->this; return &this->super;
} }
void Process_delete(Object* cast) { void Process_delete(Object* cast) {
@ -209,8 +198,8 @@ void Process_delete(Object* cast) {
free(this); free(this);
} }
void OpenBSDProcess_writeField(const Process* this, RichString* str, ProcessField field) { static void OpenBSDProcess_writeField(const Process* this, RichString* str, ProcessField field) {
//OpenBSDProcess* fp = (OpenBSDProcess*) this; //const OpenBSDProcess* op = (const OpenBSDProcess*) this;
char buffer[256]; buffer[255] = '\0'; char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR]; int attr = CRT_colors[DEFAULT_COLOR];
//int n = sizeof(buffer) - 1; //int n = sizeof(buffer) - 1;
@ -223,7 +212,7 @@ void OpenBSDProcess_writeField(const Process* this, RichString* str, ProcessFiel
RichString_append(str, attr, buffer); RichString_append(str, attr, buffer);
} }
long OpenBSDProcess_compare(const void* v1, const void* v2) { static long OpenBSDProcess_compare(const void* v1, const void* v2) {
const OpenBSDProcess *p1, *p2; const OpenBSDProcess *p1, *p2;
const Settings *settings = ((const Process*)v1)->settings; const Settings *settings = ((const Process*)v1)->settings;
@ -235,6 +224,9 @@ long OpenBSDProcess_compare(const void* v1, const void* v2) {
p1 = (const OpenBSDProcess*)v2; p1 = (const OpenBSDProcess*)v2;
} }
// remove if actually used
(void)p1; (void)p2;
switch (settings->sortKey) { switch (settings->sortKey) {
// add OpenBSD-specific fields here // add OpenBSD-specific fields here
default: default:
@ -242,6 +234,16 @@ long OpenBSDProcess_compare(const void* v1, const void* v2) {
} }
} }
const ProcessClass OpenBSDProcess_class = {
.super = {
.extends = Class(Process),
.display = Process_display,
.delete = Process_delete,
.compare = OpenBSDProcess_compare
},
.writeField = OpenBSDProcess_writeField,
};
bool Process_isThread(const Process* this) { bool Process_isThread(const Process* this) {
return (Process_isKernelThread(this)); return Process_isKernelThread(this) || Process_isUserlandThread(this);
} }

View File

@ -8,6 +8,13 @@ Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#include <stdbool.h>
#include "Object.h"
#include "Process.h"
#include "Settings.h"
typedef enum OpenBSDProcessFields_ { typedef enum OpenBSDProcessFields_ {
// Add platform-specific fields here, with ids >= 100 // Add platform-specific fields here, with ids >= 100
LAST_PROCESSFIELD = 100, LAST_PROCESSFIELD = 100,
@ -31,10 +38,6 @@ Process* OpenBSDProcess_new(const Settings* settings);
void Process_delete(Object* cast); void Process_delete(Object* cast);
void OpenBSDProcess_writeField(const Process* this, RichString* str, ProcessField field);
long OpenBSDProcess_compare(const void* v1, const void* v2);
bool Process_isThread(const Process* this); bool Process_isThread(const Process* this);
#endif #endif

View File

@ -6,46 +6,49 @@ Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#include "CRT.h"
#include "ProcessList.h"
#include "OpenBSDProcessList.h" #include "OpenBSDProcessList.h"
#include "OpenBSDProcess.h"
#include "Macros.h"
#include <err.h> #include <err.h>
#include <errno.h> #include <kvm.h>
#include <fcntl.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/resource.h>
#include <sys/sched.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/user.h>
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <sys/swap.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <uvm/uvmexp.h>
#include "CRT.h"
#include "Macros.h"
#include "Object.h"
#include "OpenBSDProcess.h"
#include "Process.h"
#include "ProcessList.h"
#include "Settings.h"
#include "XUtils.h"
static long fscale; static long fscale;
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) {
int mib[] = { CTL_HW, HW_NCPU }; const int mib[] = { CTL_HW, HW_NCPU };
int fmib[] = { CTL_KERN, KERN_FSCALE }; const int fmib[] = { CTL_KERN, KERN_FSCALE };
int i, e; int r;
OpenBSDProcessList* opl;
ProcessList* pl;
size_t size; size_t size;
char errbuf[_POSIX2_LINE_MAX]; char errbuf[_POSIX2_LINE_MAX];
opl = xCalloc(1, sizeof(OpenBSDProcessList)); OpenBSDProcessList* opl = xCalloc(1, sizeof(OpenBSDProcessList));
pl = (ProcessList*) opl; ProcessList* pl = (ProcessList*) opl;
size = sizeof(pl->cpuCount);
ProcessList_init(pl, Class(OpenBSDProcess), usersTable, pidMatchList, userId); ProcessList_init(pl, Class(OpenBSDProcess), usersTable, pidMatchList, userId);
e = sysctl(mib, 2, &pl->cpuCount, &size, NULL, 0); size = sizeof(pl->cpuCount);
if (e == -1 || pl->cpuCount < 1) { r = sysctl(mib, 2, &pl->cpuCount, &size, NULL, 0);
if (r < 0 || pl->cpuCount < 1) {
pl->cpuCount = 1; pl->cpuCount = 1;
} }
opl->cpus = xCalloc(pl->cpuCount + 1, sizeof(CPUData)); opl->cpus = xCalloc(pl->cpuCount + 1, sizeof(CPUData));
@ -55,7 +58,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
err(1, "fscale sysctl call failed"); err(1, "fscale sysctl call failed");
} }
for (i = 0; i <= pl->cpuCount; i++) { for (int i = 0; i <= pl->cpuCount; i++) {
CPUData* d = opl->cpus + i; CPUData* d = opl->cpus + i;
d->totalTime = 1; d->totalTime = 1;
d->totalPeriod = 1; d->totalPeriod = 1;
@ -70,7 +73,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
} }
void ProcessList_delete(ProcessList* this) { void ProcessList_delete(ProcessList* this) {
const OpenBSDProcessList* opl = (OpenBSDProcessList*) this; OpenBSDProcessList* opl = (OpenBSDProcessList*) this;
if (opl->kd) { if (opl->kd) {
kvm_close(opl->kd); kvm_close(opl->kd);
@ -82,8 +85,8 @@ void ProcessList_delete(ProcessList* this) {
free(this); free(this);
} }
static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) { static void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
static int uvmexp_mib[] = {CTL_VM, VM_UVMEXP}; const int uvmexp_mib[] = { CTL_VM, VM_UVMEXP };
struct uvmexp uvmexp; struct uvmexp uvmexp;
size_t size_uvmexp = sizeof(uvmexp); size_t size_uvmexp = sizeof(uvmexp);
@ -92,9 +95,10 @@ static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
} }
pl->totalMem = uvmexp.npages * CRT_pageSizeKB; pl->totalMem = uvmexp.npages * CRT_pageSizeKB;
pl->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * CRT_pageSizeKB;
// Taken from OpenBSD systat/iostat.c, top/machine.c and uvm_sysctl(9) // Taken from OpenBSD systat/iostat.c, top/machine.c and uvm_sysctl(9)
static int bcache_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT}; const int bcache_mib[] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT };
struct bcachestats bcstats; struct bcachestats bcstats;
size_t size_bcstats = sizeof(bcstats); size_t size_bcstats = sizeof(bcstats);
@ -103,52 +107,55 @@ static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
} }
pl->cachedMem = bcstats.numbufpages * CRT_pageSizeKB; pl->cachedMem = bcstats.numbufpages * CRT_pageSizeKB;
pl->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * CRT_pageSizeKB;
/* /*
const OpenBSDProcessList* opl = (OpenBSDProcessList*) pl; * Copyright (c) 1994 Thorsten Lockert <tholo@sigmasoft.com>
* All rights reserved.
*
* Taken almost directly from OpenBSD's top(1)
*
* Originally released under a BSD-3 license
* Modified through htop developers applying GPL-2
*/
int nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap > 0) {
struct swapent swdev[nswap];
int rnswap = swapctl(SWAP_STATS, swdev, nswap);
size_t len = sizeof(pl->totalMem); /* Total things up */
sysctl(MIB_hw_physmem, 2, &(pl->totalMem), &len, NULL, 0); unsigned long long int total = 0, used = 0;
pl->totalMem /= 1024; for (int i = 0; i < rnswap; i++) {
sysctl(MIB_vm_stats_vm_v_wire_count, 4, &(pl->usedMem), &len, NULL, 0); if (swdev[i].se_flags & SWF_ENABLE) {
pl->usedMem *= CRT_pageSizeKB; used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
sysctl(MIB_vm_stats_vm_v_cache_count, 4, &(pl->cachedMem), &len, NULL, 0); total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
pl->cachedMem *= CRT_pageSizeKB; }
}
struct kvm_swap swap[16]; pl->totalSwap = total;
int nswap = kvm_getswapinfo(opl->kd, swap, ARRAYSIZE(swap), 0); pl->usedSwap = used;
pl->totalSwap = 0; } else {
pl->usedSwap = 0; pl->totalSwap = pl->usedSwap = 0;
for (int i = 0; i < nswap; i++) {
pl->totalSwap += swap[i].ksw_total;
pl->usedSwap += swap[i].ksw_used;
} }
pl->totalSwap *= CRT_pageSizeKB;
pl->usedSwap *= CRT_pageSizeKB;
pl->buffersMem = 0; // not exposed to userspace
*/
} }
char* OpenBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, int* basenameEnd) { static char* OpenBSDProcessList_readProcessName(kvm_t* kd, const struct kinfo_proc* kproc, int* basenameEnd) {
char *s, **arg;
size_t len = 0;
int i;
/* /*
* Like OpenBSD's top(1), we try to fall back to the command name * Like OpenBSD's top(1), we try to fall back to the command name
* (argv[0]) if we fail to construct the full command. * (argv[0]) if we fail to construct the full command.
*/ */
arg = kvm_getargv(kd, kproc, 500); char** arg = kvm_getargv(kd, kproc, 500);
if (arg == NULL || *arg == NULL) { if (arg == NULL || *arg == NULL) {
*basenameEnd = strlen(kproc->p_comm); *basenameEnd = strlen(kproc->p_comm);
return xStrdup(kproc->p_comm); return xStrdup(kproc->p_comm);
} }
for (i = 0; arg[i] != NULL; i++) {
size_t len = 0;
for (int i = 0; arg[i] != NULL; i++) {
len += strlen(arg[i]) + 1; /* room for arg and trailing space or NUL */ len += strlen(arg[i]) + 1; /* room for arg and trailing space or NUL */
} }
/* don't use xMalloc here - we want to handle huge argv's gracefully */ /* don't use xMalloc here - we want to handle huge argv's gracefully */
char* s;
if ((s = malloc(len)) == NULL) { if ((s = malloc(len)) == NULL) {
*basenameEnd = strlen(kproc->p_comm); *basenameEnd = strlen(kproc->p_comm);
return xStrdup(kproc->p_comm); return xStrdup(kproc->p_comm);
@ -156,10 +163,9 @@ char* OpenBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, in
*s = '\0'; *s = '\0';
for (i = 0; arg[i] != NULL; i++) { for (int i = 0; arg[i] != NULL; i++) {
size_t n = strlcat(s, arg[i], len); size_t n = strlcat(s, arg[i], len);
if (i == 0) { if (i == 0) {
/* TODO: rename all basenameEnd to basenameLen, make size_t */
*basenameEnd = MINIMUM(n, len - 1); *basenameEnd = MINIMUM(n, len - 1);
} }
/* the trailing space should get truncated anyway */ /* the trailing space should get truncated anyway */
@ -176,30 +182,25 @@ static double getpcpu(const struct kinfo_proc* kp) {
if (fscale == 0) if (fscale == 0)
return 0.0; return 0.0;
#define fxtofl(fixpt) ((double)(fixpt) / fscale) return 100.0 * (double)kp->p_pctcpu / fscale;
return (100.0 * fxtofl(kp->p_pctcpu));
} }
static inline void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
const Settings* settings = this->super.settings; const Settings* settings = this->super.settings;
bool hideKernelThreads = settings->hideKernelThreads; bool hideKernelThreads = settings->hideKernelThreads;
bool hideUserlandThreads = settings->hideUserlandThreads; bool hideUserlandThreads = settings->hideUserlandThreads;
int count = 0; int count = 0;
// use KERN_PROC_KTHREAD to also include kernel threads const struct kinfo_proc* kprocs = kvm_getprocs(this->kd, KERN_PROC_KTHREAD, 0, sizeof(struct kinfo_proc), &count);
struct kinfo_proc* kprocs = kvm_getprocs(this->kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count);
//struct kinfo_proc* kprocs = getprocs(KERN_PROC_ALL, 0, &count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
struct kinfo_proc* kproc = &kprocs[i]; const struct kinfo_proc* kproc = &kprocs[i];
bool preExisting = false; bool preExisting = false;
Process* proc = ProcessList_getProcess(&this->super, kproc->p_pid, &preExisting, OpenBSDProcess_new); Process* proc = ProcessList_getProcess(&this->super, kproc->p_pid, &preExisting, OpenBSDProcess_new);
OpenBSDProcess* fp = (OpenBSDProcess*) proc; //OpenBSDProcess* fp = (OpenBSDProcess*) proc;
proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
|| (hideUserlandThreads && Process_isUserlandThread(proc)));
if (!preExisting) { if (!preExisting) {
proc->ppid = kproc->p_ppid; proc->ppid = kproc->p_ppid;
@ -226,10 +227,8 @@ static inline void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
proc->percent_mem = (proc->m_resident * CRT_pageSizeKB) / (double)(this->super.totalMem) * 100.0; proc->percent_mem = (proc->m_resident * CRT_pageSizeKB) / (double)(this->super.totalMem) * 100.0;
proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0, this->super.cpuCount * 100.0); proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0, this->super.cpuCount * 100.0);
//proc->nlwp = kproc->p_numthreads; //proc->nlwp = kproc->p_numthreads;
//proc->time = kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 10);
proc->nice = kproc->p_nice - 20; proc->nice = kproc->p_nice - 20;
proc->time = kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 1000000); proc->time = 100 * (kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 1000000));
proc->time *= 100;
proc->priority = kproc->p_priority - PZERO; proc->priority = kproc->p_priority - PZERO;
switch (kproc->p_stat) { switch (kproc->p_stat) {
@ -261,10 +260,9 @@ static unsigned long long saturatingSub(unsigned long long a, unsigned long long
} }
static void getKernelCPUTimes(int cpuId, u_int64_t* times) { static void getKernelCPUTimes(int cpuId, u_int64_t* times) {
int mib[] = { CTL_KERN, KERN_CPTIME2, cpuId }; const int mib[] = { CTL_KERN, KERN_CPTIME2, cpuId };
size_t length = sizeof(u_int64_t) * CPUSTATES; size_t length = sizeof(*times) * CPUSTATES;
if (sysctl(mib, 3, times, &length, NULL, 0) == -1 || if (sysctl(mib, 3, times, &length, NULL, 0) == -1 || length != sizeof(*times) * CPUSTATES) {
length != sizeof(u_int64_t) * CPUSTATES) {
CRT_fatalError("sysctl kern.cp_time2 failed"); CRT_fatalError("sysctl kern.cp_time2 failed");
} }
} }

View File

@ -9,6 +9,13 @@ in the source distribution for its full text.
*/ */
#include <kvm.h> #include <kvm.h>
#include <stdbool.h>
#include <sys/types.h>
#include "Hashtable.h"
#include "ProcessList.h"
#include "UsersTable.h"
typedef struct CPUData_ { typedef struct CPUData_ {
unsigned long long int totalTime; unsigned long long int totalTime;
@ -43,8 +50,6 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
void ProcessList_delete(ProcessList* this); void ProcessList_delete(ProcessList* this);
char* OpenBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, int* basenameEnd);
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate); void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate);
#endif #endif

View File

@ -7,40 +7,39 @@ in the source distribution for its full text.
*/ */
#include "Platform.h" #include "Platform.h"
#include "Macros.h"
#include "Meter.h" #include <errno.h>
#include <kvm.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/resource.h>
#include <sys/sensors.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <uvm/uvmexp.h>
#include "CPUMeter.h" #include "CPUMeter.h"
#include "MemoryMeter.h"
#include "SwapMeter.h"
#include "TasksMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
#include "ClockMeter.h" #include "ClockMeter.h"
#include "DateMeter.h" #include "DateMeter.h"
#include "DateTimeMeter.h" #include "DateTimeMeter.h"
#include "HostnameMeter.h" #include "HostnameMeter.h"
#include "SignalsPanel.h" #include "LoadAverageMeter.h"
#include "Macros.h"
#include "MemoryMeter.h"
#include "Meter.h"
#include "OpenBSDProcess.h" #include "OpenBSDProcess.h"
#include "OpenBSDProcessList.h" #include "OpenBSDProcessList.h"
#include "ProcessList.h"
#include <sys/param.h> #include "Settings.h"
#include <sys/sysctl.h> #include "SignalsPanel.h"
#include <sys/sensors.h> #include "SwapMeter.h"
#include <sys/swap.h> #include "TasksMeter.h"
#include "UptimeMeter.h"
#include <unistd.h> #include "XUtils.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <time.h>
#include <fcntl.h>
#include <kvm.h>
#include <limits.h>
#include <errno.h>
#include <math.h>
ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 }; ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
@ -131,10 +130,9 @@ void Platform_setBindings(Htop_Action* keys) {
(void) keys; (void) keys;
} }
// preserved from FreeBSD port
int Platform_getUptime() { int Platform_getUptime() {
struct timeval bootTime, currTime; struct timeval bootTime, currTime;
int mib[2] = { CTL_KERN, KERN_BOOTTIME }; const int mib[2] = { CTL_KERN, KERN_BOOTTIME };
size_t size = sizeof(bootTime); size_t size = sizeof(bootTime);
int err = sysctl(mib, 2, &bootTime, &size, NULL, 0); int err = sysctl(mib, 2, &bootTime, &size, NULL, 0);
@ -148,7 +146,7 @@ int Platform_getUptime() {
void Platform_getLoadAverage(double* one, double* five, double* fifteen) { void Platform_getLoadAverage(double* one, double* five, double* fifteen) {
struct loadavg loadAverage; struct loadavg loadAverage;
int mib[2] = { CTL_VM, VM_LOADAVG }; const int mib[2] = { CTL_VM, VM_LOADAVG };
size_t size = sizeof(loadAverage); size_t size = sizeof(loadAverage);
int err = sysctl(mib, 2, &loadAverage, &size, NULL, 0); int err = sysctl(mib, 2, &loadAverage, &size, NULL, 0);
@ -164,12 +162,12 @@ void Platform_getLoadAverage(double* one, double* five, double* fifteen) {
} }
int Platform_getMaxPid() { int Platform_getMaxPid() {
// this is hard-coded in sys/sys/proc.h - no sysctl exists // this is hard-coded in sys/proc.h - no sysctl exists
return 99999; return 99999;
} }
double Platform_setCPUValues(Meter* this, int cpu) { double Platform_setCPUValues(Meter* this, int cpu) {
const OpenBSDProcessList* pl = (OpenBSDProcessList*) this->pl; const OpenBSDProcessList* pl = (const OpenBSDProcessList*) this->pl;
const CPUData* cpuData = &(pl->cpus[cpu]); const CPUData* cpuData = &(pl->cpus[cpu]);
double total = cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod; double total = cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod;
double totalPercent; double totalPercent;
@ -195,9 +193,6 @@ double Platform_setCPUValues(Meter* this, int cpu) {
} }
totalPercent = CLAMP(totalPercent, 0.0, 100.0); totalPercent = CLAMP(totalPercent, 0.0, 100.0);
if (isnan(totalPercent)) {
totalPercent = 0.0;
}
v[CPU_METER_TEMPERATURE] = NAN; v[CPU_METER_TEMPERATURE] = NAN;
@ -216,45 +211,10 @@ void Platform_setMemoryValues(Meter* this) {
this->values[2] = cachedMem; this->values[2] = cachedMem;
} }
/*
* Copyright (c) 1994 Thorsten Lockert <tholo@sigmasoft.com>
* All rights reserved.
*
* Taken almost directly from OpenBSD's top(1)
*/
void Platform_setSwapValues(Meter* this) { void Platform_setSwapValues(Meter* this) {
const ProcessList* pl = this->pl; const ProcessList* pl = this->pl;
struct swapent* swdev; this->total = pl->totalSwap;
unsigned long long int total, used; this->values[0] = pl->usedSwap;
int nswap, rnswap, i;
nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap == 0) {
return;
}
swdev = xCalloc(nswap, sizeof(*swdev));
rnswap = swapctl(SWAP_STATS, swdev, nswap);
if (rnswap == -1) {
free(swdev);
return;
}
// if rnswap != nswap, then what?
/* Total things up */
total = used = 0;
for (i = 0; i < nswap; i++) {
if (swdev[i].se_flags & SWF_ENABLE) {
used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
}
}
this->total = pl->totalSwap = total;
this->values[0] = pl->usedSwap = used;
free(swdev);
} }
char* Platform_getProcessEnv(pid_t pid) { char* Platform_getProcessEnv(pid_t pid) {
@ -350,7 +310,7 @@ static bool findDevice(const char* name, int* mib, struct sensordev* snsrdev, si
} }
void Platform_getBattery(double* percent, ACPresence* isOnAC) { void Platform_getBattery(double* percent, ACPresence* isOnAC) {
static int mib[] = {CTL_HW, HW_SENSORS, 0, 0, 0}; int mib[] = {CTL_HW, HW_SENSORS, 0, 0, 0};
struct sensor s; struct sensor s;
size_t slen = sizeof(struct sensor); size_t slen = sizeof(struct sensor);
struct sensordev snsrdev; struct sensordev snsrdev;

View File

@ -14,9 +14,12 @@ in the source distribution for its full text.
#include "Action.h" #include "Action.h"
#include "BatteryMeter.h" #include "BatteryMeter.h"
#include "DiskIOMeter.h" #include "DiskIOMeter.h"
#include "Meter.h"
#include "Process.h"
#include "ProcessLocksScreen.h" #include "ProcessLocksScreen.h"
#include "SignalsPanel.h" #include "SignalsPanel.h"
extern ProcessFieldData Process_fields[]; extern ProcessFieldData Process_fields[];
extern ProcessField Platform_defaultFields[]; extern ProcessField Platform_defaultFields[];

View File

@ -33,17 +33,16 @@ void ZfsArcMeter_readStats(Meter* this, const ZfsArcStats* stats) {
this->values[5] = stats->size; this->values[5] = stats->size;
} }
static void ZfsArcMeter_updateValues(Meter* this, char* buffer, int size) { static void ZfsArcMeter_updateValues(Meter* this, char* buffer, size_t size) {
int written; int written;
Platform_setZfsArcValues(this); Platform_setZfsArcValues(this);
written = Meter_humanUnit(buffer, this->values[5], size); written = Meter_humanUnit(buffer, this->values[5], size);
buffer += written; METER_BUFFER_CHECK(buffer, size, written);
if ((size -= written) > 0) {
*buffer++ = '/'; METER_BUFFER_APPEND_CHR(buffer, size, '/');
size--;
Meter_humanUnit(buffer, this->total, size); Meter_humanUnit(buffer, this->total, size);
}
} }
static void ZfsArcMeter_display(const Object* cast, RichString* out) { static void ZfsArcMeter_display(const Object* cast, RichString* out) {

View File

@ -32,11 +32,11 @@ void ZfsCompressedArcMeter_readStats(Meter* this, const ZfsArcStats* stats) {
} }
} }
static void ZfsCompressedArcMeter_printRatioString(const Meter* this, char* buffer, int size) { static void ZfsCompressedArcMeter_printRatioString(const Meter* this, char* buffer, size_t size) {
xSnprintf(buffer, size, "%.2f:1", this->total / this->values[0]); xSnprintf(buffer, size, "%.2f:1", this->total / this->values[0]);
} }
static void ZfsCompressedArcMeter_updateValues(Meter* this, char* buffer, int size) { static void ZfsCompressedArcMeter_updateValues(Meter* this, char* buffer, size_t size) {
Platform_setZfsCompressedArcValues(this); Platform_setZfsCompressedArcValues(this);
ZfsCompressedArcMeter_printRatioString(this, buffer, size); ZfsCompressedArcMeter_printRatioString(this, buffer, size);