From: Ingo Schwarze Subject: Re: watch(1) - periodically execute a command and display its output To: Theo de Raadt Cc: Job Snijders , tech@openbsd.org Date: Wed, 21 May 2025 04:28:57 +0200 Hi Theo, Theo de Raadt wrote on Mon, May 19, 2025 at 06:50:03PM -0600: > Over my dead body! Just trying to save your life, 'cause it would be such a pity... ;-) I think there is nothing wrong with checking for signals at multiple points in the command_loop(), for example before every operation that might potentially take a significant time. Also, the logical place to put cleanup code is at the end of main(). To be committed after florian@'s cmdstr patch goes in, of course. OK? Ingo --- watch.c Wed May 21 04:12:27 2025 +++ watch.c Wed May 21 04:09:20 2025 @@ -50,7 +50,8 @@ typedef enum { RSLT_UPDATE, RSLT_REDRAW, RSLT_NOTOUCH, - RSLT_ERROR + RSLT_ERROR, + RSLT_QUIT } kbd_result_t; /* @@ -64,6 +65,8 @@ struct { .d = DEFAULT_INTERVAL }; +volatile sig_atomic_t got_signal = 0; + highlight_mode_t highlight_mode = HIGHLIGHT_NONE; highlight_mode_t last_highlight_mode = HIGHLIGHT_CHAR; @@ -93,7 +96,6 @@ kbd_result_t kbd_command(int); void show_help(void); void untabify(wchar_t *, int); void on_signal(int); -void quit(void); void usage(void); int @@ -206,8 +208,12 @@ main(int argc, char *argv[]) command_loop(); - /* NOTREACHED */ - abort(); + erase(); + refresh(); + endwin(); + free(cmdv); + + return got_signal ? 128 + got_signal : 0; } void @@ -231,12 +237,21 @@ command_loop(void) prev = &buf0; } + if (got_signal) + break; + read_result(cur); redraw: + if (got_signal) + break; + display(cur, prev, highlight_mode); input: + if (got_signal) + break; + to = opt_interval.tv; FD_ZERO(&readfds); FD_SET(fileno(stdin), &readfds); @@ -269,6 +284,8 @@ input: case RSLT_ERROR: /* error */ fprintf(stderr, "\007"); goto input; + case RSLT_QUIT: + return; } } } @@ -595,8 +612,7 @@ kbd_command(int ch) break; case 'q': - quit(); - break; + return (RSLT_QUIT); default: return (RSLT_ERROR); @@ -682,17 +698,7 @@ untabify(wchar_t *buf, int maxlen) void on_signal(int signum) { - quit(); -} - -void -quit(void) -{ - erase(); - refresh(); - endwin(); - free(cmdv); - exit(0); + got_signal = signum; } void