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
};
static void BatteryMeter_updateValues(Meter* this, char* buffer, int len) {
static void BatteryMeter_updateValues(Meter* this, char* buffer, size_t len) {
ACPresence isOnAC;
double percent;

View File

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

View File

@ -5,8 +5,9 @@ What's new in version 3.0.3
* Improved command display/sort functionality
(thanks to Narendran Gopalakrishnan)
* Add screen for active file locks
(thanks to Fynn J. Wulf)
* Calculate library size (M_LRS column) from maps file
(thanks to Fynn Wulf)
(thanks to Fynn J. Wulf)
* Add a Zram meter
(thanks to Murloc Knight)
* 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
* Include documentation for COMM and EXE
* 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
* Merged view for COMM, EXE and cmdline
(thanks to Narendran Gopalakrishnan and Benny Baumann)
* Consistent kernel thread display for COMM/EXE columns
* Central fault handling for all platforms
* Handle parsing envID & VPid from process status file

View File

@ -19,7 +19,7 @@ static const int ClockMeter_attributes[] = {
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);
struct tm 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 "RichString.h"
#include "Vector.h"
#include "XUtils.h"
// TO ADD A NEW SCHEME:

View File

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

View File

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

View File

@ -19,7 +19,7 @@ static const int DateMeter_attributes[] = {
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);
struct tm result;
struct tm* lt = localtime_r(&t, &result);

View File

@ -19,7 +19,7 @@ static const int DateTimeMeter_attributes[] = {
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);
struct tm result;
struct tm* lt = localtime_r(&t, &result);

View File

@ -1,6 +1,6 @@
/*
htop - DiskIOMeter.c
(C) 2020 Christian Göttsche
(C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file
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 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;
struct timeval tv;

View File

@ -1,8 +1,8 @@
#ifndef HEADER_DiskIOMeter
#define HEADER_DiskIOMeter
/*
h top - DiskIOMeter*.h
(C) 2020 Christian Göttsche
htop - DiskIOMeter.h
(C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file
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 "OptionItem.h"
#include "ProvideCurses.h"
#include "XUtils.h"
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Macros.h"
#include "XUtils.h"

View File

@ -131,21 +131,6 @@ int Header_size(Header* this, int column) {
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) {
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);
char* Header_readMeterName(Header* this, int i, int column);
MeterModeId Header_readMeterMode(Header* this, int i, int column);
void Header_reinit(Header* this);

View File

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

View File

@ -24,7 +24,7 @@ static const int LoadMeter_attributes[] = {
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]);
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);
}
static void LoadMeter_updateValues(Meter* this, char* buffer, int size) {
static void LoadMeter_updateValues(Meter* this, char* buffer, size_t size) {
double five, fifteen;
Platform_getLoadAverage(&this->values[0], &five, &fifteen);
if (this->values[0] > this->total) {

View File

@ -3,12 +3,14 @@ AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS = htop
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
applicationsdir = $(datadir)/applications
applications_DATA = htop.desktop
pixmapdir = $(datadir)/pixmaps
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_LDFLAGS =

View File

@ -19,17 +19,16 @@ static const int MemoryMeter_attributes[] = {
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;
Platform_setMemoryValues(this);
written = Meter_humanUnit(buffer, this->values[0], size);
buffer += written;
if ((size -= written) > 0) {
*buffer++ = '/';
size--;
METER_BUFFER_CHECK(buffer, size, written);
METER_BUFFER_APPEND_CHR(buffer, size, '/');
Meter_humanUnit(buffer, this->total, size);
}
}
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 "ProvideCurses.h"
#include "RichString.h"
#include "Settings.h"
#include "XUtils.h"
@ -48,10 +49,10 @@ Meter* Meter_new(const struct ProcessList_* pl, int param, const MeterClass* typ
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";
unsigned long int powi = 1;
unsigned int written, powj = 1, precision = 2;
unsigned int powj = 1, precision = 2;
for (;;) {
if (value / 1024 < powi)
@ -73,10 +74,7 @@ int Meter_humanUnit(char* buffer, unsigned long int value, int size) {
break;
}
written = snprintf(buffer, size, "%.*f%c",
precision, (double) value / powi, *prefix);
return written;
return snprintf(buffer, size, "%.*f%c", precision, (double) value / powi, *prefix);
}
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) {
char buffer[METER_BUFFER_LEN];
Meter_updateValues(this, buffer, METER_BUFFER_LEN - 1);
Meter_updateValues(this, buffer, sizeof(buffer));
(void) w;
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) {
char buffer[METER_BUFFER_LEN];
Meter_updateValues(this, buffer, METER_BUFFER_LEN - 1);
Meter_updateValues(this, buffer, sizeof(buffer));
w -= 2;
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]);
mvaddch(y, x, '[');
mvaddch(y, x + w, ']');
attrset(CRT_colors[RESET_COLOR]);
w--;
x++;
if (w < 1) {
attrset(CRT_colors[RESET_COLOR]);
if (w < 1)
return;
}
// The text in the bar is right aligned;
// calculate needed padding and generate leading spaces
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_appendChr(&bar, ' ', padding);
@ -236,13 +233,13 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
// ...then print the buffer.
offset = 0;
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]);
offset += blockSizes[i];
offset = CLAMP(offset, 0, 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);
}
@ -312,8 +309,8 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
for (int i = 0; i < nValues - 1; i++)
data->values[i] = data->values[i + 1];
char buffer[nValues];
Meter_updateValues(this, buffer, nValues - 1);
char buffer[METER_BUFFER_LEN];
Meter_updateValues(this, buffer, sizeof(buffer));
double value = 0.0;
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;
char buffer[METER_BUFFER_LEN];
Meter_updateValues(this, buffer, METER_BUFFER_LEN - 1);
Meter_updateValues(this, buffer, sizeof(buffer));
RichString_begin(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 len = RichString_sizeVal(out);
for (int i = 0; i < len; i++) {
char c = RichString_getCharVal(out, i);
int c = RichString_getCharVal(out, i);
if (c >= '0' && c <= '9') {
LEDMeterMode_drawDigit(xx, y, c - 48);
xx += 4;
@ -444,8 +441,7 @@ const MeterMode* const Meter_modes[] = {
/* Blank meter */
static void BlankMeter_updateValues(Meter* this, char* buffer, int size) {
(void) this; (void) buffer; (void) size;
static void BlankMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, size_t size) {
if (size > 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_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_;
typedef struct Meter_ Meter;
typedef void(*Meter_Init)(Meter*);
typedef void(*Meter_Done)(Meter*);
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 struct MeterClass_ {
@ -101,7 +124,7 @@ extern const MeterClass Meter_class;
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);

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_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;
struct timeval tv;

View File

@ -12,7 +12,9 @@ in the source distribution for its full text.
#include <stdlib.h>
#include "CRT.h"
#include "Macros.h"
#include "RichString.h"
#include "XUtils.h"
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 processMegabytesColor = CRT_colors[PROCESS_MEGABYTES];
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';
int attr = CRT_colors[DEFAULT_COLOR];
int baseattr = CRT_colors[PROCESS_BASENAME];
int n = sizeof(buffer) - 1;
size_t n = sizeof(buffer) - 1;
bool coloring = this->settings->highlightMegabytes;
switch (field) {
@ -312,7 +312,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
} else {
ret = snprintf(buf, n, " ");
}
if (ret < 0 || ret >= n) {
if (ret < 0 || (size_t)ret >= n) {
written = n;
} else {
written = ret;

View File

@ -10,7 +10,6 @@ in the source distribution for its full text.
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include "Object.h"
@ -177,7 +176,7 @@ void Process_printTime(RichString* str, unsigned long long totalHundredths);
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);

View File

@ -14,6 +14,7 @@ in the source distribution for its full text.
#include "CRT.h"
#include "Hashtable.h"
#include "Macros.h"
#include "Vector.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;
RichString_setLen(this, newLen);
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;
}

View File

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

View File

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

View File

@ -23,7 +23,7 @@ static const int TasksMeter_attributes[] = {
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;
this->values[0] = pl->kernelThreads;
this->values[1] = pl->userlandThreads;

View File

@ -17,7 +17,7 @@ static const int UptimeMeter_attributes[] = {
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();
if (totalseconds == -1) {
xSnprintf(buffer, len, "(unknown)");

View File

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

View File

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

View File

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.65)
AC_INIT([htop],[3.0.3-rc1],[htop@groups.io])
AC_INIT([htop],[3.0.3],[htop@groups.io])
AC_CONFIG_SRCDIR([htop.c])
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);
void ProcessList_goThroughEntries(ProcessList* super, pauseProcessUpdate);
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate);
#endif

View File

@ -248,7 +248,7 @@ char* Platform_getProcessEnv(pid_t pid) {
char* env = xMalloc(capacity);
int err = sysctl(mib, 4, env, &capacity, NULL, 0);
if (err) {
if (err || capacity == 0) {
free(env);
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 <errno.h>
#include <limits.h>
#include <sensors/sensors.h>
#include "XUtils.h"

View File

@ -11,6 +11,7 @@ in the source distribution for its full text.
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syscall.h>
#include <unistd.h>
@ -617,7 +618,7 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
bool coloring = this->settings->highlightMegabytes;
char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR];
int n = sizeof(buffer) - 1;
size_t n = sizeof(buffer) - 1;
switch ((int)field) {
case TTY_NR: {
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.
*/
#include "config.h"
#include "config.h" // IWYU pragma: keep
#include <stdbool.h>
#include <sys/types.h>
#include "IOPriority.h"
#include "Object.h"

View File

@ -13,18 +13,17 @@ in the source distribution for its full text.
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/utsname.h>
#ifdef HAVE_DELAYACCT
#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;
bool exec;
} LibraryData;
@ -883,7 +882,7 @@ static void LinuxProcessList_readSecattrData(LinuxProcess* process, openat_arg_t
}
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)
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);
ssize_t r = readlink(filename, pathBuffer, sizeof(pathBuffer) - 1);
#endif
if (r < 0) {
free(process->cwd);
process->cwd = NULL;

View File

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

View File

@ -25,7 +25,7 @@ static const int PressureStallMeter_attributes[] = {
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;
if (strstr(Meter_name(this), "CPU")) {
file = "cpu";

View File

@ -1,6 +1,6 @@
/*
htop - SELinuxMeter.c
(C) 2020 Christian Goettsche
(C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
@ -9,7 +9,6 @@ in the source distribution for its full text.
#include "CRT.h"
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
@ -71,7 +70,7 @@ static bool isSelinuxEnforcing(void) {
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();
enforcing = isSelinuxEnforcing();

View File

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

View File

@ -1,6 +1,6 @@
/*
htop - SystemdMeter.c
(C) 2020 Christian Göttsche
(C) 2020 htop dev team
Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
@ -229,7 +229,7 @@ static void updateViaExec(void) {
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);
systemState = NULL;
nFailedUnits = nInstalledJobs = nNames = nJobs = INVALID_VALUE;

View File

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

View File

@ -11,7 +11,7 @@ static const int ZramMeter_attributes[] = {
ZRAM
};
static void ZramMeter_updateValues(Meter* this, char* buffer, int size) {
static void ZramMeter_updateValues(Meter* this, char* buffer, size_t size) {
int written;
Platform_setZramValues(this);
@ -20,29 +20,18 @@ static void ZramMeter_updateValues(Meter* this, char* buffer, int size) {
this->curItems = 1;
written = Meter_humanUnit(buffer, this->values[0], size);
buffer += written;
size -= written;
if (size <= 0) {
return;
}
*buffer++ = '(';
size--;
if (size <= 0) {
return;
}
METER_BUFFER_CHECK(buffer, size, written);
METER_BUFFER_APPEND_CHR(buffer, size, '(');
written = Meter_humanUnit(buffer, this->values[1], size);
buffer += written;
size -= written;
if (size <= 0) {
return;
}
*buffer++ = ')';
size--;
if ((size -= written) > 0) {
*buffer++ = '/';
size--;
METER_BUFFER_CHECK(buffer, size, written);
METER_BUFFER_APPEND_CHR(buffer, size, ')');
METER_BUFFER_APPEND_CHR(buffer, size, '/');
Meter_humanUnit(buffer, this->total, size);
}
}
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.
*/
#include "Process.h"
#include "ProcessList.h"
#include "OpenBSDProcess.h"
#include "Platform.h"
#include "CRT.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[] = {
[0] = {
@ -200,7 +189,7 @@ Process* OpenBSDProcess_new(const Settings* settings) {
OpenBSDProcess* this = xCalloc(sizeof(OpenBSDProcess), 1);
Object_setClass(this, Class(OpenBSDProcess));
Process_init(&this->super, settings);
return &this->this;
return &this->super;
}
void Process_delete(Object* cast) {
@ -209,8 +198,8 @@ void Process_delete(Object* cast) {
free(this);
}
void OpenBSDProcess_writeField(const Process* this, RichString* str, ProcessField field) {
//OpenBSDProcess* fp = (OpenBSDProcess*) this;
static void OpenBSDProcess_writeField(const Process* this, RichString* str, ProcessField field) {
//const OpenBSDProcess* op = (const OpenBSDProcess*) this;
char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR];
//int n = sizeof(buffer) - 1;
@ -223,7 +212,7 @@ void OpenBSDProcess_writeField(const Process* this, RichString* str, ProcessFiel
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 Settings *settings = ((const Process*)v1)->settings;
@ -235,6 +224,9 @@ long OpenBSDProcess_compare(const void* v1, const void* v2) {
p1 = (const OpenBSDProcess*)v2;
}
// remove if actually used
(void)p1; (void)p2;
switch (settings->sortKey) {
// add OpenBSD-specific fields here
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) {
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.
*/
#include <stdbool.h>
#include "Object.h"
#include "Process.h"
#include "Settings.h"
typedef enum OpenBSDProcessFields_ {
// Add platform-specific fields here, with ids >= 100
LAST_PROCESSFIELD = 100,
@ -31,10 +38,6 @@ Process* OpenBSDProcess_new(const Settings* settings);
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);
#endif

View File

@ -6,46 +6,49 @@ Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
#include "CRT.h"
#include "ProcessList.h"
#include "OpenBSDProcessList.h"
#include "OpenBSDProcess.h"
#include "Macros.h"
#include <err.h>
#include <errno.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 <kvm.h>
#include <limits.h>
#include <stdlib.h>
#include <string.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;
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) {
int mib[] = { CTL_HW, HW_NCPU };
int fmib[] = { CTL_KERN, KERN_FSCALE };
int i, e;
OpenBSDProcessList* opl;
ProcessList* pl;
const int mib[] = { CTL_HW, HW_NCPU };
const int fmib[] = { CTL_KERN, KERN_FSCALE };
int r;
size_t size;
char errbuf[_POSIX2_LINE_MAX];
opl = xCalloc(1, sizeof(OpenBSDProcessList));
pl = (ProcessList*) opl;
size = sizeof(pl->cpuCount);
OpenBSDProcessList* opl = xCalloc(1, sizeof(OpenBSDProcessList));
ProcessList* pl = (ProcessList*) opl;
ProcessList_init(pl, Class(OpenBSDProcess), usersTable, pidMatchList, userId);
e = sysctl(mib, 2, &pl->cpuCount, &size, NULL, 0);
if (e == -1 || pl->cpuCount < 1) {
size = sizeof(pl->cpuCount);
r = sysctl(mib, 2, &pl->cpuCount, &size, NULL, 0);
if (r < 0 || pl->cpuCount < 1) {
pl->cpuCount = 1;
}
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");
}
for (i = 0; i <= pl->cpuCount; i++) {
for (int i = 0; i <= pl->cpuCount; i++) {
CPUData* d = opl->cpus + i;
d->totalTime = 1;
d->totalPeriod = 1;
@ -70,7 +73,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
}
void ProcessList_delete(ProcessList* this) {
const OpenBSDProcessList* opl = (OpenBSDProcessList*) this;
OpenBSDProcessList* opl = (OpenBSDProcessList*) this;
if (opl->kd) {
kvm_close(opl->kd);
@ -82,8 +85,8 @@ void ProcessList_delete(ProcessList* this) {
free(this);
}
static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
static int uvmexp_mib[] = {CTL_VM, VM_UVMEXP};
static void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
const int uvmexp_mib[] = { CTL_VM, VM_UVMEXP };
struct uvmexp 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->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * CRT_pageSizeKB;
// 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;
size_t size_bcstats = sizeof(bcstats);
@ -103,52 +107,55 @@ static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
}
pl->cachedMem = bcstats.numbufpages * CRT_pageSizeKB;
pl->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * CRT_pageSizeKB;
/*
const OpenBSDProcessList* opl = (OpenBSDProcessList*) pl;
size_t len = sizeof(pl->totalMem);
sysctl(MIB_hw_physmem, 2, &(pl->totalMem), &len, NULL, 0);
pl->totalMem /= 1024;
sysctl(MIB_vm_stats_vm_v_wire_count, 4, &(pl->usedMem), &len, NULL, 0);
pl->usedMem *= CRT_pageSizeKB;
sysctl(MIB_vm_stats_vm_v_cache_count, 4, &(pl->cachedMem), &len, NULL, 0);
pl->cachedMem *= CRT_pageSizeKB;
struct kvm_swap swap[16];
int nswap = kvm_getswapinfo(opl->kd, swap, ARRAYSIZE(swap), 0);
pl->totalSwap = 0;
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
* 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);
/* Total things up */
unsigned long long int total = 0, used = 0;
for (int i = 0; i < rnswap; i++) {
if (swdev[i].se_flags & SWF_ENABLE) {
used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
}
}
pl->totalSwap = total;
pl->usedSwap = used;
} else {
pl->totalSwap = pl->usedSwap = 0;
}
}
char* OpenBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, int* basenameEnd) {
char *s, **arg;
size_t len = 0;
int i;
static char* OpenBSDProcessList_readProcessName(kvm_t* kd, const struct kinfo_proc* kproc, int* basenameEnd) {
/*
* Like OpenBSD's top(1), we try to fall back to the command name
* (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) {
*basenameEnd = strlen(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 */
}
/* don't use xMalloc here - we want to handle huge argv's gracefully */
char* s;
if ((s = malloc(len)) == NULL) {
*basenameEnd = strlen(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';
for (i = 0; arg[i] != NULL; i++) {
for (int i = 0; arg[i] != NULL; i++) {
size_t n = strlcat(s, arg[i], len);
if (i == 0) {
/* TODO: rename all basenameEnd to basenameLen, make size_t */
*basenameEnd = MINIMUM(n, len - 1);
}
/* the trailing space should get truncated anyway */
@ -176,30 +182,25 @@ static double getpcpu(const struct kinfo_proc* kp) {
if (fscale == 0)
return 0.0;
#define fxtofl(fixpt) ((double)(fixpt) / fscale)
return (100.0 * fxtofl(kp->p_pctcpu));
return 100.0 * (double)kp->p_pctcpu / fscale;
}
static inline void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
const Settings* settings = this->super.settings;
bool hideKernelThreads = settings->hideKernelThreads;
bool hideUserlandThreads = settings->hideUserlandThreads;
int count = 0;
// use KERN_PROC_KTHREAD to also include kernel threads
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);
const struct kinfo_proc* kprocs = kvm_getprocs(this->kd, KERN_PROC_KTHREAD, 0, sizeof(struct kinfo_proc), &count);
for (int i = 0; i < count; i++) {
struct kinfo_proc* kproc = &kprocs[i];
const struct kinfo_proc* kproc = &kprocs[i];
bool preExisting = false;
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))
|| (hideUserlandThreads && Process_isUserlandThread(proc)));
proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
if (!preExisting) {
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_cpu = CLAMP(getpcpu(kproc), 0.0, this->super.cpuCount * 100.0);
//proc->nlwp = kproc->p_numthreads;
//proc->time = kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 10);
proc->nice = kproc->p_nice - 20;
proc->time = kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 1000000);
proc->time *= 100;
proc->time = 100 * (kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 1000000));
proc->priority = kproc->p_priority - PZERO;
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) {
int mib[] = { CTL_KERN, KERN_CPTIME2, cpuId };
size_t length = sizeof(u_int64_t) * CPUSTATES;
if (sysctl(mib, 3, times, &length, NULL, 0) == -1 ||
length != sizeof(u_int64_t) * CPUSTATES) {
const int mib[] = { CTL_KERN, KERN_CPTIME2, cpuId };
size_t length = sizeof(*times) * CPUSTATES;
if (sysctl(mib, 3, times, &length, NULL, 0) == -1 || length != sizeof(*times) * CPUSTATES) {
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 <stdbool.h>
#include <sys/types.h>
#include "Hashtable.h"
#include "ProcessList.h"
#include "UsersTable.h"
typedef struct CPUData_ {
unsigned long long int totalTime;
@ -43,8 +50,6 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
void ProcessList_delete(ProcessList* this);
char* OpenBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, int* basenameEnd);
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate);
#endif

View File

@ -7,40 +7,39 @@ in the source distribution for its full text.
*/
#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 "MemoryMeter.h"
#include "SwapMeter.h"
#include "TasksMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
#include "ClockMeter.h"
#include "DateMeter.h"
#include "DateTimeMeter.h"
#include "HostnameMeter.h"
#include "SignalsPanel.h"
#include "LoadAverageMeter.h"
#include "Macros.h"
#include "MemoryMeter.h"
#include "Meter.h"
#include "OpenBSDProcess.h"
#include "OpenBSDProcessList.h"
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/sensors.h>
#include <sys/swap.h>
#include <unistd.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>
#include "ProcessList.h"
#include "Settings.h"
#include "SignalsPanel.h"
#include "SwapMeter.h"
#include "TasksMeter.h"
#include "UptimeMeter.h"
#include "XUtils.h"
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;
}
// preserved from FreeBSD port
int Platform_getUptime() {
struct timeval bootTime, currTime;
int mib[2] = { CTL_KERN, KERN_BOOTTIME };
const int mib[2] = { CTL_KERN, KERN_BOOTTIME };
size_t size = sizeof(bootTime);
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) {
struct loadavg loadAverage;
int mib[2] = { CTL_VM, VM_LOADAVG };
const int mib[2] = { CTL_VM, VM_LOADAVG };
size_t size = sizeof(loadAverage);
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() {
// 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;
}
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]);
double total = cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod;
double totalPercent;
@ -195,9 +193,6 @@ double Platform_setCPUValues(Meter* this, int cpu) {
}
totalPercent = CLAMP(totalPercent, 0.0, 100.0);
if (isnan(totalPercent)) {
totalPercent = 0.0;
}
v[CPU_METER_TEMPERATURE] = NAN;
@ -216,45 +211,10 @@ void Platform_setMemoryValues(Meter* this) {
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) {
const ProcessList* pl = this->pl;
struct swapent* swdev;
unsigned long long int total, used;
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);
this->total = pl->totalSwap;
this->values[0] = pl->usedSwap;
}
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) {
static int mib[] = {CTL_HW, HW_SENSORS, 0, 0, 0};
int mib[] = {CTL_HW, HW_SENSORS, 0, 0, 0};
struct sensor s;
size_t slen = sizeof(struct sensor);
struct sensordev snsrdev;

View File

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

View File

@ -33,17 +33,16 @@ void ZfsArcMeter_readStats(Meter* this, const ZfsArcStats* stats) {
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;
Platform_setZfsArcValues(this);
written = Meter_humanUnit(buffer, this->values[5], size);
buffer += written;
if ((size -= written) > 0) {
*buffer++ = '/';
size--;
METER_BUFFER_CHECK(buffer, size, written);
METER_BUFFER_APPEND_CHR(buffer, size, '/');
Meter_humanUnit(buffer, this->total, size);
}
}
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]);
}
static void ZfsCompressedArcMeter_updateValues(Meter* this, char* buffer, int size) {
static void ZfsCompressedArcMeter_updateValues(Meter* this, char* buffer, size_t size) {
Platform_setZfsCompressedArcValues(this);
ZfsCompressedArcMeter_printRatioString(this, buffer, size);