diff options
author | 2006-03-18 20:44:43 +0000 | |
---|---|---|
committer | 2006-03-18 20:44:43 +0000 | |
commit | c6ecccdf308aa7d1bce40f0ca41494795c6b346f (patch) | |
tree | 6421f1e9e759f3a49e1e2304b654daf7e125949c | |
parent | - limit the amount of data bufferevents are going to consume to something (diff) | |
download | wireguard-openbsd-c6ecccdf308aa7d1bce40f0ca41494795c6b346f.tar.xz wireguard-openbsd-c6ecccdf308aa7d1bce40f0ca41494795c6b346f.zip |
Interchange roles: bc becomes parent, dc child. This leads to saner
tty handling (try bc | grep foo followed by ^C, as noted by deraadt@).
To make it all work, bc now waits for dc to exit after giving it a
quit command. ok deraadt@ jaredy@
-rw-r--r-- | usr.bin/bc/bc.y | 44 | ||||
-rw-r--r-- | usr.bin/bc/extern.h | 3 | ||||
-rw-r--r-- | usr.bin/bc/scan.l | 19 |
3 files changed, 48 insertions, 18 deletions
diff --git a/usr.bin/bc/bc.y b/usr.bin/bc/bc.y index 64d098d0eba..ae607d75952 100644 --- a/usr.bin/bc/bc.y +++ b/usr.bin/bc/bc.y @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: bc.y,v 1.27 2005/09/18 19:29:41 otto Exp $ */ +/* $OpenBSD: bc.y,v 1.28 2006/03/18 20:44:43 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> @@ -31,11 +31,15 @@ */ #ifndef lint -static const char rcsid[] = "$OpenBSD: bc.y,v 1.27 2005/09/18 19:29:41 otto Exp $"; +static const char rcsid[] = "$OpenBSD: bc.y,v 1.28 2006/03/18 20:44:43 otto Exp $"; #endif /* not lint */ +#include <sys/types.h> +#include <sys/wait.h> + #include <ctype.h> #include <err.h> +#include <errno.h> #include <limits.h> #include <search.h> #include <signal.h> @@ -102,6 +106,7 @@ static bool st_has_continue; static char str_table[UCHAR_MAX][2]; static bool do_fork = true; static u_short var_count; +static pid_t dc; extern char *__progname; @@ -277,9 +282,12 @@ statement : expression } | QUIT { + sigset_t mask; + putchar('q'); fflush(stdout); - exit(0); + sigprocmask(SIG_BLOCK, NULL, &mask); + sigsuspend(&mask); } | RETURN return_expression { @@ -1045,6 +1053,27 @@ escape(const char *str) return ret; } +/* ARGSUSED */ +void +sigchld(int signo) +{ + pid_t pid; + int status; + + for (;;) { + pid = waitpid(dc, &status, WCONTINUED); + if (pid == -1) { + if (errno == EINTR) + continue; + _exit(0); + } + if (WIFEXITED(status) || WIFSIGNALED(status)) + _exit(0); + else + break; + } +} + int main(int argc, char *argv[]) { @@ -1085,16 +1114,18 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; + interactive = isatty(STDIN_FILENO); for (i = 0; i < argc; i++) sargv[sargc++] = argv[i]; if (do_fork) { if (pipe(p) == -1) err(1, "cannot create pipe"); - ret = fork(); - if (ret == -1) + dc = fork(); + if (dc == -1) err(1, "cannot fork"); - else if (ret == 0) { + else if (dc != 0) { + signal(SIGCHLD, sigchld); close(STDOUT_FILENO); dup(p[1]); close(p[0]); @@ -1108,7 +1139,6 @@ main(int argc, char *argv[]) err(1, "cannot find dc"); } } - signal(SIGINT, abort_line); yywrap(); return yyparse(); } diff --git a/usr.bin/bc/extern.h b/usr.bin/bc/extern.h index fc2f5ee5b71..9ca6a175ab4 100644 --- a/usr.bin/bc/extern.h +++ b/usr.bin/bc/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.5 2004/10/19 07:36:51 otto Exp $ */ +/* $OpenBSD: extern.h,v 1.6 2006/03/18 20:44:43 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> @@ -36,3 +36,4 @@ extern int sargc; extern char **sargv; extern char *filename; extern char *cmdexpr; +bool interactive; diff --git a/usr.bin/bc/scan.l b/usr.bin/bc/scan.l index 5c557bff79c..fee5aa990b8 100644 --- a/usr.bin/bc/scan.l +++ b/usr.bin/bc/scan.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scan.l,v 1.20 2006/01/24 19:38:44 otto Exp $ */ +/* $OpenBSD: scan.l,v 1.21 2006/03/18 20:44:43 otto Exp $ */ /* * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> @@ -18,7 +18,7 @@ */ #ifndef lint -static const char rcsid[] = "$OpenBSD: scan.l,v 1.20 2006/01/24 19:38:44 otto Exp $"; +static const char rcsid[] = "$OpenBSD: scan.l,v 1.21 2006/03/18 20:44:43 otto Exp $"; #endif /* not lint */ #include <err.h> @@ -32,11 +32,11 @@ static const char rcsid[] = "$OpenBSD: scan.l,v 1.20 2006/01/24 19:38:44 otto Ex #include "y.tab.h" int lineno; +bool interactive; static char *strbuf = NULL; static size_t strbuf_sz = 1; static bool dot_seen; -static volatile sig_atomic_t interactive = 0; static void init_strbuf(void); static void add_str(const char *); @@ -232,12 +232,10 @@ abort_line(int sig) const char str[] = "[\n]P\n"; int save_errno; - if (interactive) { - save_errno = errno; - YY_FLUSH_BUFFER; /* XXX signal race? */ - write(STDOUT_FILENO, str, sizeof(str) - 1); - errno = save_errno; - } + save_errno = errno; + YY_FLUSH_BUFFER; /* XXX signal race? */ + write(STDOUT_FILENO, str, sizeof(str) - 1); + errno = save_errno; } int @@ -277,7 +275,8 @@ yywrap(void) } else if (fileindex == sargc) { fileindex++; yyin = stdin; - interactive = isatty(fileno(yyin)); + if (interactive) + signal(SIGINT, abort_line); lineno = 1; filename = "stdin"; return (0); |