Skip to content

Commit

Permalink
app/testpmd: fix interactive mode on Windows
Browse files Browse the repository at this point in the history
[ upstream commit f1d0993 ]

The cmdline_poll() function is broken and was not fully tested,
go back to using cmdline_interact().

Instead, use sigaction() to cancel read character on Unix OS's
and a new helper to cancel I/O on Windows.

Bugzilla ID: 1180
Fixes: 0fd1386 ("app/testpmd: cleanup cleanly from signal")

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
  • Loading branch information
shemminger authored and kevintraynor committed Sep 4, 2024
1 parent 37408e6 commit 06a1fb9
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 14 deletions.
27 changes: 14 additions & 13 deletions app/test-pmd/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@

static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue);

static struct cmdline *testpmd_cl;

/* *** Help command with introduction. *** */
struct cmd_help_brief_result {
cmdline_fixed_string_t help;
Expand Down Expand Up @@ -18039,30 +18041,29 @@ cmdline_read_from_file(const char *filename)
printf("Read CLI commands from %s\n", filename);
}

void
prompt_exit(void)
{
cmdline_quit(testpmd_cl);
}

/* prompt function, called from main on MAIN lcore */
void
prompt(void)
{
struct cmdline *cl;

/* initialize non-constant commands */
cmd_set_fwd_mode_init();
cmd_set_fwd_retry_mode_init();

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);
}

static void
Expand Down
11 changes: 11 additions & 0 deletions app/test-pmd/testpmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -4321,6 +4321,7 @@ static void
signal_handler(int signum __rte_unused)
{
f_quit = 1;
prompt_exit();
}

int
Expand All @@ -4331,8 +4332,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)
Expand Down
1 change: 1 addition & 0 deletions lib/cmdline/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ cmdline_quit(struct cmdline *cl)
{
if (!cl)
return;
cmdline_cancel(cl);
rdline_quit(&cl->rdl);
}

Expand Down
6 changes: 6 additions & 0 deletions lib/cmdline/cmdline_os_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,9 @@ cmdline_vdprintf(int fd, const char *format, va_list op)
{
return vdprintf(fd, format, op);
}

/* This function is not needed on Linux, instead use sigaction() */
void
cmdline_cancel(__rte_unused struct cmdline *cl)
{
}
14 changes: 14 additions & 0 deletions lib/cmdline/cmdline_os_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
5 changes: 4 additions & 1 deletion lib/cmdline/cmdline_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#define RDLINE_HISTORY_MAX_LINE 64

struct rdline {
enum rdline_status status;
volatile enum rdline_status status;
/* rdline bufs */
struct cirbuf left;
struct cirbuf right;
Expand Down Expand Up @@ -90,6 +90,9 @@ int cmdline_poll_char(struct cmdline *cl);
/* Read one character from input. */
ssize_t cmdline_read_char(struct cmdline *cl, char *c);

/* Force current cmdline read to unblock. */
void cmdline_cancel(struct cmdline *cl);

/* vdprintf(3) */
__rte_format_printf(2, 0)
int cmdline_vdprintf(int fd, const char *format, va_list op);
Expand Down

0 comments on commit 06a1fb9

Please sign in to comment.