19#define FINSH_ARG_MAX 8
35static int msh_help(
int argc,
char **argv)
45#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
58#ifdef MSH_USING_BUILT_IN_COMMANDS
59static int cmd_ps(
int argc,
char **argv)
62 extern int list_module(
void);
65 if ((argc == 2) && (strcmp(argv[1],
"-m") == 0))
75static int cmd_free(
int argc,
char **argv)
77#ifdef RT_USING_MEMHEAP_AS_HEAP
78 extern void list_memheap(
void);
81 rt_size_t total = 0, used = 0, max_used = 0;
95static int cmd_bind(
int argc,
char **argv)
105 rt_kprintf(
"Usage: bind <thread_id> <core_id>\n");
110 thread_id = (
rt_ubase_t)strtoul(argv[1], &endptr, 0);
113 rt_kprintf(
"Error: Invalid thread ID '%s'\n", argv[1]);
118 core_id = (
rt_uint8_t)strtoul(argv[2], &endptr, 0);
121 rt_kprintf(
"Error: Invalid core ID '%s'\n", argv[2]);
129 rt_kprintf(
"Error: Invalid thread ID %#lx\n", thread_id);
134 if (result == RT_EOK)
136 rt_kprintf(
"Thread 0x%lx bound to core %d successfully\n",
141 rt_kprintf(
"Failed to bind thread 0x%lx to core %d\n",
162 while (position < length)
165 while ((*ptr ==
' ' || *ptr ==
'\t') && position < length)
175 for (i = 0; i < argc; i++)
183 if (position >= length)
break;
194 while (*ptr !=
'"' && position < length)
198 if (*(ptr + 1) ==
'"')
207 if (position >= length)
break;
218 while ((*ptr !=
' ' && *ptr !=
'\t') && position < length)
223 if (position >= length)
break;
239 if (strncmp(index->
name, cmd, size) == 0 &&
240 index->
name[size] ==
'\0')
250#if defined(RT_USING_MODULE) && defined(DFS_USING_POSIX)
258 int length, cmd_length = 0;
263 while ((cmd_line[cmd_length] !=
' ' && cmd_line[cmd_length] !=
'\t') && cmd_length < size)
267 length = cmd_length + 32;
270 pg_name = (
char *)
rt_malloc(length + 3);
275 rt_memcpy(pg_name, cmd_line, cmd_length);
276 pg_name[cmd_length] =
'\0';
278 if (strstr(pg_name,
".mo") !=
RT_NULL || strstr(pg_name,
".MO") !=
RT_NULL)
281 fd =
open(pg_name, O_RDONLY, 0);
286 rt_snprintf(pg_name, length - 1,
"/bin/%.*s", cmd_length, cmd_line);
287 fd =
open(pg_name, O_RDONLY, 0);
295 strcat(pg_name,
".mo");
296 fd =
open(pg_name, O_RDONLY, 0);
301 rt_snprintf(pg_name, length - 1,
"/bin/%.*s.mo", cmd_length, cmd_line);
302 fd =
open(pg_name, O_RDONLY, 0);
310 dlmodule_exec(pg_name, cmd_line, size);
323static int _msh_exec_cmd(
char *cmd,
rt_size_t length,
int *retp)
334 while (cmd0_size < length && (cmd[cmd0_size] !=
' ' && cmd[cmd0_size] !=
'\t'))
339 cmd_func = msh_get_cmd(cmd, cmd0_size);
344 rt_memset(argv, 0x00,
sizeof(argv));
345 argc = msh_split(cmd, length, argv);
350 *retp = cmd_func(argc, argv);
354#if defined(RT_USING_SMART) && defined(DFS_USING_POSIX)
357static rt_bool_t _msh_lwp_cmd_exists(
const char *path)
360 fd =
open(path, O_RDONLY, 0);
373static char *_msh_exec_search_path(
const char *path,
const char *pg_name)
376 ssize_t pg_len = strlen(pg_name);
377 ssize_t base_len = 0;
381 base_len = strlen(path);
384 path_buffer =
rt_malloc(base_len + pg_len + 6);
392 memcpy(path_buffer, path, base_len);
393 path_buffer[base_len] =
'/';
394 path_buffer[base_len + 1] =
'\0';
400 strcat(path_buffer, pg_name);
402 if (_msh_lwp_cmd_exists(path_buffer))
407 if (strstr(path_buffer,
".elf") != NULL)
412 strcat(path_buffer,
".elf");
413 if (_msh_lwp_cmd_exists(path_buffer))
427static char *_msh_exec_search_env(
const char *pg_name)
435 if (!(exec_path = getenv(
"PATH")))
441 if (!(exec_path = strdup(exec_path)))
447 search_path = exec_path;
454 if (*pos ==
':' || *pos ==
'\0')
459 result = _msh_exec_search_path(search_path, pg_name);
460 if (result || tmp_ch ==
'\0')
479int _msh_exec_lwp(
int debug,
char *cmd,
rt_size_t length)
488 while ((cmd[cmd0_size] !=
' ' && cmd[cmd0_size] !=
'\t') && cmd0_size < length)
494 rt_memset(argv, 0x00,
sizeof(argv));
495 argc = msh_split(cmd, length, argv);
500 pg_name = _msh_exec_search_path(
"", argv[0]);
508 if (strstr(argv[0],
"/"))
514 pg_name = _msh_exec_search_path(
"/bin", argv[0]);
521 pg_name = _msh_exec_search_env(argv[0]);
532 ret = exec(pg_name, debug, argc, argv);
545 while ((length > 0) && (*cmd ==
' ' || *cmd ==
'\t'))
558 if (_msh_exec_cmd(cmd, length, &cmd_ret) == 0)
562 rt_kprintf(
"%s: command failed %d.\n", cmd, cmd_ret);
566#ifdef DFS_USING_POSIX
567#ifdef DFS_USING_WORKDIR
574#ifdef RT_USING_MODULE
584 cmd_ret = _msh_exec_lwp(0, cmd, length);
596 while (*tcmd !=
' ' && *tcmd !=
'\0')
603 if (cmd_ret == -EACCES)
615static int str_common(
const char *str1,
const char *str2)
617 const char *str = str1;
619 while ((*str != 0) && (*str2 != 0) && (*str == *str2))
628#ifdef DFS_USING_POSIX
629void msh_auto_complete_path(
char *path)
632 struct dirent *dirent =
RT_NULL;
633 char *full_path, *ptr, *index;
639 if (full_path ==
RT_NULL)
return;
644 if (full_path[rt_strlen(full_path) - 1] !=
'/')
645 strcat(full_path,
"/");
647 else *full_path =
'\0';
653 if (*ptr ==
'/') index = ptr + 1;
658 if (index ==
RT_NULL) index = path;
668 for (index = path; index != dest;)
706 if (strncmp(index, dirent->d_name, rt_strlen(index)) == 0)
711 min_length = rt_strlen(dirent->d_name);
713 strcpy(full_path, dirent->d_name);
716 length = str_common(dirent->d_name, full_path);
718 if (length < min_length)
737 if (strncmp(index, dirent->d_name, rt_strlen(index)) == 0)
742 length = index - path;
743 rt_memcpy(index, full_path, min_length);
744 path[length + min_length] =
'\0';
749 struct stat buffer = {0};
750 if ((
stat(path, &buffer) == 0))
752 if (S_ISDIR(buffer.st_mode))
756 else if (S_ISLNK(buffer.st_mode))
777 int length, min_length;
778 const char *name_ptr, *cmd_name;
790#ifdef DFS_USING_POSIX
795 ptr = prefix + rt_strlen(prefix);
796 while (ptr != prefix)
800 msh_auto_complete_path(ptr + 1);
806#if defined(RT_USING_MODULE) || defined(RT_USING_SMART)
812 msh_auto_complete_path(ptr);
823 cmd_name = (
const char *) index->
name;
824 if (strncmp(prefix, cmd_name, strlen(prefix)) == 0)
831 min_length = strlen(name_ptr);
834 length = str_common(name_ptr, cmd_name);
835 if (length < min_length)
844 if (name_ptr != NULL)
846 rt_strncpy(prefix, name_ptr, min_length);
852#ifdef FINSH_USING_OPTION_COMPLETION
853static msh_cmd_opt_t *msh_get_cmd_opt(
char *opt_str)
860 ptr = strchr(opt_str,
' ');
867 len = strlen(opt_str);
874 if (strncmp(index->
name, opt_str, len) == 0 && index->
name[len] ==
'\0')
884static int msh_get_argc(
char *prefix,
char **last_argv)
891 if ((*ch ==
' ') && *(ch + 1) && (*(ch + 1) !=
' '))
902static void msh_opt_complete(
char *opts_str,
struct msh_cmd_opt *cmd_opt)
904 struct msh_cmd_opt *opt = cmd_opt;
905 const char *name_ptr =
RT_NULL;
906 int min_length = 0, length, opts_str_len;
908 opts_str_len = strlen(opts_str);
910 for (opt = cmd_opt; opt->id; opt++)
912 if (!strncmp(opt->name, opts_str, opts_str_len))
917 name_ptr = opt->name;
919 min_length = strlen(name_ptr);
922 length = str_common(name_ptr, opt->name);
923 if (length < min_length)
933 if (name_ptr != NULL)
935 strncpy(opts_str, name_ptr, min_length);
939static void msh_opt_help(msh_cmd_opt_t *cmd_opt)
941 msh_cmd_opt_t *opt = cmd_opt;
943 for (; opt->id; opt++)
945 rt_kprintf(
"%-16s - %s\n", opt->name, opt->des);
950void msh_opt_auto_complete(
char *prefix)
956 argc = msh_get_argc(prefix, &opt_str);
959 opt = msh_get_cmd_opt(prefix);
961 else if (!msh_get_cmd(prefix, strlen(prefix)) && (
' ' == prefix[strlen(prefix) - 1]))
963 opt = msh_get_cmd_opt(prefix);
975 msh_opt_complete(opt_str, opt);
984int msh_cmd_opt_id_get(
int argc,
char *argv[],
void *options)
986 msh_cmd_opt_t *opt = (msh_cmd_opt_t *) options;
989 for (opt_id = 0; (argc >= 2) && opt && opt->id; opt++)
991 if (!strcmp(opt->name, argv[1]))
1001void msh_opt_list_dump(
void *options)
1003 msh_cmd_opt_t *opt = (msh_cmd_opt_t *) options;
1005 for (; opt && opt->id; opt++)
1007 rt_kprintf(
" %-16s - %s\n", opt->name, opt->des);
struct finsh_syscall * _syscall_table_end
#define FINSH_NEXT_SYSCALL(index)
struct finsh_syscall * _syscall_table_begin
struct dirent * readdir(DIR *d)
DIR * opendir(const char *name)
int open(const char *file, int flags,...)
int stat(const char *file, struct stat *buf)
char * getcwd(char *buf, size_t size)
rt_uint8_t rt_object_get_type(rt_object_t object)
This function will return the type of object without RT_Object_Class_Static flag.
rt_weak void rt_free(void *ptr)
This function will release the previously allocated memory block by rt_malloc. The released memory bl...
rt_weak void rt_memory_info(rt_size_t *total, rt_size_t *used, rt_size_t *max_used)
This function will caculate the total memory, the used memory, and the max used memory.
rt_weak void * rt_malloc(rt_size_t size)
Allocate a block of memory with a minimum of 'size' bytes.
#define RT_THREAD_CTRL_BIND_CPU
rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg)
This function will control thread behaviors according to control command.
struct rt_thread * rt_thread_t
#define MSH_CMD_EXPORT_ALIAS(...)
int msh_exec(char *cmd, rt_size_t length)
void msh_auto_complete(char *prefix)
int(* cmd_function_t)(int argc, char **argv)
int msh_exec_script(const char *cmd_line, int size)
int msh_exec_module(const char *cmd_line, int size)
struct finsh_shell * shell