diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index 662de2607cb..3a29b46c10c 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -823,6 +823,7 @@ struct shell_ctx { struct k_mutex wr_mtx; k_tid_t tid; + int ret_val; }; extern const struct log_backend_api log_backend_shell_api; @@ -1239,6 +1240,15 @@ int shell_obscure_set(const struct shell *sh, bool obscure); */ int shell_mode_delete_set(const struct shell *sh, bool val); +/** + * @brief Retrieve return value of most recently executed shell command. + * + * @param[in] sh Pointer to the shell instance + * + * @retval return value of previous command + */ +int shell_get_return_value(const struct shell *sh); + /** * @} */ diff --git a/subsys/shell/Kconfig b/subsys/shell/Kconfig index 5ec89ce50fc..d155622e7bb 100644 --- a/subsys/shell/Kconfig +++ b/subsys/shell/Kconfig @@ -251,6 +251,14 @@ config SHELL_AUTOSTART help If enabled, shell will be automatically started. +config SHELL_CMDS_RETURN_VALUE + bool "Retval command" + depends on SHELL_CMDS + default y + help + This option enables the retval command. It is used to retrieve + the return value from the most recently executed command. + source "subsys/shell/modules/Kconfig" endif # SHELL diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 25dcdad3129..e1f6424dbb3 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1001,7 +1001,7 @@ static void state_collect(const struct shell *sh) z_cursor_next_line_move(sh); } else { /* Command execution */ - (void)execute(sh); + sh->ctx->ret_val = execute(sh); } /* Function responsible for printing prompt * on received NL. @@ -1670,6 +1670,15 @@ int shell_use_vt100_set(const struct shell *sh, bool val) return (int)z_flag_use_vt100_set(sh, val); } +int shell_get_return_value(const struct shell *sh) +{ + if (sh == NULL) { + return -EINVAL; + } + + return z_shell_get_return_value(sh); +} + int shell_echo_set(const struct shell *sh, bool val) { if (sh == NULL) { diff --git a/subsys/shell/shell_cmds.c b/subsys/shell/shell_cmds.c index ee08eb77736..4454fb31b17 100644 --- a/subsys/shell/shell_cmds.c +++ b/subsys/shell/shell_cmds.c @@ -10,6 +10,7 @@ #include "shell_vt100.h" #define SHELL_MSG_CMD_NOT_SUPPORTED "Command not supported.\n" +#define SHELL_HELP_RETVAL "Print return value of most recent command" #define SHELL_HELP_CLEAR "Clear screen." #define SHELL_HELP_BACKENDS "List active shell backends.\n" #define SHELL_HELP_BACKSPACE_MODE "Toggle backspace key mode.\n" \ @@ -402,6 +403,15 @@ static int cmd_resize(const struct shell *sh, size_t argc, char **argv) return 0; } +static int cmd_get_retval(const struct shell *sh, size_t argc, char **argv) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + shell_print(sh, "%d", shell_get_return_value(sh)); + return 0; +} + static bool no_args(const struct shell_static_entry *entry) { return (entry->args.mandatory == 1) && (entry->args.optional == 0); @@ -498,3 +508,5 @@ SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_CMDS_RESIZE, resize, &m_sub_resize, SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_CMDS_SELECT, select, NULL, SHELL_HELP_SELECT, cmd_select, 2, SHELL_OPT_ARG_CHECK_SKIP); +SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_CMDS_RETURN_VALUE, retval, NULL, + SHELL_HELP_RETVAL, cmd_get_retval, 1, 0); diff --git a/subsys/shell/shell_ops.h b/subsys/shell/shell_ops.h index 39b66014360..59c4d8f738c 100644 --- a/subsys/shell/shell_ops.h +++ b/subsys/shell/shell_ops.h @@ -185,6 +185,11 @@ static inline uint8_t z_flag_last_nl_get(const struct shell *sh) return sh->ctx->ctx.flags.last_nl; } +static inline int z_shell_get_return_value(const struct shell *sh) +{ + return sh->ctx->ret_val; +} + static inline void z_flag_last_nl_set(const struct shell *sh, uint8_t val) { sh->ctx->ctx.flags.last_nl = val;