summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2019-09-03 23:08:43 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2019-09-03 23:08:43 +0000
commit10c59997c16d22440b91eb1d98b28ca299311815 (patch)
tree47c0e9dd571d2d0dde447ec951b1bd69b3f51b2c
parentb33a69641c6570368c68fd33d5556edb479e559e (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
-rw-r--r--usr.bin/less/ch.c9
-rw-r--r--usr.bin/less/command.c11
-rw-r--r--usr.bin/less/edit.c3
-rw-r--r--usr.bin/less/forwback.c1
-rw-r--r--usr.bin/less/input.c17
-rw-r--r--usr.bin/less/less.h6
-rw-r--r--usr.bin/less/line.c7
-rw-r--r--usr.bin/less/linenum.c9
-rw-r--r--usr.bin/less/os.c1
-rw-r--r--usr.bin/less/output.c3
-rw-r--r--usr.bin/less/screen.c1
-rw-r--r--usr.bin/less/search.c3
-rw-r--r--usr.bin/less/signal.c43
-rw-r--r--usr.bin/less/tags.c3
-rw-r--r--usr.bin/less/ttyin.c1
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;
/*