[RFT,v2] 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.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v2 - make cmdline_cancel an exposed API
app/test-pmd/cmdline.c | 27 ++++++++++++++-------------
app/test-pmd/testpmd.c | 11 +++++++++++
lib/cmdline/cmdline.h | 10 ++++++++++
lib/cmdline/cmdline_os_unix.c | 5 +++++
lib/cmdline/cmdline_os_windows.c | 14 ++++++++++++++
lib/cmdline/version.map | 3 +++
6 files changed, 57 insertions(+), 13 deletions(-)
Comments
> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, March 14, 2023 5:39 AM
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>
> Subject: [RFT v2] test-pmd: go back to using cmdline_interact
>
> 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.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
Tested-by: Wei Ling <weix.ling@intel.com>
> Subject: [RFT v2] test-pmd: go back to using cmdline_interact
>
> External email: Use caution opening links or attachments
>
>
> 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.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Confirmed that this patch fixes Bug: 1180 on Windows.
Tested-by: Pier Damouny <pdamouny@nvidia.com>
@@ -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)
@@ -60,6 +60,16 @@ int cmdline_poll(struct cmdline *cl);
void cmdline_interact(struct cmdline *cl);
void cmdline_quit(struct cmdline *cl);
+
+/**
+ * This function causes the read() in cmdline_interact to exit.
+ *
+ * @param cl
+ * The command line object.
+ */
+__rte_experimental
+void cmdline_cancel(struct cmdline *cl);
+
#ifdef __cplusplus
}
#endif
@@ -52,3 +52,8 @@ cmdline_vdprintf(int fd, const char *format, va_list op)
{
return vdprintf(fd, format, op);
}
+
+void
+cmdline_cancel(__rte_unused struct cmdline *cl)
+{
+}
@@ -203,3 +203,17 @@ cmdline_vdprintf(int fd, const char *format, va_list op)
return ret;
}
+
+void
+cmdline_cancel(struct cmdline *cl)
+{
+ if (!cl)
+ return;
+
+ /* 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);
+ }
+}
@@ -84,5 +84,8 @@ EXPERIMENTAL {
# added in 22.07
cmdline_parse_check;
+ # added in 23.03
+ cmdline_cancel;
+
local: *;
};