summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorotto <otto@openbsd.org>2006-03-18 20:44:43 +0000
committerotto <otto@openbsd.org>2006-03-18 20:44:43 +0000
commitc6ecccdf308aa7d1bce40f0ca41494795c6b346f (patch)
tree6421f1e9e759f3a49e1e2304b654daf7e125949c
parent- limit the amount of data bufferevents are going to consume to something (diff)
downloadwireguard-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.y44
-rw-r--r--usr.bin/bc/extern.h3
-rw-r--r--usr.bin/bc/scan.l19
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);