diff --git a/apps/shell/include/shmsg.h b/apps/shell/include/shmsg.h index b182db34894737b40311b35de076a16bac43f3db..d9c172a2302ef5c35fbe9b433e94a1d59a05335e 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 8329691bde180dc89a9e7c05be749e2bc1458f3f..320e60b441d7ff8b898247e2caa026033380bd25 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 46cb1c8e838c8c89b5afdb26826cd9fbdf7d15e5..1eb4710370fbf94c784474166582916f68d4b552 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 28921cd400287e1922a567c4051b89e78a7dcbae..b6330d3e39c0ca648a8a560dd12c7d2d4c668c65 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 38124666f89a3e775bca599886f778ff4bf15090..989f0713d35c25bf7b7023d2325dbea1d1e6b0dc 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; }