diff --git a/apps/shell/include/shell_pri.h b/apps/shell/include/shell_pri.h index e1a47f1d..11dd582d 100644 --- a/apps/shell/include/shell_pri.h +++ b/apps/shell/include/shell_pri.h @@ -32,13 +32,15 @@ #ifndef _SHELL_PRI_H #define _SHELL_PRI_H +#include "shell.h" + #ifdef __cplusplus #if __cplusplus extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -extern void *ShellEntry(void *argv); +extern void ShellEntry(ShellCB *shellCB); extern void *ShellTask(void *argv); #ifdef __cplusplus diff --git a/apps/shell/include/shmsg.h b/apps/shell/include/shmsg.h index 4bc60261..70ffe4a2 100644 --- a/apps/shell/include/shmsg.h +++ b/apps/shell/include/shmsg.h @@ -32,6 +32,7 @@ #ifndef _SHMSG_H #define _SHMSG_H +#include "shell_list.h" #include "shell.h" #ifdef __cplusplus @@ -61,8 +62,7 @@ extern "C" { typedef void (* OutputFunc)(const char *fmt, ...); extern int ShellTaskInit(ShellCB *shellCB); -extern int ShellEntryInit(ShellCB *shellCB); -extern void ChildExec(const char *cmdName, char *const paramArray[]); +extern void ChildExec(const char *cmdName, char *const paramArray[], bool foreground); extern void ShellCmdLineParse(char c, OutputFunc outputFunc, ShellCB *shellCB); extern int ShellNotify(ShellCB *shellCB); diff --git a/apps/shell/src/main.c b/apps/shell/src/main.c index 3cdfc803..d0ece20c 100644 --- a/apps/shell/src/main.c +++ b/apps/shell/src/main.c @@ -31,13 +31,16 @@ #define _GNU_SOURCE +#include +#include +#include +#include #include "show.h" #include "shmsg.h" #include "shcmd.h" +#include "shell_pri.h" #include "semaphore.h" #include "securec.h" -#include "unistd.h" -#include ShellCB *g_shellCB = NULL; @@ -77,13 +80,8 @@ static int OsShellCreateTask(ShellCB *shellCB) goto OUT; } - ret = ShellEntryInit(shellCB); - if (ret != SH_OK) { - goto OUT; - } - - (void)pthread_join(shellCB->shellTaskHandle, NULL); - (void)pthread_join(shellCB->shellEntryHandle, NULL); + shellCB->shellEntryHandle = pthread_self(); + return 0; OUT: ShellDeinit(shellCB); @@ -98,7 +96,7 @@ static int DoShellExec(char **argv) char *cmdLine = NULL; if (strncmp(argv[0], SHELL_EXEC_COMMAND, SHELL_EXEC_COMMAND_BYTES) == 0) { - ChildExec(argv[1], argv + 1); + ChildExec(argv[1], argv + 1, FALSE); } for (i = 0; argv[i]; i++) { len += strlen(argv[i]); @@ -125,11 +123,22 @@ static int DoShellExec(char **argv) return ret; } +static void ShellSigChildHook(int sig) +{ + (void)sig; + + while (waitpid(-1, NULL, WNOHANG) > 0) { + continue; + } +} + int main(int argc, char **argv) { int ret = SH_NOK; ShellCB *shellCB = NULL; + (void)signal(SIGCHLD, ShellSigChildHook); + if (argc > 1) { ret = DoShellExec(argv + 1); return ret; @@ -165,7 +174,12 @@ int main(int argc, char **argv) sem_init(&shellCB->shellSem, 0, 0); g_shellCB = shellCB; - return OsShellCreateTask(shellCB); + ret = OsShellCreateTask(shellCB); + if (ret != SH_OK) { + goto ERR_OUT3; + } + + ShellEntry(shellCB); ERR_OUT3: (void)pthread_mutex_destroy(&shellCB->historyMutex); diff --git a/apps/shell/src/shmsg.c b/apps/shell/src/shmsg.c index 0fb2b69d..e0cdb67b 100644 --- a/apps/shell/src/shmsg.c +++ b/apps/shell/src/shmsg.c @@ -351,7 +351,7 @@ char *GetCmdName(const char *cmdline, unsigned int len) return cmdName; } -void ChildExec(const char *cmdName, char *const paramArray[]) +void ChildExec(const char *cmdName, char *const paramArray[], bool foreground) { int ret; pid_t gid; @@ -367,10 +367,12 @@ void ChildExec(const char *cmdName, char *const paramArray[]) exit(1); } - ret = tcsetpgrp(STDIN_FILENO, gid); - if (ret != 0) { - printf("tcsetpgrp failed, errno %d\n", errno); - exit(1); + if (!foreground) { + ret = tcsetpgrp(STDIN_FILENO, gid); + if (ret != 0) { + printf("tcsetpgrp failed, errno %d\n", errno); + exit(1); + } } ret = execve(cmdName, paramArray, NULL); @@ -404,20 +406,30 @@ int CheckExit(const char *cmdName, const CmdParsed *cmdParsed) exit(ret); } -static void DoCmdExec(const char *cmdName, const char *cmdline, unsigned int len, const CmdParsed *cmdParsed) +static void DoCmdExec(const char *cmdName, const char *cmdline, unsigned int len, CmdParsed *cmdParsed) { + bool foreground = FALSE; int ret; pid_t forkPid; if (strncmp(cmdline, CMD_EXEC_COMMAND, CMD_EXEC_COMMAND_BYTES) == 0) { + if ((cmdParsed->paramCnt > 1) && (strcmp(cmdParsed->paramArray[cmdParsed->paramCnt - 1], "&") == 0)) { + free(cmdParsed->paramArray[cmdParsed->paramCnt - 1]); + cmdParsed->paramArray[cmdParsed->paramCnt - 1] = NULL; + cmdParsed->paramCnt--; + foreground = TRUE; + } + forkPid = fork(); if (forkPid < 0) { printf("Faild to fork from shell\n"); return; } else if (forkPid == 0) { - ChildExec(cmdParsed->paramArray[0], cmdParsed->paramArray); + ChildExec(cmdParsed->paramArray[0], cmdParsed->paramArray, foreground); } else { - waitpid(forkPid, 0, 0); + if (!foreground) { + (void)waitpid(forkPid, 0, 0); + } ret = tcsetpgrp(STDIN_FILENO, getpid()); if (ret != 0) { printf("tcsetpgrp failed, errno %d\n", errno); @@ -567,20 +579,10 @@ static void ExecCmdline(const char *cmdline) free(output); } -void RecycleZombieChild(void) -{ - while (waitpid(-1, NULL, WNOHANG) > 0) { - continue; - } -} - static void ShellCmdProcess(ShellCB *shellCB) { - char *buf = NULL; while (1) { - /* recycle zombine child process */ - RecycleZombieChild(); - buf = GetCmdline(shellCB); + char *buf = GetCmdline(shellCB); if (buf == NULL) { break; } @@ -654,25 +656,19 @@ static int ShellKernelReg(unsigned int shellHandle) return ioctl(STDIN_FILENO, CONSOLE_CONTROL_REG_USERTASK, shellHandle); } -void *ShellEntry(void *argv) +void ShellEntry(ShellCB *shellCB) { char ch; int ret; int n; pid_t tid = syscall(__NR_gettid); - ShellCB *shellCB = (ShellCB *)argv; if (shellCB == NULL) { - return NULL; + return; } (void)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN); - ret = prctl(PR_SET_NAME, "ShellEntry"); - if (ret != SH_OK) { - return NULL; - } - ret = ShellKernelReg((int)tid); if (ret != 0) { printf("another shell is already running!\n"); @@ -685,32 +681,5 @@ void *ShellEntry(void *argv) ShellCmdLineParse(ch, (OutputFunc)printf, shellCB); } } - return NULL; + return; } - -int ShellEntryInit(ShellCB *shellCB) -{ - int ret; - size_t stackSize = SHELL_ENTRY_STACKSIZE; - void *arg = NULL; - pthread_attr_t attr; - - if (shellCB == NULL) { - return SH_NOK; - } - - ret = pthread_attr_init(&attr); - if (ret != SH_OK) { - return SH_NOK; - } - - pthread_attr_setstacksize(&attr, stackSize); - arg = (void *)shellCB; - ret = pthread_create(&shellCB->shellEntryHandle, &attr, &ShellEntry, arg); - if (ret != SH_OK) { - return SH_NOK; - } - - return ret; -} -