[RFT] test-pmd: go back to using cmdline_interact
Checks
Commit Message
The cmdline library poll function is broken on Windows
and was never tested, don't use it.
Instead, use sigaction() to cancel read character on Unix OS's
and a new helper to cancel I/O on Windows.
Fixes: 0fd1386c30c3 ("app/testpmd: cleanup cleanly from signal")
Bugzilla ID: 1180
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test-pmd/cmdline.c | 27 ++++++++++++++-------------
app/test-pmd/testpmd.c | 11 +++++++++++
lib/cmdline/cmdline.c | 16 ++++++++++++++++
lib/cmdline/cmdline.h | 1 +
4 files changed, 42 insertions(+), 13 deletions(-)
@@ -66,6 +66,7 @@
#include "cmdline_tm.h"
#include "bpf_cmd.h"
+static struct cmdline *testpmd_cl;
static cmdline_parse_ctx_t *main_ctx;
static TAILQ_HEAD(, testpmd_driver_commands) driver_commands_head =
TAILQ_HEAD_INITIALIZER(driver_commands_head);
@@ -13028,26 +13029,26 @@ cmdline_read_from_file(const char *filename)
printf("Read CLI commands from %s\n", filename);
}
+void
+prompt_exit(void)
+{
+ cmdline_cancel(testpmd_cl);
+ cmdline_quit(testpmd_cl);
+}
+
/* prompt function, called from main on MAIN lcore */
void
prompt(void)
{
- struct cmdline *cl;
-
- cl = cmdline_stdin_new(main_ctx, "testpmd> ");
- if (cl == NULL)
+ testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> ");
+ if (testpmd_cl == NULL) {
+ fprintf(stderr,
+ "Failed to create stdin based cmdline context\n");
return;
-
- /* loop until signal or quit command */
- while (f_quit == 0 && cl_quit == 0) {
- int status = cmdline_poll(cl);
-
- if (status < 0 || status == RDLINE_EXITED)
- break;
}
- cmdline_quit(cl);
- cmdline_stdin_exit(cl);
+ cmdline_interact(testpmd_cl);
+ cmdline_stdin_exit(testpmd_cl);
}
void
@@ -4469,6 +4469,7 @@ static void
signal_handler(int signum __rte_unused)
{
f_quit = 1;
+ prompt_exit();
}
int
@@ -4479,8 +4480,18 @@ main(int argc, char** argv)
uint16_t count;
int ret;
+#ifdef RTE_EXEC_ENV_WINDOWS
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
+#else
+ /* Want read() not to be restarted on signal */
+ struct sigaction action = {
+ .sa_handler = signal_handler,
+ };
+
+ sigaction(SIGINT, &action, NULL);
+ sigaction(SIGTERM, &action, NULL);
+#endif
testpmd_logtype = rte_log_register("testpmd");
if (testpmd_logtype < 0)
@@ -176,6 +176,22 @@ cmdline_quit(struct cmdline *cl)
rdline_quit(&cl->rdl);
}
+void
+cmdline_cancel(struct cmdline *cl)
+{
+ if (!cl)
+ return;
+
+#ifdef RTE_EXEC_ENV_WINDOWS
+ /* force the outstanding read on console to exit */
+ if (cl->oldterm.is_console_input) {
+ HANDLE handle = (HANDLE)_get_osfhandle(cl->s_in);
+
+ CancelIoEx(handle, NULL);
+ }
+#endif
+}
+
int
cmdline_poll(struct cmdline *cl)
{
@@ -58,6 +58,7 @@ cmdline_get_rdline(struct cmdline *cl);
int cmdline_poll(struct cmdline *cl);
void cmdline_interact(struct cmdline *cl);
+void cmdline_cancel(struct cmdline *cl);
void cmdline_quit(struct cmdline *cl);
#ifdef __cplusplus