diff --git a/config.h.in b/config.h.in index 95d6afb..ed21f76 100644 --- a/config.h.in +++ b/config.h.in @@ -64,6 +64,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the `tcgetattr' function. */ +#undef HAVE_TCGETATTR + /* Define to 1 if you have the header file. */ #undef HAVE_TERMIOS_H diff --git a/configure b/configure index db408c5..5b2343c 100755 --- a/configure +++ b/configure @@ -4875,7 +4875,8 @@ fi -for ac_func in strchr strdup strrchr + +for ac_func in strchr strdup strrchr tcgetattr do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/configure.ac b/configure.ac index fe51eac..66f1e4b 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,6 @@ AC_PROG_GCC_TRADITIONAL #AC_FUNC_MALLOC #AC_FUNC_REALLOC AC_FUNC_STAT -AC_CHECK_FUNCS([strchr strdup strrchr]) +AC_CHECK_FUNCS([strchr strdup strrchr tcgetattr]) AC_OUTPUT(Makefile src/Makefile include/Makefile man/Makefile examples/Makefile) diff --git a/src/editline.c b/src/editline.c index 3c54436..730714f 100755 --- a/src/editline.c +++ b/src/editline.c @@ -20,6 +20,8 @@ #define META(x) ((x) | 0x80) #define ISMETA(x) ((x) & 0x80) #define UNMETA(x) ((x) & 0x7F) +#define MAPSIZE 33 +#define METAMAPSIZE 17 #if !defined(HIST_SIZE) #define HIST_SIZE 20 #endif /* !defined(HIST_SIZE) */ @@ -63,6 +65,9 @@ int rl_erase; int rl_intr; int rl_kill; int rl_quit; +#if defined(DO_SIGTSTP) +int rl_susp; +#endif /* defined(DO_SIGTSTP) */ STATIC CHAR NIL[] = ""; STATIC CONST CHAR *Input = NIL; @@ -80,8 +85,8 @@ STATIC int Point; STATIC int PushBack; STATIC int Pushed; STATIC int Signal; -FORWARD KEYMAP Map[33]; -FORWARD KEYMAP MetaMap[17]; +FORWARD KEYMAP Map[MAPSIZE]; +FORWARD KEYMAP MetaMap[METAMAPSIZE]; STATIC SIZE_T Length; STATIC SIZE_T ScreenCount; STATIC SIZE_T ScreenSize; @@ -90,18 +95,17 @@ STATIC int TTYwidth; STATIC int TTYrows; /* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */ -int rl_meta_chars = 0; +int rl_meta_chars = 1; /* ** Declarations. */ STATIC CHAR *editinput(); -extern int read(); -extern int write(); #if defined(USE_TERMCAP) extern char *getenv(); extern char *tgetstr(); extern int tgetent(); +extern int tgetnum(); #endif /* defined(USE_TERMCAP) */ /* @@ -119,7 +123,7 @@ TTYflush() STATIC void TTYput(c) - CHAR c; + CONST CHAR c; { Screen[ScreenCount] = c; if (++ScreenCount >= ScreenSize - 1) { @@ -864,12 +868,16 @@ emacs(c) STATUS s; KEYMAP *kp; +#if 0 /* Debian patch removes this to be able to handle 8-bit input */ + /* This test makes it impossible to enter eight-bit characters when + * meta-char mode is enabled. */ OldPoint = Point; if (rl_meta_chars && ISMETA(c)) { Pushed = 1; PushBack = UNMETA(c); return meta(); } +#endif /* Debian patch removal. */ for (kp = Map; kp->Function; kp++) if (kp->Key == c) break; @@ -884,7 +892,7 @@ STATIC STATUS TTYspecial(c) unsigned int c; { - if (ISMETA(c)) + if (rl_meta_chars && ISMETA(c)) return CSdispatch; if (c == rl_erase || c == DEL) @@ -907,6 +915,12 @@ TTYspecial(c) Signal = SIGQUIT; return CSeof; } +#if defined(DO_SIGTSTP) + if (c == rl_susp) { + Signal = SIGTSTP; + return CSsignal; + } +#endif /* defined(DO_SIGTSTP) */ return CSdispatch; } @@ -973,6 +987,32 @@ hist_add(p) H.Pos = H.Size - 1; } +STATIC char * +read_redirected() +{ + int size; + char *p; + char *line; + char *end; + + for (size = MEM_INC, p = line = NEW(char, size), end = p + size; ; p++) { + if (p == end) { + size += MEM_INC; + p = line = realloc(line, size); + end = p + size; + } + if (read(0, p, 1) <= 0) { + /* Ignore "incomplete" lines at EOF, just like we do for a tty. */ + free(line); + return NULL; + } + if (*p == '\n') + break; + } + *p = '\0'; + return line; +} + /* ** For compatibility with FSF readline. */ @@ -995,6 +1035,11 @@ readline(prompt) CHAR *line; int s; + if (!isatty(0)) { + TTYflush(); + return read_redirected(); + } + if (Line == NULL) { Length = MEM_INC; if ((Line = NEW(CHAR, Length)) == NULL) diff --git a/src/editline.h b/src/editline.h index 2afa15a..f0d8847 100755 --- a/src/editline.h +++ b/src/editline.h @@ -67,6 +67,9 @@ extern int rl_erase; extern int rl_intr; extern int rl_kill; extern int rl_quit; +#if defined(DO_SIGTSTP) +extern int rl_susp; +#endif /* defined(DO_SIGTSTP) */ extern char *rl_complete(); extern int rl_list_possib(char *pathname, char ***avp); extern void rl_ttyset(); @@ -81,6 +84,7 @@ extern char *strcat(); extern char *strchr(); extern char *strrchr(); extern char *strcpy(); +extern char *strdup(); extern int strcmp(); extern int strlen(); extern int strncmp(); diff --git a/src/sysunix.c b/src/sysunix.c index b865469..056874e 100755 --- a/src/sysunix.c +++ b/src/sysunix.c @@ -15,19 +15,22 @@ rl_ttyset(Reset) struct termios new; if (Reset == 0) { - (void)tcgetattr(0, &old); + if (tcgetattr(0, &old) < 0) perror("tcgetattr"); rl_erase = old.c_cc[VERASE]; rl_kill = old.c_cc[VKILL]; rl_eof = old.c_cc[VEOF]; rl_intr = old.c_cc[VINTR]; rl_quit = old.c_cc[VQUIT]; +#if defined(DO_SIGTSTP) + rl_susp = old.c_cc[VSUSP]; +#endif /* defined(DO_SIGTSTP) */ new = old; - new.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN); - new.c_iflag &= ~(ICRNL); + new.c_lflag &= ~(ECHO | ICANON | ISIG); + new.c_iflag &= ~(ISTRIP | INPCK); new.c_cc[VMIN] = 1; new.c_cc[VTIME] = 0; - (void)tcsetattr(0, TCSADRAIN, &new); + if (tcsetattr(0, TCSADRAIN, &new) < 0) perror("tcsetattr"); } else (void)tcsetattr(0, TCSADRAIN, &old); @@ -51,11 +54,13 @@ rl_ttyset(Reset) rl_eof = old.c_cc[VEOF]; rl_intr = old.c_cc[VINTR]; rl_quit = old.c_cc[VQUIT]; +#if defined(DO_SIGTSTP) + rl_susp = old.c_cc[VSUSP]; +#endif /* defined(DO_SIGTSTP) */ new = old; - new.c_cc[VINTR] = -1; - new.c_cc[VQUIT] = -1; - new.c_lflag &= ~(ECHO | ICANON); + new.c_lflag &= ~(ECHO | ICANON | ISIG); + new.c_iflag &= ~(ISTRIP | INPCK); new.c_cc[VMIN] = 1; new.c_cc[VTIME] = 0; (void)ioctl(0, TCSETAW, &new); @@ -75,6 +80,9 @@ rl_ttyset(Reset) static struct tchars old_tchars; struct sgttyb new_sgttyb; struct tchars new_tchars; +#if defined(DO_SIGTSTP) + struct ltchars old_ltchars; +#endif /* defined(DO_SIGTSTP) */ if (Reset == 0) { (void)ioctl(0, TIOCGETP, &old_sgttyb); @@ -86,9 +94,17 @@ rl_ttyset(Reset) rl_intr = old_tchars.t_intrc; rl_quit = old_tchars.t_quitc; +#if defined(DO_SIGTSTP) + (void)ioctl(0, TIOCGLTC, &old_ltchars); + rl_susp = old_ltchars.t_suspc; +#endif /* defined(DO_SIGTSTP) */ + new_sgttyb = old_sgttyb; new_sgttyb.sg_flags &= ~ECHO; new_sgttyb.sg_flags |= RAW; +#if defined(PASS8) + new_sgttyb.sg_flags |= PASS8; +#endif /* defined(PASS8) */ (void)ioctl(0, TIOCSETP, &new_sgttyb); new_tchars = old_tchars;