注解shell底层实现

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    博客输出站点(国内):http://weharmonyos.com
    博客输出站点(国外):https://openharmony.github.io
    注解文件系统:https://gitee.com/weharmony/third_party_NuttX
    注解协议栈:https://gitee.com/weharmony/third_party_lwip
    注解编译子系统:https://gitee.com/weharmony/build_lite
上级 eb3b380f
......@@ -190,19 +190,19 @@ static int OsShowPageControl(unsigned int timesPrint, unsigned int lineCap, unsi
}
return 1;
}
//确认打印的内容
static int OsSurePrintAll(unsigned int count)
{
char readChar = 0;
printf("\nDisplay all %u possibilities?(y/n)", count);
while (1) {
if (read(STDIN_FILENO, &readChar, 1) != 1) {
while (1) {//死循环等待输入
if (read(STDIN_FILENO, &readChar, 1) != 1) {//读取输入的字符
return (int)SH_ERROR;
}
if ((readChar == 'n') || (readChar == 'N') || (readChar == CTRL_C)) {
if ((readChar == 'n') || (readChar == 'N') || (readChar == CTRL_C)) {//不显示
printf("\n");
return 0;
} else if ((readChar == 'y') || (readChar == 'Y') || (readChar == '\r')) {
} else if ((readChar == 'y') || (readChar == 'Y') || (readChar == '\r')) {//显示的情况
return 1;
}
}
......@@ -296,7 +296,7 @@ static void OsCompleteStr(char *result, const char *target, char *cmdKey, unsign
(*len)++;
}
}
//当前目录下匹配名字
static int OsExecNameMatch(const char *strPath, const char *nameLooking, char *strObj, unsigned int *maxLen)
{
int count = 0;
......@@ -307,7 +307,7 @@ static int OsExecNameMatch(const char *strPath, const char *nameLooking, char *s
if (openDir == NULL) {
return (int)SH_ERROR;
}
//遍历文件夹
for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) {
if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) {
continue;
......
......@@ -93,7 +93,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
}
intSave = LOS_IntLock();//锁中断
eventCB->uwEventID = 0;
eventCB->uwEventID = 0;//事件类型初始化
LOS_ListInit(&eventCB->stEventList);//事件链表初始化
LOS_IntRestore(intSave);//恢复中断
OsHookCall(LOS_HOOK_TYPE_EVENT_INIT, eventCB);
......@@ -188,9 +188,9 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventM
return LOS_ERRNO_EVENT_READ_IN_LOCK;
}
runTask->eventMask = eventMask;//等待事件
runTask->eventMode = mode; //事件模式
runTask->taskEvent = eventCB;//事件控制块
runTask->eventMask = eventMask; //等待事件
runTask->eventMode = mode; //事件模式
runTask->taskEvent = eventCB; //事件控制块
OsTaskWaitSetPendMask(OS_TASK_WAIT_EVENT, eventMask, timeout);
ret = OsSchedTaskWait(&eventCB->stEventList, timeout, TRUE);
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
......@@ -290,13 +290,13 @@ LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32
{
UINT32 ret;
UINT32 intSave;
//事件参数检查
ret = OsEventParamCheck((VOID *)eventID, eventMask, mode);
if (ret != LOS_OK) {
return ret;
}
SCHEDULER_LOCK(intSave);
SCHEDULER_LOCK(intSave);//申请任务自旋锁
ret = OsEventPoll(eventID, eventMask, mode);
SCHEDULER_UNLOCK(intSave);
return ret;
......
......@@ -50,14 +50,14 @@
#define SIZEBUF 256
const CHAR *g_logString[] = {
"EMG",
"COMMON",
"ERR",
"WARN",
"INFO",
"DEBUG",
"TRACE"
const CHAR *g_logString[] = {//日志等级
"EMG", //紧急
"COMMON", //普通
"ERR", //错误日志
"WARN", //警告
"INFO", //信息
"DEBUG", //调试
"TRACE" //跟踪
};
const CHAR *OsLogLvGet(INT32 level)
......@@ -84,40 +84,40 @@ STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock)
UartPuts(str, len, isLock);//没有打开dmesg开关时,直接写串口
#endif
}
//输出控制处理
//控制台输出
#ifdef LOSCFG_PLATFORM_CONSOLE
STATIC VOID ConsoleOutput(const CHAR *str, UINT32 len)
{
ssize_t writen = 0;
ssize_t cnt;
ssize_t toWrite = len;
ssize_t toWrite = len;//每次写入的数量
for (;;) {
cnt = write(STDOUT_FILENO, str + writen, (size_t)toWrite);
cnt = write(STDOUT_FILENO, str + writen, (size_t)toWrite);//向控制台写入数据,STDOUT_FILENO = 1
if ((cnt < 0) || (toWrite == cnt)) {
break;
}
writen += cnt;
toWrite -= cnt;
writen += cnt; //已写入数量增加
toWrite -= cnt; //要写入数量减少
}
}
#endif
VOID OutputControl(const CHAR *str, UINT32 len, OutputType type)
{
switch (type) {
case CONSOLE_OUTPUT:
switch (type) {//输出类型
case CONSOLE_OUTPUT://控制台输出
#ifdef LOSCFG_PLATFORM_CONSOLE
if (ConsoleEnable() == TRUE) {//POSIX 定义了 STDIN_FILENO、STDOUT_FILENO 和 STDERR_FILENO 来代替 0、1、2
ConsoleOutput(str, len);
ConsoleOutput(str, len);//输出到控制台
break;//在三个文件会在 VFS中默认创建
}
#endif
/* fall-through */ //落空的情况下,会接着向串口打印数据
case UART_OUTPUT:
case UART_OUTPUT: //串口输出
UartOutput(str, len, UART_WITH_LOCK);//向串口发送数据
break;
case EXC_OUTPUT:
case EXC_OUTPUT: //异常输出
UartPuts(str, len, UART_WITH_LOCK);
break;
default:
......@@ -178,7 +178,7 @@ VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type)
systemStatus = OsGetSystemStatus();//获取系统的状态
if ((systemStatus == OS_SYSTEM_NORMAL) || (systemStatus == OS_SYSTEM_EXC_OTHER_CPU)) {//当前CPU空闲或其他CPU运行时
OutputControl(bBuf, len, type);//
OutputControl(bBuf, len, type);//输出到终端
} else if (systemStatus == OS_SYSTEM_EXC_CURR_CPU) {//当前CPU正在执行
OutputControl(bBuf, len, EXC_OUTPUT);//串口以无锁的方式输出
}
......@@ -197,7 +197,7 @@ __attribute__((noinline)) VOID UartPrintf(const CHAR *fmt, ...)
OsVprintf(fmt, ap, UART_OUTPUT);
va_end(ap);
}
//可变参数,输出到控制台
__attribute__ ((noinline)) VOID dprintf(const CHAR *fmt, ...)
{
va_list ap;
......@@ -228,7 +228,7 @@ __attribute__ ((noinline)) INT32 printf(const CHAR *fmt, ...)
return 0;
}
#endif
//系统日志的输出
__attribute__((noinline)) VOID syslog(INT32 level, const CHAR *fmt, ...)
{
va_list ap;
......@@ -237,7 +237,7 @@ __attribute__((noinline)) VOID syslog(INT32 level, const CHAR *fmt, ...)
va_end(ap);
(VOID)level;
}
//异常信息的输出
__attribute__((noinline)) VOID ExcPrintf(const CHAR *fmt, ...)
{
va_list ap;
......
......@@ -72,11 +72,11 @@ typedef struct {//shell 模块的全局信息
LosMux muxLock; //操作链表互斥锁
CmdVerifyTransID transIdHook;
} CmdModInfo;
//一个shell命令的结构体,命令有长有短,鸿蒙采用了可变数组的方式实现
typedef struct {
UINT32 count;
LOS_DL_LIST list;
CHAR cmdString[0];
UINT32 count; //字符数量
LOS_DL_LIST list; //双向链表
CHAR cmdString[0]; //字符串,可变数组的一种实现方式.
} CmdKeyLink;
//shell 静态宏方式注册
#define SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) \
......@@ -86,10 +86,10 @@ typedef struct {
paraNum, \
cmdHook \
}
//是否需要新开一行
#define NEED_NEW_LINE(timesPrint, lineCap) ((timesPrint) % (lineCap) == 0)
#define SCREEN_IS_FULL(timesPrint, lineCap) ((timesPrint) >= ((lineCap) * DEFAULT_SCREEN_HEIGNT))
//是否全屏显示
extern UINT32 OsCmdInit(VOID);
extern CmdModInfo *OsCmdInfoGet(VOID);
extern UINT32 OsCmdExec(CmdParsed *cmdParsed, CHAR *cmdStr);
......
......@@ -65,7 +65,7 @@ extern "C" {
#define CMD_MAX_LEN (256U + CMD_KEY_LEN)
#define CMD_KEY_NUM 32 //
#define CMD_HISTORY_LEN 10 //历史记录数量
#define CMD_MAX_PATH 256
#define CMD_MAX_PATH 256 //最大路径
#define DEFAULT_SCREEN_WIDTH 80 //屏幕的宽
#define DEFAULT_SCREEN_HEIGNT 24 //屏幕的高
......@@ -87,8 +87,8 @@ typedef struct {
UINT32 consoleID; //控制台ID
UINT32 shellTaskHandle; //shell服务端任务
UINT32 shellEntryHandle; //shell客户端任务
VOID *cmdKeyLink; //命令链表,所有敲过的命令链表
VOID *cmdHistoryKeyLink;//命令的历史记录链表,去重,10个
VOID *cmdKeyLink; //待处理的shell命令链表
VOID *cmdHistoryKeyLink;//已处理的历史记录链表,去重,10个
VOID *cmdMaskKeyLink; //主要用于方向键上下遍历历史命令
UINT32 shellBufOffset; //buf偏移量
UINT32 shellKeyType; //按键类型
......
......@@ -118,7 +118,7 @@ STATIC INT32 OsStrSeparate(CHAR *tabStr, CHAR *strPath, CHAR *nameLooking, UINT3
return ret;
}
/* get fullpath str */
/* get fullpath str *///获取全路径
if (*tabStr != '/') {
if (strncpy_s(strPath, CMD_MAX_PATH, shellWorkingDirectory, CMD_MAX_PATH - 1)) {
OsFreeCmdPara(&parsed);
......@@ -133,7 +133,7 @@ STATIC INT32 OsStrSeparate(CHAR *tabStr, CHAR *strPath, CHAR *nameLooking, UINT3
}
if (strncat_s(strPath, CMD_MAX_PATH, tabStr, CMD_MAX_PATH - strlen(strPath) - 1)) {
OsFreeCmdPara(&parsed);
OsFreeCmdPara(&parsed);//释放命令行中参数所占内存
return (INT32)OS_ERROR;
}
......@@ -151,12 +151,12 @@ STATIC INT32 OsStrSeparate(CHAR *tabStr, CHAR *strPath, CHAR *nameLooking, UINT3
OsFreeCmdPara(&parsed);
return LOS_OK;
}
//输出内容
STATIC INT32 OsShowPageInputControl(VOID)
{
CHAR readChar;
while (1) {
while (1) {//从 stdin 中读取内容字符
if (read(STDIN_FILENO, &readChar, 1) != 1) { /* get one CHAR from stdin */
PRINTK("\n");
return (INT32)OS_ERROR;
......@@ -170,36 +170,36 @@ STATIC INT32 OsShowPageInputControl(VOID)
}
}
}
//显示页内容控制器
STATIC INT32 OsShowPageControl(UINT32 timesPrint, UINT32 lineCap, UINT32 count)
{
if (NEED_NEW_LINE(timesPrint, lineCap)) {
if (NEED_NEW_LINE(timesPrint, lineCap)) {//是否新开一行
PRINTK("\n");
if (SCREEN_IS_FULL(timesPrint, lineCap) && (timesPrint < count)) {
PRINTK("--More--");
return OsShowPageInputControl();
return OsShowPageInputControl();//打印内容
}
}
return 1;
}
//是否打印所有内容
STATIC INT32 OsSurePrintAll(UINT32 count)
{
CHAR readChar = 0;
PRINTK("\nDisplay all %u possibilities?(y/n)", count);
while (1) {
if (read(0, &readChar, 1) != 1) {
while (1) {//死循环等待输入
if (read(0, &readChar, 1) != 1) {//从标准输入中 读取字符
return (INT32)OS_ERROR;
}
if ((readChar == 'n') || (readChar == 'N') || (readChar == CTRL_C)) {
if ((readChar == 'n') || (readChar == 'N') || (readChar == CTRL_C)) {//输入N
PRINTK("\n");
return 0;
} else if ((readChar == 'y') || (readChar == 'Y') || (readChar == '\r')) {
} else if ((readChar == 'y') || (readChar == 'Y') || (readChar == '\r')) {//输入 Y
return 1;
}
}
}
//打印匹配的列表数据
STATIC INT32 OsPrintMatchList(UINT32 count, const CHAR *strPath, const CHAR *nameLooking, UINT32 printLen)
{
UINT32 timesPrint = 0;
......@@ -216,12 +216,12 @@ STATIC INT32 OsPrintMatchList(UINT32 count, const CHAR *strPath, const CHAR *nam
}
if (count > (lineCap * DEFAULT_SCREEN_HEIGNT)) {
ret = OsSurePrintAll(count);
ret = OsSurePrintAll(count);//确认打印内容,等待用户输入 N/Y
if (ret != 1) {
return ret;
}
}
openDir = opendir(strPath);
openDir = opendir(strPath);//打开目录
if (openDir == NULL) {
return (INT32)OS_ERROR;
}
......@@ -270,6 +270,8 @@ STATIC VOID strncmp_cut(const CHAR *s1, CHAR *s2, size_t n)
}
return;
}
//匹配文件
STATIC INT32 OsExecNameMatch(const CHAR *strPath, const CHAR *nameLooking, CHAR *strObj, UINT32 *maxLen)
{
INT32 count = 0;
......@@ -280,9 +282,9 @@ STATIC INT32 OsExecNameMatch(const CHAR *strPath, const CHAR *nameLooking, CHAR
if (openDir == NULL) {
return (INT32)OS_ERROR;
}
//遍历目录下的文件夹
for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) {
if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) {
if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) {//不存在字符,
continue;
}
if (count == 0) {
......@@ -298,7 +300,7 @@ STATIC INT32 OsExecNameMatch(const CHAR *strPath, const CHAR *nameLooking, CHAR
*maxLen = strlen(readDir->d_name);
}
}
count++;
count++;//找到一个
}
if (closedir(openDir) < 0) {
......@@ -324,7 +326,12 @@ STATIC VOID OsCompleteStr(const CHAR *result, const CHAR *target, CHAR *cmdKey,
(*len)++;
}
}
//使用tab键去匹配命令
/*例如:
root@iZ7xv0x7yrn6s2or5pzw58Z:~# ls
ls lsblk lscpu lsinitramfs lslocks lsmem lsns lspci lsusb
lsattr lsb_release lshw lsipc lslogins lsmod lsof lspgpot
*/
STATIC INT32 OsTabMatchCmd(CHAR *cmdKey, UINT32 *len)
{
INT32 count = 0;
......@@ -340,12 +347,12 @@ STATIC INT32 OsTabMatchCmd(CHAR *cmdKey, UINT32 *len)
if (LOS_ListEmpty(&(g_cmdInfo.cmdList.list))) {
return (INT32)OS_ERROR;
}
//遍历现有命令
LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(g_cmdInfo.cmdList.list), CmdItemNode, list) {
if ((curCmdItem == NULL) || (curCmdItem->cmd == NULL)) {
return -1;
}
if (strncmp(cmdMajor, curCmdItem->cmd->cmdKey, strlen(cmdMajor)) > 0) {
continue;
}
......@@ -357,30 +364,30 @@ STATIC INT32 OsTabMatchCmd(CHAR *cmdKey, UINT32 *len)
if (count == 0) {
cmdItemGuard = curCmdItem;
}
++count;
++count;//匹配到一个
}
if (cmdItemGuard == NULL) {
return 0;
}
if (count == 1) {
if (count == 1) {//只有一个的情况,直接补充完整
OsCompleteStr(cmdItemGuard->cmd->cmdKey, cmdMajor, cmdKey, len);
}
ret = count;
if (count > 1) {
PRINTK("\n");
while (count--) {
while (count--) {//打印已经匹配到的命令
PRINTK("%s ", cmdItemGuard->cmd->cmdKey);
cmdItemGuard = LOS_DL_LIST_ENTRY(cmdItemGuard->list.pstNext, CmdItemNode, list);
cmdItemGuard = LOS_DL_LIST_ENTRY(cmdItemGuard->list.pstNext, CmdItemNode, list);//取下一个
}
PRINTK("\n");
}
return ret;
}
//使用tab键去匹配关键字文件
STATIC INT32 OsTabMatchFile(CHAR *cmdKey, UINT32 *len)
{
UINT32 maxLen = 0;
......@@ -400,7 +407,7 @@ STATIC INT32 OsTabMatchFile(CHAR *cmdKey, UINT32 *len)
(VOID)LOS_MemFree(m_aucSysMem0, dirOpen);
return (INT32)OS_ERROR;
}
//匹配名字
count = OsExecNameMatch(dirOpen, strCmp, strOutput, &maxLen);
/* one or more matched */
if (count >= 1) {
......@@ -533,7 +540,7 @@ LITE_OS_SEC_TEXT_MINOR BOOL OsCmdKeyCheck(const CHAR *cmdKey)
return TRUE;
}
//tab键
LITE_OS_SEC_TEXT_MINOR INT32 OsTabCompletion(CHAR *cmdKey, UINT32 *len)
{
INT32 count = 0;
......@@ -545,7 +552,7 @@ LITE_OS_SEC_TEXT_MINOR INT32 OsTabCompletion(CHAR *cmdKey, UINT32 *len)
}
/* cut left space */
while (*cmdMainStr == 0x20) {
while (*cmdMainStr == 0x20) {//空格键
cmdMainStr++;
}
......@@ -570,14 +577,14 @@ LITE_OS_SEC_TEXT_MINOR VOID OsCmdAscendingInsert(CmdItemNode *cmd)
if (cmd == NULL) {
return;
}
//遍历注册的命令项链表
for (cmdItem = LOS_DL_LIST_ENTRY((&g_cmdInfo.cmdList.list)->pstPrev, CmdItemNode, list);
&cmdItem->list != &(g_cmdInfo.cmdList.list);) {
cmdNext = LOS_DL_LIST_ENTRY(cmdItem->list.pstPrev, CmdItemNode, list);
cmdNext = LOS_DL_LIST_ENTRY(cmdItem->list.pstPrev, CmdItemNode, list);//获取实体,一个个比较
if (&cmdNext->list != &(g_cmdInfo.cmdList.list)) {
if ((strncmp(cmdItem->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) >= 0) &&
(strncmp(cmdNext->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) < 0)) {
LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));
LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));//从尾部插入
return;
}
cmdItem = cmdNext;
......@@ -591,7 +598,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsCmdAscendingInsert(CmdItemNode *cmd)
LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));
}
//shell 按键初始化
//shell 命令初始化
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellKeyInit(ShellCB *shellCB)
{
CmdKeyLink *cmdKeyLink = NULL;
......@@ -613,16 +620,16 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellKeyInit(ShellCB *shellCB)
}
cmdKeyLink->count = 0;
LOS_ListInit(&(cmdKeyLink->list));
shellCB->cmdKeyLink = (VOID *)cmdKeyLink;
LOS_ListInit(&(cmdKeyLink->list));//待处理命令链表初始化
shellCB->cmdKeyLink = (VOID *)cmdKeyLink;//链表源头
cmdHistoryLink->count = 0;
LOS_ListInit(&(cmdHistoryLink->list));
shellCB->cmdHistoryKeyLink = (VOID *)cmdHistoryLink;
shellCB->cmdMaskKeyLink = (VOID *)cmdHistoryLink;
LOS_ListInit(&(cmdHistoryLink->list));//历史记录链表初始化
shellCB->cmdHistoryKeyLink = (VOID *)cmdHistoryLink;//链表源头
shellCB->cmdMaskKeyLink = (VOID *)cmdHistoryLink;//掩码命令链表同历史记录链表,标识上下键位置.
return LOS_OK;
}
//shell的析构函数
LITE_OS_SEC_TEXT_MINOR VOID OsShellKeyDeInit(CmdKeyLink *cmdKeyLink)
{
CmdKeyLink *cmdtmp = NULL;
......@@ -630,13 +637,13 @@ LITE_OS_SEC_TEXT_MINOR VOID OsShellKeyDeInit(CmdKeyLink *cmdKeyLink)
return;
}
while (!LOS_ListEmpty(&(cmdKeyLink->list))) {
while (!LOS_ListEmpty(&(cmdKeyLink->list))) {//清空待处理命令列表
cmdtmp = LOS_DL_LIST_ENTRY(cmdKeyLink->list.pstNext, CmdKeyLink, list);
LOS_ListDelete(&cmdtmp->list);
(VOID)LOS_MemFree(m_aucSysMem0, cmdtmp);
LOS_ListDelete(&cmdtmp->list);//将自己从链表中摘出去
(VOID)LOS_MemFree(m_aucSysMem0, cmdtmp);//释放内核内存空间
}
cmdKeyLink->count = 0;
cmdKeyLink->count = 0;//链表为空,个数清0
(VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink);
}
//注册系统自带的shell命令
......@@ -746,16 +753,16 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdExec(CmdParsed *cmdParsed, CHAR *cmdStr)
return (UINT32)OS_ERROR;
}
ret = OsCmdParse(cmdStr, cmdParsed);//解析命令
ret = OsCmdParse(cmdStr, cmdParsed);//解析出命令关键字,参数
if (ret != LOS_OK) {
goto OUT;
}
//遍历链表
//遍历命令注册全局链表
LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(g_cmdInfo.cmdList.list), CmdItemNode, list) {
cmdKey = curCmdItem->cmd->cmdKey;
if ((cmdParsed->cmdType == curCmdItem->cmd->cmdType) &&
(strlen(cmdKey) == strlen(cmdParsed->cmdKeyword)) &&
(strncmp(cmdKey, (CHAR *)(cmdParsed->cmdKeyword), strlen(cmdKey)) == 0)) {
(strncmp(cmdKey, (CHAR *)(cmdParsed->cmdKeyword), strlen(cmdKey)) == 0)) {//找到命令的回调函数 例如: ls <-> osShellCmdLs
cmdHook = curCmdItem->cmd->cmdHook;
break;
}
......
......@@ -35,7 +35,7 @@
/*
* Filter out double quote or single-quoted strings at both ends
*/
*///过滤掉两端的双引号或单引号字符串
LITE_OS_SEC_TEXT_MINOR CHAR *OsCmdParseStrdup(const CHAR *str)
{
CHAR *tempStr = NULL;
......@@ -48,7 +48,7 @@ LITE_OS_SEC_TEXT_MINOR CHAR *OsCmdParseStrdup(const CHAR *str)
tempStr = newStr;
for (; *str != '\0'; str++) {
if ((*str == '\"') || (*str == '\'')) {
if ((*str == '\"') || (*str == '\'')) {//过滤掉 \" 和 \'
continue;
}
*newStr = *str;
......@@ -57,7 +57,7 @@ LITE_OS_SEC_TEXT_MINOR CHAR *OsCmdParseStrdup(const CHAR *str)
*newStr = '\0';
return tempStr;
}
//获取一个参数实体
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParseParaGet(CHAR **value, const CHAR *paraTokenStr)
{
if ((paraTokenStr == NULL) || (value == NULL)) {
......@@ -70,7 +70,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParseParaGet(CHAR **value, const CHAR *paraTo
}
return LOS_OK;
}
//解析一个令牌
//解析出一个参数
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParseOneToken(CmdParsed *cmdParsed, UINT32 index, const CHAR *token)
{
UINT32 ret = LOS_OK;
......@@ -88,11 +88,11 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdParseOneToken(CmdParsed *cmdParsed, UINT32 in
//参数限制,最多不能超过32个
if ((token != NULL) && (cmdParsed->paramCnt < CMD_MAX_PARAS)) {
tempLen = cmdParsed->paramCnt;
ret = OsCmdParseParaGet(&(cmdParsed->paramArray[tempLen]), token);
ret = OsCmdParseParaGet(&(cmdParsed->paramArray[tempLen]), token);//获取一个参数实体
if (ret != LOS_OK) {
return ret;
}
cmdParsed->paramCnt++;
cmdParsed->paramCnt++;//参数增加一个
}
return ret;
}
......
......@@ -58,15 +58,15 @@ typedef struct {
FILE *fp; //文件描述结构体
} Logger;
STATIC INT32 g_tracelevel;
STATIC INT32 g_modulelevel;
STATIC INT32 g_tracelevel;//日志等级
STATIC INT32 g_modulelevel;//模块等级
STATIC Logger g_logger = { 0 };
VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap);
LK_FUNC g_osLkHook = (LK_FUNC)OsLkDefaultFunc;
//获取日志等级
STATIC INLINE INT32 OsLkTraceLvGet(VOID)
{
return g_tracelevel;
......
......@@ -46,58 +46,58 @@
#include "console.h"
#endif
//获取输入命令buf
CHAR *ShellGetInputBuf(ShellCB *shellCB)
{
CmdKeyLink *cmdkey = shellCB->cmdKeyLink;
CmdKeyLink *cmdkey = shellCB->cmdKeyLink;//待处理的shell命令链表
CmdKeyLink *cmdNode = NULL;
(VOID)pthread_mutex_lock(&shellCB->keyMutex);
if ((cmdkey == NULL) || LOS_ListEmpty(&cmdkey->list)) {
if ((cmdkey == NULL) || LOS_ListEmpty(&cmdkey->list)) {//链表为空的处理
(VOID)pthread_mutex_unlock(&shellCB->keyMutex);
return NULL;
}
cmdNode = LOS_DL_LIST_ENTRY(cmdkey->list.pstNext, CmdKeyLink, list);
LOS_ListDelete(&(cmdNode->list)); /* 'cmdNode' freed in history save process */
cmdNode = LOS_DL_LIST_ENTRY(cmdkey->list.pstNext, CmdKeyLink, list);//获取当前命令项
LOS_ListDelete(&(cmdNode->list)); /* 'cmdNode' freed in history save process *///将自己摘出去,但在历史记录中还存在
(VOID)pthread_mutex_unlock(&shellCB->keyMutex);
return cmdNode->cmdString;
return cmdNode->cmdString;//返回命令内容
}
//保存命令历史记录,这个函数写的不太好
STATIC VOID ShellSaveHistoryCmd(const CHAR *string, ShellCB *shellCB)
{
CmdKeyLink *cmdHistory = shellCB->cmdHistoryKeyLink;
CmdKeyLink *cmdkey = LOS_DL_LIST_ENTRY(string, CmdKeyLink, cmdString);
CmdKeyLink *cmdHistory = shellCB->cmdHistoryKeyLink;//获取历史记录的源头
CmdKeyLink *cmdkey = LOS_DL_LIST_ENTRY(string, CmdKeyLink, cmdString);// @note_good ,获取CmdKeyLink,这里挺秒的,通过局部字符串找到整体
CmdKeyLink *cmdNxt = NULL;
if ((string == NULL) || (strlen(string) == 0)) {
return;
}
(VOID)pthread_mutex_lock(&shellCB->historyMutex);
if (cmdHistory->count != 0) {
cmdNxt = LOS_DL_LIST_ENTRY(cmdHistory->list.pstPrev, CmdKeyLink, list);
if (strcmp(string, cmdNxt->cmdString) == 0) {
(VOID)pthread_mutex_lock(&shellCB->historyMutex);//对链表的操作都要拿互斥锁
if (cmdHistory->count != 0) { //有历史记录的情况
cmdNxt = LOS_DL_LIST_ENTRY(cmdHistory->list.pstPrev, CmdKeyLink, list);//获取最老的历史记录
if (strcmp(string, cmdNxt->cmdString) == 0) {//比较是否一样,这个地方感觉很怪,只比较一个吗?
(VOID)LOS_MemFree(m_aucSysMem0, (VOID *)cmdkey);
(VOID)pthread_mutex_unlock(&shellCB->historyMutex);
return;
}
}
if (cmdHistory->count == CMD_HISTORY_LEN) {
cmdNxt = LOS_DL_LIST_ENTRY(cmdHistory->list.pstNext, CmdKeyLink, list);
LOS_ListDelete(&(cmdNxt->list));
LOS_ListTailInsert(&(cmdHistory->list), &(cmdkey->list));
(VOID)LOS_MemFree(m_aucSysMem0, (VOID *)cmdNxt);
(VOID)pthread_mutex_unlock(&shellCB->historyMutex);
if (cmdHistory->count == CMD_HISTORY_LEN) {//历史记录已满,一删一添导致历史记录永远是满的,所以一旦跑进来了
cmdNxt = LOS_DL_LIST_ENTRY(cmdHistory->list.pstNext, CmdKeyLink, list);//后续 ShellSaveHistoryCmd都会跑进来执行
LOS_ListDelete(&(cmdNxt->list));//先删除一个最早插入的
LOS_ListTailInsert(&(cmdHistory->list), &(cmdkey->list));//再从尾部挂入新的节点,变成最新的记录
(VOID)LOS_MemFree(m_aucSysMem0, (VOID *)cmdNxt);//释放已经删除的节点, @note_thinking , 建议和上一句换个位置,保证逻辑上的完整性
(VOID)pthread_mutex_unlock(&shellCB->historyMutex);//释放互斥锁
return;
}
//未满的情况下执行到此处
LOS_ListTailInsert(&(cmdHistory->list), &(cmdkey->list));//从尾部插入
cmdHistory->count++;//历史记录增加
LOS_ListTailInsert(&(cmdHistory->list), &(cmdkey->list));
cmdHistory->count++;
(VOID)pthread_mutex_unlock(&shellCB->historyMutex);
(VOID)pthread_mutex_unlock(&shellCB->historyMutex);//释放互斥锁
return;
}
//发送解析事件
......@@ -107,40 +107,56 @@ STATIC VOID ShellNotify(ShellCB *shellCB)
}
enum {
STAT_NOMAL_KEY,
STAT_ESC_KEY,
STAT_MULTI_KEY
STAT_NOMAL_KEY, //普通的按键
STAT_ESC_KEY, //<ESC>键在VT控制规范中时控制的起始键
STAT_MULTI_KEY //组合键
};
//解析上下左右键
/* https://www.cnblogs.com/Spiro-K/p/6592518.html
#!/bin/bash
#字符颜色显示
#-e:允许echo使用转义
#\033[:开始位
#\033[0m:结束位
#\033等同于\e
echo -e "\033[30m黑色字\033[0m"
echo -e "\033[31m红色字\033[0m"
echo -e "\033[32m绿色字\033[0m"
echo -e "\033[33m黄色字\033[0m"
echo -e "\033[34m蓝色字\033[0m"
echo -e "\033[35m紫色字\033[0m"
echo -e "\033[36m天蓝字\033[0m"
echo -e "\033[37m白色字\033[0m"
*/
STATIC INT32 ShellCmdLineCheckUDRL(const CHAR ch, ShellCB *shellCB)
{
INT32 ret = LOS_OK;
if (ch == 0x1b) { /* 0x1b: ESC */
shellCB->shellKeyType = STAT_ESC_KEY;
if (ch == 0x1b) { /* 0x1b: ESC *///按下<ESC>键(逃逸键)
shellCB->shellKeyType = STAT_ESC_KEY;//代表控制开始
return ret;
} else if (ch == 0x5b) { /* 0x5b: first Key combination */ //为[键 ,遵循 vt100 规则
if (shellCB->shellKeyType == STAT_ESC_KEY) {
shellCB->shellKeyType = STAT_MULTI_KEY;
return ret;
}
} else if (ch == 0x41) { /* up */
} else if (ch == 0x41) { /* up */ //上方向键
if (shellCB->shellKeyType == STAT_MULTI_KEY) {
OsShellHistoryShow(CMD_KEY_UP, shellCB);
shellCB->shellKeyType = STAT_NOMAL_KEY;
return ret;
}
} else if (ch == 0x42) { /* down */
} else if (ch == 0x42) { /* down *///下方向键
if (shellCB->shellKeyType == STAT_MULTI_KEY) {
shellCB->shellKeyType = STAT_NOMAL_KEY;
OsShellHistoryShow(CMD_KEY_DOWN, shellCB);
return ret;
}
} else if (ch == 0x43) { /* right */
} else if (ch == 0x43) { /* right *///右方向键
if (shellCB->shellKeyType == STAT_MULTI_KEY) {
shellCB->shellKeyType = STAT_NOMAL_KEY;
return ret;
}
} else if (ch == 0x44) { /* left */
} else if (ch == 0x44) { /* left *///左方向键
if (shellCB->shellKeyType == STAT_MULTI_KEY) {
shellCB->shellKeyType = STAT_NOMAL_KEY;
return ret;
......@@ -148,12 +164,12 @@ STATIC INT32 ShellCmdLineCheckUDRL(const CHAR ch, ShellCB *shellCB)
}
return LOS_NOK;
}
//对命令行内容分解
//对命令行内容解析
LITE_OS_SEC_TEXT_MINOR VOID ShellCmdLineParse(CHAR c, pf_OUTPUT outputFunc, ShellCB *shellCB)
{
const CHAR ch = c;
INT32 ret;
//不是碰到回车键和字符串结束
//不是回车键和字符串结束,且偏移量为0
if ((shellCB->shellBufOffset == 0) && (ch != '\n') && (ch != '\0')) {
(VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN);//重置buf
}
......@@ -189,18 +205,18 @@ LITE_OS_SEC_TEXT_MINOR VOID ShellCmdLineParse(CHAR c, pf_OUTPUT outputFunc, Shel
if (ret == LOS_OK) {
return;
}
if ((ch != '\n') && (ch != '\0')) {
if (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1)) {
shellCB->shellBuf[shellCB->shellBufOffset] = ch;
if ((ch != '\n') && (ch != '\0')) {//普通的字符的处理
if (shellCB->shellBufOffset < (SHOW_MAX_LEN - 1)) {//buf范围
shellCB->shellBuf[shellCB->shellBufOffset] = ch;//直接加入
} else {
shellCB->shellBuf[SHOW_MAX_LEN - 1] = '\0';
shellCB->shellBuf[SHOW_MAX_LEN - 1] = '\0';//加入字符串结束符
}
shellCB->shellBufOffset++;
outputFunc("%c", ch);
shellCB->shellBufOffset++;//偏移量增加
outputFunc("%c", ch);//向终端输出字符
}
shellCB->shellKeyType = STAT_NOMAL_KEY;
shellCB->shellKeyType = STAT_NOMAL_KEY;//普通字符
}
//获取shell消息类型
LITE_OS_SEC_TEXT_MINOR UINT32 ShellMsgTypeGet(CmdParsed *cmdParsed, const CHAR *cmdType)
......@@ -227,7 +243,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 ShellMsgTypeGet(CmdParsed *cmdParsed, const CHAR *
return OS_INVALID;
}
//获取命令名称和参数,并执行
STATIC UINT32 ShellMsgNameGetAndExec(CmdParsed *cmdParsed, const CHAR *output, UINT32 len)
{
UINT32 loop;
......@@ -264,12 +280,12 @@ STATIC UINT32 ShellMsgNameGetAndExec(CmdParsed *cmdParsed, const CHAR *output, U
if (ret != LOS_OK) {
PRINTK("%s:command not found", msgName);
} else {
(VOID)OsCmdExec(cmdParsed, (CHAR *)output);
(VOID)OsCmdExec(cmdParsed, (CHAR *)output);//真正的执行命令 output为输出设备
}
(VOID)LOS_MemFree(m_aucSysMem0, msgName);
return ret;
}
//命令内容解析
LITE_OS_SEC_TEXT_MINOR UINT32 ShellMsgParse(const VOID *msg)
{
CHAR *output = NULL;
......@@ -304,7 +320,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 ShellMsgParse(const VOID *msg)
if (output == NULL) {
PRINTK("malloc failure in %s[%d]\n", __FUNCTION__, __LINE__);
goto END;
}
}//对字符串缓冲区,调用函数“OsCmdKeyShift”来挤压和清除无用或过多的空间
/* Call function 'OsCmdKeyShift' to squeeze and clear useless or overmuch space if string buffer */
ret = OsCmdKeyShift((CHAR *)msg, output, len + 1);
if ((ret != LOS_OK) || (strlen(output) == 0)) {
......@@ -314,7 +330,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 ShellMsgParse(const VOID *msg)
(VOID)memset_s(&cmdParsed, sizeof(CmdParsed), 0, sizeof(CmdParsed));
ret = ShellMsgNameGetAndExec(&cmdParsed, output, len);
ret = ShellMsgNameGetAndExec(&cmdParsed, output, len);////获取命令名称和参数,并执行
END_FREE_OUTPUT:
(VOID)LOS_MemFree(m_aucSysMem0, output);
......@@ -338,18 +354,18 @@ LITE_OS_SEC_TEXT_MINOR UINT32 ShellEntry(UINTPTR param)
return 1;
}
(VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN);
(VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN);//重置shell命令buf
while (1) {
#ifdef LOSCFG_PLATFORM_CONSOLE
if (!IsConsoleOccupied(consoleCB)) {//控制台是否被占用
#endif
/* is console ready for shell ? */
n = read(consoleCB->fd, &ch, 1);//从控制台读取一个字符内容
n = read(consoleCB->fd, &ch, 1);//从控制台读取一个字符内容,字符一个个处理
if (n == 1) {//如果能读到一个字符
ShellCmdLineParse(ch, (pf_OUTPUT)dprintf, shellCB);
}
if (is_nonblock(consoleCB)) {
if (is_nonblock(consoleCB)) {//在非阻塞模式下暂停 50ms
LOS_Msleep(50); /* 50: 50MS for sleep */
}
#ifdef LOSCFG_PLATFORM_CONSOLE
......@@ -363,7 +379,7 @@ STATIC VOID ShellCmdProcess(ShellCB *shellCB)
{
CHAR *buf = NULL;
while (1) {
buf = ShellGetInputBuf(shellCB);//获取输入的buf
buf = ShellGetInputBuf(shellCB);//获取命令buf
if (buf == NULL) {
break;
}
......@@ -405,7 +421,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 ShellTask(UINTPTR param1,
#define SERIAL_ENTRY_TASK_NAME "SerialEntryTask"
#define TELNET_SHELL_TASK_NAME "TelnetShellTask"
#define TELNET_ENTRY_TASK_NAME "TelnetEntryTask"
//shell 任务初始化
//shell 服务端任务初始化,这个任务负责解析和执行命令
LITE_OS_SEC_TEXT_MINOR UINT32 ShellTaskInit(ShellCB *shellCB)
{
CHAR *name = NULL;
......@@ -419,18 +435,18 @@ LITE_OS_SEC_TEXT_MINOR UINT32 ShellTaskInit(ShellCB *shellCB)
return LOS_NOK;
}
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellTask;//任务入口地址,主要是解析shell命令
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellTask;//任务入口函数,主要是解析shell命令
initParam.usTaskPrio = 9; /* 9:shell task priority */
initParam.auwArgs[0] = (UINTPTR)shellCB;
initParam.uwStackSize = 0x3000;
initParam.pcName = name;
initParam.uwResved = LOS_TASK_STATUS_DETACHED;
(VOID)LOS_EventInit(&shellCB->shellEvent);
(VOID)LOS_EventInit(&shellCB->shellEvent);//初始化事件,以事件方式通知任务解析命令
return LOS_TaskCreate(&shellCB->shellTaskHandle, &initParam);
return LOS_TaskCreate(&shellCB->shellTaskHandle, &initParam);//创建任务
}
//进入shell初始化
//进入shell客户端任务初始化,这个任务负责编辑命令,处理命令产生的过程,例如如何处理方向键,退格键,回车键等
LITE_OS_SEC_TEXT_MINOR UINT32 ShellEntryInit(ShellCB *shellCB)
{
UINT32 ret;
......@@ -445,16 +461,16 @@ LITE_OS_SEC_TEXT_MINOR UINT32 ShellEntryInit(ShellCB *shellCB)
return LOS_NOK;
}
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellEntry;//主要是读取命令行内容
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ShellEntry;//任务入口函数
initParam.usTaskPrio = 9; /* 9:shell task priority */
initParam.auwArgs[0] = (UINTPTR)shellCB;
initParam.uwStackSize = 0x1000;
initParam.pcName = name;
initParam.uwResved = LOS_TASK_STATUS_DETACHED;
ret = LOS_TaskCreate(&shellCB->shellEntryHandle, &initParam);
ret = LOS_TaskCreate(&shellCB->shellEntryHandle, &initParam);//创建任务
#ifdef LOSCFG_PLATFORM_CONSOLE
(VOID)ConsoleTaskReg((INT32)shellCB->consoleID, shellCB->shellEntryHandle);
(VOID)ConsoleTaskReg((INT32)shellCB->consoleID, shellCB->shellEntryHandle);//将任务注册到控制台
#endif
return ret;
......
......@@ -157,19 +157,19 @@ INT32 OsShellDeinit(INT32 consoleId)
return 0;
}
//获取shell的工作目录
CHAR *OsShellGetWorkingDirtectory(VOID)
{
CONSOLE_CB *consoleCB = OsGetConsoleByTaskID(OsCurrTaskGet()->taskID);
CONSOLE_CB *consoleCB = OsGetConsoleByTaskID(OsCurrTaskGet()->taskID);//获取当前任务控制台
ShellCB *shellCB = NULL;
if (consoleCB == NULL) {
return NULL;
}
shellCB = (ShellCB *)consoleCB->shellHandle;
shellCB = (ShellCB *)consoleCB->shellHandle;//获取控制台的shell实体
if (shellCB == NULL) {
return NULL;
}
return shellCB->shellWorkingDirectory;
return shellCB->shellWorkingDirectory;//返回shell工作目录
}
git add -A
git commit -m ' shell编辑,解析,执行三步走过程解析
git commit -m ' 注解shell底层实现
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
博客输出站点(国内):http://weharmonyos.com
博客输出站点(国外):https://openharmony.github.io
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册