From 6a8556733ab37fb228eb108743854f299f982021 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Mon, 6 Apr 2015 14:45:07 +0200 Subject: [PATCH] Add support for disabling default SIGINT and EOF behavior. This patch adds support for `--disable-eof` and `--disable-sigint` to the Editline configure script. With either of these two switches the `tty_special()` function bypasses the special TTY checks making it possible to bind Ctrl-C and Ctrl-D to custom callbacks. This can be useful if you want to emulate a Cisco style CLI rather than traditional UNIX. The user can of course also redefine the VINTR and VEOF special terminal control characters, but these configure script switches may be easier to use for some. Also, the CLI example has been updated to bind Ctrl-D, Ctrl-C and Ctrl-Z for testing purposes. Signed-off-by: Joachim Nilsson --- config.h.in | 6 ++++++ configure | 26 +++++++++++++++++++++++++- configure.ac | 10 +++++++++- examples/cli.c | 21 +++++++++++++++++++++ src/editline.c | 4 ++++ 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/config.h.in b/config.h.in index 4d91e03..44c95ba 100644 --- a/config.h.in +++ b/config.h.in @@ -12,6 +12,12 @@ /* Define to enable the default completion handler. */ #undef CONFIG_DEFAULT_COMPLETE +/* Define to enable EOF (Ctrl-C) key. */ +#undef CONFIG_EOF + +/* Define to enable SIGINT (Ctrl-C) key. */ +#undef CONFIG_SIGINT + /* Define to enable SIGSTOP (Ctrl-Z) key. */ #undef CONFIG_SIGSTOP diff --git a/configure b/configure index bc42575..96640ac 100755 --- a/configure +++ b/configure @@ -764,6 +764,8 @@ enable_libtool_lock enable_unique_history enable_default_complete enable_arrow_keys +enable_eof +enable_sigint enable_sigstop enable_terminal_bell enable_termcap @@ -1410,7 +1412,9 @@ Optional Features: --disable-default-complete Disable default (filename) completion handler. --disable-arrow-keys Disable ANSI arrow keys. - --enable-sigstop Enable SIGSTOP key. + --disable-eof Disable default EOF (Ctrl-D) behavior. + --disable-sigint Disable default SIGINT (Ctrl-C) behavior. + --enable-sigstop Enable SIGSTOP (Ctrl-Z) behavior. --enable-terminal-bell Enable terminal bell on completion. --enable-termcap Use termcap library to query terminal size. @@ -12043,6 +12047,26 @@ $as_echo "#define CONFIG_ANSI_ARROWS 1" >>confdefs.h fi +# Check whether --enable-eof was given. +if test "${enable_eof+set}" = set; then : + enableval=$enable_eof; +else + +$as_echo "#define CONFIG_EOF 1" >>confdefs.h + +fi + + +# Check whether --enable-sigint was given. +if test "${enable_sigint+set}" = set; then : + enableval=$enable_sigint; +else + +$as_echo "#define CONFIG_SIGINT 1" >>confdefs.h + +fi + + # Check whether --enable-sigstop was given. if test "${enable_sigstop+set}" = set; then : enableval=$enable_sigstop; diff --git a/configure.ac b/configure.ac index ba98aab..1f5dda6 100644 --- a/configure.ac +++ b/configure.ac @@ -64,8 +64,16 @@ AC_ARG_ENABLE(arrow-keys, [AS_HELP_STRING([--disable-arrow-keys], [Disable ANSI arrow keys.])], , AC_DEFINE(CONFIG_ANSI_ARROWS, 1, [Define to include ANSI arrow keys support.])) +AC_ARG_ENABLE(eof, + [AS_HELP_STRING([--disable-eof], [Disable default EOF (Ctrl-D) behavior.])], + , AC_DEFINE([CONFIG_EOF], 1, [Define to enable EOF (Ctrl-C) key.])) + +AC_ARG_ENABLE(sigint, + [AS_HELP_STRING([--disable-sigint], [Disable default SIGINT (Ctrl-C) behavior.])], + , AC_DEFINE([CONFIG_SIGINT], 1, [Define to enable SIGINT (Ctrl-C) key.])) + AC_ARG_ENABLE(sigstop, - [AS_HELP_STRING([--enable-sigstop], [Enable SIGSTOP key.])], + [AS_HELP_STRING([--enable-sigstop], [Enable SIGSTOP (Ctrl-Z) behavior.])], AC_DEFINE([CONFIG_SIGSTOP], 1, [Define to enable SIGSTOP (Ctrl-Z) key.])) AC_ARG_ENABLE(terminal-bell, diff --git a/examples/cli.c b/examples/cli.c index 105fb79..7878c47 100644 --- a/examples/cli.c +++ b/examples/cli.c @@ -102,6 +102,24 @@ el_status_t list_possible(void) return el_ring_bell(); } +el_status_t do_break(void) +{ + puts("Breakout!"); + return CSeof; +} + +el_status_t do_exit(void) +{ + puts("Bye bye!"); + return CSeof; +} + +el_status_t do_suspend(void) +{ + puts("Abort!"); + return CSstay; +} + int main(int ac __attribute__ ((unused)), char *av[] __attribute__ ((unused))) { char *line; @@ -111,6 +129,9 @@ int main(int ac __attribute__ ((unused)), char *av[] __attribute__ ((unused))) rl_set_complete_func(&my_rl_complete); rl_set_list_possib_func(&my_rl_list_possib); el_bind_key('?', list_possible); + el_bind_key(CTL('C'), do_break); + el_bind_key(CTL('D'), do_exit); + el_bind_key(CTL('Z'), do_suspend); read_history(HISTORY); while ((line = readline(prompt)) != NULL) { diff --git a/src/editline.c b/src/editline.c index df42b05..1805f34 100644 --- a/src/editline.c +++ b/src/editline.c @@ -924,10 +924,12 @@ static el_status_t emacs(int c) static el_status_t tty_special(int c) { +#ifdef CONFIG_SIGINT if (c == rl_intr) { el_intr_pending = SIGINT; return CSsignal; } +#endif if (c == rl_quit) { el_intr_pending = SIGQUIT; return CSeof; @@ -953,8 +955,10 @@ static el_status_t tty_special(int c) return kill_line(); } +#ifdef CONFIG_EOF if (c == rl_eof && rl_point == 0 && rl_end == 0) return CSeof; +#endif return CSdispatch; }