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);

Reply via email to