diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2011-08-03 08:48:20 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2011-08-03 08:48:20 +0000 |
commit | e55ab35365dcfbded607c1343250e012364300c1 (patch) | |
tree | ea376906d73486df5160062d5b33067b0b55c9b0 /usr.bin/bc | |
parent | 463b9cfa17b8ead66a88d09f608b50ee1a7efe61 (diff) |
save/restore tty state on SIGTSTP/SIGCONT. ok deraadt@ nicm@
Diffstat (limited to 'usr.bin/bc')
-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); |