blob: 848c7ae749b51369ac400e67a6651b89a0a1a334 [file] [log] [blame]
Nathan Scott36389fb2021-03-23 15:04:54 +11001/*
2htop - CommandLine.c
3(C) 2004-2011 Hisham H. Muhammad
4(C) 2020-2021 htop dev team
Daniel Lange94ad1112021-09-22 11:33:00 +02005Released under the GNU GPLv2+, see the COPYING file
Nathan Scott36389fb2021-03-23 15:04:54 +11006in the source distribution for its full text.
7*/
8
9#include "config.h" // IWYU pragma: keep
10
11#include "CommandLine.h"
12
13#include <assert.h>
набdfa62502021-10-04 15:08:55 +020014#include <ctype.h>
Nathan Scott36389fb2021-03-23 15:04:54 +110015#include <getopt.h>
16#include <locale.h>
17#include <stdbool.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <time.h>
22#include <unistd.h>
23
24#include "Action.h"
25#include "CRT.h"
Sohaib Mohamed6f2021f2021-07-11 03:11:29 +020026#include "DynamicColumn.h"
Nathan Scottf0ed0fd2021-06-23 17:44:56 +100027#include "DynamicMeter.h"
Nathan Scott36389fb2021-03-23 15:04:54 +110028#include "Hashtable.h"
29#include "Header.h"
30#include "IncSet.h"
31#include "MainPanel.h"
32#include "MetersPanel.h"
33#include "Panel.h"
34#include "Platform.h"
35#include "Process.h"
36#include "ProcessList.h"
37#include "ProvideCurses.h"
38#include "ScreenManager.h"
39#include "Settings.h"
40#include "UsersTable.h"
41#include "XUtils.h"
42
43
44static void printVersionFlag(const char* name) {
45 printf("%s " VERSION "\n", name);
46}
47
48static void printHelpFlag(const char* name) {
49 printf("%s " VERSION "\n"
Benny Baumann68edf922021-07-14 19:20:16 +020050 COPYRIGHT "\n"
Daniel Lange94ad1112021-09-22 11:33:00 +020051 "Released under the GNU GPLv2+.\n\n"
Benny Baumann68edf922021-07-14 19:20:16 +020052 "-C --no-color Use a monochrome color scheme\n"
53 "-d --delay=DELAY Set the delay between updates, in tenths of seconds\n"
54 "-F --filter=FILTER Show only the commands matching the given filter\n"
55 "-h --help Print this help screen\n"
Daniel Langedf955c82022-04-07 12:33:22 +020056 "-H --highlight-changes[=DELAY] Highlight new and old processes\n", name);
Daniel Lange6a7b3fd2022-04-07 11:52:22 +020057#ifdef HAVE_GETMOUSE
Daniel Langedf955c82022-04-07 12:33:22 +020058 printf("-M --no-mouse Disable the mouse\n");
Daniel Lange6a7b3fd2022-04-07 11:52:22 +020059#endif
Sahil Siddiq87db3792023-01-31 21:20:57 +053060 printf("-n --max-iterations=NUMBER Exit htop after NUMBER iterations/frame updates\n"
61 "-p --pid=PID[,PID,PID...] Show only the given PIDs\n"
Benny Baumann68edf922021-07-14 19:20:16 +020062 " --readonly Disable all system and process changing features\n"
63 "-s --sort-key=COLUMN Sort by COLUMN in list view (try --sort-key=help for a list)\n"
64 "-t --tree Show the tree view (can be combined with -s)\n"
65 "-u --user[=USERNAME] Show only processes for a given user (or $USER)\n"
66 "-U --no-unicode Do not use unicode but plain ASCII\n"
Daniel Langedf955c82022-04-07 12:33:22 +020067 "-V --version Print version info\n");
Nathan Scott36389fb2021-03-23 15:04:54 +110068 Platform_longOptionsUsage(name);
69 printf("\n"
Benny Baumann68edf922021-07-14 19:20:16 +020070 "Press F1 inside %s for online help.\n"
71 "See 'man %s' for more information.\n", name, name);
Nathan Scott36389fb2021-03-23 15:04:54 +110072}
73
74// ----------------------------------------
75
76typedef struct CommandLineSettings_ {
77 Hashtable* pidMatchList;
78 char* commFilter;
79 uid_t userId;
80 int sortKey;
81 int delay;
Sahil Siddiq87db3792023-01-31 21:20:57 +053082 int iterationsRemaining;
Nathan Scott36389fb2021-03-23 15:04:54 +110083 bool useColors;
Christian Göttsche1b5e0072022-08-09 20:12:08 +020084#ifdef HAVE_GETMOUSE
Nathan Scott36389fb2021-03-23 15:04:54 +110085 bool enableMouse;
Christian Göttsche1b5e0072022-08-09 20:12:08 +020086#endif
Nathan Scott36389fb2021-03-23 15:04:54 +110087 bool treeView;
88 bool allowUnicode;
89 bool highlightChanges;
90 int highlightDelaySecs;
Christian Göttsche36880cd2021-01-21 20:27:37 +010091 bool readonly;
Nathan Scott36389fb2021-03-23 15:04:54 +110092} CommandLineSettings;
93
Nathan Scott14da84f2023-04-04 16:47:11 +100094static CommandLineStatus parseArguments(int argc, char** argv, CommandLineSettings* flags) {
Nathan Scott36389fb2021-03-23 15:04:54 +110095
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +030096 *flags = (CommandLineSettings) {
Nathan Scott36389fb2021-03-23 15:04:54 +110097 .pidMatchList = NULL,
98 .commFilter = NULL,
99 .userId = (uid_t)-1, // -1 is guaranteed to be an invalid uid_t (see setreuid(2))
100 .sortKey = 0,
101 .delay = -1,
Sahil Siddiq87db3792023-01-31 21:20:57 +0530102 .iterationsRemaining = -1,
Nathan Scott36389fb2021-03-23 15:04:54 +1100103 .useColors = true,
Christian Göttsche1b5e0072022-08-09 20:12:08 +0200104#ifdef HAVE_GETMOUSE
Nathan Scott36389fb2021-03-23 15:04:54 +1100105 .enableMouse = true,
Christian Göttsche1b5e0072022-08-09 20:12:08 +0200106#endif
Nathan Scott36389fb2021-03-23 15:04:54 +1100107 .treeView = false,
108 .allowUnicode = true,
109 .highlightChanges = false,
110 .highlightDelaySecs = -1,
Christian Göttsche36880cd2021-01-21 20:27:37 +0100111 .readonly = false,
Nathan Scott36389fb2021-03-23 15:04:54 +1100112 };
113
114 const struct option long_opts[] =
115 {
116 {"help", no_argument, 0, 'h'},
117 {"version", no_argument, 0, 'V'},
118 {"delay", required_argument, 0, 'd'},
Sahil Siddiq87db3792023-01-31 21:20:57 +0530119 {"max-iterations", required_argument, 0, 'n'},
Nathan Scott36389fb2021-03-23 15:04:54 +1100120 {"sort-key", required_argument, 0, 's'},
121 {"user", optional_argument, 0, 'u'},
122 {"no-color", no_argument, 0, 'C'},
123 {"no-colour", no_argument, 0, 'C'},
124 {"no-mouse", no_argument, 0, 'M'},
125 {"no-unicode", no_argument, 0, 'U'},
126 {"tree", no_argument, 0, 't'},
127 {"pid", required_argument, 0, 'p'},
128 {"filter", required_argument, 0, 'F'},
129 {"highlight-changes", optional_argument, 0, 'H'},
Christian Göttsche36880cd2021-01-21 20:27:37 +0100130 {"readonly", no_argument, 0, 128},
Nathan Scott36389fb2021-03-23 15:04:54 +1100131 PLATFORM_LONG_OPTIONS
Benny Baumann0d85af22021-07-14 19:18:27 +0200132 {0, 0, 0, 0}
Nathan Scott36389fb2021-03-23 15:04:54 +1100133 };
134
Benny Baumann0d85af22021-07-14 19:18:27 +0200135 int opt, opti = 0;
Nathan Scott36389fb2021-03-23 15:04:54 +1100136 /* Parse arguments */
Sahil Siddiq87db3792023-01-31 21:20:57 +0530137 while ((opt = getopt_long(argc, argv, "hVMCs:td:n:u::Up:F:H::", long_opts, &opti))) {
Benny Baumanne7f8d7b2021-07-14 19:11:18 +0200138 if (opt == EOF)
139 break;
Nathan Scott36389fb2021-03-23 15:04:54 +1100140 switch (opt) {
141 case 'h':
142 printHelpFlag(program);
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300143 return STATUS_OK_EXIT;
Nathan Scott36389fb2021-03-23 15:04:54 +1100144 case 'V':
145 printVersionFlag(program);
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300146 return STATUS_OK_EXIT;
Nathan Scott36389fb2021-03-23 15:04:54 +1100147 case 's':
148 assert(optarg); /* please clang analyzer, cause optarg can be NULL in the 'u' case */
149 if (String_eq(optarg, "help")) {
150 for (int j = 1; j < LAST_PROCESSFIELD; j++) {
151 const char* name = Process_fields[j].name;
152 const char* description = Process_fields[j].description;
Benny Baumann40104582022-10-22 19:19:39 +0200153 if (name)
154 printf("%19s %s\n", name, description);
Nathan Scott36389fb2021-03-23 15:04:54 +1100155 }
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300156 return STATUS_OK_EXIT;
Nathan Scott36389fb2021-03-23 15:04:54 +1100157 }
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300158 flags->sortKey = 0;
Nathan Scott36389fb2021-03-23 15:04:54 +1100159 for (int j = 1; j < LAST_PROCESSFIELD; j++) {
160 if (Process_fields[j].name == NULL)
161 continue;
162 if (String_eq(optarg, Process_fields[j].name)) {
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300163 flags->sortKey = j;
Nathan Scott36389fb2021-03-23 15:04:54 +1100164 break;
165 }
166 }
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300167 if (flags->sortKey == 0) {
Nathan Scott36389fb2021-03-23 15:04:54 +1100168 fprintf(stderr, "Error: invalid column \"%s\".\n", optarg);
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300169 return STATUS_ERROR_EXIT;
Nathan Scott36389fb2021-03-23 15:04:54 +1100170 }
171 break;
172 case 'd':
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300173 if (sscanf(optarg, "%16d", &(flags->delay)) == 1) {
Benny Baumann40104582022-10-22 19:19:39 +0200174 if (flags->delay < 1)
175 flags->delay = 1;
176 if (flags->delay > 100)
177 flags->delay = 100;
Nathan Scott36389fb2021-03-23 15:04:54 +1100178 } else {
179 fprintf(stderr, "Error: invalid delay value \"%s\".\n", optarg);
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300180 return STATUS_ERROR_EXIT;
Nathan Scott36389fb2021-03-23 15:04:54 +1100181 }
182 break;
Sahil Siddiq87db3792023-01-31 21:20:57 +0530183 case 'n':
184 if (sscanf(optarg, "%16d", &flags->iterationsRemaining) == 1) {
185 if (flags->iterationsRemaining <= 0) {
186 fprintf(stderr, "Error: maximum iteration count must be positive.\n");
187 return STATUS_ERROR_EXIT;
188 }
189 } else {
190 fprintf(stderr, "Error: invalid maximum iteration count \"%s\".\n", optarg);
191 return STATUS_ERROR_EXIT;
192 }
193 break;
Nathan Scott36389fb2021-03-23 15:04:54 +1100194 case 'u':
195 {
Benny Baumann40104582022-10-22 19:19:39 +0200196 const char* username = optarg;
Nathan Scott36389fb2021-03-23 15:04:54 +1100197 if (!username && optind < argc && argv[optind] != NULL &&
198 (argv[optind][0] != '\0' && argv[optind][0] != '-')) {
199 username = argv[optind++];
200 }
201
202 if (!username) {
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300203 flags->userId = geteuid();
204 } else if (!Action_setUserOnly(username, &(flags->userId))) {
Benny Baumann40104582022-10-22 19:19:39 +0200205 for (const char* itr = username; *itr; ++itr)
набdfa62502021-10-04 15:08:55 +0200206 if (!isdigit((unsigned char)*itr)) {
207 fprintf(stderr, "Error: invalid user \"%s\".\n", username);
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300208 return STATUS_ERROR_EXIT;
набdfa62502021-10-04 15:08:55 +0200209 }
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300210 flags->userId = atol(username);
Nathan Scott36389fb2021-03-23 15:04:54 +1100211 }
212 break;
213 }
214 case 'C':
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300215 flags->useColors = false;
Nathan Scott36389fb2021-03-23 15:04:54 +1100216 break;
217 case 'M':
niae8f27eb2021-07-14 21:07:43 +0200218#ifdef HAVE_GETMOUSE
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300219 flags->enableMouse = false;
niae8f27eb2021-07-14 21:07:43 +0200220#endif
Nathan Scott36389fb2021-03-23 15:04:54 +1100221 break;
222 case 'U':
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300223 flags->allowUnicode = false;
Nathan Scott36389fb2021-03-23 15:04:54 +1100224 break;
225 case 't':
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300226 flags->treeView = true;
Nathan Scott36389fb2021-03-23 15:04:54 +1100227 break;
228 case 'p': {
229 assert(optarg); /* please clang analyzer, cause optarg can be NULL in the 'u' case */
230 char* argCopy = xStrdup(optarg);
231 char* saveptr;
232 const char* pid = strtok_r(argCopy, ",", &saveptr);
233
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300234 if (!flags->pidMatchList) {
235 flags->pidMatchList = Hashtable_new(8, false);
Nathan Scott36389fb2021-03-23 15:04:54 +1100236 }
237
Benny Baumann40104582022-10-22 19:19:39 +0200238 while (pid) {
239 unsigned int num_pid = atoi(pid);
240 // deepcode ignore CastIntegerToAddress: we just want a non-NULL pointer here
241 Hashtable_put(flags->pidMatchList, num_pid, (void*) 1);
242 pid = strtok_r(NULL, ",", &saveptr);
Nathan Scott36389fb2021-03-23 15:04:54 +1100243 }
244 free(argCopy);
245
246 break;
247 }
248 case 'F': {
249 assert(optarg);
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300250 free_and_xStrdup(&flags->commFilter, optarg);
Nathan Scott36389fb2021-03-23 15:04:54 +1100251 break;
252 }
253 case 'H': {
Benny Baumann40104582022-10-22 19:19:39 +0200254 const char* delay = optarg;
Nathan Scott36389fb2021-03-23 15:04:54 +1100255 if (!delay && optind < argc && argv[optind] != NULL &&
256 (argv[optind][0] != '\0' && argv[optind][0] != '-')) {
Benny Baumann40104582022-10-22 19:19:39 +0200257 delay = argv[optind++];
Nathan Scott36389fb2021-03-23 15:04:54 +1100258 }
259 if (delay) {
Benny Baumann40104582022-10-22 19:19:39 +0200260 if (sscanf(delay, "%16d", &(flags->highlightDelaySecs)) == 1) {
261 if (flags->highlightDelaySecs < 1)
262 flags->highlightDelaySecs = 1;
263 } else {
264 fprintf(stderr, "Error: invalid highlight delay value \"%s\".\n", delay);
265 return STATUS_ERROR_EXIT;
266 }
Nathan Scott36389fb2021-03-23 15:04:54 +1100267 }
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300268 flags->highlightChanges = true;
Nathan Scott36389fb2021-03-23 15:04:54 +1100269 break;
270 }
Christian Göttsche36880cd2021-01-21 20:27:37 +0100271 case 128:
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300272 flags->readonly = true;
Christian Göttsche36880cd2021-01-21 20:27:37 +0100273 break;
Nathan Scott36389fb2021-03-23 15:04:54 +1100274
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300275 default: {
276 CommandLineStatus status;
277 if ((status = Platform_getLongOption(opt, argc, argv)) != STATUS_OK)
278 return status;
279 break;
280 }
Nathan Scott36389fb2021-03-23 15:04:54 +1100281 }
282 }
Christian Göttsche2f387af2022-10-20 14:57:42 +0200283
284 if (optind < argc) {
285 fprintf(stderr, "Error: unsupported non-option ARGV-elements:");
286 while (optind < argc)
287 fprintf(stderr, " %s", argv[optind++]);
288 fprintf(stderr, "\n");
289 return STATUS_ERROR_EXIT;
290 }
291
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300292 return STATUS_OK;
Nathan Scott36389fb2021-03-23 15:04:54 +1100293}
294
Nathan Scott0bdade12023-05-02 09:02:22 +1000295static void CommandLine_delay(Machine* host, unsigned long millisec) {
Nathan Scott36389fb2021-03-23 15:04:54 +1100296 struct timespec req = {
297 .tv_sec = 0,
298 .tv_nsec = millisec * 1000000L
299 };
Nathan Scott36756112021-04-08 09:26:48 +1000300 while (nanosleep(&req, &req) == -1)
Nathan Scott36389fb2021-03-23 15:04:54 +1100301 continue;
Nathan Scott0bdade12023-05-02 09:02:22 +1000302 Platform_gettime_realtime(&host->realtime, &host->realtimeMs);
Nathan Scott36389fb2021-03-23 15:04:54 +1100303}
304
305static void setCommFilter(State* state, char** commFilter) {
Nathan Scott0f751e92023-08-22 16:11:05 +1000306 Table* table = state->host->activeTable;
Nathan Scott36389fb2021-03-23 15:04:54 +1100307 IncSet* inc = state->mainPanel->inc;
308
309 IncSet_setFilter(inc, *commFilter);
Nathan Scott0f751e92023-08-22 16:11:05 +1000310 table->incFilter = IncSet_filter(inc);
Nathan Scott36389fb2021-03-23 15:04:54 +1100311
312 free(*commFilter);
313 *commFilter = NULL;
314}
315
Nathan Scott14da84f2023-04-04 16:47:11 +1000316int CommandLine_run(int argc, char** argv) {
Nathan Scott36389fb2021-03-23 15:04:54 +1100317
318 /* initialize locale */
319 const char* lc_ctype;
320 if ((lc_ctype = getenv("LC_CTYPE")) || (lc_ctype = getenv("LC_ALL")))
321 setlocale(LC_CTYPE, lc_ctype);
322 else
323 setlocale(LC_CTYPE, "");
324
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300325 CommandLineStatus status = STATUS_OK;
326 CommandLineSettings flags = { 0 };
327
Nathan Scott14da84f2023-04-04 16:47:11 +1000328 if ((status = parseArguments(argc, argv, &flags)) != STATUS_OK)
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300329 return status != STATUS_OK_EXIT ? 1 : 0;
Nathan Scott36389fb2021-03-23 15:04:54 +1100330
Christian Göttsche36880cd2021-01-21 20:27:37 +0100331 if (flags.readonly)
332 Settings_enableReadonly();
333
Volodymyr Vasiutyk2ef70ad2021-10-06 10:45:07 +0300334 if (!Platform_init())
335 return 1;
Nathan Scott36389fb2021-03-23 15:04:54 +1100336
Nathan Scott36389fb2021-03-23 15:04:54 +1100337 UsersTable* ut = UsersTable_new();
Nathan Scottf0ed0fd2021-06-23 17:44:56 +1000338 Hashtable* dm = DynamicMeters_new();
Nathan Scotte7f447b2023-04-04 16:24:37 +1000339 Hashtable* dc = DynamicColumns_new();
Sohaib Mohamed6f2021f2021-07-11 03:11:29 +0200340 if (!dc)
341 dc = Hashtable_new(0, true);
Nathan Scott36389fb2021-03-23 15:04:54 +1100342
Nathan Scott0bdade12023-05-02 09:02:22 +1000343 Machine* host = Machine_new(ut, flags.userId);
344 ProcessList* pl = ProcessList_new(host, flags.pidMatchList);
345 Settings* settings = Settings_new(host->activeCPUs, dm, dc);
Sohaib Mohamed6f2021f2021-07-11 03:11:29 +0200346
Nathan Scott0bdade12023-05-02 09:02:22 +1000347 host->settings = settings;
Nathan Scott0f751e92023-08-22 16:11:05 +1000348 Machine_addTable(host, &pl->super, true);
Nathan Scott36389fb2021-03-23 15:04:54 +1100349
Nathan Scott0bdade12023-05-02 09:02:22 +1000350 Header* header = Header_new(host, 2);
Nathan Scott36389fb2021-03-23 15:04:54 +1100351 Header_populateFromSettings(header);
352
353 if (flags.delay != -1)
354 settings->delay = flags.delay;
355 if (!flags.useColors)
356 settings->colorScheme = COLORSCHEME_MONOCHROME;
niae8f27eb2021-07-14 21:07:43 +0200357#ifdef HAVE_GETMOUSE
Nathan Scott36389fb2021-03-23 15:04:54 +1100358 if (!flags.enableMouse)
359 settings->enableMouse = false;
niae8f27eb2021-07-14 21:07:43 +0200360#endif
Nathan Scott36389fb2021-03-23 15:04:54 +1100361 if (flags.treeView)
Hisham Muhammad72ba20f2021-08-31 15:38:52 +1000362 settings->ss->treeView = true;
Nathan Scott36389fb2021-03-23 15:04:54 +1100363 if (flags.highlightChanges)
364 settings->highlightChanges = true;
365 if (flags.highlightDelaySecs != -1)
366 settings->highlightDelaySecs = flags.highlightDelaySecs;
367 if (flags.sortKey > 0) {
368 // -t -s <key> means "tree sorted by key"
369 // -s <key> means "list sorted by key" (previous existing behavior)
370 if (!flags.treeView) {
Hisham Muhammad72ba20f2021-08-31 15:38:52 +1000371 settings->ss->treeView = false;
Nathan Scott36389fb2021-03-23 15:04:54 +1100372 }
Hisham Muhammad72ba20f2021-08-31 15:38:52 +1000373 ScreenSettings_setSortKey(settings->ss, flags.sortKey);
Nathan Scott36389fb2021-03-23 15:04:54 +1100374 }
375
Sahil Siddiq87db3792023-01-31 21:20:57 +0530376 host->iterationsRemaining = flags.iterationsRemaining;
Sahil Siddiqdc883b22023-05-22 11:09:11 +0530377 CRT_init(settings, flags.allowUnicode, flags.iterationsRemaining != -1);
Nathan Scott36389fb2021-03-23 15:04:54 +1100378
379 MainPanel* panel = MainPanel_new();
Nathan Scott0f751e92023-08-22 16:11:05 +1000380 Table_setPanel(&pl->super, (Panel*) panel);
Nathan Scott36389fb2021-03-23 15:04:54 +1100381
Daniel Langec6f946e2022-03-25 14:51:14 +0100382 MainPanel_updateLabels(panel, settings->ss->treeView, flags.commFilter);
Nathan Scott36389fb2021-03-23 15:04:54 +1100383
384 State state = {
Nathan Scott0bdade12023-05-02 09:02:22 +1000385 .host = host,
Nathan Scott36389fb2021-03-23 15:04:54 +1100386 .mainPanel = panel,
387 .header = header,
Nathan Scotte4ebe182023-02-14 11:51:54 +1100388 .pauseUpdate = false,
389 .hideSelection = false,
Christian Göttsche15fe50d2022-10-20 15:03:17 +0200390 .hideMeters = false,
Nathan Scott36389fb2021-03-23 15:04:54 +1100391 };
392
393 MainPanel_setState(panel, &state);
394 if (flags.commFilter)
395 setCommFilter(&state, &(flags.commFilter));
396
Nathan Scott0bdade12023-05-02 09:02:22 +1000397 ScreenManager* scr = ScreenManager_new(header, host, &state, true);
Nathan Scott36389fb2021-03-23 15:04:54 +1100398 ScreenManager_add(scr, (Panel*) panel, -1);
399
Nathan Scott72235d82023-05-02 16:56:18 +1000400 Machine_scan(host);
Nathan Scott0f751e92023-08-22 16:11:05 +1000401 Machine_scanTables(host);
Nathan Scott0bdade12023-05-02 09:02:22 +1000402 CommandLine_delay(host, 75);
Nathan Scott72235d82023-05-02 16:56:18 +1000403 Machine_scan(host);
Nathan Scott0f751e92023-08-22 16:11:05 +1000404 Machine_scanTables(host);
Nathan Scott36389fb2021-03-23 15:04:54 +1100405
Hisham Muhammad72ba20f2021-08-31 15:38:52 +1000406 if (settings->ss->allBranchesCollapsed)
Nathan Scott0f751e92023-08-22 16:11:05 +1000407 Table_collapseAllBranches(&pl->super);
Nathan Scott36389fb2021-03-23 15:04:54 +1100408
Hisham Muhammad72ba20f2021-08-31 15:38:52 +1000409 ScreenManager_run(scr, NULL, NULL, NULL);
Nathan Scott36389fb2021-03-23 15:04:54 +1100410
Nathan Scott36389fb2021-03-23 15:04:54 +1100411 Platform_done();
412
413 CRT_done();
414
415 if (settings->changed) {
Christian Göttsche1f5f40c2021-05-16 19:55:31 +0200416 int r = Settings_write(settings, false);
Nathan Scott36389fb2021-03-23 15:04:54 +1100417 if (r < 0)
418 fprintf(stderr, "Can not save configuration to %s: %s\n", settings->filename, strerror(-r));
419 }
420
421 Header_delete(header);
Nathan Scott0bdade12023-05-02 09:02:22 +1000422 Machine_delete(host);
Nathan Scott36389fb2021-03-23 15:04:54 +1100423
424 ScreenManager_delete(scr);
425 MetersPanel_cleanup();
426
427 UsersTable_delete(ut);
Nathan Scott36389fb2021-03-23 15:04:54 +1100428
429 if (flags.pidMatchList)
430 Hashtable_delete(flags.pidMatchList);
431
Christian Göttsche68460b22021-08-14 19:52:26 +0200432 CRT_resetSignalHandlers();
433
Sohaib Mohamed6f2021f2021-07-11 03:11:29 +0200434 /* Delete these last, since they can get accessed in the crash handler */
Christian Göttsche1f5f40c2021-05-16 19:55:31 +0200435 Settings_delete(settings);
Nathan Scottc0c2bb92021-09-03 12:11:31 +1000436 DynamicColumns_delete(dc);
437 DynamicMeters_delete(dm);
Christian Göttsche1f5f40c2021-05-16 19:55:31 +0200438
Nathan Scott36389fb2021-03-23 15:04:54 +1100439 return 0;
440}