Hi,
if you are using a shell in cooked mode (e.g. csh) ^Z did not reset
the terminal to the proper state.
This should fix that. It's a pity libedit only has a all or nothing
function for signal handling...
Please test (with all shells!) and review, I want this to make
release,
-Otto
Index: bc.y
===================================================================
RCS file: /cvs/src/usr.bin/bc/bc.y,v
retrieving revision 1.38
diff -u -p -r1.38 bc.y
--- bc.y 8 Jul 2011 23:29:46 -0000 1.38
+++ bc.y 28 Jul 2011 10:05:38 -0000
@@ -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);
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.bin/bc/extern.h,v
retrieving revision 1.8
diff -u -p -r1.8 extern.h
--- extern.h 3 Jun 2011 06:10:33 -0000 1.8
+++ extern.h 28 Jul 2011 10:05:38 -0000
@@ -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;
Index: scan.l
===================================================================
RCS file: /cvs/src/usr.bin/bc/scan.l,v
retrieving revision 1.26
diff -u -p -r1.26 scan.l
--- scan.l 3 Jun 2011 06:10:33 -0000 1.26
+++ scan.l 28 Jul 2011 10:05:38 -0000
@@ -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,46 @@ 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)
+{
+ sigset_t nset, oset;
+ 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 +349,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);