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