Fix input handling so $ and # can be typed. This also fixes handling of ^C and ^D during line editing.

The issue with $ and # resulted from incompatible definitions of the CTRL macro between our code and the system headers.
This commit is contained in:
Stephen Heumann 2014-11-19 20:44:25 -06:00
parent d958c364f9
commit 97eb1defae

View File

@ -2349,6 +2349,8 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
#else #else
struct sgttyb initial_settings; struct sgttyb initial_settings;
struct sgttyb new_settings; struct sgttyb new_settings;
struct tchars initial_tchars;
struct tchars new_tchars;
#endif #endif
char read_key_buffer[KEYCODE_BUFFER_SIZE]; char read_key_buffer[KEYCODE_BUFFER_SIZE];
@ -2359,6 +2361,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
|| !(initial_settings.c_lflag & ECHO) || !(initial_settings.c_lflag & ECHO)
#else #else
if (ioctl(STDIN_FILENO, TIOCGETP, &initial_settings) < 0 if (ioctl(STDIN_FILENO, TIOCGETP, &initial_settings) < 0
|| ioctl(STDIN_FILENO, TIOCGETC, &initial_tchars) < 0
|| !(initial_settings.sg_flags & ECHO) || !(initial_settings.sg_flags & ECHO)
#endif #endif
) { ) {
@ -2421,6 +2424,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
new_settings.sg_flags |= CBREAK; new_settings.sg_flags |= CBREAK;
new_settings.sg_flags &= ~(CRMOD|ECHO); new_settings.sg_flags &= ~(CRMOD|ECHO);
ioctl(STDIN_FILENO, TIOCSETN, &new_settings); ioctl(STDIN_FILENO, TIOCSETN, &new_settings);
/* Contrary to documentation, tchars aren't fully disabled in CBREAK mode,
* so do it explicitly. Maybe other characters should be disabled too? */
new_tchars = initial_tchars;
new_tchars.t_intrc = (char)-1;
ioctl(STDIN_FILENO, TIOCSETC, &new_tchars);
#endif #endif
#if ENABLE_USERNAME_OR_HOMEDIR #if ENABLE_USERNAME_OR_HOMEDIR
@ -2798,7 +2806,9 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
if (initial_settings.c_cc[VINTR] != 0 if (initial_settings.c_cc[VINTR] != 0
&& ic_raw == initial_settings.c_cc[VINTR] && ic_raw == initial_settings.c_cc[VINTR]
#else #else
if (ic_raw == CINTR if (initial_tchars.t_intrc != (char)-1
&& initial_tchars.t_intrc != 0
&& ic_raw == initial_tchars.t_intrc
#endif #endif
) { ) {
/* Ctrl-C (usually) - stop gathering input */ /* Ctrl-C (usually) - stop gathering input */
@ -2811,7 +2821,9 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
if (initial_settings.c_cc[VEOF] != 0 if (initial_settings.c_cc[VEOF] != 0
&& ic_raw == initial_settings.c_cc[VEOF] && ic_raw == initial_settings.c_cc[VEOF]
#else #else
if (ic_raw == CEOF if (initial_tchars.t_eofc != (char)-1
&& initial_tchars.t_eofc != 0
&& ic_raw == initial_tchars.t_eofc
#endif #endif
) { ) {
/* Ctrl-D (usually) - delete one character, /* Ctrl-D (usually) - delete one character,
@ -2930,6 +2942,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
tcsetattr_stdin_TCSANOW(&initial_settings); tcsetattr_stdin_TCSANOW(&initial_settings);
#else #else
ioctl(STDIN_FILENO, TIOCSETN, &initial_settings); ioctl(STDIN_FILENO, TIOCSETN, &initial_settings);
ioctl(STDIN_FILENO, TIOCSETC, &initial_tchars);
#endif #endif
/* restore SIGWINCH handler */ /* restore SIGWINCH handler */
signal(SIGWINCH, previous_SIGWINCH_handler); signal(SIGWINCH, previous_SIGWINCH_handler);