diff options
| author | Greg Hudson <ghudson@mit.edu> | 2011-07-22 00:26:56 +0000 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2011-07-22 00:26:56 +0000 |
| commit | ed8bc7b5e8ba1f72a0ae083b3005fbe18718544b (patch) | |
| tree | fc6cd75398fa2adb8ce685a50fcf56d5ee193e43 /src/util | |
| parent | 0d1a70cd014579f6134d73fc073dc090f574e1c8 (diff) | |
| download | krb5-ed8bc7b5e8ba1f72a0ae083b3005fbe18718544b.tar.gz krb5-ed8bc7b5e8ba1f72a0ae083b3005fbe18718544b.tar.xz krb5-ed8bc7b5e8ba1f72a0ae083b3005fbe18718544b.zip | |
Add libedit/readline support to ss
By default, look for libedit (using pkg-config) and use it in libss.
Alternatively, the builder can explicitly ask for GNU Readline, but
using it will break the dejagnu test suite and will also add a GPL
dependency to libss and the programs using it.
ticket: 6931
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25035 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/util')
| -rw-r--r-- | src/util/ss/Makefile.in | 2 | ||||
| -rw-r--r-- | src/util/ss/listen.c | 54 |
2 files changed, 36 insertions, 20 deletions
diff --git a/src/util/ss/Makefile.in b/src/util/ss/Makefile.in index 3f6fd84f9..48f022925 100644 --- a/src/util/ss/Makefile.in +++ b/src/util/ss/Makefile.in @@ -26,7 +26,7 @@ install-unix:: install-libs # hard coded ../et is so com_err.h works # CFLAGS= -g # CPPFLAGS= -I${INCDIR} -I. -I.. -I../et -LOCALINCLUDES= -I. -I$(srcdir)/ +LOCALINCLUDES= -I. -I$(srcdir)/ $(RL_CFLAGS) # with ss_err.o first, ss_err.h should get rebuilt first too. should not # be relying on this, though. diff --git a/src/util/ss/listen.c b/src/util/ss/listen.c index f7be47b13..10e04654a 100644 --- a/src/util/ss/listen.c +++ b/src/util/ss/listen.c @@ -14,20 +14,43 @@ #include <termios.h> #include <sys/param.h> +#if defined(HAVE_LIBEDIT) +#include <editline/readline.h> +#include <editline/history.h> +#elif defined(HAVE_READLINE) +#include <readline/readline.h> +#include <readline/history.h> +#else +#define NO_READLINE +#endif + static ss_data *current_info; static jmp_buf listen_jmpb; -static RETSIGTYPE print_prompt() +#ifdef NO_READLINE +/* Dumb replacement for readline when we don't have support for a real one. */ +static char *readline(const char *prompt) { struct termios termbuf; + char input[BUFSIZ]; if (tcgetattr(STDIN_FILENO, &termbuf) == 0) { termbuf.c_lflag |= ICANON|ISIG|ECHO; tcsetattr(STDIN_FILENO, TCSANOW, &termbuf); } - (void) fputs(current_info->prompt, stdout); - (void) fflush(stdout); + printf("%s", prompt); + fflush(stdout); + if (fgets(input, BUFSIZ, stdin) == NULL) + return NULL; + input[strcspn(input, "\r\n")] = '\0'; + return strdup(input); +} + +/* No-op replacement for add_history() when we have no readline support. */ +static void add_history(const char *line) +{ } +#endif static RETSIGTYPE listen_int_handler(signo) int signo; @@ -41,9 +64,7 @@ int ss_listen (sci_idx) { register char *cp; register ss_data *info; - char input[BUFSIZ]; - char buffer[BUFSIZ]; - char *volatile end = buffer; + char *input; int code; jmp_buf old_jmpb; ss_data *old_info = current_info; @@ -88,8 +109,6 @@ int ss_listen (sci_idx) (void) sigsetmask(mask); #endif while(!info->abort) { - print_prompt(); - *end = '\0'; #ifdef POSIX_SIGNALS nsig.sa_handler = listen_int_handler; /* fgets is not signal-safe */ osig = csig; @@ -98,29 +117,26 @@ int ss_listen (sci_idx) csig = osig; #else old_sig_cont = sig_cont; - sig_cont = signal(SIGCONT, print_prompt); - if (sig_cont == print_prompt) + sig_cont = signal(SIGCONT, listen_int_handler); + if (sig_cont == listen_int_handler) sig_cont = old_sig_cont; #endif - if (fgets(input, BUFSIZ, stdin) != input) { + + input = readline(current_info->prompt); + if (input == NULL) { code = SS_ET_EOF; goto egress; } - cp = strchr(input, '\n'); - if (cp) { - *cp = '\0'; - if (cp == input) - continue; - } + add_history(input); + #ifdef POSIX_SIGNALS sigaction(SIGCONT, &csig, (struct sigaction *)0); #else (void) signal(SIGCONT, sig_cont); #endif - for (end = input; *end; end++) - ; code = ss_execute_line (sci_idx, input); + free(input); if (code == SS_ET_COMMAND_NOT_FOUND) { register char *c = input; while (*c == ' ' || *c == '\t') |
