* [PATCH] app/testpmd: allow multiple cmdline-file parameters
@ 2025-07-04 14:05 Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 0/3] improve cmdline file handling in testpmd Bruce Richardson
0 siblings, 1 reply; 5+ messages in thread
From: Bruce Richardson @ 2025-07-04 14:05 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson
While testpmd allows a set of pre-prepared commands to be passed into it
at startup via the "cmdline-file" (and cmdline-file-noecho) parameters,
this is currently limited to a single file. By extending this support
to allow the parameter to be passed multiple (up to 16) times, we enable
users to have a library of pre-canned cmdline files and pass multiple of
these in to the same run, e.g. have one cmdline file per NIC feature and
enable multiple features by passing in multiple filenames.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
app/test-pmd/cmdline.c | 11 ++++++++---
app/test-pmd/parameters.c | 15 +++++++++++----
app/test-pmd/testpmd.c | 12 +++++++++---
app/test-pmd/testpmd.h | 8 ++++++--
4 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 7b4e27eddf..ad4094fa29 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -11646,7 +11646,9 @@ cmd_load_from_file_parsed(
{
struct cmd_cmdfile_result *res = parsed_result;
- cmdline_read_from_file(res->filename);
+ if (cmdline_read_from_file(res->filename) != 0) {
+ fprintf(stderr, "Failed to load commands from file: %s\n", res->filename);
+ }
}
static cmdline_parse_inst_t cmd_load_from_file = {
@@ -14151,11 +14153,12 @@ init_cmdline(void)
}
/* read cmdline commands from file */
-void
+int
cmdline_read_from_file(const char *filename)
{
struct cmdline *cl;
int fd = -1;
+ int ret = 0;
/* cmdline_file_new does not produce any output
* so when echoing is requested we open filename directly
@@ -14168,7 +14171,7 @@ cmdline_read_from_file(const char *filename)
if (fd < 0) {
fprintf(stderr, "Failed to open file %s: %s\n",
filename, strerror(errno));
- return;
+ return -1;
}
cl = cmdline_new(main_ctx, "testpmd> ", fd, STDOUT_FILENO);
@@ -14177,6 +14180,7 @@ cmdline_read_from_file(const char *filename)
fprintf(stderr,
"Failed to create file based cmdline context: %s\n",
filename);
+ ret = -1;
goto end;
}
@@ -14190,6 +14194,7 @@ cmdline_read_from_file(const char *filename)
end:
if (fd >= 0)
close(fd);
+ return ret;
}
void
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 1132972913..64c16b4f36 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -963,10 +963,17 @@ launch_args_parse(int argc, char** argv)
echo_cmdline_file = true;
/* fall-through */
case TESTPMD_OPT_CMDLINE_FILE_NOECHO_NUM:
- printf("CLI commands to be read from %s\n",
- optarg);
- strlcpy(cmdline_filename, optarg,
- sizeof(cmdline_filename));
+ if (cmdline_file_count >= RTE_DIM(cmdline_filenames)) {
+ fprintf(stderr, "Too many cmdline files specified (maximum %zu)\n",
+ RTE_DIM(cmdline_filenames));
+ exit(EXIT_FAILURE);
+ }
+ printf("CLI commands to be read from %s\n", optarg);
+ strlcpy(cmdline_filenames[cmdline_file_count], optarg,
+ sizeof(cmdline_filenames[cmdline_file_count]));
+ cmdline_file_count++;
+ /* reset flag for next time */
+ echo_cmdline_file = false;
break;
case TESTPMD_OPT_TX_FIRST_NUM:
printf("Ports to start sending a burst of "
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index bb88555328..3f82c1018d 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -105,7 +105,8 @@ int testpmd_logtype; /**< Log type for testpmd logs */
uint8_t interactive = 0;
uint8_t auto_start = 0;
uint8_t tx_first;
-char cmdline_filename[PATH_MAX] = {0};
+char cmdline_filenames[MAX_CMDLINE_FILENAMES][PATH_MAX] = {0};
+unsigned int cmdline_file_count;
bool echo_cmdline_file;
/*
@@ -4508,8 +4509,13 @@ main(int argc, char** argv)
rte_exit(EXIT_FAILURE,
"Could not initialise cmdline context.\n");
- if (strlen(cmdline_filename) != 0)
- cmdline_read_from_file(cmdline_filename);
+ for (unsigned int i = 0; i < cmdline_file_count; i++) {
+ if (cmdline_read_from_file(cmdline_filenames[i]) != 0) {
+ fprintf(stderr, "Failed to process cmdline file: %s\n",
+ cmdline_filenames[i]);
+ break;
+ }
+ }
if (interactive == 1) {
if (auto_start) {
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index e629edaa02..9525a04626 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -36,6 +36,9 @@
extern uint8_t cl_quit;
extern volatile uint8_t f_quit;
+/* Max number of cmdline files we can take on testpmd cmdline */
+#define MAX_CMDLINE_FILENAMES 16
+
/*
* It is used to allocate the memory for hash key.
* The hash key size is NIC dependent.
@@ -509,7 +512,8 @@ extern int testpmd_logtype; /**< Log type for testpmd logs */
extern uint8_t interactive;
extern uint8_t auto_start;
extern uint8_t tx_first;
-extern char cmdline_filename[PATH_MAX]; /**< offline commands file */
+extern char cmdline_filenames[MAX_CMDLINE_FILENAMES][PATH_MAX]; /**< offline commands files */
+extern unsigned int cmdline_file_count; /**< number of cmdline files */
extern bool echo_cmdline_file; /** unset if cmdline-file-noecho is used */
extern uint8_t numa_support; /**< set by "--numa" parameter */
extern uint16_t port_topology; /**< set by "--port-topology" parameter */
@@ -928,7 +932,7 @@ unsigned int parse_hdrs_list(const char *str, const char *item_name,
unsigned int *parsed_items);
void launch_args_parse(int argc, char** argv);
void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue);
-void cmdline_read_from_file(const char *filename);
+int cmdline_read_from_file(const char *filename);
int init_cmdline(void);
void prompt(void);
void prompt_exit(void);
--
2.48.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 0/3] improve cmdline file handling in testpmd
2025-07-04 14:05 [PATCH] app/testpmd: allow multiple cmdline-file parameters Bruce Richardson
@ 2025-07-04 18:34 ` Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 1/3] app/testpmd: explicitly set command echoing on file load Bruce Richardson
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Bruce Richardson @ 2025-07-04 18:34 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson
Some small improvements to cmdline file handling testpmd, inspired by the
desire to have support for multiple cmdline files passed on the commandline
of a testpmd run.
The implementation is somewhat complicated by the setting for echo/noecho
of the commands, because the current implementation uses a global flag for
that - shared between cmdline parameters and interactive CLI commands.
V2:
* remove global echo flag, and now support echo/noecho per file loaded
* when echoing, output the file being processed, to clarify things when
loading multiple files.
Bruce Richardson (3):
app/testpmd: explicitly set command echoing on file load
app/testpmd: allow multiple commandline file parameters
app/testpmd: improve output when processing cmdline files
app/test-pmd/cmdline.c | 78 ++++++++++++++++++---
app/test-pmd/parameters.c | 17 +++--
app/test-pmd/testpmd.c | 13 ++--
app/test-pmd/testpmd.h | 15 +++-
doc/guides/testpmd_app_ug/run_app.rst | 3 +-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 12 ++--
6 files changed, 110 insertions(+), 28 deletions(-)
--
2.48.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/3] app/testpmd: explicitly set command echoing on file load
2025-07-04 18:34 ` [PATCH v2 0/3] improve cmdline file handling in testpmd Bruce Richardson
@ 2025-07-04 18:34 ` Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 2/3] app/testpmd: allow multiple commandline file parameters Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 3/3] app/testpmd: improve output when processing cmdline files Bruce Richardson
2 siblings, 0 replies; 5+ messages in thread
From: Bruce Richardson @ 2025-07-04 18:34 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson
The echoing of commands contained in a file loaded via the "load"
command on testpmd CLI is governed by whether or not a cmdline-file or
cmdline-file-noecho had been passed to testpmd on the commandline.
Remove the use of a global setting for this, and explicitly add a
"load_echo" command to match the "load" command.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
app/test-pmd/cmdline.c | 51 +++++++++++++++++++--
app/test-pmd/testpmd.c | 2 +-
app/test-pmd/testpmd.h | 2 +-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +-
4 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 7b4e27eddf..5433678b5e 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -11646,7 +11646,9 @@ cmd_load_from_file_parsed(
{
struct cmd_cmdfile_result *res = parsed_result;
- cmdline_read_from_file(res->filename);
+ if (cmdline_read_from_file(res->filename, false) != 0) {
+ fprintf(stderr, "Failed to load commands from file: %s\n", res->filename);
+ }
}
static cmdline_parse_inst_t cmd_load_from_file = {
@@ -11660,6 +11662,41 @@ static cmdline_parse_inst_t cmd_load_from_file = {
},
};
+/* command to load a file with echoing commands */
+struct cmd_load_echo_result {
+ cmdline_fixed_string_t load_echo;
+ cmdline_fixed_string_t filename;
+};
+
+/* CLI fields for file load with echo command */
+static cmdline_parse_token_string_t cmd_load_echo =
+ TOKEN_STRING_INITIALIZER(struct cmd_load_echo_result, load_echo, "load_echo");
+static cmdline_parse_token_string_t cmd_load_echo_filename =
+ TOKEN_STRING_INITIALIZER(struct cmd_load_echo_result, filename, NULL);
+
+static void
+cmd_load_echo_file_parsed(
+ void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_load_echo_result *res = parsed_result;
+
+ if (cmdline_read_from_file(res->filename, true) != 0)
+ fprintf(stderr, "Failed to load commands from file: %s\n", res->filename);
+}
+
+static cmdline_parse_inst_t cmd_load_echo_file = {
+ .f = cmd_load_echo_file_parsed,
+ .data = NULL,
+ .help_str = "load_echo <filename>",
+ .tokens = {
+ (void *)&cmd_load_echo,
+ (void *)&cmd_load_echo_filename,
+ NULL,
+ },
+};
+
/* Get Rx offloads capabilities */
struct cmd_rx_offload_get_capa_result {
cmdline_fixed_string_t show;
@@ -13865,6 +13902,7 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
&cmd_help_long,
&cmd_quit,
&cmd_load_from_file,
+ &cmd_load_echo_file,
&cmd_showport,
&cmd_showqueue,
&cmd_showeeprom,
@@ -14151,24 +14189,25 @@ init_cmdline(void)
}
/* read cmdline commands from file */
-void
-cmdline_read_from_file(const char *filename)
+int
+cmdline_read_from_file(const char *filename, bool echo)
{
struct cmdline *cl;
int fd = -1;
+ int ret = 0;
/* cmdline_file_new does not produce any output
* so when echoing is requested we open filename directly
* and then pass that to cmdline_new with stdout as the output path.
*/
- if (!echo_cmdline_file) {
+ if (!echo) {
cl = cmdline_file_new(main_ctx, "testpmd> ", filename);
} else {
fd = open(filename, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Failed to open file %s: %s\n",
filename, strerror(errno));
- return;
+ return -1;
}
cl = cmdline_new(main_ctx, "testpmd> ", fd, STDOUT_FILENO);
@@ -14177,6 +14216,7 @@ cmdline_read_from_file(const char *filename)
fprintf(stderr,
"Failed to create file based cmdline context: %s\n",
filename);
+ ret = -1;
goto end;
}
@@ -14190,6 +14230,7 @@ cmdline_read_from_file(const char *filename)
end:
if (fd >= 0)
close(fd);
+ return ret;
}
void
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index bb88555328..b498e6d9fe 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -4509,7 +4509,7 @@ main(int argc, char** argv)
"Could not initialise cmdline context.\n");
if (strlen(cmdline_filename) != 0)
- cmdline_read_from_file(cmdline_filename);
+ cmdline_read_from_file(cmdline_filename, echo_cmdline_file);
if (interactive == 1) {
if (auto_start) {
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index e629edaa02..1d34f40deb 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -928,7 +928,7 @@ unsigned int parse_hdrs_list(const char *str, const char *item_name,
unsigned int *parsed_items);
void launch_args_parse(int argc, char** argv);
void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue);
-void cmdline_read_from_file(const char *filename);
+int cmdline_read_from_file(const char *filename, bool echo);
int init_cmdline(void);
void prompt(void);
void prompt_exit(void);
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 6ad83ae50d..e12585f025 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -95,7 +95,7 @@ practical or possible testpmd supports alternative methods for executing command
* At run-time additional commands can be loaded in bulk by invoking the ``load FILENAME``
- command.
+ or ``load_echo FILENAME`` command.
.. code-block:: console
--
2.48.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/3] app/testpmd: allow multiple commandline file parameters
2025-07-04 18:34 ` [PATCH v2 0/3] improve cmdline file handling in testpmd Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 1/3] app/testpmd: explicitly set command echoing on file load Bruce Richardson
@ 2025-07-04 18:34 ` Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 3/3] app/testpmd: improve output when processing cmdline files Bruce Richardson
2 siblings, 0 replies; 5+ messages in thread
From: Bruce Richardson @ 2025-07-04 18:34 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson
While testpmd allows a set of pre-prepared commands to be passed into it
at startup via the "cmdline-file" (and cmdline-file-noecho) parameters,
this is currently limited to a single file. By extending this support
to allow the parameter to be passed multiple (up to 16) times, we enable
users to have a library of pre-canned cmdline files and pass multiple of
these in to the same run, e.g. have one cmdline file per NIC feature and
enable multiple features by passing in multiple filenames.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
app/test-pmd/parameters.c | 17 +++++++++++------
app/test-pmd/testpmd.c | 13 +++++++++----
app/test-pmd/testpmd.h | 13 +++++++++++--
doc/guides/testpmd_app_ug/run_app.rst | 3 ++-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 6 +++---
5 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 1132972913..ce2ba1c826 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -960,13 +960,18 @@ launch_args_parse(int argc, char** argv)
exit(EXIT_SUCCESS);
break;
case TESTPMD_OPT_CMDLINE_FILE_NUM:
- echo_cmdline_file = true;
- /* fall-through */
case TESTPMD_OPT_CMDLINE_FILE_NOECHO_NUM:
- printf("CLI commands to be read from %s\n",
- optarg);
- strlcpy(cmdline_filename, optarg,
- sizeof(cmdline_filename));
+ if (cmdline_file_count >= RTE_DIM(cmdline_files)) {
+ fprintf(stderr, "Too many cmdline files specified (maximum %zu)\n",
+ RTE_DIM(cmdline_files));
+ exit(EXIT_FAILURE);
+ }
+ printf("CLI commands to be read from %s\n", optarg);
+ strlcpy(cmdline_files[cmdline_file_count].filename, optarg,
+ sizeof(cmdline_files[cmdline_file_count].filename));
+ cmdline_files[cmdline_file_count].echo =
+ (opt == TESTPMD_OPT_CMDLINE_FILE_NUM);
+ cmdline_file_count++;
break;
case TESTPMD_OPT_TX_FIRST_NUM:
printf("Ports to start sending a burst of "
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index b498e6d9fe..505e0283fa 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -105,8 +105,8 @@ int testpmd_logtype; /**< Log type for testpmd logs */
uint8_t interactive = 0;
uint8_t auto_start = 0;
uint8_t tx_first;
-char cmdline_filename[PATH_MAX] = {0};
-bool echo_cmdline_file;
+struct cmdline_file_info cmdline_files[MAX_CMDLINE_FILENAMES] = {0};
+unsigned int cmdline_file_count;
/*
* NUMA support configuration.
@@ -4508,8 +4508,13 @@ main(int argc, char** argv)
rte_exit(EXIT_FAILURE,
"Could not initialise cmdline context.\n");
- if (strlen(cmdline_filename) != 0)
- cmdline_read_from_file(cmdline_filename, echo_cmdline_file);
+ for (unsigned int i = 0; i < cmdline_file_count; i++) {
+ if (cmdline_read_from_file(cmdline_files[i].filename, cmdline_files[i].echo) != 0) {
+ fprintf(stderr, "Failed to process cmdline file: %s\n",
+ cmdline_files[i].filename);
+ break;
+ }
+ }
if (interactive == 1) {
if (auto_start) {
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 1d34f40deb..6ee229cb5c 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -36,6 +36,15 @@
extern uint8_t cl_quit;
extern volatile uint8_t f_quit;
+/* Max number of cmdline files we can take on testpmd cmdline */
+#define MAX_CMDLINE_FILENAMES 16
+
+/* Structure to track cmdline files and their echo settings */
+struct cmdline_file_info {
+ char filename[PATH_MAX]; /**< Path to the cmdline file */
+ bool echo; /**< Whether to echo commands from this file */
+};
+
/*
* It is used to allocate the memory for hash key.
* The hash key size is NIC dependent.
@@ -509,8 +518,8 @@ extern int testpmd_logtype; /**< Log type for testpmd logs */
extern uint8_t interactive;
extern uint8_t auto_start;
extern uint8_t tx_first;
-extern char cmdline_filename[PATH_MAX]; /**< offline commands file */
-extern bool echo_cmdline_file; /** unset if cmdline-file-noecho is used */
+extern struct cmdline_file_info cmdline_files[MAX_CMDLINE_FILENAMES]; /**< offline commands files */
+extern unsigned int cmdline_file_count; /**< number of cmdline files */
extern uint8_t numa_support; /**< set by "--numa" parameter */
extern uint16_t port_topology; /**< set by "--port-topology" parameter */
extern uint8_t no_flush_rx; /**<set by "--no-flush-rx" parameter */
diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index 330c37f2d9..680ecefac2 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -41,8 +41,9 @@ The command line options are:
* ``--cmdline-file=filename, --cmdline-file-noecho=filename``
- Read and execute commands from a file.
+ At startup, read and execute commands from a file.
The file should contain the same commands that can be entered interactively.
+ This option can be specified multiple times to process several files in sequence.
When using ``cmdline-file``, each command is printed as it is executed.
When using ``cmdline-file-noecho``, the commands are executed silently.
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index e12585f025..b8a401fa6f 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -67,13 +67,13 @@ Command File Functions
To facilitate loading large number of commands or to avoid cutting and pasting where not
practical or possible testpmd supports alternative methods for executing commands.
-* If started with the ``--cmdline-file=FILENAME`` command line argument testpmd
- will execute all CLI commands contained within the file immediately before
+* If started with the ``--cmdline-file=FILENAME`` or ``--cmdline-file-noecho=FILENAME`` command line argument,
+ testpmd will execute all CLI commands contained within the file immediately before
starting packet forwarding or entering interactive mode.
.. code-block:: console
- ./dpdk-testpmd -n4 -r2 ... -- -i --cmdline-file=/home/ubuntu/flow-create-commands.txt
+ ./dpdk-testpmd ... -- -i --cmdline-file-noecho=/home/ubuntu/flow-create-commands.txt
Interactive-mode selected
CLI commands to be read from /home/ubuntu/flow-create-commands.txt
Configuring Port 0 (socket 0)
--
2.48.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 3/3] app/testpmd: improve output when processing cmdline files
2025-07-04 18:34 ` [PATCH v2 0/3] improve cmdline file handling in testpmd Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 1/3] app/testpmd: explicitly set command echoing on file load Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 2/3] app/testpmd: allow multiple commandline file parameters Bruce Richardson
@ 2025-07-04 18:34 ` Bruce Richardson
2 siblings, 0 replies; 5+ messages in thread
From: Bruce Richardson @ 2025-07-04 18:34 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson
Two small improvements for the cmdline file processing in testpmd.
* Now that we support multiple files, change the prompt to indicate what
file is currently being processed, and just print an EOF message when
done.
* When not echoing, the "Read" verb in the message "Read CLI commands..."
is a little ambiguous, as it could mean "I have read", or "Go and read",
i.e. job done or job about to start. Tweak the text to "Finished reading"
which is unambiguous.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
app/test-pmd/cmdline.c | 27 ++++++++++++++++++---
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 4 +--
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 5433678b5e..b2a7aa8afd 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
+#include <libgen.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
@@ -14195,6 +14196,7 @@ cmdline_read_from_file(const char *filename, bool echo)
struct cmdline *cl;
int fd = -1;
int ret = 0;
+ char *prompt = NULL;
/* cmdline_file_new does not produce any output
* so when echoing is requested we open filename directly
@@ -14203,6 +14205,18 @@ cmdline_read_from_file(const char *filename, bool echo)
if (!echo) {
cl = cmdline_file_new(main_ctx, "testpmd> ", filename);
} else {
+ char *filename_copy = strdup(filename);
+
+ if (filename_copy == NULL) {
+ fprintf(stderr, "Failed to allocate memory for filename\n");
+ return -1;
+ }
+ if (asprintf(&prompt, "[%s] ", basename(filename_copy)) < 0) {
+ fprintf(stderr, "Failed to allocate prompt string\n");
+ return -1;
+ }
+ free(filename_copy);
+
fd = open(filename, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Failed to open file %s: %s\n",
@@ -14210,7 +14224,7 @@ cmdline_read_from_file(const char *filename, bool echo)
return -1;
}
- cl = cmdline_new(main_ctx, "testpmd> ", fd, STDOUT_FILENO);
+ cl = cmdline_new(main_ctx, prompt, fd, STDOUT_FILENO);
}
if (cl == NULL) {
fprintf(stderr,
@@ -14221,15 +14235,22 @@ cmdline_read_from_file(const char *filename, bool echo)
}
cmdline_interact(cl);
- cmdline_quit(cl);
+ /* when done, if we have echo, we only need to print end of file,
+ * but if no echo, we need to use printf and include the filename.
+ */
+ if (echo)
+ cmdline_printf(cl, "<End-Of-File>\n");
+ else
+ printf("Finished reading CLI commands from %s\n", filename);
+ cmdline_quit(cl);
cmdline_free(cl);
- printf("Read CLI commands from %s\n", filename);
end:
if (fd >= 0)
close(fd);
+ free(prompt);
return ret;
}
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index b8a401fa6f..2b0c4897ba 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -90,7 +90,7 @@ practical or possible testpmd supports alternative methods for executing command
...
Flow rule #498 created
Flow rule #499 created
- Read all CLI commands from /home/ubuntu/flow-create-commands.txt
+ Finished reading all CLI commands from /home/ubuntu/flow-create-commands.txt
testpmd>
@@ -106,7 +106,7 @@ practical or possible testpmd supports alternative methods for executing command
...
Flow rule #498 created
Flow rule #499 created
- Read all CLI commands from /home/ubuntu/flow-create-commands.txt
+ Finished reading all CLI commands from /home/ubuntu/flow-create-commands.txt
testpmd>
--
2.48.1
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-07-04 18:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-04 14:05 [PATCH] app/testpmd: allow multiple cmdline-file parameters Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 0/3] improve cmdline file handling in testpmd Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 1/3] app/testpmd: explicitly set command echoing on file load Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 2/3] app/testpmd: allow multiple commandline file parameters Bruce Richardson
2025-07-04 18:34 ` [PATCH v2 3/3] app/testpmd: improve output when processing cmdline files Bruce Richardson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).