From f7b2ea938d6a2f38f23376119db03d51b65497f8 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Mon, 9 Jun 2008 21:37:01 +0200 Subject: [PATCH] Check for tcgetattr() to enable HAVE_TCGETATTR in sysunix.c this seems to work better on embedded targets running off the initial console. Also, first merge of patches from Debian. This part holds all of the sysunix.c changes and some 8-bit patches and SIGSTP patches in the editline.c file. --- config.h.in | 3 +++ configure | 3 ++- configure.ac | 2 +- src/editline.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------ src/editline.h | 4 ++++ src/sysunix.c | 30 +++++++++++++++++++------ 6 files changed, 85 insertions(+), 16 deletions(-) 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;