From 65357c8c46154de4e4eca14075bfe5523bb5fc14 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Mon, 7 Dec 2020 10:26:01 +0100 Subject: New upstream version 3.0.3 --- htop.c | 221 +++++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 147 insertions(+), 74 deletions(-) (limited to 'htop.c') diff --git a/htop.c b/htop.c index 2cf2602..23da081 100644 --- a/htop.c +++ b/htop.c @@ -1,63 +1,71 @@ /* htop - htop.c (C) 2004-2011 Hisham H. Muhammad -Released under the GNU GPL, see the COPYING file +Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ -#include "config.h" - -#include "FunctionBar.h" -#include "Hashtable.h" -#include "ColumnsPanel.h" -#include "CRT.h" -#include "MainPanel.h" -#include "ProcessList.h" -#include "ScreenManager.h" -#include "Settings.h" -#include "UsersTable.h" -#include "Platform.h" +#include "config.h" // IWYU pragma: keep +#include #include #include +#include #include #include #include #include #include -//#link m +#include "Action.h" +#include "CRT.h" +#include "Hashtable.h" +#include "Header.h" +#include "IncSet.h" +#include "MainPanel.h" +#include "MetersPanel.h" +#include "Panel.h" +#include "Platform.h" +#include "Process.h" +#include "ProcessList.h" +#include "ProvideCurses.h" +#include "ScreenManager.h" +#include "Settings.h" +#include "UsersTable.h" +#include "XUtils.h" -static void printVersionFlag() { - fputs("htop " VERSION "\n", stdout); - exit(0); +static void printVersionFlag(void) { + fputs(PACKAGE " " VERSION "\n", stdout); } -static void printHelpFlag() { - fputs("htop " VERSION "\n" - "Released under the GNU GPL.\n\n" - "-C --no-color Use a monochrome color scheme\n" - "-m --no-mouse Disable the mouse\n" - "-d --delay=DELAY Set the delay between updates, in tenths of seconds\n" - "-h --help Print this help screen\n" - "-s --sort-key=COLUMN Sort by COLUMN (try --sort-key=help for a list)\n" - "-t --tree Show the tree view by default\n" - "-u --user[=USERNAME] Show only processes for a given user (or $USER)\n" - "-U --no-unicode Do not use unicode but plain ASCII\n" - "-p --pid=PID,[,PID,PID...] Show only the given PIDs\n" - "-v --version Print version info\n" +static void printHelpFlag(void) { + fputs(PACKAGE " " VERSION "\n" + COPYRIGHT "\n" + "Released under the GNU GPLv2.\n\n" + "-C --no-color Use a monochrome color scheme\n" + "-d --delay=DELAY Set the delay between updates, in tenths of seconds\n" + "-F --filter=FILTER Show only the commands matching the given filter\n" + "-h --help Print this help screen\n" + "-H --highlight-changes[=DELAY] Highlight new and old processes\n" + "-M --no-mouse Disable the mouse\n" + "-p --pid=PID[,PID,PID...] Show only the given PIDs\n" + "-s --sort-key=COLUMN Sort by COLUMN (try --sort-key=help for a list)\n" + "-t --tree Show the tree view by default\n" + "-u --user[=USERNAME] Show only processes for a given user (or $USER)\n" + "-U --no-unicode Do not use unicode but plain ASCII\n" + "-V --version Print version info\n" "\n" "Long options may be passed with a single dash.\n\n" - "Press F1 inside htop for online help.\n" - "See 'man htop' for more information.\n", + "Press F1 inside " PACKAGE " for online help.\n" + "See 'man " PACKAGE "' for more information.\n", stdout); - exit(0); } // ---------------------------------------- typedef struct CommandLineSettings_ { Hashtable* pidMatchList; + char* commFilter; uid_t userId; int sortKey; int delay; @@ -65,58 +73,74 @@ typedef struct CommandLineSettings_ { bool enableMouse; bool treeView; bool allowUnicode; + bool highlightChanges; + int highlightDelaySecs; } CommandLineSettings; static CommandLineSettings parseArguments(int argc, char** argv) { CommandLineSettings flags = { .pidMatchList = NULL, - .userId = -1, // -1 is guaranteed to be an invalid uid_t (see setreuid(2)) + .commFilter = NULL, + .userId = (uid_t)-1, // -1 is guaranteed to be an invalid uid_t (see setreuid(2)) .sortKey = 0, .delay = -1, .useColors = true, .enableMouse = true, .treeView = false, .allowUnicode = true, + .highlightChanges = false, + .highlightDelaySecs = -1, }; static struct option long_opts[] = { {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, {"delay", required_argument, 0, 'd'}, {"sort-key", required_argument, 0, 's'}, {"user", optional_argument, 0, 'u'}, {"no-color", no_argument, 0, 'C'}, {"no-colour", no_argument, 0, 'C'}, - {"no-mouse", no_argument, 0, 'm'}, + {"no-mouse", no_argument, 0, 'M'}, {"no-unicode", no_argument, 0, 'U'}, {"tree", no_argument, 0, 't'}, {"pid", required_argument, 0, 'p'}, + {"filter", required_argument, 0, 'F'}, + {"highlight-changes", optional_argument, 0, 'H'}, {0,0,0,0} }; int opt, opti=0; /* Parse arguments */ - while ((opt = getopt_long(argc, argv, "hvmCs:td:u::Up:", long_opts, &opti))) { + while ((opt = getopt_long(argc, argv, "hVMCs:td:u::Up:F:H::", long_opts, &opti))) { if (opt == EOF) break; switch (opt) { case 'h': printHelpFlag(); - break; - case 'v': + exit(0); + case 'V': printVersionFlag(); - break; + exit(0); case 's': - if (strcmp(optarg, "help") == 0) { + assert(optarg); /* please clang analyzer, cause optarg can be NULL in the 'u' case */ + if (String_eq(optarg, "help")) { for (int j = 1; j < Platform_numberOfFields; j++) { const char* name = Process_fields[j].name; if (name) printf ("%s\n", name); } exit(0); } - flags.sortKey = ColumnsPanel_fieldNameToIndex(optarg); - if (flags.sortKey == -1) { + flags.sortKey = 0; + for (int j = 1; j < Platform_numberOfFields; j++) { + if (Process_fields[j].name == NULL) + continue; + if (String_eq(optarg, Process_fields[j].name)) { + flags.sortKey = j; + break; + } + } + if (flags.sortKey == 0) { fprintf(stderr, "Error: invalid column \"%s\".\n", optarg); exit(1); } @@ -131,25 +155,25 @@ static CommandLineSettings parseArguments(int argc, char** argv) { } break; case 'u': - if (!optarg && optind < argc && argv[optind] != NULL && + { + const char *username = optarg; + if (!username && optind < argc && argv[optind] != NULL && (argv[optind][0] != '\0' && argv[optind][0] != '-')) { - optarg = argv[optind++]; + username = argv[optind++]; } - if (!optarg) { - optarg = getenv("USER"); + if (!username) { flags.userId = geteuid(); - } - - if (!Action_setUserOnly(optarg, &(flags.userId))) { - fprintf(stderr, "Error: invalid user \"%s\".\n", optarg); + } else if (!Action_setUserOnly(username, &(flags.userId))) { + fprintf(stderr, "Error: invalid user \"%s\".\n", username); exit(1); } break; + } case 'C': flags.useColors = false; break; - case 'm': + case 'M': flags.enableMouse = false; break; case 'U': @@ -159,6 +183,7 @@ static CommandLineSettings parseArguments(int argc, char** argv) { flags.treeView = true; break; case 'p': { + assert(optarg); /* please clang analyzer, cause optarg can be NULL in the 'u' case */ char* argCopy = xStrdup(optarg); char* saveptr; char* pid = strtok_r(argCopy, ",", &saveptr); @@ -169,6 +194,7 @@ static CommandLineSettings parseArguments(int argc, char** argv) { while(pid) { unsigned int num_pid = atoi(pid); + // deepcode ignore CastIntegerToAddress: we just want a non-NUll pointer here Hashtable_put(flags.pidMatchList, num_pid, (void *) 1); pid = strtok_r(NULL, ",", &saveptr); } @@ -176,6 +202,30 @@ static CommandLineSettings parseArguments(int argc, char** argv) { break; } + case 'F': { + assert(optarg); + flags.commFilter = xStrdup(optarg); + + break; + } + case 'H': { + const char *delay = optarg; + if (!delay && optind < argc && argv[optind] != NULL && + (argv[optind][0] != '\0' && argv[optind][0] != '-')) { + delay = argv[optind++]; + } + if (delay) { + if (sscanf(delay, "%16d", &(flags.highlightDelaySecs)) == 1) { + if (flags.highlightDelaySecs < 1) + flags.highlightDelaySecs = 1; + } else { + fprintf(stderr, "Error: invalid highlight delay value \"%s\".\n", delay); + exit(1); + } + } + flags.highlightChanges = true; + break; + } default: exit(1); } @@ -193,24 +243,35 @@ static void millisleep(unsigned long millisec) { } } +static void setCommFilter(State* state, char** commFilter) { + MainPanel* panel = (MainPanel*)state->panel; + ProcessList* pl = state->pl; + IncSet* inc = panel->inc; + size_t maxlen = sizeof(inc->modes[INC_FILTER].buffer) - 1; + char* buffer = inc->modes[INC_FILTER].buffer; + + strncpy(buffer, *commFilter, maxlen); + buffer[maxlen] = 0; + inc->modes[INC_FILTER].index = strlen(buffer); + inc->filtering = true; + pl->incFilter = IncSet_filter(inc); + + free(*commFilter); + *commFilter = NULL; +} + int main(int argc, char** argv) { - char *lc_ctype = getenv("LC_CTYPE"); - if(lc_ctype != NULL) - setlocale(LC_CTYPE, lc_ctype); - else if ((lc_ctype = getenv("LC_ALL"))) + /* initialize locale */ + const char* lc_ctype; + if ((lc_ctype = getenv("LC_CTYPE")) || (lc_ctype = getenv("LC_ALL"))) setlocale(LC_CTYPE, lc_ctype); else setlocale(LC_CTYPE, ""); - CommandLineSettings flags = parseArguments(argc, argv); // may exit() + CommandLineSettings flags = parseArguments(argc, argv); -#ifdef HTOP_LINUX - if (access(PROCDIR, R_OK) != 0) { - fprintf(stderr, "Error: could not read procfs (compiled to look in %s).\n", PROCDIR); - exit(1); - } -#endif + Platform_init(); Process_setupColumnWidths(); @@ -232,19 +293,23 @@ int main(int argc, char** argv) { settings->enableMouse = false; if (flags.treeView) settings->treeView = true; + if (flags.highlightChanges) + settings->highlightChanges = true; + if (flags.highlightDelaySecs != -1) + settings->highlightDelaySecs = flags.highlightDelaySecs; + if (flags.sortKey > 0) { + settings->sortKey = flags.sortKey; + settings->treeView = false; + settings->direction = 1; + } - CRT_init(settings->delay, settings->colorScheme, flags.allowUnicode); + CRT_init(&(settings->delay), settings->colorScheme, flags.allowUnicode); MainPanel* panel = MainPanel_new(); ProcessList_setPanel(pl, (Panel*) panel); MainPanel_updateTreeFunctions(panel, settings->treeView); - if (flags.sortKey > 0) { - settings->sortKey = flags.sortKey; - settings->treeView = false; - settings->direction = 1; - } ProcessList_printHeader(pl, Panel_getHeader((Panel*)panel)); State state = { @@ -253,15 +318,20 @@ int main(int argc, char** argv) { .pl = pl, .panel = (Panel*) panel, .header = header, + .pauseProcessUpdate = false, + .hideProcessSelection = false, }; + MainPanel_setState(panel, &state); + if (flags.commFilter) + setCommFilter(&state, &(flags.commFilter)); - ScreenManager* scr = ScreenManager_new(0, header->height, 0, -1, HORIZONTAL, header, settings, true); + ScreenManager* scr = ScreenManager_new(header, settings, &state, true); ScreenManager_add(scr, (Panel*) panel, -1); - ProcessList_scan(pl); + ProcessList_scan(pl, false); millisleep(75); - ProcessList_scan(pl); + ProcessList_scan(pl, false); ScreenManager_run(scr, NULL, NULL); @@ -270,6 +340,8 @@ int main(int argc, char** argv) { attroff(CRT_colors[RESET_COLOR]); refresh(); + Platform_done(); + CRT_done(); if (settings->changed) Settings_write(settings); @@ -277,12 +349,13 @@ int main(int argc, char** argv) { ProcessList_delete(pl); ScreenManager_delete(scr); + MetersPanel_cleanup(); UsersTable_delete(ut); Settings_delete(settings); - if(flags.pidMatchList) { + if (flags.pidMatchList) Hashtable_delete(flags.pidMatchList); - } + return 0; } -- cgit v1.2.3