summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2011-07-22 00:26:56 +0000
committerGreg Hudson <ghudson@mit.edu>2011-07-22 00:26:56 +0000
commited8bc7b5e8ba1f72a0ae083b3005fbe18718544b (patch)
treefc6cd75398fa2adb8ce685a50fcf56d5ee193e43 /src/util
parent0d1a70cd014579f6134d73fc073dc090f574e1c8 (diff)
downloadkrb5-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.in2
-rw-r--r--src/util/ss/listen.c54
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')