diff options
author | 2011-08-03 08:48:19 +0000 | |
---|---|---|
committer | 2011-08-03 08:48:19 +0000 | |
commit | 03cc04594bef28ab47a4fa96fa1481db7daf783f (patch) | |
tree | 5c8bf211b6324a76ed29b2dc0ef0be87715bd9e8 | |
parent | Alexander Polakov found a use of an uninitialized pointer in the scsi (diff) | |
download | wireguard-openbsd-03cc04594bef28ab47a4fa96fa1481db7daf783f.tar.xz wireguard-openbsd-03cc04594bef28ab47a4fa96fa1481db7daf783f.zip |
save/restore tty state on SIGTSTP/SIGCONT. ok deraadt@ nicm@
-rw-r--r-- | usr.bin/bc/bc.y | 9 | ||||
-rw-r--r-- | usr.bin/bc/extern.h | 7 | ||||
-rw-r--r-- | usr.bin/bc/scan.l | 47 |
3 files changed, 55 insertions, 8 deletions
diff --git a/usr.bin/bc/bc.y b/usr.bin/bc/bc.y index 2a98248a846..4314d99e205 100644 --- a/usr.bin/bc/bc.y +++ b/usr.bin/bc/bc.y @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: bc.y,v 1.38 2011/07/08 23:29:46 tedu Exp $ */ +/* $OpenBSD: bc.y,v 1.39 2011/08/03 08:48:19 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> @@ -43,6 +43,7 @@ #include <stdarg.h> #include <stdbool.h> #include <string.h> +#include <termios.h> #include <unistd.h> #include "extern.h" @@ -1061,12 +1062,13 @@ sigchld(int signo) int status, save_errno = errno; for (;;) { - pid = waitpid(dc, &status, WCONTINUED); + pid = waitpid(dc, &status, WCONTINUED | WNOHANG); if (pid == -1) { if (errno == EINTR) continue; _exit(0); - } + } else if (pid == 0) + break; if (WIFEXITED(status) || WIFSIGNALED(status)) _exit(0); else @@ -1139,6 +1141,7 @@ main(int argc, char *argv[]) close(p[0]); close(p[1]); if (interactive) { + gettty(&ttysaved); el = el_init("bc", stdin, stderr, stderr); hist = history_init(); history(hist, &he, H_SETSIZE, 100); diff --git a/usr.bin/bc/extern.h b/usr.bin/bc/extern.h index be03bd33a5f..3fb7e318daa 100644 --- a/usr.bin/bc/extern.h +++ b/usr.bin/bc/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.8 2011/06/03 06:10:33 otto Exp $ */ +/* $OpenBSD: extern.h,v 1.9 2011/08/03 08:48:19 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> @@ -27,6 +27,7 @@ int yylex(void); void yyerror(char *); void fatal(const char *); void abort_line(int); +int gettty(struct termios *); unsigned char bc_eof(EditLine *, int); extern int lineno; @@ -41,5 +42,5 @@ extern EditLine *el; extern History *hist; extern HistEvent he; extern char *cmdexpr; - -bool interactive; +extern struct termios ttysaved; +extern bool interactive; diff --git a/usr.bin/bc/scan.l b/usr.bin/bc/scan.l index 8cef4b294f9..a49ef2cb38c 100644 --- a/usr.bin/bc/scan.l +++ b/usr.bin/bc/scan.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scan.l,v 1.26 2011/06/03 06:10:33 otto Exp $ */ +/* $OpenBSD: scan.l,v 1.27 2011/08/03 08:48:19 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> @@ -22,6 +22,7 @@ #include <signal.h> #include <stdbool.h> #include <string.h> +#include <termios.h> #include <unistd.h> #include "extern.h" @@ -40,6 +41,7 @@ static size_t strbuf_sz = 1; static bool dot_seen; static int use_el; static volatile sig_atomic_t skipchars; +struct termios ttysaved, ttyedit; static void init_strbuf(void); static void add_str(const char *); @@ -253,6 +255,45 @@ abort_line(int sig) errno = save_errno; } +int +settty(struct termios *t) +{ + int ret; + + while ((ret = tcsetattr(0, TCSADRAIN, t) == -1) && errno == EINTR) + continue; + return ret; +} + +int +gettty(struct termios *t) +{ + int ret; + + while ((ret = tcgetattr(0, t) == -1) && errno == EINTR) + continue; + return ret; +} + +/* ARGSUSED */ +void +tstpcont(int sig) +{ + int save_errno = errno; + + if (sig == SIGTSTP) { + signal(SIGCONT, tstpcont); + gettty(&ttyedit); + settty(&ttysaved); + } else { + signal(SIGTSTP, tstpcont); + settty(&ttyedit); + } + signal(sig, SIG_DFL); + kill(0, sig); + errno = save_errno; +} + /* * Avoid the echo of ^D by the default code of editline and take * into account skipchars to make ^D work when the cursor is at start of @@ -307,8 +348,10 @@ yywrap(void) } else if (fileindex == sargc) { fileindex++; yyin = stdin; - if (interactive) + if (interactive) { signal(SIGINT, abort_line); + signal(SIGTSTP, tstpcont); + } lineno = 1; filename = "stdin"; return (0); |