htop/CRT.c

1273 lines
46 KiB
C

/*
htop - CRT.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/
#include "config.h" // IWYU pragma: keep
#include "CRT.h"
#include <errno.h>
#include <fcntl.h>
#include <langinfo.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ProvideCurses.h"
#include "XUtils.h"
#if !defined(NDEBUG) && defined(HAVE_MEMFD_CREATE)
#include <sys/mman.h>
#endif
#if defined(HAVE_LIBUNWIND_H) && defined(HAVE_LIBUNWIND)
#define PRINT_BACKTRACE
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#if defined(HAVE_DLADDR)
#include <dlfcn.h>
#endif
#elif defined(HAVE_EXECINFO_H)
#define PRINT_BACKTRACE
#include <execinfo.h>
#endif
#define ColorIndex(i, j) ((7 - (i)) * 8 + (j))
#define ColorPair(i, j) COLOR_PAIR(ColorIndex(i, j))
#define Black COLOR_BLACK
#define Red COLOR_RED
#define Green COLOR_GREEN
#define Yellow COLOR_YELLOW
#define Blue COLOR_BLUE
#define Magenta COLOR_MAGENTA
#define Cyan COLOR_CYAN
#define White COLOR_WHITE
#define ColorPairGrayBlack ColorPair(Magenta, Magenta)
#define ColorIndexGrayBlack ColorIndex(Magenta, Magenta)
#define ColorPairWhiteDefault ColorPair(Red, Red)
#define ColorIndexWhiteDefault ColorIndex(Red, Red)
static const char *const CRT_treeStrAscii[LAST_TREE_STR] = {
[TREE_STR_VERT] = "|",
[TREE_STR_RTEE] = "`",
[TREE_STR_BEND] = "`",
[TREE_STR_TEND] = ",",
[TREE_STR_OPEN] = "+",
[TREE_STR_SHUT] = "-",
[TREE_STR_ASC] = "+",
[TREE_STR_DESC] = "-",
};
#ifdef HAVE_LIBNCURSESW
static const char *const CRT_treeStrUtf8[LAST_TREE_STR] = {
[TREE_STR_VERT] = "\xe2\x94\x82", // │
[TREE_STR_RTEE] = "\xe2\x94\x9c", // ├
[TREE_STR_BEND] = "\xe2\x94\x94", // └
[TREE_STR_TEND] = "\xe2\x94\x8c", // ┌
[TREE_STR_OPEN] = "+", // +, TODO use 🮯 'BOX DRAWINGS LIGHT HORIZONTAL
// WITH VERTICAL STROKE' (U+1FBAF, "\xf0\x9f\xae\xaf") when
// Unicode 13 is common
[TREE_STR_SHUT] = "\xe2\x94\x80", // ─
[TREE_STR_ASC] = "\xe2\x96\xb3", // △
[TREE_STR_DESC] = "\xe2\x96\xbd", // ▽
};
bool CRT_utf8 = false;
#endif
const char *const *CRT_treeStr = CRT_treeStrAscii;
static const Settings *CRT_crashSettings;
static const int *CRT_delay;
const char *CRT_degreeSign;
static const char *initDegreeSign(void)
{
#ifdef HAVE_LIBNCURSESW
if (CRT_utf8)
return "\xc2\xb0";
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 "";
}
const int *CRT_colors;
static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[COLORSCHEME_DEFAULT] = {
[RESET_COLOR] = ColorPair(White, Black),
[DEFAULT_COLOR] = ColorPair(White, Black),
[FUNCTION_BAR] = ColorPair(Black, Cyan),
[FUNCTION_KEY] = ColorPair(White, Black),
[PANEL_HEADER_FOCUS] = ColorPair(Black, Green),
[PANEL_HEADER_UNFOCUS] = ColorPair(Black, Green),
[PANEL_SELECTION_FOCUS] = ColorPair(Black, Cyan),
[PANEL_SELECTION_FOLLOW] = ColorPair(Black, Yellow),
[PANEL_SELECTION_UNFOCUS] = ColorPair(Black, White),
[FAILED_SEARCH] = ColorPair(Red, Cyan),
[FAILED_READ] = A_BOLD | ColorPair(Red, Black),
[PAUSED] = A_BOLD | ColorPair(Yellow, Cyan),
[UPTIME] = A_BOLD | ColorPair(Cyan, Black),
[TEMP] = A_BOLD | ColorPair(Cyan, Black),
[FREQ] = A_BOLD | ColorPair(Cyan, Black),
[BATTERY] = A_BOLD | ColorPair(Cyan, Black),
[LARGE_NUMBER] = A_BOLD | ColorPair(Red, Black),
[METER_SHADOW] = A_BOLD | ColorPairGrayBlack,
[METER_TEXT] = ColorPair(Cyan, Black),
[METER_VALUE] = A_BOLD | ColorPair(Cyan, Black),
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red, Black),
[METER_VALUE_IOREAD] = ColorPair(Green, Black),
[METER_VALUE_IOWRITE] = ColorPair(Blue, Black),
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(White, Black),
[METER_VALUE_OK] = ColorPair(Green, Black),
[METER_VALUE_WARN] = A_BOLD | ColorPair(Yellow, Black),
[LED_COLOR] = ColorPair(Green, Black),
[TASKS_RUNNING] = A_BOLD | ColorPair(Green, Black),
[PROCESS] = A_NORMAL,
[PROCESS_SHADOW] = A_BOLD | ColorPairGrayBlack,
[PROCESS_TAG] = A_BOLD | ColorPair(Yellow, Black),
[PROCESS_MEGABYTES] = ColorPair(Cyan, Black),
[PROCESS_GIGABYTES] = ColorPair(Green, Black),
[PROCESS_BASENAME] = A_BOLD | ColorPair(Cyan, Black),
[PROCESS_TREE] = ColorPair(Cyan, Black),
[PROCESS_RUN_STATE] = ColorPair(Green, Black),
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
[PROCESS_NEW] = ColorPair(Black, Green),
[PROCESS_TOMB] = ColorPair(Black, Red),
[PROCESS_THREAD] = ColorPair(Green, Black),
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green, Black),
[PROCESS_COMM] = ColorPair(Magenta, Black),
[PROCESS_THREAD_COMM] = ColorPair(Blue, Black),
[BAR_BORDER] = A_BOLD,
[BAR_SHADOW] = A_BOLD | ColorPairGrayBlack,
[SWAP] = ColorPair(Red, Black),
[SWAP_CACHE] = ColorPair(Yellow, Black),
[GRAPH_1] = A_BOLD | ColorPair(Cyan, Black),
[GRAPH_2] = ColorPair(Cyan, Black),
[MEMORY_USED] = ColorPair(Green, Black),
[MEMORY_BUFFERS] = ColorPair(Blue, Black),
[MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Blue, Black),
[MEMORY_CACHE] = ColorPair(Yellow, Black),
[MEMORY_SHARED] = ColorPair(Magenta, Black),
[HUGEPAGE_1] = ColorPair(Green, Black),
[HUGEPAGE_2] = ColorPair(Yellow, Black),
[HUGEPAGE_3] = ColorPair(Red, Black),
[HUGEPAGE_4] = ColorPair(Blue, Black),
[LOAD_AVERAGE_FIFTEEN] = ColorPair(Cyan, Black),
[LOAD_AVERAGE_FIVE] = A_BOLD | ColorPair(Cyan, Black),
[LOAD_AVERAGE_ONE] = A_BOLD | ColorPair(White, Black),
[LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD | ColorPair(Cyan, Black),
[HELP_SHADOW] = A_BOLD | ColorPairGrayBlack,
[CLOCK] = A_BOLD,
[DATE] = A_BOLD,
[DATETIME] = A_BOLD,
[CHECK_BOX] = ColorPair(Cyan, Black),
[CHECK_MARK] = A_BOLD,
[CHECK_TEXT] = A_NORMAL,
[HOSTNAME] = A_BOLD,
[CPU_NICE] = ColorPair(Blue, Black),
[CPU_NICE_TEXT] = A_BOLD | ColorPair(Blue, Black),
[CPU_NORMAL] = ColorPair(Green, Black),
[CPU_SYSTEM] = ColorPair(Red, Black),
[CPU_IOWAIT] = A_BOLD | ColorPairGrayBlack,
[CPU_IRQ] = ColorPair(Yellow, Black),
[CPU_SOFTIRQ] = ColorPair(Magenta, Black),
[CPU_STEAL] = ColorPair(Cyan, Black),
[CPU_GUEST] = ColorPair(Cyan, Black),
[PANEL_EDIT] = ColorPair(White, Blue),
[SCREENS_OTH_BORDER] = ColorPair(Blue, Blue),
[SCREENS_OTH_TEXT] = ColorPair(Black, Blue),
[SCREENS_CUR_BORDER] = ColorPair(Green, Green),
[SCREENS_CUR_TEXT] = ColorPair(Black, Green),
[PRESSURE_STALL_THREEHUNDRED] = ColorPair(Cyan, Black),
[PRESSURE_STALL_SIXTY] = A_BOLD | ColorPair(Cyan, Black),
[PRESSURE_STALL_TEN] = A_BOLD | ColorPair(White, Black),
[ZFS_MFU] = ColorPair(Blue, Black),
[ZFS_MRU] = ColorPair(Yellow, Black),
[ZFS_ANON] = ColorPair(Magenta, Black),
[ZFS_HEADER] = ColorPair(Cyan, Black),
[ZFS_OTHER] = ColorPair(Magenta, Black),
[ZFS_COMPRESSED] = ColorPair(Blue, Black),
[ZFS_RATIO] = ColorPair(Magenta, Black),
[ZRAM] = ColorPair(Yellow, Black),
[DYNAMIC_GRAY] = ColorPairGrayBlack,
[DYNAMIC_DARKGRAY] = A_BOLD | ColorPairGrayBlack,
[DYNAMIC_RED] = ColorPair(Red, Black),
[DYNAMIC_GREEN] = ColorPair(Green, Black),
[DYNAMIC_BLUE] = ColorPair(Blue, Black),
[DYNAMIC_CYAN] = ColorPair(Cyan, Black),
[DYNAMIC_MAGENTA] = ColorPair(Magenta, Black),
[DYNAMIC_YELLOW] = ColorPair(Yellow, Black),
[DYNAMIC_WHITE] = ColorPair(White, Black),
},
[COLORSCHEME_MONOCHROME] = {
[RESET_COLOR] = A_NORMAL,
[DEFAULT_COLOR] = A_NORMAL,
[FUNCTION_BAR] = A_REVERSE,
[FUNCTION_KEY] = A_NORMAL,
[PANEL_HEADER_FOCUS] = A_REVERSE,
[PANEL_HEADER_UNFOCUS] = A_REVERSE,
[PANEL_SELECTION_FOCUS] = A_REVERSE,
[PANEL_SELECTION_FOLLOW] = A_REVERSE,
[PANEL_SELECTION_UNFOCUS] = A_BOLD,
[FAILED_SEARCH] = A_REVERSE | A_BOLD,
[FAILED_READ] = A_BOLD,
[PAUSED] = A_BOLD | A_REVERSE,
[UPTIME] = A_BOLD,
[TEMP] = A_BOLD,
[FREQ] = A_BOLD,
[BATTERY] = A_BOLD,
[LARGE_NUMBER] = A_BOLD,
[METER_SHADOW] = A_DIM,
[METER_TEXT] = A_NORMAL,
[METER_VALUE] = A_BOLD,
[METER_VALUE_ERROR] = A_BOLD,
[METER_VALUE_IOREAD] = A_NORMAL,
[METER_VALUE_IOWRITE] = A_NORMAL,
[METER_VALUE_NOTICE] = A_BOLD,
[METER_VALUE_OK] = A_NORMAL,
[METER_VALUE_WARN] = A_BOLD,
[LED_COLOR] = A_NORMAL,
[TASKS_RUNNING] = A_BOLD,
[PROCESS] = A_NORMAL,
[PROCESS_SHADOW] = A_DIM,
[PROCESS_TAG] = A_BOLD,
[PROCESS_MEGABYTES] = A_BOLD,
[PROCESS_GIGABYTES] = A_BOLD,
[PROCESS_BASENAME] = A_BOLD,
[PROCESS_TREE] = A_BOLD,
[PROCESS_RUN_STATE] = A_BOLD,
[PROCESS_D_STATE] = A_BOLD,
[PROCESS_HIGH_PRIORITY] = A_BOLD,
[PROCESS_LOW_PRIORITY] = A_DIM,
[PROCESS_NEW] = A_BOLD,
[PROCESS_TOMB] = A_DIM,
[PROCESS_THREAD] = A_BOLD,
[PROCESS_THREAD_BASENAME] = A_REVERSE,
[PROCESS_COMM] = A_BOLD,
[PROCESS_THREAD_COMM] = A_REVERSE,
[BAR_BORDER] = A_BOLD,
[BAR_SHADOW] = A_DIM,
[SWAP] = A_BOLD,
[SWAP_CACHE] = A_NORMAL,
[GRAPH_1] = A_BOLD,
[GRAPH_2] = A_NORMAL,
[MEMORY_USED] = A_BOLD,
[MEMORY_BUFFERS] = A_NORMAL,
[MEMORY_BUFFERS_TEXT] = A_NORMAL,
[MEMORY_CACHE] = A_NORMAL,
[MEMORY_SHARED] = A_NORMAL,
[HUGEPAGE_1] = A_BOLD,
[HUGEPAGE_2] = A_NORMAL,
[HUGEPAGE_3] = A_REVERSE | A_BOLD,
[HUGEPAGE_4] = A_REVERSE,
[LOAD_AVERAGE_FIFTEEN] = A_DIM,
[LOAD_AVERAGE_FIVE] = A_NORMAL,
[LOAD_AVERAGE_ONE] = A_BOLD,
[LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD,
[HELP_SHADOW] = A_DIM,
[CLOCK] = A_BOLD,
[DATE] = A_BOLD,
[DATETIME] = A_BOLD,
[CHECK_BOX] = A_BOLD,
[CHECK_MARK] = A_NORMAL,
[CHECK_TEXT] = A_NORMAL,
[HOSTNAME] = A_BOLD,
[CPU_NICE] = A_NORMAL,
[CPU_NICE_TEXT] = A_NORMAL,
[CPU_NORMAL] = A_BOLD,
[CPU_SYSTEM] = A_BOLD,
[CPU_IOWAIT] = A_NORMAL,
[CPU_IRQ] = A_BOLD,
[CPU_SOFTIRQ] = A_BOLD,
[CPU_STEAL] = A_DIM,
[CPU_GUEST] = A_DIM,
[PANEL_EDIT] = A_BOLD,
[SCREENS_OTH_BORDER] = A_DIM,
[SCREENS_OTH_TEXT] = A_DIM,
[SCREENS_CUR_BORDER] = A_REVERSE,
[SCREENS_CUR_TEXT] = A_REVERSE,
[PRESSURE_STALL_THREEHUNDRED] = A_DIM,
[PRESSURE_STALL_SIXTY] = A_NORMAL,
[PRESSURE_STALL_TEN] = A_BOLD,
[ZFS_MFU] = A_NORMAL,
[ZFS_MRU] = A_NORMAL,
[ZFS_ANON] = A_DIM,
[ZFS_HEADER] = A_BOLD,
[ZFS_OTHER] = A_DIM,
[ZFS_COMPRESSED] = A_BOLD,
[ZFS_RATIO] = A_BOLD,
[ZRAM] = A_NORMAL,
[DYNAMIC_GRAY] = A_DIM,
[DYNAMIC_DARKGRAY] = A_DIM,
[DYNAMIC_RED] = A_BOLD,
[DYNAMIC_GREEN] = A_NORMAL,
[DYNAMIC_BLUE] = A_NORMAL,
[DYNAMIC_CYAN] = A_BOLD,
[DYNAMIC_MAGENTA] = A_NORMAL,
[DYNAMIC_YELLOW] = A_NORMAL,
[DYNAMIC_WHITE] = A_BOLD,
},
[COLORSCHEME_BLACKONWHITE] = {
[RESET_COLOR] = ColorPair(Black, White),
[DEFAULT_COLOR] = ColorPair(Black, White),
[FUNCTION_BAR] = ColorPair(Black, Cyan),
[FUNCTION_KEY] = ColorPair(Black, White),
[PANEL_HEADER_FOCUS] = ColorPair(Black, Green),
[PANEL_HEADER_UNFOCUS] = ColorPair(Black, Green),
[PANEL_SELECTION_FOCUS] = ColorPair(Black, Cyan),
[PANEL_SELECTION_FOLLOW] = ColorPair(Black, Yellow),
[PANEL_SELECTION_UNFOCUS] = ColorPair(Blue, White),
[FAILED_SEARCH] = ColorPair(Red, Cyan),
[FAILED_READ] = ColorPair(Red, White),
[PAUSED] = A_BOLD | ColorPair(Yellow, Cyan),
[UPTIME] = ColorPair(Yellow, White),
[TEMP] = ColorPair(Yellow, White),
[FREQ] = ColorPair(Yellow, White),
[BATTERY] = ColorPair(Yellow, White),
[LARGE_NUMBER] = ColorPair(Red, White),
[METER_SHADOW] = ColorPair(Blue, White),
[METER_TEXT] = ColorPair(Blue, White),
[METER_VALUE] = ColorPair(Black, White),
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red, White),
[METER_VALUE_IOREAD] = ColorPair(Green, White),
[METER_VALUE_IOWRITE] = ColorPair(Yellow, White),
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(Yellow, White),
[METER_VALUE_OK] = ColorPair(Green, White),
[METER_VALUE_WARN] = A_BOLD | ColorPair(Yellow, White),
[LED_COLOR] = ColorPair(Green, White),
[TASKS_RUNNING] = ColorPair(Green, White),
[PROCESS] = ColorPair(Black, White),
[PROCESS_SHADOW] = A_BOLD | ColorPair(Black, White),
[PROCESS_TAG] = ColorPair(White, Blue),
[PROCESS_MEGABYTES] = ColorPair(Blue, White),
[PROCESS_GIGABYTES] = ColorPair(Green, White),
[PROCESS_BASENAME] = ColorPair(Blue, White),
[PROCESS_TREE] = ColorPair(Green, White),
[PROCESS_RUN_STATE] = ColorPair(Green, White),
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, White),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, White),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, White),
[PROCESS_NEW] = ColorPair(White, Green),
[PROCESS_TOMB] = ColorPair(White, Red),
[PROCESS_THREAD] = ColorPair(Blue, White),
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue, White),
[PROCESS_COMM] = ColorPair(Magenta, White),
[PROCESS_THREAD_COMM] = ColorPair(Green, White),
[BAR_BORDER] = ColorPair(Blue, White),
[BAR_SHADOW] = ColorPair(Black, White),
[SWAP] = ColorPair(Red, White),
[SWAP_CACHE] = ColorPair(Yellow, White),
[GRAPH_1] = A_BOLD | ColorPair(Blue, White),
[GRAPH_2] = ColorPair(Blue, White),
[MEMORY_USED] = ColorPair(Green, White),
[MEMORY_BUFFERS] = ColorPair(Cyan, White),
[MEMORY_BUFFERS_TEXT] = ColorPair(Cyan, White),
[MEMORY_CACHE] = ColorPair(Yellow, White),
[MEMORY_SHARED] = ColorPair(Magenta, White),
[HUGEPAGE_1] = ColorPair(Green, White),
[HUGEPAGE_2] = ColorPair(Yellow, White),
[HUGEPAGE_3] = ColorPair(Red, White),
[HUGEPAGE_4] = ColorPair(Blue, White),
[LOAD_AVERAGE_FIFTEEN] = ColorPair(Black, White),
[LOAD_AVERAGE_FIVE] = ColorPair(Black, White),
[LOAD_AVERAGE_ONE] = ColorPair(Black, White),
[LOAD] = ColorPair(Black, White),
[HELP_BOLD] = ColorPair(Blue, White),
[HELP_SHADOW] = A_BOLD | ColorPair(Black, White),
[CLOCK] = ColorPair(Black, White),
[DATE] = ColorPair(Black, White),
[DATETIME] = ColorPair(Black, White),
[CHECK_BOX] = ColorPair(Blue, White),
[CHECK_MARK] = ColorPair(Black, White),
[CHECK_TEXT] = ColorPair(Black, White),
[HOSTNAME] = ColorPair(Black, White),
[CPU_NICE] = ColorPair(Cyan, White),
[CPU_NICE_TEXT] = ColorPair(Cyan, White),
[CPU_NORMAL] = ColorPair(Green, White),
[CPU_SYSTEM] = ColorPair(Red, White),
[CPU_IOWAIT] = A_BOLD | ColorPair(Black, White),
[CPU_IRQ] = ColorPair(Blue, White),
[CPU_SOFTIRQ] = ColorPair(Blue, White),
[CPU_STEAL] = ColorPair(Cyan, White),
[CPU_GUEST] = ColorPair(Cyan, White),
[PANEL_EDIT] = ColorPair(White, Blue),
[SCREENS_OTH_BORDER] = A_BOLD | ColorPair(Black, White),
[SCREENS_OTH_TEXT] = A_BOLD | ColorPair(Black, White),
[SCREENS_CUR_BORDER] = ColorPair(Green, Green),
[SCREENS_CUR_TEXT] = ColorPair(Black, Green),
[PRESSURE_STALL_THREEHUNDRED] = ColorPair(Black, White),
[PRESSURE_STALL_SIXTY] = ColorPair(Black, White),
[PRESSURE_STALL_TEN] = ColorPair(Black, White),
[ZFS_MFU] = ColorPair(Cyan, White),
[ZFS_MRU] = ColorPair(Yellow, White),
[ZFS_ANON] = ColorPair(Magenta, White),
[ZFS_HEADER] = ColorPair(Yellow, White),
[ZFS_OTHER] = ColorPair(Magenta, White),
[ZFS_COMPRESSED] = ColorPair(Cyan, White),
[ZFS_RATIO] = ColorPair(Magenta, White),
[ZRAM] = ColorPair(Yellow, White),
[DYNAMIC_GRAY] = ColorPair(Black, White),
[DYNAMIC_DARKGRAY] = A_BOLD | ColorPair(Black, White),
[DYNAMIC_RED] = ColorPair(Red, White),
[DYNAMIC_GREEN] = ColorPair(Green, White),
[DYNAMIC_BLUE] = ColorPair(Blue, White),
[DYNAMIC_CYAN] = ColorPair(Yellow, White),
[DYNAMIC_MAGENTA] = ColorPair(Magenta, White),
[DYNAMIC_YELLOW] = ColorPair(Yellow, White),
[DYNAMIC_WHITE] = A_BOLD | ColorPair(Black, White),
},
[COLORSCHEME_LIGHTTERMINAL] = {
[RESET_COLOR] = ColorPair(Black, Black),
[DEFAULT_COLOR] = ColorPair(Black, Black),
[FUNCTION_BAR] = ColorPair(Black, Cyan),
[FUNCTION_KEY] = ColorPair(Black, Black),
[PANEL_HEADER_FOCUS] = ColorPair(Black, Green),
[PANEL_HEADER_UNFOCUS] = ColorPair(Black, Green),
[PANEL_SELECTION_FOCUS] = ColorPair(Black, Cyan),
[PANEL_SELECTION_FOLLOW] = ColorPair(Black, Yellow),
[PANEL_SELECTION_UNFOCUS] = ColorPair(Blue, Black),
[FAILED_SEARCH] = ColorPair(Red, Cyan),
[FAILED_READ] = ColorPair(Red, Black),
[PAUSED] = A_BOLD | ColorPair(Yellow, Cyan),
[UPTIME] = ColorPair(Yellow, Black),
[TEMP] = ColorPair(Yellow, Black),
[FREQ] = ColorPair(Yellow, Black),
[BATTERY] = ColorPair(Yellow, Black),
[LARGE_NUMBER] = ColorPair(Red, Black),
[METER_SHADOW] = A_BOLD | ColorPairGrayBlack,
[METER_TEXT] = ColorPair(Blue, Black),
[METER_VALUE] = ColorPair(Black, Black),
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red, Black),
[METER_VALUE_IOREAD] = ColorPair(Green, Black),
[METER_VALUE_IOWRITE] = ColorPair(Yellow, Black),
[METER_VALUE_NOTICE] = A_BOLD | ColorPairWhiteDefault,
[METER_VALUE_OK] = ColorPair(Green, Black),
[METER_VALUE_WARN] = A_BOLD | ColorPair(Yellow, Black),
[LED_COLOR] = ColorPair(Green, Black),
[TASKS_RUNNING] = ColorPair(Green, Black),
[PROCESS] = ColorPair(Black, Black),
[PROCESS_SHADOW] = A_BOLD | ColorPairGrayBlack,
[PROCESS_TAG] = ColorPair(White, Blue),
[PROCESS_MEGABYTES] = ColorPair(Blue, Black),
[PROCESS_GIGABYTES] = ColorPair(Green, Black),
[PROCESS_BASENAME] = ColorPair(Green, Black),
[PROCESS_TREE] = ColorPair(Blue, Black),
[PROCESS_RUN_STATE] = ColorPair(Green, Black),
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
[PROCESS_NEW] = ColorPair(Black, Green),
[PROCESS_TOMB] = ColorPair(Black, Red),
[PROCESS_THREAD] = ColorPair(Blue, Black),
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue, Black),
[PROCESS_COMM] = ColorPair(Magenta, Black),
[PROCESS_THREAD_COMM] = ColorPair(Yellow, Black),
[BAR_BORDER] = ColorPair(Blue, Black),
[BAR_SHADOW] = ColorPairGrayBlack,
[SWAP] = ColorPair(Red, Black),
[SWAP_CACHE] = ColorPair(Yellow, Black),
[GRAPH_1] = A_BOLD | ColorPair(Cyan, Black),
[GRAPH_2] = ColorPair(Cyan, Black),
[MEMORY_USED] = ColorPair(Green, Black),
[MEMORY_BUFFERS] = ColorPair(Cyan, Black),
[MEMORY_BUFFERS_TEXT] = ColorPair(Cyan, Black),
[MEMORY_CACHE] = ColorPair(Yellow, Black),
[MEMORY_SHARED] = ColorPair(Magenta, Black),
[HUGEPAGE_1] = ColorPair(Green, Black),
[HUGEPAGE_2] = ColorPair(Yellow, Black),
[HUGEPAGE_3] = ColorPair(Red, Black),
[HUGEPAGE_4] = ColorPair(Blue, Black),
[LOAD_AVERAGE_FIFTEEN] = ColorPair(Black, Black),
[LOAD_AVERAGE_FIVE] = ColorPair(Black, Black),
[LOAD_AVERAGE_ONE] = ColorPair(Black, Black),
[LOAD] = ColorPairWhiteDefault,
[HELP_BOLD] = ColorPair(Blue, Black),
[HELP_SHADOW] = A_BOLD | ColorPairGrayBlack,
[CLOCK] = ColorPairWhiteDefault,
[DATE] = ColorPairWhiteDefault,
[DATETIME] = ColorPairWhiteDefault,
[CHECK_BOX] = ColorPair(Blue, Black),
[CHECK_MARK] = ColorPair(Black, Black),
[CHECK_TEXT] = ColorPair(Black, Black),
[HOSTNAME] = ColorPairWhiteDefault,
[CPU_NICE] = ColorPair(Cyan, Black),
[CPU_NICE_TEXT] = ColorPair(Cyan, Black),
[CPU_NORMAL] = ColorPair(Green, Black),
[CPU_SYSTEM] = ColorPair(Red, Black),
[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black),
[CPU_IRQ] = A_BOLD | ColorPair(Blue, Black),
[CPU_SOFTIRQ] = ColorPair(Blue, Black),
[CPU_STEAL] = ColorPair(Black, Black),
[CPU_GUEST] = ColorPair(Black, Black),
[PANEL_EDIT] = ColorPair(White, Blue),
[SCREENS_OTH_BORDER] = ColorPair(Blue, Black),
[SCREENS_OTH_TEXT] = ColorPair(Blue, Black),
[SCREENS_CUR_BORDER] = ColorPair(Green, Green),
[SCREENS_CUR_TEXT] = ColorPair(Black, Green),
[PRESSURE_STALL_THREEHUNDRED] = ColorPair(Black, Black),
[PRESSURE_STALL_SIXTY] = ColorPair(Black, Black),
[PRESSURE_STALL_TEN] = ColorPair(Black, Black),
[ZFS_MFU] = ColorPair(Cyan, Black),
[ZFS_MRU] = ColorPair(Yellow, Black),
[ZFS_ANON] = A_BOLD | ColorPair(Magenta, Black),
[ZFS_HEADER] = ColorPair(Black, Black),
[ZFS_OTHER] = A_BOLD | ColorPair(Magenta, Black),
[ZFS_COMPRESSED] = ColorPair(Cyan, Black),
[ZFS_RATIO] = A_BOLD | ColorPair(Magenta, Black),
[ZRAM] = ColorPair(Yellow, Black),
[DYNAMIC_GRAY] = ColorPairGrayBlack,
[DYNAMIC_DARKGRAY] = A_BOLD | ColorPairGrayBlack,
[DYNAMIC_RED] = ColorPair(Red, Black),
[DYNAMIC_GREEN] = ColorPair(Green, Black),
[DYNAMIC_BLUE] = ColorPair(Blue, Black),
[DYNAMIC_CYAN] = ColorPair(Cyan, Black),
[DYNAMIC_MAGENTA] = ColorPair(Magenta, Black),
[DYNAMIC_YELLOW] = ColorPair(Yellow, Black),
[DYNAMIC_WHITE] = ColorPairWhiteDefault,
},
[COLORSCHEME_MIDNIGHT] = {
[RESET_COLOR] = ColorPair(White, Blue),
[DEFAULT_COLOR] = ColorPair(White, Blue),
[FUNCTION_BAR] = ColorPair(Black, Cyan),
[FUNCTION_KEY] = A_NORMAL,
[PANEL_HEADER_FOCUS] = ColorPair(Black, Cyan),
[PANEL_HEADER_UNFOCUS] = ColorPair(Black, Cyan),
[PANEL_SELECTION_FOCUS] = ColorPair(Black, White),
[PANEL_SELECTION_FOLLOW] = ColorPair(Black, Yellow),
[PANEL_SELECTION_UNFOCUS] = A_BOLD | ColorPair(Yellow, Blue),
[FAILED_SEARCH] = ColorPair(Red, Cyan),
[FAILED_READ] = A_BOLD | ColorPair(Red, Blue),
[PAUSED] = A_BOLD | ColorPair(Yellow, Cyan),
[UPTIME] = A_BOLD | ColorPair(Yellow, Blue),
[TEMP] = A_BOLD | ColorPair(Yellow, Blue),
[FREQ] = A_BOLD | ColorPair(Yellow, Blue),
[BATTERY] = A_BOLD | ColorPair(Yellow, Blue),
[LARGE_NUMBER] = A_BOLD | ColorPair(Red, Blue),
[METER_SHADOW] = ColorPair(Cyan, Blue),
[METER_TEXT] = ColorPair(Cyan, Blue),
[METER_VALUE] = A_BOLD | ColorPair(Cyan, Blue),
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red, Blue),
[METER_VALUE_IOREAD] = ColorPair(Green, Blue),
[METER_VALUE_IOWRITE] = ColorPair(Black, Blue),
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(White, Blue),
[METER_VALUE_OK] = ColorPair(Green, Blue),
[METER_VALUE_WARN] = A_BOLD | ColorPair(Yellow, Black),
[LED_COLOR] = ColorPair(Green, Blue),
[TASKS_RUNNING] = A_BOLD | ColorPair(Green, Blue),
[PROCESS] = ColorPair(White, Blue),
[PROCESS_SHADOW] = A_BOLD | ColorPair(Black, Blue),
[PROCESS_TAG] = A_BOLD | ColorPair(Yellow, Blue),
[PROCESS_MEGABYTES] = ColorPair(Cyan, Blue),
[PROCESS_GIGABYTES] = ColorPair(Green, Blue),
[PROCESS_BASENAME] = A_BOLD | ColorPair(Cyan, Blue),
[PROCESS_TREE] = ColorPair(Cyan, Blue),
[PROCESS_RUN_STATE] = ColorPair(Green, Blue),
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Blue),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Blue),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Blue),
[PROCESS_NEW] = ColorPair(Blue, Green),
[PROCESS_TOMB] = ColorPair(Blue, Red),
[PROCESS_THREAD] = ColorPair(Green, Blue),
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green, Blue),
[PROCESS_COMM] = ColorPair(Magenta, Blue),
[PROCESS_THREAD_COMM] = ColorPair(Black, Blue),
[BAR_BORDER] = A_BOLD | ColorPair(Yellow, Blue),
[BAR_SHADOW] = ColorPair(Cyan, Blue),
[SWAP] = ColorPair(Red, Blue),
[SWAP_CACHE] = A_BOLD | ColorPair(Yellow, Blue),
[GRAPH_1] = A_BOLD | ColorPair(Cyan, Blue),
[GRAPH_2] = ColorPair(Cyan, Blue),
[MEMORY_USED] = A_BOLD | ColorPair(Green, Blue),
[MEMORY_BUFFERS] = A_BOLD | ColorPair(Cyan, Blue),
[MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Cyan, Blue),
[MEMORY_CACHE] = A_BOLD | ColorPair(Yellow, Blue),
[MEMORY_SHARED] = A_BOLD | ColorPair(Magenta, Blue),
[HUGEPAGE_1] = A_BOLD | ColorPair(Green, Blue),
[HUGEPAGE_2] = A_BOLD | ColorPair(Yellow, Blue),
[HUGEPAGE_3] = A_BOLD | ColorPair(Red, Blue),
[HUGEPAGE_4] = A_BOLD | ColorPair(White, Blue),
[LOAD_AVERAGE_FIFTEEN] = A_BOLD | ColorPair(Black, Blue),
[LOAD_AVERAGE_FIVE] = A_NORMAL | ColorPair(White, Blue),
[LOAD_AVERAGE_ONE] = A_BOLD | ColorPair(White, Blue),
[LOAD] = A_BOLD | ColorPair(White, Blue),
[HELP_BOLD] = A_BOLD | ColorPair(Cyan, Blue),
[HELP_SHADOW] = A_BOLD | ColorPair(Black, Blue),
[CLOCK] = ColorPair(White, Blue),
[DATE] = ColorPair(White, Blue),
[DATETIME] = ColorPair(White, Blue),
[CHECK_BOX] = ColorPair(Cyan, Blue),
[CHECK_MARK] = A_BOLD | ColorPair(White, Blue),
[CHECK_TEXT] = A_NORMAL | ColorPair(White, Blue),
[HOSTNAME] = ColorPair(White, Blue),
[CPU_NICE] = A_BOLD | ColorPair(Cyan, Blue),
[CPU_NICE_TEXT] = A_BOLD | ColorPair(Cyan, Blue),
[CPU_NORMAL] = A_BOLD | ColorPair(Green, Blue),
[CPU_SYSTEM] = A_BOLD | ColorPair(Red, Blue),
[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Blue),
[CPU_IRQ] = A_BOLD | ColorPair(Black, Blue),
[CPU_SOFTIRQ] = ColorPair(Black, Blue),
[CPU_STEAL] = ColorPair(White, Blue),
[CPU_GUEST] = ColorPair(White, Blue),
[PANEL_EDIT] = ColorPair(White, Blue),
[SCREENS_OTH_BORDER] = A_BOLD | ColorPair(Yellow, Blue),
[SCREENS_OTH_TEXT] = ColorPair(Cyan, Blue),
[SCREENS_CUR_BORDER] = ColorPair(Cyan, Cyan),
[SCREENS_CUR_TEXT] = ColorPair(Black, Cyan),
[PRESSURE_STALL_THREEHUNDRED] = A_BOLD | ColorPair(Black, Blue),
[PRESSURE_STALL_SIXTY] = A_NORMAL | ColorPair(White, Blue),
[PRESSURE_STALL_TEN] = A_BOLD | ColorPair(White, Blue),
[ZFS_MFU] = A_BOLD | ColorPair(White, Blue),
[ZFS_MRU] = A_BOLD | ColorPair(Yellow, Blue),
[ZFS_ANON] = A_BOLD | ColorPair(Magenta, Blue),
[ZFS_HEADER] = A_BOLD | ColorPair(Yellow, Blue),
[ZFS_OTHER] = A_BOLD | ColorPair(Magenta, Blue),
[ZFS_COMPRESSED] = A_BOLD | ColorPair(White, Blue),
[ZFS_RATIO] = A_BOLD | ColorPair(Magenta, Blue),
[ZRAM] = A_BOLD | ColorPair(Yellow, Blue),
[DYNAMIC_GRAY] = ColorPairGrayBlack,
[DYNAMIC_DARKGRAY] = A_BOLD | ColorPairGrayBlack,
[DYNAMIC_RED] = ColorPair(Red, Blue),
[DYNAMIC_GREEN] = ColorPair(Green, Blue),
[DYNAMIC_BLUE] = ColorPair(Black, Blue),
[DYNAMIC_CYAN] = ColorPair(Cyan, Blue),
[DYNAMIC_MAGENTA] = ColorPair(Magenta, Blue),
[DYNAMIC_YELLOW] = ColorPair(Yellow, Blue),
[DYNAMIC_WHITE] = ColorPair(White, Blue),
},
[COLORSCHEME_BLACKNIGHT] = {
[RESET_COLOR] = ColorPair(Cyan, Black),
[DEFAULT_COLOR] = ColorPair(Cyan, Black),
[FUNCTION_BAR] = ColorPair(Black, Green),
[FUNCTION_KEY] = ColorPair(Cyan, Black),
[PANEL_HEADER_FOCUS] = ColorPair(Black, Green),
[PANEL_HEADER_UNFOCUS] = ColorPair(Black, Green),
[PANEL_SELECTION_FOCUS] = ColorPair(Black, Cyan),
[PANEL_SELECTION_FOLLOW] = ColorPair(Black, Yellow),
[PANEL_SELECTION_UNFOCUS] = ColorPair(Black, White),
[FAILED_SEARCH] = ColorPair(Red, Green),
[FAILED_READ] = A_BOLD | ColorPair(Red, Black),
[PAUSED] = A_BOLD | ColorPair(Yellow, Green),
[UPTIME] = ColorPair(Green, Black),
[TEMP] = ColorPair(Green, Black),
[FREQ] = ColorPair(Green, Black),
[BATTERY] = ColorPair(Green, Black),
[LARGE_NUMBER] = A_BOLD | ColorPair(Red, Black),
[METER_SHADOW] = A_BOLD | ColorPairGrayBlack,
[METER_TEXT] = ColorPair(Cyan, Black),
[METER_VALUE] = ColorPair(Green, Black),
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red, Black),
[METER_VALUE_IOREAD] = ColorPair(Green, Black),
[METER_VALUE_IOWRITE] = ColorPair(Blue, Black),
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(White, Black),
[METER_VALUE_OK] = ColorPair(Green, Black),
[METER_VALUE_WARN] = A_BOLD | ColorPair(Yellow, Black),
[LED_COLOR] = ColorPair(Green, Black),
[TASKS_RUNNING] = A_BOLD | ColorPair(Green, Black),
[PROCESS] = ColorPair(Cyan, Black),
[PROCESS_SHADOW] = A_BOLD | ColorPairGrayBlack,
[PROCESS_TAG] = A_BOLD | ColorPair(Yellow, Black),
[PROCESS_MEGABYTES] = A_BOLD | ColorPair(Green, Black),
[PROCESS_GIGABYTES] = A_BOLD | ColorPair(Yellow, Black),
[PROCESS_BASENAME] = A_BOLD | ColorPair(Green, Black),
[PROCESS_TREE] = ColorPair(Cyan, Black),
[PROCESS_THREAD] = ColorPair(Green, Black),
[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue, Black),
[PROCESS_COMM] = ColorPair(Magenta, Black),
[PROCESS_THREAD_COMM] = ColorPair(Yellow, Black),
[PROCESS_RUN_STATE] = ColorPair(Green, Black),
[PROCESS_D_STATE] = A_BOLD | ColorPair(Red, Black),
[PROCESS_HIGH_PRIORITY] = ColorPair(Red, Black),
[PROCESS_LOW_PRIORITY] = ColorPair(Green, Black),
[PROCESS_NEW] = ColorPair(Black, Green),
[PROCESS_TOMB] = ColorPair(Black, Red),
[BAR_BORDER] = A_BOLD | ColorPair(Green, Black),
[BAR_SHADOW] = ColorPair(Cyan, Black),
[SWAP] = ColorPair(Red, Black),
[SWAP_CACHE] = ColorPair(Yellow, Black),
[GRAPH_1] = A_BOLD | ColorPair(Green, Black),
[GRAPH_2] = ColorPair(Green, Black),
[MEMORY_USED] = ColorPair(Green, Black),
[MEMORY_BUFFERS] = ColorPair(Blue, Black),
[MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Blue, Black),
[MEMORY_CACHE] = ColorPair(Yellow, Black),
[MEMORY_SHARED] = ColorPair(Magenta, Black),
[HUGEPAGE_1] = ColorPair(Green, Black),
[HUGEPAGE_2] = ColorPair(Yellow, Black),
[HUGEPAGE_3] = ColorPair(Red, Black),
[HUGEPAGE_4] = ColorPair(Blue, Black),
[LOAD_AVERAGE_FIFTEEN] = ColorPair(Green, Black),
[LOAD_AVERAGE_FIVE] = ColorPair(Green, Black),
[LOAD_AVERAGE_ONE] = A_BOLD | ColorPair(Green, Black),
[LOAD] = A_BOLD,
[HELP_BOLD] = A_BOLD | ColorPair(Cyan, Black),
[HELP_SHADOW] = A_BOLD | ColorPairGrayBlack,
[CLOCK] = ColorPair(Green, Black),
[CHECK_BOX] = ColorPair(Green, Black),
[CHECK_MARK] = A_BOLD | ColorPair(Green, Black),
[CHECK_TEXT] = ColorPair(Cyan, Black),
[HOSTNAME] = ColorPair(Green, Black),
[CPU_NICE] = ColorPair(Blue, Black),
[CPU_NICE_TEXT] = A_BOLD | ColorPair(Blue, Black),
[CPU_NORMAL] = ColorPair(Green, Black),
[CPU_SYSTEM] = ColorPair(Red, Black),
[CPU_IOWAIT] = ColorPair(Yellow, Black),
[CPU_IRQ] = A_BOLD | ColorPair(Blue, Black),
[CPU_SOFTIRQ] = ColorPair(Blue, Black),
[CPU_STEAL] = ColorPair(Cyan, Black),
[CPU_GUEST] = ColorPair(Cyan, Black),
[PANEL_EDIT] = ColorPair(White, Cyan),
[SCREENS_OTH_BORDER] = ColorPair(White, Black),
[SCREENS_OTH_TEXT] = ColorPair(Cyan, Black),
[SCREENS_CUR_BORDER] = A_BOLD | ColorPair(White, Black),
[SCREENS_CUR_TEXT] = A_BOLD | ColorPair(Green, Black),
[PRESSURE_STALL_THREEHUNDRED] = ColorPair(Green, Black),
[PRESSURE_STALL_SIXTY] = ColorPair(Green, Black),
[PRESSURE_STALL_TEN] = A_BOLD | ColorPair(Green, Black),
[ZFS_MFU] = ColorPair(Blue, Black),
[ZFS_MRU] = ColorPair(Yellow, Black),
[ZFS_ANON] = ColorPair(Magenta, Black),
[ZFS_HEADER] = ColorPair(Yellow, Black),
[ZFS_OTHER] = ColorPair(Magenta, Black),
[ZFS_COMPRESSED] = ColorPair(Blue, Black),
[ZFS_RATIO] = ColorPair(Magenta, Black),
[ZRAM] = ColorPair(Yellow, Black),
[DYNAMIC_GRAY] = ColorPairGrayBlack,
[DYNAMIC_DARKGRAY] = A_BOLD | ColorPairGrayBlack,
[DYNAMIC_RED] = ColorPair(Red, Black),
[DYNAMIC_GREEN] = ColorPair(Green, Black),
[DYNAMIC_BLUE] = ColorPair(Blue, Black),
[DYNAMIC_CYAN] = ColorPair(Cyan, Black),
[DYNAMIC_MAGENTA] = ColorPair(Magenta, Black),
[DYNAMIC_YELLOW] = ColorPair(Yellow, Black),
[DYNAMIC_WHITE] = ColorPair(White, Black),
},
[COLORSCHEME_BROKENGRAY] = {0} // dynamically generated.
};
int CRT_scrollHAmount = 5;
int CRT_scrollWheelVAmount = 10;
ColorScheme CRT_colorScheme = COLORSCHEME_DEFAULT;
ATTR_NORETURN
static void CRT_handleSIGTERM(ATTR_UNUSED int sgn)
{
CRT_done();
_exit(0);
}
#ifndef NDEBUG
static int stderrRedirectNewFd = -1;
static int stderrRedirectBackupFd = -1;
static int createStderrCacheFile(void)
{
#if defined(HAVE_MEMFD_CREATE)
return memfd_create("htop.stderr-redirect", 0);
#elif defined(O_TMPFILE)
return open("/tmp", O_TMPFILE | O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
#else
char tmpName[] = "htop.stderr-redirectXXXXXX";
mode_t curUmask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
int r = mkstemp(tmpName);
umask(curUmask);
if (r < 0)
return r;
(void)unlink(tmpName);
return r;
#endif /* HAVE_MEMFD_CREATE */
}
static void redirectStderr(void)
{
stderrRedirectNewFd = createStderrCacheFile();
if (stderrRedirectNewFd < 0)
{
/* ignore failure */
return;
}
stderrRedirectBackupFd = dup(STDERR_FILENO);
dup2(stderrRedirectNewFd, STDERR_FILENO);
}
static void dumpStderr(void)
{
if (stderrRedirectNewFd < 0)
return;
fsync(STDERR_FILENO);
dup2(stderrRedirectBackupFd, STDERR_FILENO);
close(stderrRedirectBackupFd);
stderrRedirectBackupFd = -1;
lseek(stderrRedirectNewFd, 0, SEEK_SET);
bool header = false;
char buffer[8192];
for (;;)
{
errno = 0;
ssize_t res = read(stderrRedirectNewFd, buffer, sizeof(buffer));
if (res < 0)
{
if (errno == EINTR)
continue;
break;
}
if (res == 0)
{
break;
}
if (res > 0)
{
if (!header)
{
fprintf(stderr, ">>>>>>>>>> stderr output >>>>>>>>>>\n");
header = true;
}
(void)!write(STDERR_FILENO, buffer, res);
}
}
if (header)
fprintf(stderr, "\n<<<<<<<<<< stderr output <<<<<<<<<<\n");
close(stderrRedirectNewFd);
stderrRedirectNewFd = -1;
}
void CRT_debug_impl(const char *file, size_t lineno, const char *func, const char *fmt, ...)
{
va_list args;
fprintf(stderr, "[%s:%zu (%s)]: ", file, lineno, func);
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
}
#else /* !NDEBUG */
static void redirectStderr(void)
{
}
static void dumpStderr(void)
{
}
#endif /* !NDEBUG */
static struct sigaction old_sig_handler[32];
static void CRT_installSignalHandlers(void)
{
struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_flags = (int)SA_RESETHAND | SA_NODEFER;
act.sa_handler = CRT_handleSIGSEGV;
sigaction(SIGSEGV, &act, &old_sig_handler[SIGSEGV]);
sigaction(SIGFPE, &act, &old_sig_handler[SIGFPE]);
sigaction(SIGILL, &act, &old_sig_handler[SIGILL]);
sigaction(SIGBUS, &act, &old_sig_handler[SIGBUS]);
sigaction(SIGPIPE, &act, &old_sig_handler[SIGPIPE]);
sigaction(SIGSYS, &act, &old_sig_handler[SIGSYS]);
sigaction(SIGABRT, &act, &old_sig_handler[SIGABRT]);
signal(SIGCHLD, SIG_DFL);
signal(SIGINT, CRT_handleSIGTERM);
signal(SIGTERM, CRT_handleSIGTERM);
signal(SIGQUIT, CRT_handleSIGTERM);
}
void CRT_resetSignalHandlers(void)
{
sigaction(SIGSEGV, &old_sig_handler[SIGSEGV], NULL);
sigaction(SIGFPE, &old_sig_handler[SIGFPE], NULL);
sigaction(SIGILL, &old_sig_handler[SIGILL], NULL);
sigaction(SIGBUS, &old_sig_handler[SIGBUS], NULL);
sigaction(SIGPIPE, &old_sig_handler[SIGPIPE], NULL);
sigaction(SIGSYS, &old_sig_handler[SIGSYS], NULL);
sigaction(SIGABRT, &old_sig_handler[SIGABRT], NULL);
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
}
void CRT_setMouse(bool enabled)
{
#ifdef HAVE_GETMOUSE
if (enabled)
{
#if NCURSES_MOUSE_VERSION > 1
mousemask(BUTTON1_RELEASED | BUTTON4_PRESSED | BUTTON5_PRESSED, NULL);
#else
mousemask(BUTTON1_RELEASED, NULL);
#endif
}
else
{
mousemask(0, NULL);
}
#endif
}
void CRT_init(const Settings *settings, bool allowUnicode)
{
redirectStderr();
initscr();
noecho();
CRT_crashSettings = settings;
CRT_delay = &(settings->delay);
CRT_colors = CRT_colorSchemes[settings->colorScheme];
CRT_colorScheme = settings->colorScheme;
for (int i = 0; i < LAST_COLORELEMENT; i++)
{
unsigned int color = CRT_colorSchemes[COLORSCHEME_DEFAULT][i];
CRT_colorSchemes[COLORSCHEME_BROKENGRAY][i] = color == (A_BOLD | ColorPairGrayBlack) ? ColorPair(White, Black) : color;
}
halfdelay(*CRT_delay);
nonl();
intrflush(stdscr, false);
keypad(stdscr, true);
#ifdef HAVE_GETMOUSE
mouseinterval(0);
#endif
curs_set(0);
if (has_colors())
{
start_color();
}
const char *termType = getenv("TERM");
if (termType && String_eq(termType, "linux"))
{
CRT_scrollHAmount = 20;
}
else
{
CRT_scrollHAmount = 5;
}
if (termType && (String_startsWith(termType, "xterm") || String_eq(termType, "vt220")))
{
#ifdef HTOP_NETBSD
#define define_key(s_, k_) define_key((char *)s_, k_)
IGNORE_WCASTQUAL_BEGIN
#endif
define_key("\033[H", KEY_HOME);
define_key("\033[F", KEY_END);
define_key("\033[7~", KEY_HOME);
define_key("\033[8~", KEY_END);
define_key("\033OP", KEY_F(1));
define_key("\033OQ", KEY_F(2));
define_key("\033OR", KEY_F(3));
define_key("\033OS", KEY_F(4));
define_key("\033O2R", KEY_F(15));
define_key("\033[11~", KEY_F(1));
define_key("\033[12~", KEY_F(2));
define_key("\033[13~", KEY_F(3));
define_key("\033[14~", KEY_F(4));
define_key("\033[14;2~", KEY_F(15));
define_key("\033[17;2~", KEY_F(18));
define_key("\033[Z", KEY_SHIFT_TAB);
char sequence[3] = "\033a";
for (char c = 'a'; c <= 'z'; c++)
{
sequence[1] = c;
define_key(sequence, KEY_ALT('A' + (c - 'a')));
}
#ifdef HTOP_NETBSD
IGNORE_WCASTQUAL_END
#undef define_key
#endif
}
if (termType && (String_startsWith(termType, "rxvt")))
{
define_key("\033[Z", KEY_SHIFT_TAB);
}
CRT_installSignalHandlers();
use_default_colors();
if (!has_colors())
CRT_colorScheme = COLORSCHEME_MONOCHROME;
CRT_setColors(CRT_colorScheme);
#ifdef HAVE_LIBNCURSESW
if (allowUnicode && String_eq(nl_langinfo(CODESET), "UTF-8"))
{
CRT_utf8 = true;
}
else
{
CRT_utf8 = false;
}
#else
(void)allowUnicode;
#endif
CRT_treeStr =
#ifdef HAVE_LIBNCURSESW
CRT_utf8 ? CRT_treeStrUtf8 :
#endif
CRT_treeStrAscii;
CRT_setMouse(settings->enableMouse);
CRT_degreeSign = initDegreeSign();
}
void CRT_done()
{
int resetColor = CRT_colors ? CRT_colors[RESET_COLOR] : CRT_colorSchemes[COLORSCHEME_DEFAULT][RESET_COLOR];
attron(resetColor);
mvhline(LINES - 1, 0, ' ', COLS);
attroff(resetColor);
refresh();
curs_set(1);
endwin();
dumpStderr();
}
void CRT_fatalError(const char *note)
{
const char *sysMsg = strerror(errno);
CRT_done();
fprintf(stderr, "%s: %s\n", note, sysMsg);
exit(2);
}
int CRT_readKey()
{
nocbreak();
cbreak();
nodelay(stdscr, FALSE);
int ret = getch();
halfdelay(*CRT_delay);
return ret;
}
void CRT_disableDelay()
{
nocbreak();
cbreak();
nodelay(stdscr, TRUE);
}
void CRT_enableDelay()
{
halfdelay(*CRT_delay);
}
void CRT_setColors(int colorScheme)
{
CRT_colorScheme = colorScheme;
for (short int i = 0; i < 8; i++)
{
for (short int j = 0; j < 8; j++)
{
if (ColorIndex(i, j) != ColorIndexGrayBlack && ColorIndex(i, j) != ColorIndexWhiteDefault)
{
short int bg = (colorScheme != COLORSCHEME_BLACKNIGHT)
? (j == 0 ? -1 : j)
: j;
init_pair(ColorIndex(i, j), i, bg);
}
}
}
short int grayBlackFg = COLORS > 8 ? 8 : 0;
short int grayBlackBg = (colorScheme != COLORSCHEME_BLACKNIGHT) ? -1 : 0;
init_pair(ColorIndexGrayBlack, grayBlackFg, grayBlackBg);
init_pair(ColorIndexWhiteDefault, White, -1);
CRT_colors = CRT_colorSchemes[colorScheme];
}
#ifdef PRINT_BACKTRACE
static void print_backtrace(void)
{
#if defined(HAVE_LIBUNWIND_H) && defined(HAVE_LIBUNWIND)
unw_context_t context;
unw_getcontext(&context);
unw_cursor_t cursor;
unw_init_local(&cursor, &context);
unsigned int item = 0;
while (unw_step(&cursor) > 0)
{
unw_word_t pc;
unw_get_reg(&cursor, UNW_REG_IP, &pc);
if (pc == 0)
break;
char symbolName[256] = "?";
unw_word_t offset = 0;
unw_get_proc_name(&cursor, symbolName, sizeof(symbolName), &offset);
unw_proc_info_t pip;
pip.unwind_info = NULL;
const char *fname = "?";
const void *ptr = 0;
if (unw_get_proc_info(&cursor, &pip) == 0)
{
ptr = (const void *)(pip.start_ip + offset);
#ifdef HAVE_DLADDR
Dl_info dlinfo;
if (dladdr(ptr, &dlinfo) && dlinfo.dli_fname && *dlinfo.dli_fname)
fname = dlinfo.dli_fname;
#endif
}
const char *frame = "";
if (unw_is_signal_frame(&cursor) > 0)
frame = "{signal frame}";
fprintf(stderr, "%2u: %#14lx %s (%s+%#lx) [%p]%s%s\n", item++, pc, fname, symbolName, offset, ptr, frame ? " " : "", frame);
}
#elif defined(HAVE_EXECINFO_H)
void *backtraceArray[256];
size_t size = backtrace(backtraceArray, ARRAYSIZE(backtraceArray));
backtrace_symbols_fd(backtraceArray, size, STDERR_FILENO);
#else
#error No implementation for print_backtrace()!
#endif
}
#endif
void CRT_handleSIGSEGV(int signal)
{
CRT_done();
fprintf(stderr, "\n\n"
"FATAL PROGRAM ERROR DETECTED\n"
"============================\n"
"Please check at https://htop.dev/issues whether this issue has already been reported.\n"
"If no similar issue has been reported before, please create a new issue with the following information:\n"
" - Your " PACKAGE " version: '" VERSION "'\n"
" - Your OS and kernel version (uname -a)\n"
" - Your distribution and release (lsb_release -a)\n"
" - Likely steps to reproduce (How did it happen?)\n");
#ifdef PRINT_BACKTRACE
fprintf(stderr, " - Backtrace of the issue (see below)\n");
#endif
fprintf(stderr,
"\n");
const char *signal_str = strsignal(signal);
if (!signal_str)
{
signal_str = "unknown reason";
}
fprintf(stderr,
"Error information:\n"
"------------------\n"
"A signal %d (%s) was received.\n"
"\n",
signal, signal_str);
fprintf(stderr,
"Setting information:\n"
"--------------------\n");
Settings_write(CRT_crashSettings, true);
fprintf(stderr, "\n\n");
#ifdef PRINT_BACKTRACE
fprintf(stderr,
"Backtrace information:\n"
"----------------------\n");
print_backtrace();
fprintf(stderr,
"\n"
"To make the above information more practical to work with, "
"please also provide a disassembly of your " PACKAGE " binary. "
"This can usually be done by running the following command:\n"
"\n");
#ifdef HTOP_DARWIN
fprintf(stderr, " otool -tvV `which " PACKAGE "` > ~/htop.otool\n");
#else
fprintf(stderr, " objdump -d -S -w `which " PACKAGE "` > ~/htop.objdump\n");
#endif
fprintf(stderr,
"\n"
"Please include the generated file in your report.\n");
#endif
fprintf(stderr,
"Running this program with debug symbols or inside a debugger may provide further insights.\n"
"\n"
"Thank you for helping to improve " PACKAGE "!\n"
"\n");
/* Call old sigsegv handler; may be default exit or third party one (e.g. ASAN) */
if (sigaction(signal, &old_sig_handler[signal], NULL) < 0)
{
/* This avoids an infinite loop in case the handler could not be reset. */
fprintf(stderr,
"!!! Chained handler could not be restored. Forcing exit.\n");
_exit(1);
}
/* Trigger the previous signal handler. */
raise(signal);
// Always terminate, even if installed handler returns
fprintf(stderr,
"!!! Chained handler did not exit. Forcing exit.\n");
_exit(1);
}