shell: Add shell_exec

This adds shell_exec which can be used to execute commands directly
without the use of a console which is useful for both testing as well
as interfacing with applications/upper layer which would like to have
access to shell commands directly.

In addition to that this may be more trivial to interface with instead
of using fifos like uart_register_input and telnet_register_input do.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2017-05-25 21:14:08 +03:00 committed by Anas Nashif
commit 1a8cd31d64
2 changed files with 46 additions and 23 deletions

View file

@ -119,6 +119,22 @@ void shell_register_prompt_handler(shell_prompt_function_t handler);
*/
void shell_register_default_module(const char *name);
/** @brief Execute command line.
*
* Pass command line to shell to execute. The line cannot be a C string literal
* since it will be modified in place, instead a variable can be used:
*
* char cmd[] = "command";
* shell_exec(cmd);
*
* Note: This by no means makes any of the commands a stable interface, so
* this function should only be used for debugging/diagnostic.
*
* @param line Command line to be executed
* @returns Result of the execution
*/
int shell_exec(char *line);
/**
* @}
*/

View file

@ -350,44 +350,51 @@ static inline void print_cmd_unknown(char *argv)
printk("Type 'help' for list of available commands\n");
}
static void shell(void *p1, void *p2, void *p3)
int shell_exec(char *line)
{
char *argv[ARGC_MAX + 1];
size_t argc;
int err;
shell_cmd_function_t cb;
argc = line2argv(line, argv, ARRAY_SIZE(argv));
if (!argc) {
return -EINVAL;
}
cb = get_cb(argc, argv);
if (!cb) {
if (app_cmd_handler != NULL) {
cb = app_cmd_handler;
} else {
print_cmd_unknown(argv[0]);
return -EINVAL;
}
}
/* Execute callback with arguments */
err = cb(argc, argv);
if (err < 0) {
show_cmd_help(argv);
}
return err;
}
static void shell(void *p1, void *p2, void *p3)
{
ARG_UNUSED(p1);
ARG_UNUSED(p2);
ARG_UNUSED(p3);
while (1) {
struct console_input *cmd;
shell_cmd_function_t cb;
printk("%s", get_prompt());
cmd = k_fifo_get(&cmds_queue, K_FOREVER);
argc = line2argv(cmd->line, argv, ARRAY_SIZE(argv));
if (!argc) {
k_fifo_put(&avail_queue, cmd);
continue;
}
cb = get_cb(argc, argv);
if (!cb) {
if (app_cmd_handler != NULL) {
cb = app_cmd_handler;
} else {
print_cmd_unknown(argv[0]);
k_fifo_put(&avail_queue, cmd);
continue;
}
}
/* Execute callback with arguments */
if (cb(argc, argv) < 0) {
show_cmd_help(argv);
}
shell_exec(cmd->line);
k_fifo_put(&avail_queue, cmd);
}