更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
shcmd.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "shcmd.h"
33#include "shell_pri.h"
34#include "show.h"
35#include "stdlib.h"
36#include "unistd.h"
37#include "dirent.h"
38#include "securec.h"
39#include "los_mux.h"
40#include "los_memory.h"
41#include "los_typedef.h"
42
43
44#define SHELL_INIT_MAGIC_FLAG 0xABABABAB ///< shell的魔法数字
45#define CTRL_C 0x03 /* 0x03: ctrl+c ASCII */
46
47STATIC CmdModInfo g_cmdInfo; ///< shell 命令模块信息,上面挂了所有的命令项(ls,cd ,cp ==)
48
51/// 获取全局变量
53{
54 return &g_cmdInfo;
55}
56/// 释放命令行参数所占内存
57STATIC VOID OsFreeCmdPara(CmdParsed *cmdParsed)
58{
59 UINT32 i;
60 for (i = 0; i < cmdParsed->paramCnt; i++) {//遍历参数个数
61 if ((cmdParsed->paramArray[i]) != NULL) {//一个个释放内存
62 (VOID)LOS_MemFree(m_aucSysMem0, (cmdParsed->paramArray[i]));
63 cmdParsed->paramArray[i] = NULL;//重新初始化
64 }
65 }
66}
67
68STATIC INT32 OsStrSeparateTabStrGet(CHAR **tabStr, CmdParsed *parsed, UINT32 tabStrLen)
69{
70 CHAR *shiftStr = NULL;
71 CHAR *tempStr = (CHAR *)LOS_MemAlloc(m_aucSysMem0, SHOW_MAX_LEN << 1);
72 if (tempStr == NULL) {
73 return (INT32)OS_ERROR;
74 }
75
76 (VOID)memset_s(tempStr, SHOW_MAX_LEN << 1, 0, SHOW_MAX_LEN << 1);
77 shiftStr = tempStr + SHOW_MAX_LEN;
78
79 if (strncpy_s(tempStr, SHOW_MAX_LEN - 1, *tabStr, tabStrLen)) {
80 (VOID)LOS_MemFree(m_aucSysMem0, tempStr);
81 return (INT32)OS_ERROR;
82 }
83
84 parsed->cmdType = CMD_TYPE_STD;
85
86 /* cut useless or repeat space */
87 if (OsCmdKeyShift(tempStr, shiftStr, SHOW_MAX_LEN - 1)) {
88 (VOID)LOS_MemFree(m_aucSysMem0, tempStr);
89 return (INT32)OS_ERROR;
90 }
91
92 /* get exact position of string to complete */
93 /* situation different if end space lost or still exist */
94 if ((strlen(shiftStr) == 0) || (tempStr[strlen(tempStr) - 1] != shiftStr[strlen(shiftStr) - 1])) {
95 *tabStr = "";
96 } else {
97 if (OsCmdTokenSplit(shiftStr, ' ', parsed)) {
98 (VOID)LOS_MemFree(m_aucSysMem0, tempStr);
99 return (INT32)OS_ERROR;
100 }
101 *tabStr = parsed->paramArray[parsed->paramCnt - 1];
102 }
103
104 (VOID)LOS_MemFree(m_aucSysMem0, tempStr);
105 return LOS_OK;
106}
107
108STATIC INT32 OsStrSeparate(CHAR *tabStr, CHAR *strPath, CHAR *nameLooking, UINT32 tabStrLen)
109{
110 CHAR *strEnd = NULL;
111 CHAR *cutPos = NULL;
112 CmdParsed parsed = {0};
113 CHAR *shellWorkingDirectory = OsShellGetWorkingDirectory();
114 INT32 ret;
115
116 ret = OsStrSeparateTabStrGet(&tabStr, &parsed, tabStrLen);
117 if (ret != LOS_OK) {
118 return ret;
119 }
120
121 /* get fullpath str *///获取全路径
122 if (*tabStr != '/') {
123 if (strncpy_s(strPath, CMD_MAX_PATH, shellWorkingDirectory, CMD_MAX_PATH - 1)) {
124 OsFreeCmdPara(&parsed);
125 return (INT32)OS_ERROR;
126 }
127 if (strcmp(shellWorkingDirectory, "/")) {
128 if (strncat_s(strPath, CMD_MAX_PATH, "/", CMD_MAX_PATH - strlen(strPath) - 1)) {
129 OsFreeCmdPara(&parsed);
130 return (INT32)OS_ERROR;
131 }
132 }
133 }
134
135 if (strncat_s(strPath, CMD_MAX_PATH, tabStr, CMD_MAX_PATH - strlen(strPath) - 1)) {
136 OsFreeCmdPara(&parsed);//释放命令行中参数所占内存
137 return (INT32)OS_ERROR;
138 }
139
140 /* split str by last '/' */
141 strEnd = strrchr(strPath, '/');
142 cutPos = strEnd;
143 if (strEnd != NULL) {
144 if (strncpy_s(nameLooking, CMD_MAX_PATH, strEnd + 1, CMD_MAX_PATH - 1)) { /* get cmp str */
145 OsFreeCmdPara(&parsed);
146 return (INT32)OS_ERROR;
147 }
148 *(cutPos + 1) = '\0';
149 }
150
151 OsFreeCmdPara(&parsed);
152 return LOS_OK;
153}
154/// 输出内容
156{
157 CHAR readChar;
158
159 while (1) {//从 stdin 中读取内容字符
160 if (read(STDIN_FILENO, &readChar, 1) != 1) { /* get one CHAR from stdin */
161 PRINTK("\n");
162 return (INT32)OS_ERROR;
163 }
164 if ((readChar == 'q') || (readChar == 'Q') || (readChar == CTRL_C)) {
165 PRINTK("\n");
166 return 0;
167 } else if (readChar == '\r') {
168 PRINTK("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b");
169 return 1;
170 }
171 }
172}
173///显示页内容控制器
174STATIC INT32 OsShowPageControl(UINT32 timesPrint, UINT32 lineCap, UINT32 count)
175{
176 if (NEED_NEW_LINE(timesPrint, lineCap)) {//是否新开一行
177 PRINTK("\n");
178 if (SCREEN_IS_FULL(timesPrint, lineCap) && (timesPrint < count)) {
179 PRINTK("--More--");
180 return OsShowPageInputControl();//打印内容
181 }
182 }
183 return 1;
184}
185///是否打印所有内容
187{
188 CHAR readChar = 0;
189 PRINTK("\nDisplay all %u possibilities?(y/n)", count);
190 while (1) {//死循环等待输入
191 if (read(0, &readChar, 1) != 1) {//从标准输入中 读取字符
192 return (INT32)OS_ERROR;
193 }
194 if ((readChar == 'n') || (readChar == 'N') || (readChar == CTRL_C)) {//输入N
195 PRINTK("\n");
196 return 0;
197 } else if ((readChar == 'y') || (readChar == 'Y') || (readChar == '\r')) {//输入 Y
198 return 1;
199 }
200 }
201}
202///打印匹配的列表数据
203STATIC INT32 OsPrintMatchList(UINT32 count, const CHAR *strPath, const CHAR *nameLooking, UINT32 printLen)
204{
205 UINT32 timesPrint = 0;
206 UINT32 lineCap;
207 INT32 ret;
208 DIR *openDir = NULL;
209 struct dirent *readDir = NULL;
210 CHAR formatChar[10] = {0}; /* 10:for formatChar length */
211
212 printLen = (printLen > (DEFAULT_SCREEN_WIDTH - 2)) ? (DEFAULT_SCREEN_WIDTH - 2) : printLen; /* 2:revered 2 bytes */
213 lineCap = DEFAULT_SCREEN_WIDTH / (printLen + 2); /* 2:DEFAULT_SCREEN_WIDTH revered 2 bytes */
214 if (snprintf_s(formatChar, sizeof(formatChar) - 1, 7, "%%-%us ", printLen) < 0) { /* 7:format-len */
215 return (INT32)OS_ERROR;
216 }
217
218 if (count > (lineCap * DEFAULT_SCREEN_HEIGHT)) {
219 ret = OsSurePrintAll(count);//确认打印内容,等待用户输入 N/Y
220 if (ret != 1) {
221 return ret;
222 }
223 }
224 openDir = opendir(strPath);//打开目录
225 if (openDir == NULL) {
226 return (INT32)OS_ERROR;
227 }
228
229 PRINTK("\n");
230 for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) {
231 if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) {
232 continue;
233 }
234 PRINTK(formatChar, readDir->d_name);
235 timesPrint++;
236 ret = OsShowPageControl(timesPrint, lineCap, count);
237 if (ret != 1) {
238 if (closedir(openDir) < 0) {
239 return (INT32)OS_ERROR;
240 }
241 return ret;
242 }
243 }
244
245 PRINTK("\n");
246 if (closedir(openDir) < 0) {
247 return (INT32)OS_ERROR;
248 }
249
250 return LOS_OK;
251}
252
253STATIC VOID strncmp_cut(const CHAR *s1, CHAR *s2, size_t n)
254{
255 if ((n == 0) || (s1 == NULL) || (s2 == NULL)) {
256 return;
257 }
258 do {
259 if (*s1 && *s2 && (*s1 == *s2)) {
260 s1++;
261 s2++;
262 } else {
263 break;
264 }
265 } while (--n != 0);
266 if (n > 0) {
267 /* NULL pad the remaining n-1 bytes */
268 while (n-- != 0)
269 *s2++ = 0;
270 }
271 return;
272}
273
274//匹配文件
275STATIC INT32 OsExecNameMatch(const CHAR *strPath, const CHAR *nameLooking, CHAR *strObj, UINT32 *maxLen)
276{
277 INT32 count = 0;
278 DIR *openDir = NULL;
279 struct dirent *readDir = NULL;
280
281 openDir = opendir(strPath);
282 if (openDir == NULL) {
283 return (INT32)OS_ERROR;
284 }
285 //遍历目录下的文件夹
286 for (readDir = readdir(openDir); readDir != NULL; readDir = readdir(openDir)) {
287 if (strncmp(nameLooking, readDir->d_name, strlen(nameLooking)) != 0) {//不存在字符,
288 continue;
289 }
290 if (count == 0) {
291 if (strncpy_s(strObj, CMD_MAX_PATH, readDir->d_name, CMD_MAX_PATH - 1)) {
292 (VOID)closedir(openDir);
293 return (INT32)OS_ERROR;
294 }
295 *maxLen = strlen(readDir->d_name);
296 } else {
297 /* strncmp&cut the same strings of name matched */
298 strncmp_cut(readDir->d_name, strObj, strlen(strObj));
299 if (strlen(readDir->d_name) > *maxLen) {
300 *maxLen = strlen(readDir->d_name);
301 }
302 }
303 count++;//找到一个
304 }
305
306 if (closedir(openDir) < 0) {
307 return (INT32)OS_ERROR;
308 }
309
310 return count;
311}
312
313STATIC VOID OsCompleteStr(const CHAR *result, const CHAR *target, CHAR *cmdKey, UINT32 *len)
314{
315 UINT32 size = strlen(result) - strlen(target);
316 CHAR *des = cmdKey + *len;
317 CHAR *src = (CHAR *)result + strlen(target);
318
319 while (size-- > 0) {
320 PRINTK("%c", *src);
321 if (*len == (SHOW_MAX_LEN - 1)) {
322 *des = '\0';
323 break;
324 }
325 *des++ = *src++;
326 (*len)++;
327 }
328}
329///使用tab键去匹配命令
330/*例如:
331root@iZ7xv0x7yrn6s2or5pzw58Z:~# ls
332ls lsblk lscpu lsinitramfs lslocks lsmem lsns lspci lsusb
333lsattr lsb_release lshw lsipc lslogins lsmod lsof lspgpot
334*/
335STATIC INT32 OsTabMatchCmd(CHAR *cmdKey, UINT32 *len)
336{
337 INT32 count = 0;
338 INT32 ret;
339 CmdItemNode *cmdItemGuard = NULL;
340 CmdItemNode *curCmdItem = NULL;
341 const CHAR *cmdMajor = (const CHAR *)cmdKey;
342
343 while (*cmdMajor == 0x20) { /* cut left space */
344 cmdMajor++;
345 }
346
348 return (INT32)OS_ERROR;
349 }
350 //遍历现有命令
351 LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(g_cmdInfo.cmdList.list), CmdItemNode, list) {
352 if ((curCmdItem == NULL) || (curCmdItem->cmd == NULL)) {
353 return -1;
354 }
355
356 if (strncmp(cmdMajor, curCmdItem->cmd->cmdKey, strlen(cmdMajor)) > 0) {
357 continue;
358 }
359
360 if (strncmp(cmdMajor, curCmdItem->cmd->cmdKey, strlen(cmdMajor)) != 0) {
361 break;
362 }
363
364 if (count == 0) {
365 cmdItemGuard = curCmdItem;
366 }
367 ++count;//匹配到一个
368 }
369
370 if (cmdItemGuard == NULL) {
371 return 0;
372 }
373
374 if (count == 1) {//只有一个的情况,直接补充完整
375 OsCompleteStr(cmdItemGuard->cmd->cmdKey, cmdMajor, cmdKey, len);
376 }
377
378 ret = count;
379 if (count > 1) {
380 PRINTK("\n");
381 while (count--) {//打印已经匹配到的命令
382 PRINTK("%s ", cmdItemGuard->cmd->cmdKey);
383 cmdItemGuard = LOS_DL_LIST_ENTRY(cmdItemGuard->list.pstNext, CmdItemNode, list);//取下一个
384 }
385 PRINTK("\n");
386 }
387
388 return ret;
389}
390///使用tab键去匹配关键字文件
391STATIC INT32 OsTabMatchFile(CHAR *cmdKey, UINT32 *len)
392{
393 UINT32 maxLen = 0;
394 INT32 count;
395 CHAR *strOutput = NULL;
396 CHAR *strCmp = NULL;
397 CHAR *dirOpen = (CHAR *)LOS_MemAlloc(m_aucSysMem0, CMD_MAX_PATH * 3); /* 3:dirOpen\strOutput\strCmp */
398 if (dirOpen == NULL) {
399 return (INT32)OS_ERROR;
400 }
401
402 (VOID)memset_s(dirOpen, CMD_MAX_PATH * 3, 0, CMD_MAX_PATH * 3); /* 3:dirOpen\strOutput\strCmp */
403 strOutput = dirOpen + CMD_MAX_PATH;
404 strCmp = strOutput + CMD_MAX_PATH;
405
406 if (OsStrSeparate(cmdKey, dirOpen, strCmp, *len)) {
407 (VOID)LOS_MemFree(m_aucSysMem0, dirOpen);
408 return (INT32)OS_ERROR;
409 }
410 //匹配名字
411 count = OsExecNameMatch(dirOpen, strCmp, strOutput, &maxLen);
412 /* one or more matched */
413 if (count >= 1) {
414 OsCompleteStr(strOutput, strCmp, cmdKey, len);
415
416 if (count == 1) {
417 (VOID)LOS_MemFree(m_aucSysMem0, dirOpen);
418 return 1;
419 }
420 if (OsPrintMatchList((UINT32)count, dirOpen, strCmp, maxLen) == -1) {
421 (VOID)LOS_MemFree(m_aucSysMem0, dirOpen);
422 return (INT32)OS_ERROR;
423 }
424 }
425
426 (VOID)LOS_MemFree(m_aucSysMem0, dirOpen);
427 return count;
428}
429
430/*
431 * Description: Pass in the string and clear useless space ,which inlcude:
432 * 1) The overmatch space which is not be marked by Quote's area
433 * Squeeze the overmatch space into one space
434 * 2) Clear all space before first vaild charatctor
435 * Input: cmdKey : Pass in the buff string, which is ready to be operated
436 * cmdOut : Pass out the buffer string ,which has already been operated
437 * size : cmdKey length
438 */
439LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdKeyShift(const CHAR *cmdKey, CHAR *cmdOut, UINT32 size)
440{
441 CHAR *output = NULL;
442 CHAR *outputBak = NULL;
443 UINT32 len;
444 INT32 ret;
445 BOOL quotes = FALSE;
446
447 if ((cmdKey == NULL) || (cmdOut == NULL)) {
448 return (UINT32)OS_ERROR;
449 }
450
451 len = strlen(cmdKey);
452 if (len >= size) {
453 return (UINT32)OS_ERROR;
454 }
455 output = (CHAR*)LOS_MemAlloc(m_aucSysMem0, len + 1);
456 if (output == NULL) {
457 PRINTK("malloc failure in %s[%d]", __FUNCTION__, __LINE__);
458 return (UINT32)OS_ERROR;
459 }
460 /* Backup the 'output' start address */
461 outputBak = output;
462 /* Scan each charactor in 'cmdKey',and squeeze the overmuch space and ignore invaild charactor */
463 for (; *cmdKey != '\0'; cmdKey++) {
464 /* Detected a Double Quotes, switch the matching status */
465 if (*(cmdKey) == '\"') {
466 SWITCH_QUOTES_STATUS(quotes);
467 }
468 /* Ignore the current charactor in following situation */
469 /* 1) Quotes matching status is FALSE (which said that the space is not been marked by double quotes) */
470 /* 2) Current charactor is a space */
471 /* 3) Next charactor is a space too, or the string is been seeked to the end already(\0) */
472 /* 4) Invaild charactor, such as single quotes */
473 if ((*cmdKey == ' ') && ((*(cmdKey + 1) == ' ') || (*(cmdKey + 1) == '\0')) && QUOTES_STATUS_CLOSE(quotes)) {
474 continue;
475 }
476 if (*cmdKey == '\'') {
477 continue;
478 }
479 *output = *cmdKey;
480 output++;
481 }
482 *output = '\0';
483 /* Restore the 'output' start address */
484 output = outputBak;
485 len = strlen(output);
486 /* Clear the space which is located at the first charactor in buffer */
487 if (*outputBak == ' ') {
488 output++;
489 len--;
490 }
491 /* Copy out the buffer which is been operated already */
492 ret = strncpy_s(cmdOut, size, output, len);
493 if (ret != EOK) {
494 PRINT_ERR("%s,%d strncpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
495 (VOID)LOS_MemFree(m_aucSysMem0, output);
496 return OS_ERROR;
497 }
498 cmdOut[len] = '\0';
499
500 (VOID)LOS_MemFree(m_aucSysMem0, output);
501
502 return LOS_OK;
503}
504///类型变量命名,必须是数字字母下划线,首字母不能是数字
505LITE_OS_SEC_TEXT_MINOR BOOL OsCmdKeyCheck(const CHAR *cmdKey)
506{
507 const CHAR *temp = cmdKey;
508 enum Stat {
509 STAT_NONE, //普通
510 STAT_DIGIT, //数字
511 STAT_OTHER //其余
512 } state = STAT_NONE;
513
514 if (strlen(cmdKey) >= CMD_KEY_LEN) {//长度不能超 16个字符
515 return FALSE;
516 }
517 //命令只支持数字,字母,下划线,中划线
518 while (*temp != '\0') {
519 if (!((*temp <= '9') && (*temp >= '0')) &&
520 !((*temp <= 'z') && (*temp >= 'a')) &&
521 !((*temp <= 'Z') && (*temp >= 'A')) &&
522 (*temp != '_') && (*temp != '-')) {
523 return FALSE;
524 }
525 //数字
526 if ((*temp >= '0') && (*temp <= '9')) {
527 if (state == STAT_NONE) {
528 state = STAT_DIGIT;
529 }
530 } else {
531 state = STAT_OTHER;
532 }
533
534 temp++;
535 }
536
537 if (state == STAT_DIGIT) {
538 return FALSE;
539 }
540
541 return TRUE;
542}
543///tab键
544LITE_OS_SEC_TEXT_MINOR INT32 OsTabCompletion(CHAR *cmdKey, UINT32 *len)
545{
546 INT32 count = 0;
547 CHAR *space = NULL;
548 CHAR *cmdMainStr = cmdKey;
549
550 if ((cmdKey == NULL) || (len == NULL)) {
551 return (INT32)OS_ERROR;
552 }
553
554 /* cut left space */
555 while (*cmdMainStr == 0x20) {//空格键
556 cmdMainStr++;
557 }
558
559 /* try to find space in remain */
560 space = strrchr(cmdMainStr, 0x20);
561 if ((space == NULL) && (*cmdMainStr != '\0')) {
562 count = OsTabMatchCmd(cmdKey, len);
563 }
564
565 if (count == 0) {
566 count = OsTabMatchFile(cmdKey, len);
567 }
568
569 return count;
570}
571///按升序插入到链表中
572LITE_OS_SEC_TEXT_MINOR VOID OsCmdAscendingInsert(CmdItemNode *cmd)
573{
574 CmdItemNode *cmdItem = NULL;
575 CmdItemNode *cmdNext = NULL;
576
577 if (cmd == NULL) {
578 return;
579 }
580 //遍历注册的命令项链表
581 for (cmdItem = LOS_DL_LIST_ENTRY((&g_cmdInfo.cmdList.list)->pstPrev, CmdItemNode, list);
582 &cmdItem->list != &(g_cmdInfo.cmdList.list);) {
583 cmdNext = LOS_DL_LIST_ENTRY(cmdItem->list.pstPrev, CmdItemNode, list);//获取实体,一个个比较
584 if (&cmdNext->list != &(g_cmdInfo.cmdList.list)) {
585 if ((strncmp(cmdItem->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) >= 0) &&
586 (strncmp(cmdNext->cmd->cmdKey, cmd->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) < 0)) {
587 LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));//从尾部插入
588 return;
589 }
590 cmdItem = cmdNext;
591 } else {
592 if (strncmp(cmd->cmd->cmdKey, cmdItem->cmd->cmdKey, strlen(cmd->cmd->cmdKey)) > 0) {
593 cmdItem = cmdNext;
594 }
595 break;
596 }
597 }
598
599 LOS_ListTailInsert(&(cmdItem->list), &(cmd->list));
600}
601///shell 命令初始化
602LITE_OS_SEC_TEXT_MINOR UINT32 OsShellKeyInit(ShellCB *shellCB)
603{
604 CmdKeyLink *cmdKeyLink = NULL;
605 CmdKeyLink *cmdHistoryLink = NULL;
606
607 if (shellCB == NULL) {
608 return OS_ERROR;
609 }
610 cmdKeyLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink));
611 if (cmdKeyLink == NULL) {
612 PRINT_ERR("Shell CmdKeyLink memory alloc error!\n");
613 return OS_ERROR;
614 }
615 cmdHistoryLink = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink));
616 if (cmdHistoryLink == NULL) {
617 (VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink);
618 PRINT_ERR("Shell CmdHistoryLink memory alloc error!\n");
619 return OS_ERROR;
620 }
621
622 cmdKeyLink->count = 0;
623 LOS_ListInit(&(cmdKeyLink->list));//待处理命令链表初始化
624 shellCB->cmdKeyLink = (VOID *)cmdKeyLink;//链表源头
625
626 cmdHistoryLink->count = 0;
627 LOS_ListInit(&(cmdHistoryLink->list));//历史记录链表初始化
628 shellCB->cmdHistoryKeyLink = (VOID *)cmdHistoryLink;//链表源头
629 shellCB->cmdMaskKeyLink = (VOID *)cmdHistoryLink;//掩码命令链表同历史记录链表,标识上下键位置.
630 return LOS_OK;
631}
632///shell的析构函数
633LITE_OS_SEC_TEXT_MINOR VOID OsShellKeyDeInit(CmdKeyLink *cmdKeyLink)
634{
635 CmdKeyLink *cmdtmp = NULL;
636 if (cmdKeyLink == NULL) {
637 return;
638 }
639
640 while (!LOS_ListEmpty(&(cmdKeyLink->list))) {//清空待处理命令列表
641 cmdtmp = LOS_DL_LIST_ENTRY(cmdKeyLink->list.pstNext, CmdKeyLink, list);
642 LOS_ListDelete(&cmdtmp->list);//将自己从链表中摘出去
643 (VOID)LOS_MemFree(m_aucSysMem0, cmdtmp);//释放内核内存空间
644 }
645
646 cmdKeyLink->count = 0;//链表为空,个数清0
647 (VOID)LOS_MemFree(m_aucSysMem0, cmdKeyLink);
648}
649///注册系统自带的shell命令
650LITE_OS_SEC_TEXT_MINOR UINT32 OsShellSysCmdRegister(VOID)
651{
652 UINT32 i;
653 UINT8 *cmdItemGroup = NULL;
654 UINT32 index = ((UINTPTR)(&g_shellcmdEnd) - (UINTPTR)(&g_shellcmd[0])) / sizeof(CmdItem);//获取个数
655 CmdItemNode *cmdItem = NULL;
656
657 cmdItemGroup = (UINT8 *)LOS_MemAlloc(m_aucSysMem0, index * sizeof(CmdItemNode));//分配命令项
658 if (cmdItemGroup == NULL) {
659 PRINT_ERR("[%s]System memory allocation failure!\n", __FUNCTION__);
660 return (UINT32)OS_ERROR;
661 }
662
663 for (i = 0; i < index; ++i) {//循环插入
664 cmdItem = (CmdItemNode *)(cmdItemGroup + i * sizeof(CmdItemNode));
665 cmdItem->cmd = &g_shellcmd[i];//一个个取
666 OsCmdAscendingInsert(cmdItem);//按升序插入到链表中
667 }
668 g_cmdInfo.listNum += index;//命令数量叠加
669 return LOS_OK;
670}
671///将shell命令 string 以 CmdKeyLink 方式加入链表
672LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdPush(const CHAR *string, CmdKeyLink *cmdKeyLink)
673{
674 CmdKeyLink *cmdNewNode = NULL;
675 UINT32 len;
676
677 if ((string == NULL) || (strlen(string) == 0)) {
678 return;
679 }
680
681 len = strlen(string);//获取string的长度,注意CmdKeyLink结构体中,cmdString[0],可变数组的实现.
682 cmdNewNode = (CmdKeyLink *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdKeyLink) + len + 1);//申请内核内存
683 if (cmdNewNode == NULL) {
684 return;
685 }
686
687 (VOID)memset_s(cmdNewNode, sizeof(CmdKeyLink) + len + 1, 0, sizeof(CmdKeyLink) + len + 1);
688 if (strncpy_s(cmdNewNode->cmdString, len + 1, string, len)) {//将string拷贝至cmdString中
689 (VOID)LOS_MemFree(m_aucSysMem0, cmdNewNode);
690 return;
691 }
692
693 LOS_ListTailInsert(&(cmdKeyLink->list), &(cmdNewNode->list));//从尾部插入链表
694
695 return;
696}
697///显示shell命令历史记录,支持上下键方式
698LITE_OS_SEC_TEXT_MINOR VOID OsShellHistoryShow(UINT32 value, ShellCB *shellCB)
699{
700 CmdKeyLink *cmdtmp = NULL;
701 CmdKeyLink *cmdNode = shellCB->cmdHistoryKeyLink;
702 CmdKeyLink *cmdMask = shellCB->cmdMaskKeyLink;
703 errno_t ret;
704
705 (VOID)pthread_mutex_lock(&shellCB->historyMutex);
706 if (value == CMD_KEY_DOWN) {//方向下键切换下一条历史
707 if (cmdMask == cmdNode) {
708 goto END;
709 }
710
711 cmdtmp = LOS_DL_LIST_ENTRY(cmdMask->list.pstNext, CmdKeyLink, list);//下一条命令
712 if (cmdtmp != cmdNode) {
713 cmdMask = cmdtmp;
714 } else {
715 goto END;
716 }
717 } else if (value == CMD_KEY_UP) {
718 cmdtmp = LOS_DL_LIST_ENTRY(cmdMask->list.pstPrev, CmdKeyLink, list);//上一条命令
719 if (cmdtmp != cmdNode) {
720 cmdMask = cmdtmp;
721 } else {
722 goto END;
723 }
724 }
725
726 while (shellCB->shellBufOffset--) {//@note_why 这段代码不知道啥意思
727 PRINTK("\b \b");
728 }
729 PRINTK("%s", cmdMask->cmdString);//打印命令
730 shellCB->shellBufOffset = strlen(cmdMask->cmdString);//获取命令长度
731 (VOID)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN);//整个buf进行重置,
732 ret = memcpy_s(shellCB->shellBuf, SHOW_MAX_LEN, cmdMask->cmdString, shellCB->shellBufOffset);//将命令拷贝进buf,以便继续添加内容
733 if (ret != EOK) {
734 PRINT_ERR("%s, %d memcpy failed!\n", __FUNCTION__, __LINE__);
735 goto END;
736 }
737 shellCB->cmdMaskKeyLink = (VOID *)cmdMask;//记录按上下键命令的位置
738
739END:
740 (VOID)pthread_mutex_unlock(&shellCB->historyMutex);
741 return;
742}
743///执行命令,shell是运行程序的程序.
744LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdExec(CmdParsed *cmdParsed, CHAR *cmdStr)
745{
746 UINT32 ret;
747 CmdCallBackFunc cmdHook = NULL;
748 CmdItemNode *curCmdItem = NULL;
749 UINT32 i;
750 const CHAR *cmdKey = NULL;
751
752 if ((cmdParsed == NULL) || (cmdStr == NULL) || (strlen(cmdStr) == 0)) {
753 return (UINT32)OS_ERROR;
754 }
755
756 ret = OsCmdParse(cmdStr, cmdParsed);//解析出命令关键字,参数
757 if (ret != LOS_OK) {
758 goto OUT;
759 }
760 //遍历命令注册全局链表
761 LOS_DL_LIST_FOR_EACH_ENTRY(curCmdItem, &(g_cmdInfo.cmdList.list), CmdItemNode, list) {
762 cmdKey = curCmdItem->cmd->cmdKey;
763 if ((cmdParsed->cmdType == curCmdItem->cmd->cmdType) &&
764 (strlen(cmdKey) == strlen(cmdParsed->cmdKeyword)) &&
765 (strncmp(cmdKey, (CHAR *)(cmdParsed->cmdKeyword), strlen(cmdKey)) == 0)) {//找到命令的回调函数 例如: ls <-> osShellCmdLs
766 cmdHook = curCmdItem->cmd->cmdHook;
767 break;
768 }
769 }
770
771 ret = OS_ERROR;
772 if (cmdHook != NULL) {//执行命令,即回调函数
773 ret = (cmdHook)(cmdParsed->paramCnt, (const CHAR **)cmdParsed->paramArray);
774 }
775
776OUT:
777 for (i = 0; i < cmdParsed->paramCnt; i++) {//无效的命令要释放掉保存参数的内存
778 if (cmdParsed->paramArray[i] != NULL) {
779 (VOID)LOS_MemFree(m_aucSysMem0, cmdParsed->paramArray[i]);
780 cmdParsed->paramArray[i] = NULL;
781 }
782 }
783
784 return (UINT32)ret;
785}
786/*! 命令初始化,用于存放支持的命令,目前鸿蒙支持如下命令
787arp cat cd chgrp chmod chown cp cpup
788date dhclient dmesg dns format free help hwi
789ifconfig ipdebug kill log ls lsfd memcheck mkdir
790mount netstat oom partinfo partition ping ping6 pwd
791reset rm rmdir sem statfs su swtmr sync
792systeminfo task telnet test tftp touch umount uname
793watch writeproc
794*/
795LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdInit(VOID)
796{
797 UINT32 ret;
798 LOS_ListInit(&(g_cmdInfo.cmdList.list));//初始化双向链表
799 g_cmdInfo.listNum = 0; //命令数量
800 g_cmdInfo.initMagicFlag = SHELL_INIT_MAGIC_FLAG;//魔法数字
801 ret = LOS_MuxInit(&g_cmdInfo.muxLock, NULL);//初始化互斥量,确保链表安全访问
802 if (ret != LOS_OK) {
803 PRINT_ERR("Create mutex for shell cmd info failed\n");
804 return OS_ERROR;
805 }
806 return LOS_OK;
807}
808///创建一个命令项,例如 chmod
809STATIC UINT32 OsCmdItemCreate(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
810{
811 CmdItem *cmdItem = NULL;
812 CmdItemNode *cmdItemNode = NULL;
813 //1.构造命令节点过程
814 cmdItem = (CmdItem *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItem));
815 if (cmdItem == NULL) {
816 return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR;
817 }
818 (VOID)memset_s(cmdItem, sizeof(CmdItem), '\0', sizeof(CmdItem));
819
820 cmdItemNode = (CmdItemNode *)LOS_MemAlloc(m_aucSysMem0, sizeof(CmdItemNode));
821 if (cmdItemNode == NULL) {
822 (VOID)LOS_MemFree(m_aucSysMem0, cmdItem);
823 return OS_ERRNO_SHELL_CMDREG_MEMALLOC_ERROR;
824 }
825 (VOID)memset_s(cmdItemNode, sizeof(CmdItemNode), '\0', sizeof(CmdItemNode));
826 cmdItemNode->cmd = cmdItem; //命令项
827 cmdItemNode->cmd->cmdHook = cmdProc;//回调函数 osShellCmdLs
828 cmdItemNode->cmd->paraNum = paraNum;//`777`,'/home'
829 cmdItemNode->cmd->cmdType = cmdType;//关键字类型
830 cmdItemNode->cmd->cmdKey = cmdKey; //`chmod`
831 //2.完成构造后挂入全局链表
832 (VOID)LOS_MuxLock(&g_cmdInfo.muxLock, LOS_WAIT_FOREVER);
833 OsCmdAscendingInsert(cmdItemNode);//按升序方式插入
834 g_cmdInfo.listNum++;//命令总数增加
836
837 return LOS_OK;
838}
839
840/* open API */
841/*!
842 * @brief osCmdReg 以动态方式注册命令
843 *
844 * @param cmdKey 命令关键字,函数在Shell中访问的名称。
845 * @param cmdProc 命令执行函数地址,即命令实际执行函数。
846 * @param cmdType CMD_TYPE_EX:不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,
847 例如:输入ls /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。
848 CMD_TYPE_STD:支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。
849 * @param paraNum 调用的执行函数的入参最大个数,暂不支持该参数;当前为默认值XARGS(0xFFFFFFFF)。
850 * @attention 命令关键字必须是唯一的,也即两个不同的命令项不能拥有相同的命令关键字,否则只会执行其中一个。
851 Shell在执行用户命令时,如果存在多个命令关键字相同的命令,只会执行其中在"help"命令中排序在最前面的一个。
852 * @return
853 *
854 * @see
855 */
856LITE_OS_SEC_TEXT_MINOR UINT32 osCmdReg(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
857{
858 CmdItemNode *cmdItemNode = NULL;
859 //1.确保先拿到锁,魔法数字检查
860 (VOID)LOS_MuxLock(&g_cmdInfo.muxLock, LOS_WAIT_FOREVER);
861 if (g_cmdInfo.initMagicFlag != SHELL_INIT_MAGIC_FLAG) { //验证全局变量的有效性
863 PRINT_ERR("[%s] shell is not yet initialized!\n", __FUNCTION__);
864 return OS_ERRNO_SHELL_NOT_INIT;
865 }
867 //2.参数检查
868 if ((cmdProc == NULL) || (cmdKey == NULL) ||
869 (cmdType >= CMD_TYPE_BUTT) || (strlen(cmdKey) >= CMD_KEY_LEN) || !strlen(cmdKey)) {
870 return OS_ERRNO_SHELL_CMDREG_PARA_ERROR;
871 }
872
873 if (paraNum > CMD_MAX_PARAS) {
874 if (paraNum != XARGS) {
875 return OS_ERRNO_SHELL_CMDREG_PARA_ERROR;
876 }
877 }
878 //3.关键字检查 ;例如:'chmod 777 /home' ,此处检查 'chmod'的合法性
879 if (OsCmdKeyCheck(cmdKey) != TRUE) {
880 return OS_ERRNO_SHELL_CMDREG_CMD_ERROR;
881 }
882 //4.遍历链表节点,验证是否命令存在
883 (VOID)LOS_MuxLock(&g_cmdInfo.muxLock, LOS_WAIT_FOREVER);
884 LOS_DL_LIST_FOR_EACH_ENTRY(cmdItemNode, &(g_cmdInfo.cmdList.list), CmdItemNode, list) {
885 if ((cmdType == cmdItemNode->cmd->cmdType) &&
886 ((strlen(cmdKey) == strlen(cmdItemNode->cmd->cmdKey)) &&
887 (strncmp((CHAR *)(cmdItemNode->cmd->cmdKey), cmdKey, strlen(cmdKey)) == 0))) {
889 return OS_ERRNO_SHELL_CMDREG_CMD_EXIST;//已存在就退出
890 }
891 }
893 //5.正式创建命令,挂入链表
894 return OsCmdItemCreate(cmdType, cmdKey, paraNum, cmdProc);
895}
896
unsigned int OsCmdParse(char *cmdStr, CmdParsed *cmdParsed)
解析cmd命令,将关键字,参数分离出来
Definition: shcmdparse.c:147
unsigned int OsCmdTokenSplit(char *cmdStr, char split, CmdParsed *cmdParsed)
将shell命令按 ' ' 分开处理
Definition: shcmdparse.c:99
@ CMD_KEY_DOWN
方向下键
Definition: shell.h:97
@ CMD_KEY_UP
方向上键
Definition: shell.h:96
CmdType
Definition: shell.h:88
@ CMD_TYPE_BUTT
Definition: shell.h:92
@ CMD_TYPE_STD
支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。
Definition: shell.h:90
unsigned int OsCmdExec(CmdParsed *cmdParsed, char *cmdStr)
Definition: shcmd.c:586
unsigned int OsShellKeyInit(ShellCB *shellCB)
Definition: shcmd.c:465
void OsShellHistoryShow(unsigned int value, ShellCB *shellCB)
Definition: shcmd.c:540
void OsShellCmdPush(const char *string, CmdKeyLink *cmdKeyLink)
Definition: shcmd.c:514
char * OsShellGetWorkingDirectory(void)
Definition: shcmd.c:94
int OsTabCompletion(char *cmdKey, unsigned int *len)
Definition: shcmd.c:452
void OsShellKeyDeInit(CmdKeyLink *cmdKeyLink)
Definition: shcmd.c:497
unsigned int OsCmdKeyShift(const char *cmdKey, char *cmdOut, unsigned int size)
Definition: shcmd.c:386
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
Definition: los_list.h:244
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
Definition: los_memory.c:1369
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
Definition: los_memory.c:107
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
初始化互斥锁
Definition: los_mux.c:262
LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex)
释放锁
Definition: los_mux.c:559
LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout)
拿互斥锁,
Definition: los_mux.c:437
signed int INT32
Definition: los_typedef.h:60
unsigned char UINT8
Definition: los_typedef.h:55
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
size_t BOOL
Definition: los_typedef.h:88
int pthread_mutex_lock(pthread_mutex_t *mutex)
互斥锁加锁操作
int pthread_mutex_unlock(pthread_mutex_t *mutex)
解锁互斥锁
CmdItem g_shellcmdEnd
CmdItem g_shellcmd[]
LITE_OS_SEC_TEXT_MINOR VOID OsCmdAscendingInsert(CmdItemNode *cmd)
按升序插入到链表中
Definition: shcmd.c:572
LOS_HAL_TABLE_BEGIN(g_shellcmd, shellcmd)
LITE_OS_SEC_TEXT_MINOR BOOL OsCmdKeyCheck(const CHAR *cmdKey)
类型变量命名,必须是数字字母下划线,首字母不能是数字
Definition: shcmd.c:505
LITE_OS_SEC_TEXT_MINOR UINT32 OsCmdInit(VOID)
Definition: shcmd.c:795
STATIC INT32 OsShowPageControl(UINT32 timesPrint, UINT32 lineCap, UINT32 count)
显示页内容控制器
Definition: shcmd.c:174
LITE_OS_SEC_TEXT_MINOR UINT32 osCmdReg(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
osCmdReg 以动态方式注册命令
Definition: shcmd.c:856
LOS_HAL_TABLE_END(g_shellcmdEnd, shellcmd)
STATIC INT32 OsShowPageInputControl(VOID)
输出内容
Definition: shcmd.c:155
STATIC INT32 OsStrSeparateTabStrGet(CHAR **tabStr, CmdParsed *parsed, UINT32 tabStrLen)
Definition: shcmd.c:68
STATIC VOID OsFreeCmdPara(CmdParsed *cmdParsed)
释放命令行参数所占内存
Definition: shcmd.c:57
STATIC VOID strncmp_cut(const CHAR *s1, CHAR *s2, size_t n)
Definition: shcmd.c:253
STATIC INT32 OsStrSeparate(CHAR *tabStr, CHAR *strPath, CHAR *nameLooking, UINT32 tabStrLen)
Definition: shcmd.c:108
STATIC INT32 OsPrintMatchList(UINT32 count, const CHAR *strPath, const CHAR *nameLooking, UINT32 printLen)
打印匹配的列表数据
Definition: shcmd.c:203
STATIC UINT32 OsCmdItemCreate(CmdType cmdType, const CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc)
创建一个命令项,例如 chmod
Definition: shcmd.c:809
STATIC INT32 OsTabMatchFile(CHAR *cmdKey, UINT32 *len)
使用tab键去匹配关键字文件
Definition: shcmd.c:391
STATIC INT32 OsSurePrintAll(UINT32 count)
是否打印所有内容
Definition: shcmd.c:186
STATIC VOID OsCompleteStr(const CHAR *result, const CHAR *target, CHAR *cmdKey, UINT32 *len)
Definition: shcmd.c:313
STATIC CmdModInfo g_cmdInfo
shell 命令模块信息,上面挂了所有的命令项(ls,cd ,cp ==)
Definition: shcmd.c:47
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellSysCmdRegister(VOID)
注册系统自带的shell命令
Definition: shcmd.c:650
STATIC INT32 OsExecNameMatch(const CHAR *strPath, const CHAR *nameLooking, CHAR *strObj, UINT32 *maxLen)
Definition: shcmd.c:275
CmdModInfo * OsCmdInfoGet(VOID)
获取全局变量
Definition: shcmd.c:52
STATIC INT32 OsTabMatchCmd(CHAR *cmdKey, UINT32 *len)
使用tab键去匹配命令
Definition: shcmd.c:335
Definition: shcmd.h:53
const CHAR * cmdKey
命令关键字,例如:ls 函数在Shell中访问的名称。
Definition: shcmd.h:57
CmdCallBackFunc cmdHook
命令执行函数地址,即命令实际执行函数。
Definition: shcmd.h:59
UINT32 paraNum
调用的执行函数的入参最大个数,暂不支持。
Definition: shcmd.h:58
CmdType cmdType
Definition: shcmd.h:54
CmdItem * cmd
命令项
Definition: shcmd.h:64
LOS_DL_LIST list
双向链表
Definition: shcmd.h:63
CmdItemNode cmdList
命令项节点
Definition: shcmd.h:69
UINT32 initMagicFlag
初始魔法标签 0xABABABAB
Definition: shcmd.h:71
LosMux muxLock
操作链表互斥锁
Definition: shcmd.h:72
UINT32 listNum
节点数量
Definition: shcmd.h:70
char cmdKeyword[CMD_KEY_LEN]
Definition: shcmdparse.h:50
char * paramArray[CMD_MAX_PARAS]
Definition: shcmdparse.h:51
unsigned int paramCnt
Definition: shcmdparse.h:48
CmdType cmdType
Definition: shcmdparse.h:49
struct LOS_DL_LIST * pstPrev
Definition: los_list.h:83
struct LOS_DL_LIST * pstNext
Definition: los_list.h:84
struct SH_List * pstPrev
Definition: shell_list.h:51
struct SH_List * pstNext
Definition: shell_list.h:52
Definition: shell.h:71
char shellBuf[SHOW_MAX_LEN]
接受shell命令 buf大小
Definition: shell.h:83
void * cmdKeyLink
命令链表,所有敲过的命令链表
Definition: shell.h:75
void * cmdHistoryKeyLink
命令的历史记录链表,去重,10个
Definition: shell.h:76
unsigned int shellBufOffset
buf偏移量
Definition: shell.h:78
pthread_mutex_t historyMutex
操作cmdHistoryKeyLink的互斥量
Definition: shell.h:82
void * cmdMaskKeyLink
主要用于方向键上下遍历历史命令
Definition: shell.h:77
u32_t(* CmdCallBackFunc)(u32_t argc, const char **argv)
Definition: types_adapt.h:86