From fc8ccab5d62d4b3162ce748dc85582345a6551ff Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Tue, 16 Mar 2021 10:11:30 +0800 Subject: [PATCH 1/2] execve add script support --- components/lwp/lwp_syscall.c | 248 +++++++++++++++++++++++++++++++---- 1 file changed, 221 insertions(+), 27 deletions(-) diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index e8791e77bc..f4caf26c62 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -1598,12 +1598,195 @@ void lwp_user_obj_free(struct rt_lwp *lwp); lwp_new->member = tmp;\ } while (0) +struct lwp_args_info +{ + char **argv; + char **envp; + int argc; + int envc; + int size; +}; + +static char *_insert_args(int new_argc, char *new_argv[], struct lwp_args_info *args) +{ + void *page = NULL; + int err = 0; + char **nargv; + char **nenvp; + char *p; + int i, len; + int nsize; + + if (new_argc == 0) + { + goto quit; + } + page = rt_pages_alloc(0); /* 1 page */ + if (!page) + { + goto quit; + } + + nsize = new_argc * sizeof(char *); + for (i = 0; i < new_argc; i++) + { + nsize += rt_strlen(new_argv[i]) + 1; + } + if (nsize + args->size > ARCH_PAGE_SIZE) + { + err = 1; + goto quit; + } + nargv = (char **)page; + nenvp = nargv + args->argc + new_argc + 1; + p = (char *)(nenvp + args->envc + 1); + /* insert argv */ + for (i = 0; i < new_argc; i++) + { + nargv[i] = p; + len = rt_strlen(new_argv[i]) + 1; + rt_memcpy(p, new_argv[i], len); + p += len; + } + /* copy argv */ + nargv += new_argc; + for (i = 0; i < args->argc; i++) + { + nargv[i] = p; + len = rt_strlen(args->argv[i]) + 1; + rt_memcpy(p, args->argv[i], len); + p += len; + } + nargv[i] = NULL; + /* copy envp */ + for (i = 0; i < args->envc; i++) + { + nenvp[i] = p; + len = rt_strlen(args->envp[i]) + 1; + rt_memcpy(p, args->envp[i], len); + p += len; + } + nenvp[i] = NULL; + + /* update args */ + args->argv = (char **)page; + args->argc = args->argc + new_argc; + args->envp = args->argv + args->argc + 1; + /* args->envc no change */ + args->size = args->size + nsize; + +quit: + if (err && page) + { + rt_pages_free(page, 0); + page = NULL; + } + return page; +} + +#define INTERP_BUF_SIZE 128 +static char *_load_script(const char *filename, struct lwp_args_info *args) +{ + void *page = NULL; + char *new_page; + int fd = -1; + int len; + char interp[INTERP_BUF_SIZE]; + char *cp; + char *i_name; + char *i_arg; + + fd = open(filename, O_BINARY | O_RDONLY, 0); + if (fd < 0) + { + goto quit; + } + len = read(fd, interp, INTERP_BUF_SIZE); + if (len < 2) + { + goto quit; + } + + if ((interp[0] != '#') || (interp[1] != '!')) + { + goto quit; + } + + if (len == INTERP_BUF_SIZE) + { + len--; + } + interp[len] = '\0'; + + if ((cp = strchr(interp, '\n')) == NULL) + { + cp = interp + INTERP_BUF_SIZE - 1; + } + *cp = '\0'; + while (cp > interp) + { + cp--; + if ((*cp == ' ') || (*cp == '\t')) + { + *cp = '\0'; + } + else + { + break; + } + } + for (cp = interp + 2; (*cp == ' ') || (*cp == '\t'); cp++) + { + /* nothing */ + } + if (*cp == '\0') + { + goto quit; /* No interpreter name found */ + } + i_name = cp; + i_arg = NULL; + for (; *cp && (*cp != ' ') && (*cp != '\t'); cp++) + { + /* nothing */ + } + while ((*cp == ' ') || (*cp == '\t')) + { + *cp++ = '\0'; + } + if (*cp) + { + i_arg = cp; + } + + if (i_arg) + { + new_page = _insert_args(1, &i_arg, args); + rt_pages_free(page, 0); + page = new_page; + if (!page) + { + goto quit; + } + } + new_page = _insert_args(1, &i_name, args); + rt_pages_free(page, 0); + page = new_page; + +quit: + if (fd >= 0) + { + close(fd); + } + return page; +} + int sys_execve(const char *path, char *const argv[], char *const envp[]) { int ret = -1; int argc = 0; int envc = 0; void *page = NULL; + void *new_page; int size = 0; size_t len; int access_err; @@ -1617,6 +1800,7 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) rt_thread_t thread; struct process_aux *aux; int i; + struct lwp_args_info args_info; lwp = lwp_self(); thread = rt_thread_self(); @@ -1643,6 +1827,8 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) rt_set_errno(EFAULT); goto quit; } + + size += sizeof(char *); if (argv) { while (1) @@ -1652,7 +1838,6 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) rt_set_errno(EFAULT); goto quit; } - size += sizeof(char *); if (!argv[argc]) { break; @@ -1663,11 +1848,11 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) rt_set_errno(EFAULT); goto quit; } - size += len + 1; + size += sizeof(char *) + len + 1; argc++; } - size += sizeof(char *); } + size += sizeof(char *); if (envp) { while (1) @@ -1677,7 +1862,6 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) rt_set_errno(EFAULT); goto quit; } - size += sizeof(char *); if (!envp[envc]) { break; @@ -1688,10 +1872,9 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) rt_set_errno(EFAULT); goto quit; } - size += len + 1; + size += sizeof(char *) + len + 1; envc++; } - size += sizeof(char *); } if (size > ARCH_PAGE_SIZE) { @@ -1713,13 +1896,10 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) { for (i = 0; i < argc; i++) { - if (argv[i]) - { - kargv[i] = p; - len = rt_strlen(argv[i]) + 1; - rt_memcpy(p, argv[i], len); - p += len; - } + kargv[i] = p; + len = rt_strlen(argv[i]) + 1; + rt_memcpy(p, argv[i], len); + p += len; } kargv[i] = NULL; } @@ -1728,13 +1908,10 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) { for (i = 0; i < envc; i++) { - if (envp[i]) - { - kenvp[i] = p; - len = rt_strlen(envp[i]) + 1; - rt_memcpy(p, envp[i], len); - p += len; - } + kenvp[i] = p; + len = rt_strlen(envp[i]) + 1; + rt_memcpy(p, envp[i], len); + p += len; } kenvp[i] = NULL; } @@ -1754,24 +1931,39 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) rt_set_errno(ENOMEM); goto quit; } - if ((aux = lwp_argscopy(new_lwp, argc, kargv, kenvp)) == NULL) + /* file is a script ? */ + args_info.argc = argc; + args_info.argv = kargv; + args_info.envc = envc; + args_info.envp = kenvp; + args_info.size = size; + do + { + new_page = _load_script(args_info.argv[0], &args_info); + if (new_page) + { + rt_pages_free(page, 0); + page = new_page; + } + } while (new_page); + + /* now load elf */ + if ((aux = lwp_argscopy(new_lwp, args_info.argc, args_info.argv, args_info.envp)) == NULL) { rt_set_errno(ENOMEM); goto quit; } - rt_pages_free(page, 0); - page = NULL; - - ret = lwp_load(path, new_lwp, RT_NULL, 0, aux); + ret = lwp_load(args_info.argv[0], new_lwp, RT_NULL, 0, aux); if (ret == RT_EOK) { int off = 0; int last_backslash = 0; + char *run_name = args_info.argv[0]; /* find last \ or / */ while (1) { - char c = path[off++]; + char c = run_name[off++]; if (c == '\0') { @@ -1786,7 +1978,9 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) /* load ok, now set thread name and swap the data of lwp and new_lwp */ level = rt_hw_interrupt_disable(); - rt_strncpy(thread->name, path + last_backslash, RT_NAME_MAX); + rt_strncpy(thread->name, run_name + last_backslash, RT_NAME_MAX); + + rt_pages_free(page, 0); #ifdef RT_USING_USERSPACE _swap_lwp_data(lwp, new_lwp, rt_mmu_info, mmu_info); -- Gitee From 5a981d3559c157c2a411ba1433b26d8be317cb06 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Tue, 16 Mar 2021 14:02:12 +0800 Subject: [PATCH 2/2] =?UTF-8?q?lwp=5Fargs=5Finfo=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E5=88=B0lwp.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/lwp/lwp.h | 9 +++++++++ components/lwp/lwp_syscall.c | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h index 5f82b7a4c4..b9ee52a319 100644 --- a/components/lwp/lwp.h +++ b/components/lwp/lwp.h @@ -230,4 +230,13 @@ struct process_aux struct process_aux_item item[AUX_ARRAY_ITEMS_NR]; }; +struct lwp_args_info +{ + char **argv; + char **envp; + int argc; + int envc; + int size; +}; + #endif diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index f4caf26c62..f28e9e245b 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -1598,15 +1598,6 @@ void lwp_user_obj_free(struct rt_lwp *lwp); lwp_new->member = tmp;\ } while (0) -struct lwp_args_info -{ - char **argv; - char **envp; - int argc; - int envc; - int size; -}; - static char *_insert_args(int new_argc, char *new_argv[], struct lwp_args_info *args) { void *page = NULL; -- Gitee