diff --git a/apps/shell/include/shmsg.h b/apps/shell/include/shmsg.h index b182db34..d9c172a2 100644 --- a/apps/shell/include/shmsg.h +++ b/apps/shell/include/shmsg.h @@ -47,6 +47,9 @@ extern "C" { #define SHELL_EXEC_COMMAND_BYTES 4 #define CMD_EXEC_COMMAND SHELL_EXEC_COMMAND" " #define CMD_EXEC_COMMAND_BYTES (SHELL_EXEC_COMMAND_BYTES+1) +#define CMD_EXIT_COMMAND "exit" +#define CMD_EXIT_COMMAND_BYTES 4 +#define CMD_EXIT_CODE_BASE_DEC 10 #define CONSOLE_IOC_MAGIC 'c' #define CONSOLE_CONTROL_REG_USERTASK _IO(CONSOLE_IOC_MAGIC, 7) diff --git a/apps/shell/src/shmsg.c b/apps/shell/src/shmsg.c index 8329691b..320e60b4 100644 --- a/apps/shell/src/shmsg.c +++ b/apps/shell/src/shmsg.c @@ -44,7 +44,10 @@ #include "shell_pri.h" #include "shcmd.h" +#define CHAR_CTRL_C '\x03' +#define CHAR_CTRL_DEL '\x7F' +#define VISIABLE_CHAR(ch) ((ch) > 0x1F && (ch) < 0x7F) char *GetCmdline(ShellCB *shellCB) { @@ -202,7 +205,21 @@ void ParseEnterKey(OutputFunc outputFunc, ShellCB *shellCB) shellCB->shellBuf[shellCB->shellBufOffset] = '\0'; } NOTIFY: - outputFunc("\n"); + shellCB->shellBufOffset = 0; + ShellTaskNotify(shellCB); +} + +void ParseCancelKey(OutputFunc outputFunc, ShellCB *shellCB) +{ + if ((shellCB == NULL) || (outputFunc == NULL)) { + return; + } + + if (shellCB->shellBufOffset <= (SHOW_MAX_LEN - 1)) { + shellCB->shellBuf[0] = CHAR_CTRL_C; + shellCB->shellBuf[1] = '\0'; + } + shellCB->shellBufOffset = 0; ShellTaskNotify(shellCB); } @@ -238,7 +255,7 @@ void ParseTabKey(OutputFunc outputFunc, ShellCB *shellCB) void ParseNormalChar(char ch, OutputFunc outputFunc, ShellCB *shellCB) { - if ((shellCB == NULL) || (outputFunc == NULL)) { + if ((shellCB == NULL) || (outputFunc == NULL) || !VISIABLE_CHAR(ch)) { return; } @@ -256,7 +273,7 @@ void ShellCmdLineParse(char c, OutputFunc outputFunc, ShellCB *shellCB) const char ch = c; int ret; - if ((shellCB->shellBufOffset == 0) && (ch != '\n') && (ch != '\0')) { + if ((shellCB->shellBufOffset == 0) && (ch != '\n') && (ch != CHAR_CTRL_C) && (ch != '\0')) { (void)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN); } @@ -265,8 +282,11 @@ void ShellCmdLineParse(char c, OutputFunc outputFunc, ShellCB *shellCB) case '\n': /* enter */ ParseEnterKey(outputFunc, shellCB); break; + case CHAR_CTRL_C: /* ctrl + c */ + ParseCancelKey(outputFunc, shellCB); + break; case '\b': /* backspace */ - case 0x7F: /* delete(0x7F) */ + case CHAR_CTRL_DEL: /* delete(0x7F) */ ParseDeleteKey(outputFunc, shellCB); break; case '\t': /* tab */ @@ -358,6 +378,30 @@ void ChildExec(const char *cmdName, char *const paramArray[]) } } +int CheckExit(const char *cmdName, const CmdParsed *cmdParsed) +{ + int ret = 0; + + if (strlen(cmdName) != CMD_EXIT_COMMAND_BYTES || strncmp(cmdName, CMD_EXIT_COMMAND, CMD_EXIT_COMMAND_BYTES) != 0) { + return 0; + } + + if (cmdParsed->paramCnt > 1) { + printf("exit: too many arguments\n"); + return -1; + } + if (cmdParsed->paramCnt == 1) { + char *p; + ret = strtol(cmdParsed->paramArray[0], &p, CMD_EXIT_CODE_BASE_DEC); + if (*p != '\0') { + printf("exit: bad number: %s\n", cmdParsed->paramArray[0]); + return -1; + } + } + + exit(ret); +} + static void DoCmdExec(const char *cmdName, const char *cmdline, unsigned int len, const CmdParsed *cmdParsed) { int ret; @@ -378,6 +422,9 @@ static void DoCmdExec(const char *cmdName, const char *cmdline, unsigned int len } } } else { + if (CheckExit(cmdName, cmdParsed) < 0) { + return; + } (void)syscall(__NR_shellexec, cmdName, cmdline); } } @@ -535,7 +582,11 @@ static void ShellCmdProcess(ShellCB *shellCB) if (buf == NULL) { break; } - + if (buf[0] == CHAR_CTRL_C) { + printf("^C"); + buf[0] = '\n'; + } + printf("\n"); ExecCmdline(buf); ShellSaveHistoryCmd(buf, shellCB); shellCB->cmdMaskKeyLink = shellCB->cmdHistoryKeyLink; diff --git a/kernel/common/console.c b/kernel/common/console.c index 46cb1c8e..1eb47103 100644 --- a/kernel/common/console.c +++ b/kernel/common/console.c @@ -67,6 +67,9 @@ STATIC SPIN_LOCK_INIT(g_consoleSpin); #define CONSOLE_SEND_TASK_EXIT 0x04U #define CONSOLE_SEND_TASK_RUNNING 0x10U +#define SHELL_ENTRY_NAME "ShellEntry" +#define SHELL_ENTRY_NAME_LEN 10 + CONSOLE_CB *g_console[CONSOLE_NUM]; #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -1440,15 +1443,31 @@ BOOL ConsoleEnable(VOID) return FALSE; } +BOOL IsShellEntryRunning(UINT32 shellEntryId) +{ + LosTaskCB *taskCB; + if (shellEntryId == SHELL_ENTRYID_INVALID) { + return FALSE; + } + taskCB = OsGetTaskCB(shellEntryId); + return !OsTaskIsUnused(taskCB) && + (strlen(taskCB->taskName) == SHELL_ENTRY_NAME_LEN && + strncmp(taskCB->taskName, SHELL_ENTRY_NAME, SHELL_ENTRY_NAME_LEN) == 0); +} + INT32 ConsoleTaskReg(INT32 consoleID, UINT32 taskID) { - if (g_console[consoleID - 1]->shellEntryId == SHELL_ENTRYID_INVALID) { + UINT32 intSave; + + LOS_SpinLockSave(&g_consoleSpin, &intSave); + if (!IsShellEntryRunning(g_console[consoleID - 1]->shellEntryId)) { g_console[consoleID - 1]->shellEntryId = taskID; + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); (VOID)OsSetCurrProcessGroupID(OsGetUserInitProcessID()); return LOS_OK; } - - return LOS_NOK; + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + return g_console[consoleID - 1]->shellEntryId == taskID ? LOS_OK : LOS_NOK; } BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB) diff --git a/net/lwip-2.1/enhancement/src/api_shell.c b/net/lwip-2.1/enhancement/src/api_shell.c index 28921cd4..b6330d3e 100644 --- a/net/lwip-2.1/enhancement/src/api_shell.c +++ b/net/lwip-2.1/enhancement/src/api_shell.c @@ -1568,7 +1568,7 @@ static void lwip_ping_usage(void) "\n ping [-n cnt] [-w interval] [-l data_len] destination" "\n ping [-t] [-w interval] destination" "\n ping -k"); - PRINTK("\n -t means ping forever, user can use -k to stop the forever ping"); + PRINTK("\n -t means ping forever, user can use -k to stop the forever ping\n"); } LWIP_STATIC int osPingFunc(u32_t destip, u32_t cnt, u32_t interval, u32_t data_len) diff --git a/shell/full/src/cmds/shell_shellcmd.c b/shell/full/src/cmds/shell_shellcmd.c index 38124666..989f0713 100644 --- a/shell/full/src/cmds/shell_shellcmd.c +++ b/shell/full/src/cmds/shell_shellcmd.c @@ -31,6 +31,10 @@ #include "shcmd.h" +#define DEFAULT_SCREEN_WIDTH 80 +#define MAX_CMD_KEY_WIDTH 12 +#define CMD_ITEM_PER_LINE (DEFAULT_SCREEN_WIDTH / (MAX_CMD_KEY_WIDTH + 1)) + UINT32 OsShellCmdHelp(UINT32 argc, const CHAR **argv) { UINT32 loop = 0; @@ -45,15 +49,16 @@ UINT32 OsShellCmdHelp(UINT32 argc, const CHAR **argv) PRINTK("*******************shell commands:*************************\n"); LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(cmdInfo->cmdList.list), CmdItemNode, list) { - if ((loop & (8 - 1)) == 0) { /* 8 - 1:just align print */ + if ((loop % CMD_ITEM_PER_LINE) == 0) { /* just align print */ PRINTK("\n"); } - PRINTK("%-12s ", curCmdItem->cmd->cmdKey); + PRINTK("%-12s ", curCmdItem->cmd->cmdKey); loop++; } - - PRINTK("\n"); + PRINTK("\n\nAfter shell prompt \"OHOS # \":\n" + "Use ` [args ...]` to run built-in shell commands listed above.\n" + "Use `exec [args ...]` or `./ [args ...]` to run external commands.\n"); return 0; }