From c44f32e513569858e95f1aa4e9ab531b8577e398 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Thu, 27 Mar 2014 16:15:56 +0800 Subject: [PATCH] [msh] cd to path when possible When DFS_USING_WORKDIR is enabled, msh will try to chdir if the command is not found. For example, if there is folder named "SD", and there is no `SD` command and `SD.mo` module, typing "SD" in msh will cd to the folder. In more detail, the execution order right now is: 1. built-in command 2. module 3. cd to path If you have a folder named "ps", you have to run `cd ps` to change the working dir. --- components/finsh/msh.c | 125 ++++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 45 deletions(-) diff --git a/components/finsh/msh.c b/components/finsh/msh.c index f2b6d20860..354f884913 100644 --- a/components/finsh/msh.c +++ b/components/finsh/msh.c @@ -178,35 +178,37 @@ static cmd_function_t msh_get_cmd(char *cmd, int size) } #if defined(RT_USING_MODULE) && defined(RT_USING_DFS) +/* Return 0 on module executed. Other value indicate error. + */ int msh_exec_module(char* cmd_line, int size) { + int ret; int fd = -1; char *pg_name; int length, cmd_length = 0; - if (size == 0) return -RT_ERROR; /* no command */ - /* get the length of command0 */ - while ((cmd_line[cmd_length] != ' ' && cmd_line[cmd_length] != '\t') && cmd_length < size) - cmd_length ++; + if (size == 0) + return -RT_ERROR; + /* get the length of command0 */ + while ((cmd_line[cmd_length] != ' ' && cmd_line[cmd_length] != '\t') && cmd_length < size) + cmd_length ++; /* get name length */ length = cmd_length + 32; - /* allocate program name memory */ + /* allocate program name memory */ pg_name = (char*) rt_malloc(length); - if (pg_name == RT_NULL) return -RT_ENOMEM; /* no memory */ + if (pg_name == RT_NULL) + return -RT_ENOMEM; - /* copy command0 */ - memcpy(pg_name, cmd_line, cmd_length); - pg_name[cmd_length] = '\0'; + /* copy command0 */ + memcpy(pg_name, cmd_line, cmd_length); + pg_name[cmd_length] = '\0'; if (strstr(pg_name, ".mo") != RT_NULL || strstr(pg_name, ".MO") != RT_NULL) { /* try to open program */ - if (fd < 0) - { - fd = open(pg_name, O_RDONLY, 0); - } + fd = open(pg_name, O_RDONLY, 0); /* search in /bin path */ if (fd < 0) @@ -220,16 +222,13 @@ int msh_exec_module(char* cmd_line, int size) /* add .mo and open program */ /* try to open program */ - if (fd < 0) - { - strcat(pg_name, ".mo"); - fd = open(pg_name, O_RDONLY, 0); - } + strcat(pg_name, ".mo"); + fd = open(pg_name, O_RDONLY, 0); /* search in /bin path */ if (fd < 0) { - rt_snprintf(pg_name, length - 1, "/bin/%.*s.mo", cmd_length, cmd_line); + rt_snprintf(pg_name, length - 1, "/bin/%.*s.mo", cmd_length, cmd_line); fd = open(pg_name, O_RDONLY, 0); } } @@ -239,57 +238,93 @@ int msh_exec_module(char* cmd_line, int size) /* found program */ close(fd); rt_module_exec_cmd(pg_name, cmd_line, size); + ret = 0; } else { - rt_kprintf("%s: program not found.\n", cmd_line); + ret = -1; } rt_free(pg_name); - return 0; + return ret; } #endif -int msh_exec(char* cmd, rt_size_t length) +static int _msh_exec_cmd(char* cmd, rt_size_t length, int *retp) { int argc; - char *argv[RT_FINSH_ARG_MAX]; int cmd0_size = 0; cmd_function_t cmd_func; + char *argv[RT_FINSH_ARG_MAX]; - /* strim the beginning of command */ - while(*cmd == ' ' || *cmd == '\t'){cmd++; length--;} - /* find the size of first command */ + RT_ASSERT(cmd); + RT_ASSERT(retp); + + /* find the size of first command */ while ((cmd[cmd0_size] != ' ' && cmd[cmd0_size] != '\t') && cmd0_size < length) cmd0_size ++; - if (cmd0_size == 0) return -1; /* no command found */ + if (cmd0_size == 0) + return -RT_ERROR; - /* try to get built-in command */ cmd_func = msh_get_cmd(cmd, cmd0_size); if (cmd_func == RT_NULL) - { -#ifdef RT_USING_MODULE - msh_exec_module(cmd, length); -#else - argv[0] = cmd; - while(*cmd != ' ') - { - if (*cmd == 0) break; - cmd++; - } - if (*cmd == ' ') *cmd = 0; - rt_kprintf("%s: command not found.\n", argv[0]); -#endif - return -1; - } + return -RT_ERROR; /* split arguments */ memset(argv, 0x00, sizeof(argv)); argc = msh_split(cmd, length, argv); - if (argc == 0) return -1; + if (argc == 0) + return -RT_ERROR; /* exec this command */ - return cmd_func(argc, argv); + *retp = cmd_func(argc, argv); + return 0; +} + +int msh_exec(char* cmd, rt_size_t length) +{ + int cmd_ret; + + /* strim the beginning of command */ + while(*cmd == ' ' || *cmd == '\t') + { + cmd++; + length--; + } + + /* Exec sequence: + * 1. built-in command + * 2. module(if enabled) + * 3. chdir to the directry(if possible) + */ + if (_msh_exec_cmd(cmd, length, &cmd_ret) == 0) + { + return cmd_ret; + } +#ifdef RT_USING_MODULE + if (msh_exec_module(cmd, length) == 0) + { + return 0; + } +#endif +#ifdef DFS_USING_WORKDIR + if (chdir(cmd) == 0) + { + return 0; + } +#endif + /* truncate the cmd at the first space. */ + { + char *tcmd; + tcmd = cmd; + while(*tcmd != ' ' && *tcmd != '\0') + { + tcmd++; + } + *tcmd = '\0'; + } + rt_kprintf("%s: command not found.\n", cmd); + return -1; } static int str_common(const char *str1, const char *str2) -- GitLab