diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2019-09-03 23:08:43 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2019-09-03 23:08:43 +0000 |
commit | 10c59997c16d22440b91eb1d98b28ca299311815 (patch) | |
tree | 47c0e9dd571d2d0dde447ec951b1bd69b3f51b2c /usr.bin/less | |
parent | b33a69641c6570368c68fd33d5556edb479e559e (diff) |
less uses a correct raceless signal method of indicating signal events in
a volatile sig_atomic_t variable, and then processing events in the mainloop.
But only one variable was used for 3 signals, with |= bit operations which
are signal interruptable! Rewrite the code to use 3 independent variables
and cleanup how the mainloop observes indications.
ok schwarze
Diffstat (limited to 'usr.bin/less')
-rw-r--r-- | usr.bin/less/ch.c | 9 | ||||
-rw-r--r-- | usr.bin/less/command.c | 11 | ||||
-rw-r--r-- | usr.bin/less/edit.c | 3 | ||||
-rw-r--r-- | usr.bin/less/forwback.c | 1 | ||||
-rw-r--r-- | usr.bin/less/input.c | 17 | ||||
-rw-r--r-- | usr.bin/less/less.h | 6 | ||||
-rw-r--r-- | usr.bin/less/line.c | 7 | ||||
-rw-r--r-- | usr.bin/less/linenum.c | 9 | ||||
-rw-r--r-- | usr.bin/less/os.c | 1 | ||||
-rw-r--r-- | usr.bin/less/output.c | 3 | ||||
-rw-r--r-- | usr.bin/less/screen.c | 1 | ||||
-rw-r--r-- | usr.bin/less/search.c | 3 | ||||
-rw-r--r-- | usr.bin/less/signal.c | 43 | ||||
-rw-r--r-- | usr.bin/less/tags.c | 3 | ||||
-rw-r--r-- | usr.bin/less/ttyin.c | 1 |
15 files changed, 57 insertions, 61 deletions
diff --git a/usr.bin/less/ch.c b/usr.bin/less/ch.c index 6c4bae2df63..1a679767a42 100644 --- a/usr.bin/less/ch.c +++ b/usr.bin/less/ch.c @@ -122,7 +122,6 @@ static int ch_ungotchar = -1; static int maxbufs = -1; extern int autobuf; -extern volatile sig_atomic_t sigs; extern int secure; extern int screen_trashed; extern int follow_mode; @@ -304,7 +303,7 @@ read_more: } } } - if (sigs) + if (any_sigs()) return (EOI); } @@ -361,7 +360,7 @@ end_logfile(void) tried = TRUE; ierror("Finishing logfile", NULL); while (ch_forw_get() != EOI) - if (ABORT_SIGS()) + if (abort_sigs()) break; } close(logfile); @@ -447,7 +446,7 @@ ch_seek(off_t pos) while (ch_fpos < pos) { if (ch_forw_get() == EOI) return (1); - if (ABORT_SIGS()) + if (abort_sigs()) return (1); } return (0); @@ -482,7 +481,7 @@ ch_end_seek(void) * Do it the slow way: read till end of data. */ while (ch_forw_get() != EOI) - if (ABORT_SIGS()) + if (abort_sigs()) return (1); return (0); } diff --git a/usr.bin/less/command.c b/usr.bin/less/command.c index 2447887bcdd..4a90d74d185 100644 --- a/usr.bin/less/command.c +++ b/usr.bin/less/command.c @@ -19,7 +19,6 @@ #include "position.h" extern int erase_char, erase2_char, kill_char; -extern volatile sig_atomic_t sigs; extern int quit_if_one_screen; extern int less_is_more; extern int squished; @@ -885,7 +884,7 @@ forw_loop(int until_hilite) curr_len = ch_length(); highest_hilite = until_hilite ? curr_len : -1; ignore_eoi = 1; - while (!sigs) { + while (!any_sigs()) { if (until_hilite && highest_hilite > curr_len) { ring_bell(); break; @@ -900,7 +899,7 @@ forw_loop(int until_hilite) * This gets us back in "F mode" after processing * a non-abort signal (e.g. window-change). */ - if (sigs && !ABORT_SIGS()) + if (any_sigs() && !abort_sigs()) return (until_hilite ? A_F_UNTIL_HILITE : A_F_FOREVER); return (A_NOACTION); @@ -938,7 +937,7 @@ commands(void) /* * See if any signals need processing. */ - if (sigs) { + if (any_sigs()) { psignals(); if (quitting) quit(QUIT_SAVED_STATUS); @@ -949,13 +948,13 @@ commands(void) */ cmd_reset(); prompt(); - if (sigs) + if (any_sigs()) continue; if (newaction == A_NOACTION) c = getcc(); again: - if (sigs) + if (any_sigs()) continue; if (newaction != A_NOACTION) { diff --git a/usr.bin/less/edit.c b/usr.bin/less/edit.c index 8acd89231d0..eff4d28dcf7 100644 --- a/usr.bin/less/edit.c +++ b/usr.bin/less/edit.c @@ -21,7 +21,6 @@ extern char *every_first_cmd; extern int any_display; extern int force_open; extern int is_tty; -extern volatile sig_atomic_t sigs; extern IFILE curr_ifile; extern IFILE old_ifile; extern struct scrpos initial_scrpos; @@ -478,7 +477,7 @@ edit_istep(IFILE h, int n, int dir) */ return (1); } - if (ABORT_SIGS()) { + if (abort_sigs()) { /* * Interrupt breaks out, if we're in a long * list of files that can't be opened. diff --git a/usr.bin/less/forwback.c b/usr.bin/less/forwback.c index bc31a5ea279..023e93ec985 100644 --- a/usr.bin/less/forwback.c +++ b/usr.bin/less/forwback.c @@ -22,7 +22,6 @@ int squished; int no_back_scroll = 0; int forw_prompt; -extern volatile sig_atomic_t sigs; extern int top_scroll; extern int quiet; extern int sc_width, sc_height; diff --git a/usr.bin/less/input.c b/usr.bin/less/input.c index dd5f622e07c..18ce8a93341 100644 --- a/usr.bin/less/input.c +++ b/usr.bin/less/input.c @@ -25,7 +25,6 @@ extern int squeeze; extern int chopline; extern int hshift; extern int quit_if_one_screen; -extern volatile sig_atomic_t sigs; extern int ignore_eoi; extern int status_col; extern off_t start_attnpos; @@ -75,7 +74,7 @@ get_forw_line: */ base_pos = curr_pos; for (;;) { - if (ABORT_SIGS()) { + if (abort_sigs()) { null_line(); return (-1); } @@ -97,7 +96,7 @@ get_forw_line: (void) ch_seek(base_pos); new_pos = base_pos; while (new_pos < curr_pos) { - if (ABORT_SIGS()) { + if (abort_sigs()) { null_line(); return (-1); } @@ -128,7 +127,7 @@ get_forw_line: * Read each character in the line and append to the line buffer. */ for (;;) { - if (ABORT_SIGS()) { + if (abort_sigs()) { null_line(); return (-1); } @@ -160,7 +159,7 @@ get_forw_line: */ if (chopline || hshift > 0) { do { - if (ABORT_SIGS()) { + if (abort_sigs()) { null_line(); return (-1); } @@ -199,7 +198,7 @@ get_forw_line: * and pretend it is the one which we are returning. */ while ((c = ch_forw_get()) == '\n' || c == '\r') - if (ABORT_SIGS()) { + if (abort_sigs()) { null_line(); return (-1); } @@ -255,7 +254,7 @@ get_back_line: * since we skipped them in forw_line(). */ while ((c = ch_back_get()) == '\n' || c == '\r') - if (ABORT_SIGS()) { + if (abort_sigs()) { null_line(); return (-1); } @@ -271,7 +270,7 @@ get_back_line: * Scan backwards until we hit the beginning of the line. */ for (;;) { - if (ABORT_SIGS()) { + if (abort_sigs()) { null_line(); return (-1); } @@ -318,7 +317,7 @@ loop: do { c = ch_forw_get(); - if (c == EOI || ABORT_SIGS()) { + if (c == EOI || abort_sigs()) { null_line(); return (-1); } diff --git a/usr.bin/less/less.h b/usr.bin/less/less.h index 3bd9e307201..259ade82ed9 100644 --- a/usr.bin/less/less.h +++ b/usr.bin/less/less.h @@ -151,10 +151,8 @@ struct textlist { #define CONTROL(c) ((c)&037) #define ESC CONTROL('[') -#define S_INTERRUPT 01 -#define S_STOP 02 -#define S_WINCH 04 -#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP)) +extern int any_sigs(void); +extern int abort_sigs(void); #define QUIT_OK 0 #define QUIT_ERROR 1 diff --git a/usr.bin/less/line.c b/usr.bin/less/line.c index 123353d2121..b76b067c875 100644 --- a/usr.bin/less/line.c +++ b/usr.bin/less/line.c @@ -46,7 +46,6 @@ static int attr_swidth(int); static int attr_ewidth(int); static int do_append(LWCHAR, char *, off_t); -extern volatile sig_atomic_t sigs; extern int bs_mode; extern int linenums; extern int ctldisp; @@ -685,7 +684,7 @@ pappend(char c, off_t pos) mbc_buf[mbc_buf_index++] = c; memset(&mbs, 0, sizeof(mbs)); sz = mbrtowc(&ch, mbc_buf, mbc_buf_index, &mbs); - + /* Incomplete UTF-8: wait for more bytes. */ if (sz == (size_t)-2) return (0); @@ -1034,7 +1033,7 @@ forw_raw_line(off_t curr_pos, char **linep, int *line_lenp) n = 0; for (;;) { - if (c == '\n' || c == EOI || ABORT_SIGS()) { + if (c == '\n' || c == EOI || abort_sigs()) { new_pos = ch_tell(); break; } @@ -1077,7 +1076,7 @@ back_raw_line(off_t curr_pos, char **linep, int *line_lenp) linebuf[--n] = '\0'; for (;;) { c = ch_back_get(); - if (c == '\n' || ABORT_SIGS()) { + if (c == '\n' || abort_sigs()) { /* * This is the newline ending the previous line. * We have hit the beginning of the line. diff --git a/usr.bin/less/linenum.c b/usr.bin/less/linenum.c index 14a569cef1f..c76984078d6 100644 --- a/usr.bin/less/linenum.c +++ b/usr.bin/less/linenum.c @@ -69,7 +69,6 @@ static struct linenum_info pool[NPOOL]; /* The pool itself */ static struct linenum_info *spare; /* We always keep one spare entry */ extern int linenums; -extern volatile sig_atomic_t sigs; extern int sc_height; extern int screen_trashed; @@ -308,7 +307,7 @@ find_linenum(off_t pos) * Allow a signal to abort this loop. */ cpos = forw_raw_line(cpos, NULL, NULL); - if (ABORT_SIGS()) { + if (abort_sigs()) { abort_long(); return (0); } @@ -338,7 +337,7 @@ find_linenum(off_t pos) * Allow a signal to abort this loop. */ cpos = back_raw_line(cpos, NULL, NULL); - if (ABORT_SIGS()) { + if (abort_sigs()) { abort_long(); return (0); } @@ -395,7 +394,7 @@ find_pos(off_t linenum) * Allow a signal to abort this loop. */ cpos = forw_raw_line(cpos, NULL, NULL); - if (ABORT_SIGS()) + if (abort_sigs()) return (-1); if (cpos == -1) return (-1); @@ -413,7 +412,7 @@ find_pos(off_t linenum) * Allow a signal to abort this loop. */ cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL); - if (ABORT_SIGS()) + if (abort_sigs()) return (-1); if (cpos == -1) return (-1); diff --git a/usr.bin/less/os.c b/usr.bin/less/os.c index 6eca5824fc3..e0be4af7097 100644 --- a/usr.bin/less/os.c +++ b/usr.bin/less/os.c @@ -27,7 +27,6 @@ #include "less.h" -extern volatile sig_atomic_t sigs; /* * Like read() system call, but is deliberately interruptible. diff --git a/usr.bin/less/output.c b/usr.bin/less/output.c index bafe48b8146..3dee60bab1a 100644 --- a/usr.bin/less/output.c +++ b/usr.bin/less/output.c @@ -17,7 +17,6 @@ int errmsgs; /* Count of messages displayed by error() */ -extern volatile sig_atomic_t sigs; extern int sc_width; extern int so_s_width, so_e_width; extern int screen_trashed; @@ -37,7 +36,7 @@ put_line(void) int i; int a; - if (ABORT_SIGS()) { + if (abort_sigs()) { /* * Don't output if a signal is pending. */ diff --git a/usr.bin/less/screen.c b/usr.bin/less/screen.c index a794afc680b..893eb8def8c 100644 --- a/usr.bin/less/screen.c +++ b/usr.bin/less/screen.c @@ -81,7 +81,6 @@ extern int no_back_scroll; extern int swindow; extern int no_init; extern int no_keypad; -extern volatile sig_atomic_t sigs; extern int wscroll; extern int screen_trashed; extern int tty; diff --git a/usr.bin/less/search.c b/usr.bin/less/search.c index 770ff0cf5b1..9d7613b665b 100644 --- a/usr.bin/less/search.c +++ b/usr.bin/less/search.c @@ -21,7 +21,6 @@ #define MINPOS(a, b) (((a) < (b)) ? (a) : (b)) #define MAXPOS(a, b) (((a) > (b)) ? (a) : (b)) -extern volatile sig_atomic_t sigs; extern int how_search; extern int caseless; extern int linenums; @@ -677,7 +676,7 @@ search_range(off_t pos, off_t endpos, int search_type, int matches, * we hit end-of-file (or beginning-of-file if we're * going backwards), or until we hit the end position. */ - if (ABORT_SIGS()) { + if (abort_sigs()) { /* * A signal aborts the search. */ diff --git a/usr.bin/less/signal.c b/usr.bin/less/signal.c index 5bf672c06bb..d2ae3319c76 100644 --- a/usr.bin/less/signal.c +++ b/usr.bin/less/signal.c @@ -22,9 +22,11 @@ #include "less.h" /* - * "sigs" contains bits indicating signals which need to be processed. + * signals which need to be processed. */ -volatile sig_atomic_t sigs; +volatile sig_atomic_t signal_intr; +volatile sig_atomic_t signal_stop; +volatile sig_atomic_t signal_winch; extern int sc_width, sc_height; extern int screen_trashed; @@ -39,7 +41,7 @@ extern long jump_sline_fraction; static void u_interrupt(int type) { - sigs |= S_INTERRUPT; + signal_intr = 1; } /* @@ -48,7 +50,7 @@ u_interrupt(int type) static void stop(int type) { - sigs |= S_STOP; + signal_stop = 1; } /* @@ -57,7 +59,7 @@ stop(int type) void sigwinch(int type) { - sigs |= S_WINCH; + signal_winch = 1; } /* @@ -87,18 +89,12 @@ init_signals(int on) /* * Process any signals we have received. - * A received signal cause a bit to be set in "sigs". */ void psignals(void) { - int tsignals; - - if ((tsignals = sigs) == 0) - return; - sigs = 0; - - if (tsignals & S_STOP) { + if (signal_stop) { + signal_stop = 0; /* * Clean up the terminal. */ @@ -120,9 +116,10 @@ psignals(void) raw_mode(1); init(); screen_trashed = 1; - tsignals |= S_WINCH; + signal_winch = 1; } - if (tsignals & S_WINCH) { + if (signal_winch) { + signal_winch = 0; int old_width, old_height; /* * Re-execute scrsize() to read the new window size. @@ -137,7 +134,8 @@ psignals(void) screen_trashed = 1; } } - if (tsignals & S_INTERRUPT) { + if (signal_intr) { + signal_intr = 0; ring_bell(); if (quit_on_intr) quit(QUIT_INTERRUPT); @@ -159,3 +157,16 @@ lsignal(int s, void (*a)(int)) return (SIG_ERR); return (osa.sa_handler); } + +int +any_sigs(void) +{ + return (signal_intr || signal_stop || signal_winch); +} + +int +abort_sigs(void) +{ + return (signal_intr || signal_stop); +} + diff --git a/usr.bin/less/tags.c b/usr.bin/less/tags.c index 9c7cba96883..ddc8d6541df 100644 --- a/usr.bin/less/tags.c +++ b/usr.bin/less/tags.c @@ -19,7 +19,6 @@ static int total; static int curseq; extern int linenums; -extern volatile sig_atomic_t sigs; enum tag_result { TAG_FOUND, @@ -331,7 +330,7 @@ ctagsearch(void) * Get lines until we find a matching one or * until we hit end-of-file. */ - if (ABORT_SIGS()) + if (abort_sigs()) return (-1); /* diff --git a/usr.bin/less/ttyin.c b/usr.bin/less/ttyin.c index 7511f44765a..cfe051365f5 100644 --- a/usr.bin/less/ttyin.c +++ b/usr.bin/less/ttyin.c @@ -16,7 +16,6 @@ #include "less.h" int tty; -extern volatile sig_atomic_t sigs; extern int utf_mode; /* |