summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2021-01-06 12:28:01 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2021-01-06 14:09:21 +0100
commitbc2d5f79c2ea00250458685266b59f869d33141b (patch)
tree4968acb09b85cd73d3a7faf1132ae88eeb4c3b01
parent9420423900a2e4312c570632f7531483dea604a2 (diff)
cli: use plain readline() interface with libedit
Instead of the alternate interface [1]. I spent a bit of time debugging an issue with libedit support 9420423900a2 ("cli: add libedit support") that broke tests/shell. This is the reproducer: # nft -i << EOF list ruleset EOF which makes rl_callback_read_char() loop forever on read() as shown by strace. The rl_line_buffer variable does not accumulate the typed characters as it should when redirecting the standard input for some reason. Given our interactive interface is fairly simple at this stage, switch to use the readline() interface instead of rl_callback_read_char(). [1] https://docs.freebsd.org/info/readline/readline.info.Alternate_Interface.html Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/cli.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/cli.c b/src/cli.c
index 45811595..4845e5cf 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -154,6 +154,16 @@ static void cli_complete(char *line)
free(line);
}
+void cli_exit(void)
+{
+ rl_callback_handler_remove();
+ rl_deprep_terminal();
+ write_history(histfile);
+}
+#endif
+
+#if defined(HAVE_LIBREADLINE)
+
static char **cli_completion(const char *text, int start, int end)
{
return NULL;
@@ -179,11 +189,32 @@ int cli_init(struct nft_ctx *nft)
return 0;
}
-void cli_exit(void)
+#elif defined(HAVE_LIBEDIT)
+
+int cli_init(struct nft_ctx *nft)
{
- rl_callback_handler_remove();
- rl_deprep_terminal();
- write_history(histfile);
+ char *line;
+
+ cli_nft = nft;
+ rl_readline_name = (char *)"nft";
+ rl_instream = stdin;
+ rl_outstream = stdout;
+
+ init_histfile();
+
+ read_history(histfile);
+ history_set_pos(history_length);
+
+ rl_set_prompt(CMDLINE_PROMPT);
+ while ((line = readline(rl_prompt)) != NULL) {
+ line = cli_append_multiline(line);
+ if (!line)
+ continue;
+
+ cli_complete(line);
+ }
+
+ return 0;
}
#else /* HAVE_LINENOISE */