更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
vfs_shellcmd.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 "los_config.h"
33#include "sys/mount.h"
34
35#ifdef LOSCFG_SHELL
36
37#include "los_typedef.h"
38#include "shell.h"
39#include "sys/stat.h"
40#include "stdlib.h"
41#include "unistd.h"
42#include "fcntl.h"
43#include "sys/statfs.h"
44#include "stdio.h"
45#include "pthread.h"
46
47#include "shcmd.h"
48#include "securec.h"
49#include "show.h"
50#include "los_syscall.h"
51
52#include "los_process_pri.h"
53#include <ctype.h>
54#include "fs/fs_operation.h"
55
56typedef enum
57{
58 RM_RECURSIVER, //递归删除
59 RM_FILE, //删除文件
60 RM_DIR, //删除目录
61 CP_FILE, //拷贝文件
62 CP_COUNT //拷贝数量
64
65#define ERROR_OUT_IF(condition, message_function, handler) \ //这种写法挺妙的
66 do \
67 { \
68 if (condition) \
69 { \
70 message_function; \
71 handler; \
72 } \
73 } \
74 while (0)
75
76static inline void set_err(int errcode, const char *err_message)
77{
78 set_errno(errcode);
79 perror(err_message);
80}
81
82int osShellCmdDoChdir(const char *path)
83{
84 char *fullpath = NULL;
85 char *fullpath_bak = NULL;
86 int ret;
87 char *shell_working_directory = OsShellGetWorkingDirectory();
88 if (shell_working_directory == NULL)
89 {
90 return -1;
91 }
92
93 if (path == NULL)
94 {
96 PRINTK("%s\n", shell_working_directory);
98
99 return 0;
100 }
101
102 ERROR_OUT_IF(strlen(path) > PATH_MAX, set_err(ENOTDIR, "cd error"), return -1);
103
104 ret = vfs_normalize_path(shell_working_directory, path, &fullpath);
105 ERROR_OUT_IF(ret < 0, set_err(-ret, "cd error"), return -1);
106
107 fullpath_bak = fullpath;
108 ret = chdir(fullpath);
109 if (ret < 0)
110 {
111 free(fullpath_bak);
112 perror("cd");
113 return -1;
114 }
115
116 /* copy full path to working directory */
117
118 LOS_TaskLock();
119 ret = strncpy_s(shell_working_directory, PATH_MAX, fullpath, strlen(fullpath));
120 if (ret != EOK)
121 {
122 free(fullpath_bak);
124 return -1;
125 }
127 /* release normalize directory path name */
128
129 free(fullpath_bak);
130
131 return 0;
132}
133/**
134 * @brief 添加内置命令 ls
135 * @verbatim
136 命令功能
137 ls命令用来显示当前目录的内容。
138
139 命令格式
140 ls [path]
141
142 path为空时,显示当前目录的内容。
143 path为无效文件名时,显示失败,提示:
144 ls error: No such directory。
145 path为有效目录路径时,会显示对应目录下的内容。
146
147 使用指南
148 ls命令显示当前目录的内容。
149 ls可以显示文件的大小。
150 proc下ls无法统计文件大小,显示为0。
151 * @endverbatim
152 * @param argc Shell命令中,参数个数。
153 * @param argv 为指针数组,每个元素指向一个字符串,可以根据选择命令类型,决定是否要把命令关键字传入给注册函数。
154 * @return int
155 */
156int osShellCmdLs(int argc, const char **argv)
157{
158 char *fullpath = NULL;
159 const char *filename = NULL;
160 int ret;
161 char *shell_working_directory = OsShellGetWorkingDirectory();//获取当前工作目录
162 if (shell_working_directory == NULL)
163 {
164 return -1;
165 }
166
167 ERROR_OUT_IF(argc > 1, PRINTK("ls or ls [DIRECTORY]\n"), return -1);
168
169 if (argc == 0)//木有参数时 -> #ls
170 {
171 ls(shell_working_directory);//执行ls 当前工作目录
172 return 0;
173 }
174
175 filename = argv[0];//有参数时 -> #ls ../harmony or #ls /no such file or directory
176 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);//获取全路径,注意这里带出来fullpath,而fullpath已经在内核空间
177 ERROR_OUT_IF(ret < 0, set_err(-ret, "ls error"), return -1);
178
179 ls(fullpath);//执行 ls 全路径
180 free(fullpath);//释放全路径,为啥要释放,因为fullpath已经由内核空间分配
181
182 return 0;
183}
184
185/**
186 * @brief
187 * @verbatim
188 命令功能
189 cd命令用来改变当前目录。
190
191 命令格式
192 cd [path]
193
194 未指定目录参数时,会跳转至根目录。
195 cd后加路径名时,跳转至该路径。
196 路径名以 /(斜杠)开头时,表示根目录。
197 .(点)表示当前目录。
198 ..(点点)表示父目录。
199 cd ..
200 * @endverbatim
201 * @param argc
202 * @param argv
203 * @return int
204 */
205int osShellCmdCd(int argc, const char **argv)
206{
207 if (argc == 0)//没有参数时 #cd
208 {
209 (void)osShellCmdDoChdir("/");
210 return 0;
211 }
212
213 (void)osShellCmdDoChdir(argv[0]);//#cd .. 带参数情况
214
215 return 0;
216}
217
218#define CAT_BUF_SIZE 512
219#define CAT_TASK_PRIORITY 10
220#define CAT_TASK_STACK_SIZE 0x3000
221pthread_mutex_t g_mutex_cat = PTHREAD_MUTEX_INITIALIZER;
222
223/**
224 * @brief
225 * @verbatim
226cat用于显示文本文件的内容。
227
228命令格式
229cat [pathname]
230
231使用指南
232cat用于显示文本文件的内容。
233
234使用实例
235举例:cat harmony.txt
236 * @endverbatim
237 * @param arg
238 * @return int
239 */
240int osShellCmdDoCatShow(UINTPTR arg) //shellcmd_cat 任务实现
241{
242 int ret = 0;
243 char buf[CAT_BUF_SIZE];
244 size_t size, written, toWrite;
245 ssize_t cnt;
246 char *fullpath = (char *)arg;
247 FILE *ini = NULL;
248
249 (void)pthread_mutex_lock(&g_mutex_cat);
250 ini = fopen(fullpath, "r");//打开文件
251 if (ini == NULL)
252 {
253 ret = -1;
254 perror("cat error");
255 goto out;
256 }
257
258 do
259 {
260 (void)memset_s(buf, sizeof(buf), 0, CAT_BUF_SIZE);
261 size = fread(buf, 1, CAT_BUF_SIZE, ini); //读取文件内容
262 if ((int)size < 0)
263 {
264 ret = -1;
265 perror("cat error");
266 goto out_with_fclose;
267 }
268
269 for (toWrite = size, written = 0; toWrite > 0;)
270 {
271 cnt = write(1, buf + written, toWrite);//stdout:1 标准输出文件
272 if (cnt == 0)
273 {
274 /* avoid task-starvation */
276 continue;
277 }
278 else if (cnt < 0)
279 {
280 perror("cat write error");
281 break;
282 }
283
284 written += cnt;
285 toWrite -= cnt;
286 }
287 }
288 while (size > 0);
289
290out_with_fclose:
291 (void)fclose(ini);
292out:
293 free(fullpath);
294 (void)pthread_mutex_unlock(&g_mutex_cat);
295 return ret;
296}
297/*!
298cat用于显示文本文件的内容。cat [pathname]
299cat weharmony.txt
300*/
301int osShellCmdCat(int argc, const char **argv)
302{
303 char *fullpath = NULL;
304 int ret;
305 unsigned int ca_task;
306 struct Vnode *vnode = NULL;
307 TSK_INIT_PARAM_S init_param;
308 char *shell_working_directory = OsShellGetWorkingDirectory();//显示当前目录 pwd
309 if (shell_working_directory == NULL)
310 {
311 return -1;
312 }
313
314 ERROR_OUT_IF(argc != 1, PRINTK("cat [FILE]\n"), return -1);
315
316 ret = vfs_normalize_path(shell_working_directory, argv[0], &fullpath);//由相对路径获取绝对路径
317 ERROR_OUT_IF(ret < 0, set_err(-ret, "cat error"), return -1);
318
319 VnodeHold();
320 ret = VnodeLookup(fullpath, &vnode, O_RDONLY);
321 if (ret != LOS_OK)
322 {
323 set_errno(-ret);
324 perror("cat error");
325 VnodeDrop();
326 free(fullpath);
327 return -1;
328 }
329 if (vnode->type != VNODE_TYPE_REG)
330 {
331 set_errno(EINVAL);
332 perror("cat error");
333 VnodeDrop();
334 free(fullpath);
335 return -1;
336 }
337 VnodeDrop();
338 (void)memset_s(&init_param, sizeof(init_param), 0, sizeof(TSK_INIT_PARAM_S));
340 init_param.usTaskPrio = CAT_TASK_PRIORITY; //优先级10
341 init_param.auwArgs[0] = (UINTPTR)fullpath; //入口参数
342 init_param.uwStackSize = CAT_TASK_STACK_SIZE;//内核栈大小
343 init_param.pcName = "shellcmd_cat"; //任务名称
344 init_param.uwResved = LOS_TASK_STATUS_DETACHED | OS_TASK_FLAG_SPECIFIES_PROCESS;
345 init_param.processID = 2; /* 2: kProcess */ //内核任务
346
347 ret = (int)LOS_TaskCreate(&ca_task, &init_param);//创建任务显示cat内容
348
349 if (ret != LOS_OK)
350 {
351 free(fullpath);
352 }
353
354 return ret;
355}
356
357static int nfs_mount_ref(const char *server_ip_and_path, const char *mount_path,
358 unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount")));
359
360static unsigned long get_mountflags(const char *options)
361{
362 unsigned long mountfalgs = 0;
363 char *p;
364 while ((options != NULL) && (p = strsep((char**)&options, ",")) != NULL) {
365 if (strncmp(p, "ro", strlen("ro")) == 0) {
366 mountfalgs |= MS_RDONLY;
367 } else if (strncmp(p, "rw", strlen("rw")) == 0) {
368 mountfalgs &= ~MS_RDONLY;
369 } else if (strncmp(p, "nosuid", strlen("nosuid")) == 0) {
370 mountfalgs |= MS_NOSUID;
371 } else if (strncmp(p, "suid", strlen("suid")) == 0) {
372 mountfalgs &= ~MS_NOSUID;
373 } else {
374 continue;
375 }
376 }
377
378 return mountfalgs;
379}
380static inline void print_mount_usage(void)//mount 用法
381{
382 PRINTK("mount [DEVICE] [PATH] [NAME]\n");
383}
384
385/**
386 * @brief
387 * @verbatim
388 命令功能
389 mount命令用来将设备挂载到指定目录。
390 命令格式
391 mount <device> <path> <name> [uid gid]
392 device 要挂载的设备(格式为设备所在路径)。系统拥有的设备。
393 path 指定目录。用户必须具有指定目录中的执行(搜索)许可权。N/A
394 name 文件系统的种类。 vfat, yaffs, jffs, ramfs, nfs,procfs, romfs.
395 uid gid uid是指用户ID。 gid是指组ID。可选参数,缺省值uid:0,gid:0。
396
397 使用指南
398 mount后加需要挂载的设备信息、指定目录以及设备文件格式,就能成功挂载文件系统到指定目录。
399 使用实例
400 举例:mount /dev/mmcblk0p0 /bin/vs/sd vfat
401 * @endverbatim
402 * @param argc
403 * @param argv
404 * @return int
405 */
406int osShellCmdMount(int argc, const char **argv)
407{
408 int ret;
409 char *fullpath = NULL;
410 const char *filename = NULL;
411 unsigned int gid, uid;
412 char *data = NULL;
413 char *filessystemtype = NULL;
414 unsigned long mountfalgs;
415 char *shell_working_directory = OsShellGetWorkingDirectory();
416 if (shell_working_directory == NULL)
417 {
418 return -1;
419 }
420
421 ERROR_OUT_IF(argc < 3, print_mount_usage(), return OS_FAIL);
422
423 if (strncmp(argv[0], "-t", 2) == 0 || strncmp(argv[0], "-o", 2) == 0)
424 {
425 if (argc < 4)
426 {
427 PRINTK("mount -t/-o [DEVICE] [PATH] [NAME]\n");
428 return -1;
429 }
430
431 filename = argv[2];
432 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
433 ERROR_OUT_IF(ret < 0, set_err(-ret, "mount error"), return -1);
434
435 if (strncmp(argv[3], "nfs", 3) == 0)
436 {
437 if (argc <= 6)
438 {
439 uid = ((argc >= 5) && (argv[4] != NULL)) ? (unsigned int)strtoul(argv[4], (char **)NULL, 0) : 0;
440 gid = ((argc == 6) && (argv[5] != NULL)) ? (unsigned int)strtoul(argv[5], (char **)NULL, 0) : 0;
441
442 if (nfs_mount_ref != NULL)
443 {
444 ret = nfs_mount_ref(argv[1], fullpath, uid, gid);
445 if (ret != LOS_OK)
446 {
447 PRINTK("mount -t [DEVICE] [PATH] [NAME]\n");
448 }
449 }
450 else
451 {
452 PRINTK("can't find nfs_mount\n");
453 }
454 free(fullpath);
455 return 0;
456 }
457 }
458
459 filessystemtype = (argc >= 4) ? (char *)argv[3] : NULL; /* 3: fs type */
460 mountfalgs = (argc >= 5) ? get_mountflags((const char *)argv[4]) : 0; /* 4: usr option */
461 data = (argc >= 6) ? (char *)argv[5] : NULL; /* 5: usr option data */
462
463 if (strcmp(argv[1], "0") == 0)
464 {
465 ret = mount((const char *)NULL, fullpath, filessystemtype, mountfalgs, data);
466 }
467 else
468 {
469 ret = mount(argv[1], fullpath, filessystemtype, mountfalgs, data); /* 3: fs type */
470 }
471 if (ret != LOS_OK)
472 {
473 perror("mount error");
474 }
475 else
476 {
477 PRINTK("mount ok\n");
478 }
479 }
480 else
481 {
482 filename = argv[1];
483 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
484 ERROR_OUT_IF(ret < 0, set_err(-ret, "mount error"), return -1);
485
486 if (strncmp(argv[2], "nfs", 3) == 0)
487 {
488 if (argc <= 5)
489 {
490 uid = ((argc >= 4) && (argv[3] != NULL)) ? (unsigned int)strtoul(argv[3], (char **)NULL, 0) : 0;
491 gid = ((argc == 5) && (argv[4] != NULL)) ? (unsigned int)strtoul(argv[4], (char **)NULL, 0) : 0;
492
493 if (nfs_mount_ref != NULL)
494 {
495 ret = nfs_mount_ref(argv[0], fullpath, uid, gid);
496 if (ret != LOS_OK)
497 {
498 PRINTK("mount [DEVICE] [PATH] [NAME]\n");
499 }
500 }
501 else
502 {
503 PRINTK("can't find nfs_mount\n");
504 }
505 free(fullpath);
506 return 0;
507 }
508
510 free(fullpath);
511 return 0;
512 }
513
514 mountfalgs = (argc >= 4) ? get_mountflags((const char *)argv[3]) : 0; /* 3: usr option */
515 data = (argc >= 5) ? (char *)argv[4] : NULL; /* 4: usr option data */
516
517 if (strcmp(argv[0], "0") == 0)
518 {
519 ret = mount((const char *)NULL, fullpath, argv[2], mountfalgs, data);
520 }
521 else
522 {
523 ret = mount(argv[0], fullpath, argv[2], mountfalgs, data); /* 2: fs type */
524 }
525 if (ret != LOS_OK)
526 {
527 perror("mount error");
528 }
529 else
530 {
531 PRINTK("mount ok\n");
532 }
533 }
534
535 free(fullpath);
536 return 0;
537}
538
539/**
540 * @brief
541 * @verbatim
542 命令功能
543 umount命令用来卸载指定文件系统。
544 命令格式
545 umount [dir]
546 参数说明
547 dir 需要卸载文件系统对应的目录。 系统已挂载的文件系统的目录。
548 使用指南
549 umount后加上需要卸载的指定文件系统的目录,即将指定文件系统卸载。
550 使用实例
551 举例:mount /bin/vs/sd
552 * @endverbatim
553 * @param argc
554 * @param argv
555 * @return int
556 */
557int osShellCmdUmount(int argc, const char **argv)
558{
559 int ret;
560 const char *filename = NULL;
561 char *fullpath = NULL;
562 char *target_path = NULL;
563 int cmp_num;
564 char *work_path = NULL;
565 char *shell_working_directory = OsShellGetWorkingDirectory();
566 if (shell_working_directory == NULL)
567 {
568 return -1;
569 }
570 work_path = shell_working_directory;
571
572 ERROR_OUT_IF(argc == 0, PRINTK("umount [PATH]\n"), return 0);
573
574 filename = argv[0];
575 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
576 ERROR_OUT_IF(ret < 0, set_err(-ret, "umount error"), return -1);
577
578 target_path = fullpath;
579 cmp_num = strlen(fullpath);
580 ret = strncmp(work_path, target_path, cmp_num);
581 if (ret == 0)
582 {
583 work_path += cmp_num;
584 if (*work_path == '/' || *work_path == '\0')
585 {
586 set_errno(EBUSY);
587 perror("umount error");
588 free(fullpath);
589 return -1;
590 }
591 }
592
593 ret = umount(fullpath);
594 free(fullpath);
595 if (ret != LOS_OK)
596 {
597 perror("umount error");
598 return 0;
599 }
600
601 PRINTK("umount ok\n");
602 return 0;
603}
604
605/**
606 * @brief
607 * @verbatim
608 命令功能
609 mkdir命令用来创建一个目录。
610 命令格式
611 mkdir [directory]
612 参数说明
613 directory 需要创建的目录。
614 使用指南
615 mkdir后加所需要创建的目录名会在当前目录下创建目录。
616 mkdir后加路径,再加上需要创建的目录名,即在指定目录下创建目录。
617
618 使用实例
619 举例:mkdir harmony
620 * @endverbatim
621 * @param argc
622 * @param argv
623 * @return int
624 */
625int osShellCmdMkdir(int argc, const char **argv)
626{
627 int ret;
628 char *fullpath = NULL;
629 const char *filename = NULL;
630 char *shell_working_directory = OsShellGetWorkingDirectory();
631 if (shell_working_directory == NULL)
632 {
633 return -1;
634 }
635
636 ERROR_OUT_IF(argc != 1, PRINTK("mkdir [DIRECTORY]\n"), return 0);
637
638 filename = argv[0];
639 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
640 ERROR_OUT_IF(ret < 0, set_err(-ret, "mkdir error"), return -1);
641
642 ret = mkdir(fullpath, S_IRWXU | S_IRWXG | S_IRWXO);
643 if (ret == -1)
644 {
645 perror("mkdir error");
646 }
647 free(fullpath);
648 return 0;
649}
650
651/**
652 * @brief
653 * @verbatim
654 命令功能
655 pwd命令用来显示当前路径。
656 命令格式
657
658 使用指南
659 pwd 命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用 / (斜线)分隔。
660 第一个 / 表示根目录, 最后一个目录是当前目录。
661 * @endverbatim
662 * @param argc
663 * @param argv
664 * @return int
665 */
666int osShellCmdPwd(int argc, const char **argv)
667{
668 char buf[SHOW_MAX_LEN] = {0};
669 DIR *dir = NULL;
670 char *shell_working_directory = OsShellGetWorkingDirectory();//获取当前工作路径
671 if (shell_working_directory == NULL)
672 {
673 return -1;
674 }
675
676 ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: pwd\n"), return -1);
677
678 dir = opendir(shell_working_directory);
679 if (dir == NULL)
680 {
681 perror("pwd error");
682 return -1;
683 }
684
685 LOS_TaskLock();
686 if (strncpy_s(buf, SHOW_MAX_LEN, shell_working_directory, SHOW_MAX_LEN - 1) != EOK)
687 {
689 PRINTK("pwd error: strncpy_s error!\n");
690 (void)closedir(dir);
691 return -1;
692 }
694
695 PRINTK("%s\n", buf);
696 (void)closedir(dir);
697 return 0;
698}
699
700static inline void print_statfs_usage(void)
701{
702 PRINTK("Usage :\n");
703 PRINTK(" statfs <path>\n");
704 PRINTK(" path : Mounted file system path that requires query information\n");
705 PRINTK("Example:\n");
706 PRINTK(" statfs /ramfs\n");
707}
708
709/**
710 * @brief
711 * @verbatim
712 命令功能
713 statfs 命令用来打印文件系统的信息,如该文件系统类型、总大小、可用大小等信息。
714 命令格式
715 statfs [directory]
716 参数说明
717 directory 文件系统的路径。 必须是存在的文件系统,并且其支持statfs命令,当前支持的文件系统有:JFFS2,FAT,NFS。
718 使用指南
719 打印信息因文件系统而异。
720 以nfs文件系统为例: statfs /nfs
721 * @endverbatim
722 * @param argc
723 * @param argv
724 * @return int
725 */
726int osShellCmdStatfs(int argc, const char **argv)
727{
728 struct statfs sfs;
729 int result;
730 unsigned long long total_size, free_size;
731 char *fullpath = NULL;
732 const char *filename = NULL;
733 char *shell_working_directory = OsShellGetWorkingDirectory();
734 if (shell_working_directory == NULL)
735 {
736 return -1;
737 }
738
739 ERROR_OUT_IF(argc != 1, PRINTK("statfs failed! Invalid argument!\n"), return -1);
740
741 (void)memset_s(&sfs, sizeof(sfs), 0, sizeof(sfs));
742
743 filename = argv[0];
744 result = vfs_normalize_path(shell_working_directory, filename, &fullpath);
745 ERROR_OUT_IF(result < 0, set_err(-result, "statfs error"), return -1);
746
747 result = statfs(fullpath, &sfs);//命令实现体
748 free(fullpath);
749
750 if (result != 0 || sfs.f_type == 0)
751 {
752 PRINTK("statfs failed! Invalid argument!\n");
754 return -1;
755 }
756
757 total_size = (unsigned long long)sfs.f_bsize * sfs.f_blocks;
758 free_size = (unsigned long long)sfs.f_bsize * sfs.f_bfree;
759
760 PRINTK("statfs got:\n f_type = %d\n cluster_size = %d\n", sfs.f_type, sfs.f_bsize);
761 PRINTK(" total_clusters = %llu\n free_clusters = %llu\n", sfs.f_blocks, sfs.f_bfree);
762 PRINTK(" avail_clusters = %llu\n f_namelen = %d\n", sfs.f_bavail, sfs.f_namelen);
763 PRINTK("\n%s\n total size: %4llu Bytes\n free size: %4llu Bytes\n", argv[0], total_size, free_size);
764
765 return 0;
766}
767
768/**
769 * @brief
770 * @verbatim
771 touch命令用来在指定的目录下创建一个不存在的空文件。
772 touch命令操作已存在的文件会成功,不会更新时间戳。touch [filename]
773 touch命令用来创建一个空文件,该文件可读写。
774 使用touch命令一次只能创建一个文件。
775 * @endverbatim
776 * @param argc
777 * @param argv
778 * @return int
779 */
780int osShellCmdTouch(int argc, const char **argv)
781{
782 int ret;
783 int fd = -1;
784 char *fullpath = NULL;
785 const char *filename = NULL;
786 char *shell_working_directory = OsShellGetWorkingDirectory();
787 if (shell_working_directory == NULL)
788 {
789 return -1;
790 }
791
792 ERROR_OUT_IF(argc != 1, PRINTK("touch [FILE]\n"), return -1);
793
794 filename = argv[0];
795 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
796 ERROR_OUT_IF(ret < 0, set_err(-ret, "touch error"), return -1);
797 //如果没有就创建文件方式
798 fd = open(fullpath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
799 free(fullpath);
800 if (fd == -1)
801 {
802 perror("touch error");
803 return -1;
804 }
805
806 (void)close(fd);
807 return 0;
808}
809
810#define CP_BUF_SIZE 4096
811pthread_mutex_t g_mutex_cp = PTHREAD_MUTEX_INITIALIZER;
812
813/**
814 * @brief
815 * @verbatim
816 cp 拷贝文件,创建一份副本。
817 cp [SOURCEFILE] [DESTFILE]
818 使用指南
819 同一路径下,源文件与目的文件不能重名。
820 源文件必须存在,且不为目录。
821 源文件路径支持“*”和“?”通配符,“*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。
822 目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。
823 目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。
824 目前不支持多文件拷贝。参数大于2个时,只对前2个参数进行操作。
825 目的文件不存在时创建新文件,已存在则覆盖。
826 拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-0 文件时,会产生系统卡死现象。
827 举例:cp weharmony.txt ./tmp/
828 * @endverbatim
829 * @param argc
830 * @param argv
831 * @return int
832 */
833static int os_shell_cmd_do_cp(const char *src_filepath, const char *dst_filename)
834{
835 int ret;
836 char *src_fullpath = NULL;
837 char *dst_fullpath = NULL;
838 const char *src_filename = NULL;
839 char *dst_filepath = NULL;
840 char *buf = NULL;
841 const char *filename = NULL;
842 ssize_t r_size, w_size;
843 int src_fd = -1;
844 int dst_fd = -1;
845 struct stat stat_buf;
846 mode_t src_mode;
847 char *shell_working_directory = OsShellGetWorkingDirectory();
848 if (shell_working_directory == NULL)
849 {
850 return -1;
851 }
852
853 buf = (char *)malloc(CP_BUF_SIZE);
854 if (buf == NULL)
855 {
856 PRINTK("cp error: Out of memory!\n");
857 return -1;
858 }
859
860 /* Get source fullpath. */
861
862 ret = vfs_normalize_path(shell_working_directory, src_filepath, &src_fullpath);
863 if (ret < 0)
864 {
865 set_errno(-ret);
866 PRINTK("cp error: %s\n", strerror(errno));
867 free(buf);
868 return -1;
869 }
870
871 /* Is source path exist? */
872
873 ret = stat(src_fullpath, &stat_buf);
874 if (ret == -1)
875 {
876 PRINTK("cp %s error: %s\n", src_fullpath, strerror(errno));
877 goto errout_with_srcpath;
878 }
879 src_mode = stat_buf.st_mode;
880 /* Is source path a directory? */
881
882 if (S_ISDIR(stat_buf.st_mode))
883 {
884 PRINTK("cp %s error: Source file can't be a directory.\n", src_fullpath);
885 goto errout_with_srcpath;
886 }
887
888 /* Get dest fullpath. */
889
890 dst_fullpath = strdup(dst_filename);
891 if (dst_fullpath == NULL)
892 {
893 PRINTK("cp error: Out of memory.\n");
894 goto errout_with_srcpath;
895 }
896
897 /* Is dest path exist? */
898
899 ret = stat(dst_fullpath, &stat_buf);
900 if (ret == 0)
901 {
902 /* Is dest path a directory? */
903
904 if (S_ISDIR(stat_buf.st_mode))
905 {
906 /* Get source file name without '/'. */
907
908 src_filename = src_filepath;
909 while (1)
910 {
911 filename = strchr(src_filename, '/');
912 if (filename == NULL)
913 {
914 break;
915 }
916 src_filename = filename + 1;
917 }
918
919 /* Add the source file after dest path. */
920
921 ret = vfs_normalize_path(dst_fullpath, src_filename, &dst_filepath);
922 if (ret < 0)
923 {
924 set_errno(-ret);
925 PRINTK("cp error. %s.\n", strerror(errno));
926 goto errout_with_path;
927 }
928 free(dst_fullpath);
929 dst_fullpath = dst_filepath;
930 }
931 }
932
933 /* Is dest file same as source file? */
934
935 if (strcmp(src_fullpath, dst_fullpath) == 0)
936 {
937 PRINTK("cp error: '%s' and '%s' are the same file\n", src_fullpath, dst_fullpath);
938 goto errout_with_path;
939 }
940
941 /* Copy begins. */
942
944 src_fd = open(src_fullpath, O_RDONLY);
945 if (src_fd < 0)
946 {
947 PRINTK("cp error: can't open %s. %s.\n", src_fullpath, strerror(errno));
948 goto errout_with_mutex;
949 }
950
951 dst_fd = open(dst_fullpath, O_CREAT | O_WRONLY | O_TRUNC, src_mode);
952 if (dst_fd < 0)
953 {
954 PRINTK("cp error: can't create %s. %s.\n", dst_fullpath, strerror(errno));
955 goto errout_with_srcfd;
956 }
957
958 do
959 {
960 (void)memset_s(buf, CP_BUF_SIZE, 0, CP_BUF_SIZE);
961 r_size = read(src_fd, buf, CP_BUF_SIZE);
962 if (r_size < 0)
963 {
964 PRINTK("cp %s %s failed. %s.\n", src_fullpath, dst_fullpath, strerror(errno));
965 goto errout_with_fd;
966 }
967 w_size = write(dst_fd, buf, r_size);
968 if (w_size != r_size)
969 {
970 PRINTK("cp %s %s failed. %s.\n", src_fullpath, dst_fullpath, strerror(errno));
971 goto errout_with_fd;
972 }
973 }
974 while (r_size == CP_BUF_SIZE);
975
976 /* Release resource. */
977
978 free(buf);
979 free(src_fullpath);
980 free(dst_fullpath);
981 (void)close(src_fd);
982 (void)close(dst_fd);
984 return LOS_OK;
985
986errout_with_fd:
987 (void)close(dst_fd);
988errout_with_srcfd:
989 (void)close(src_fd);
990errout_with_mutex:
992errout_with_path:
993 free(dst_fullpath);
994errout_with_srcpath:
995 free(src_fullpath);
996 free(buf);
997 return -1;
998}
999
1000/* The separator and EOF for a directory fullpath: '/'and '\0' */
1001
1002#define SEPARATOR_EOF_LEN 2
1003
1004/**
1005 * @brief
1006 * @verbatim
1007 rmdir命令用来删除一个目录。
1008 rmdir [dir]
1009 dir 需要删除目录的名称,删除目录必须为空,支持输入路径。
1010 使用指南
1011 rmdir命令只能用来删除目录。
1012 rmdir一次只能删除一个目录。
1013 rmdir只能删除空目录。
1014
1015 举例:输入rmdir dir
1016 * @endverbatim
1017 * @param pathname
1018 * @return int
1019 */
1020static int os_shell_cmd_do_rmdir(const char *pathname)
1021{
1022 struct dirent *dirent = NULL;
1023 struct stat stat_info;
1024 DIR *d = NULL;
1025 char *fullpath = NULL;
1026 int ret;
1027
1028 (void)memset_s(&stat_info, sizeof(stat_info), 0, sizeof(struct stat));
1029 if (stat(pathname, &stat_info) != 0)
1030 {
1031 return -1;
1032 }
1033
1034 if (S_ISREG(stat_info.st_mode) || S_ISLNK(stat_info.st_mode))
1035 {
1036 return remove(pathname);
1037 }
1038 d = opendir(pathname);
1039 if (d == NULL)
1040 {
1041 return -1;
1042 }
1043 while (1)
1044 {
1045 dirent = readdir(d);
1046 if (dirent == NULL)
1047 {
1048 break;
1049 }
1050 if (strcmp(dirent->d_name, "..") && strcmp(dirent->d_name, "."))
1051 {
1052 size_t fullpath_buf_size = strlen(pathname) + strlen(dirent->d_name) + SEPARATOR_EOF_LEN;
1053 if (fullpath_buf_size <= 0)
1054 {
1055 PRINTK("buffer size is invalid!\n");
1056 (void)closedir(d);
1057 return -1;
1058 }
1059 fullpath = (char *)malloc(fullpath_buf_size);
1060 if (fullpath == NULL)
1061 {
1062 PRINTK("malloc failure!\n");
1063 (void)closedir(d);
1064 return -1;
1065 }
1066 ret = snprintf_s(fullpath, fullpath_buf_size, fullpath_buf_size - 1, "%s/%s", pathname, dirent->d_name);
1067 if (ret < 0)
1068 {
1069 PRINTK("name is too long!\n");
1070 free(fullpath);
1071 (void)closedir(d);
1072 return -1;
1073 }
1074 (void)os_shell_cmd_do_rmdir(fullpath);
1075 free(fullpath);
1076 }
1077 }
1078 (void)closedir(d);
1079 return rmdir(pathname);
1080}
1081
1082/* Wildcard matching operations */
1083//确定路径中是否存在通配符
1084static int os_wildcard_match(const char *src, const char *filename)
1085{
1086 int ret;
1087
1088 if (*src != '\0')
1089 {
1090 if (*filename == '*')
1091 {
1092 while ((*filename == '*') || (*filename == '?'))
1093 {
1094 filename++;
1095 }
1096
1097 if (*filename == '\0')
1098 {
1099 return 0;
1100 }
1101
1102 while (*src != '\0' && !(*src == *filename))
1103 {
1104 src++;
1105 }
1106
1107 if (*src == '\0')
1108 {
1109 return -1;
1110 }
1111
1112 ret = os_wildcard_match(src, filename);
1113
1114 while ((ret != 0) && (*(++src) != '\0'))
1115 {
1116 if (*src == *filename)
1117 {
1118 ret = os_wildcard_match(src, filename);
1119 }
1120 }
1121 return ret;
1122 }
1123 else
1124 {
1125 if ((*src == *filename) || (*filename == '?'))
1126 {
1127 return os_wildcard_match(++src, ++filename);
1128 }
1129 return -1;
1130 }
1131 }
1132
1133 while (*filename != '\0')
1134 {
1135 if (*filename != '*')
1136 {
1137 return -1;
1138 }
1139 filename++;
1140 }
1141 return 0;
1142}
1143
1144/* To determine whether a wildcard character exists in a path */
1145//文件名是否存在通配符
1146static int os_is_containers_wildcard(const char *filename)
1147{
1148 while (*filename != '\0')
1149 {
1150 if ((*filename == '*') || (*filename == '?'))
1151 {
1152 return 1;
1153 }
1154 filename++;
1155 }
1156 return 0;
1157}
1158
1159/* Delete a matching file or directory */
1160//删除匹配的文件或目录
1161static int os_wildcard_delete_file_or_dir(const char *fullpath, wildcard_type mark)
1162{
1163 int ret;
1164
1165 switch (mark)
1166 {
1167 case RM_RECURSIVER://递归删除
1168 ret = os_shell_cmd_do_rmdir(fullpath);//删除目录,其中递归调用 rmdir
1169 break;
1170 case RM_FILE://删除文件
1171 ret = unlink(fullpath);
1172 break;
1173 case RM_DIR://删除目录
1174 ret = rmdir(fullpath);
1175 break;
1176 default:
1177 return VFS_ERROR;
1178 }
1179 if (ret == -1)
1180 {
1181 PRINTK("%s ", fullpath);
1182 perror("rm/rmdir error!");
1183 return ret;
1184 }
1185
1186 PRINTK("%s match successful!delete!\n", fullpath);
1187 return 0;
1188}
1189
1190/* Split the path with wildcard characters */
1191//使用通配符拆分路径
1192static char* os_wildcard_split_path(char *fullpath, char **handle, char **wait)
1193{
1194 int n = 0;
1195 int a = 0;
1196 int b = 0;
1197 int len = strlen(fullpath);
1198
1199 for (n = 0; n < len; n++)
1200 {
1201 if (fullpath[n] == '/')
1202 {
1203 if (b != 0)
1204 {
1205 fullpath[n] = '\0';
1206 *wait = fullpath + n + 1;
1207 break;
1208 }
1209 a = n;
1210 }
1211 else if (fullpath[n] == '*' || fullpath[n] == '?')
1212 {
1213 b = n;
1214 fullpath[a] = '\0';
1215 if (a == 0)
1216 {
1217 *handle = fullpath + a + 1;
1218 continue;
1219 }
1220 *handle = fullpath + a + 1;
1221 }
1222 }
1223 return fullpath;
1224}
1225
1226/* Handling entry of the path with wildcard characters */
1227//处理具有通配符的目录
1228static int os_wildcard_extract_directory(char *fullpath, void *dst, wildcard_type mark)
1229{
1230 char separator[] = "/";
1231 char src[PATH_MAX] = {0};
1232 struct dirent *dirent = NULL;
1233 char *f = NULL;
1234 char *s = NULL;
1235 char *t = NULL;
1236 int ret = 0;
1237 DIR *d = NULL;
1238 struct stat stat_buf;
1239 int deleteFlag = 0;
1240
1241 f = os_wildcard_split_path(fullpath, &s, &t);
1242
1243 if (s == NULL)
1244 {
1245 if (mark == CP_FILE)
1246 {
1247 ret = os_shell_cmd_do_cp(fullpath, dst);
1248 }
1249 else if (mark == CP_COUNT)
1250 {
1251 ret = stat(fullpath, &stat_buf);
1252 if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)))
1253 {
1254 (*(int *)dst)++;
1255 }
1256 }
1257 else
1258 {
1259 ret = os_wildcard_delete_file_or_dir(fullpath, mark);
1260 }
1261 return ret;
1262 }
1263
1264 d = (*f == '\0') ? opendir("/") : opendir(f);
1265
1266 if (d == NULL)
1267 {
1268 perror("opendir error");
1269 return VFS_ERROR;
1270 }
1271
1272 while (1)
1273 {
1274 dirent = readdir(d);
1275 if (dirent == NULL)
1276 {
1277 break;
1278 }
1279
1280 ret = strcpy_s(src, PATH_MAX, f);
1281 if (ret != EOK)
1282 {
1283 goto closedir_out;
1284 }
1285
1286 ret = os_wildcard_match(dirent->d_name, s);
1287 if (ret == 0)
1288 {
1289 ret = strcat_s(src, sizeof(src), separator);
1290 if (ret != EOK)
1291 {
1292 goto closedir_out;
1293 }
1294 ret = strcat_s(src, sizeof(src), dirent->d_name);
1295 if (ret != EOK)
1296 {
1297 goto closedir_out;
1298 }
1299 if (t == NULL)
1300 {
1301 if (mark == CP_FILE)
1302 {
1303 ret = os_shell_cmd_do_cp(src, dst);
1304 }
1305 else if (mark == CP_COUNT)
1306 {
1307 ret = stat(src, &stat_buf);
1308 if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)))
1309 {
1310 (*(int *)dst)++;
1311 if ((*(int *)dst) > 1)
1312 {
1313 break;
1314 }
1315 }
1316 }
1317 else
1318 {
1319 ret = os_wildcard_delete_file_or_dir(src, mark);
1320 if (ret == 0)
1321 {
1322 deleteFlag = 1;
1323 }
1324 }
1325 }
1326 else
1327 {
1328 ret = strcat_s(src, sizeof(src), separator);
1329 if (ret != EOK)
1330 {
1331 goto closedir_out;
1332 }
1333 ret = strcat_s(src, sizeof(src), t);
1334 if (ret != EOK)
1335 {
1336 goto closedir_out;
1337 }
1338 ret = os_wildcard_extract_directory(src, dst, mark);
1339 if (mark == CP_COUNT && (*(int *)dst) > 1)
1340 {
1341 break;
1342 }
1343 }
1344 }
1345 }
1346 (void)closedir(d);
1347 if (deleteFlag == 1)
1348 {
1349 ret = 0;
1350 }
1351 return ret;
1352closedir_out:
1353 (void)closedir(d);
1354 return VFS_ERROR;
1355}
1356
1357/**
1358 * @brief
1359 * @verbatim
1360 命令功能
1361 拷贝文件,创建一份副本。
1362
1363 命令格式
1364 cp [SOURCEFILE] [DESTFILE]
1365
1366 SOURCEFILE - 源文件路径。- 目前只支持文件,不支持目录。
1367 DESTFILE - 目的文件路径。 - 支持目录以及文件。
1368
1369 使用指南
1370 同一路径下,源文件与目的文件不能重名。
1371 源文件必须存在,且不为目录。
1372 源文件路径支持“*”和“?”通配符,“*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。
1373 目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。
1374 目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。
1375 目前不支持多文件拷贝。参数大于2个时,只对前2个参数进行操作。
1376 目的文件不存在时创建新文件,已存在则覆盖。
1377 拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-0 文件时,会产生系统卡死现象。
1378
1379 使用实例
1380 举例:cp harmony.txt ./tmp/
1381 * @endverbatim
1382 * @param argc
1383 * @param argv
1384 * @return int
1385 */
1386int osShellCmdCp(int argc, const char **argv)
1387{
1388 int ret;
1389 const char *src = NULL;
1390 const char *dst = NULL;
1391 char *src_fullpath = NULL;
1392 char *dst_fullpath = NULL;
1393 struct stat stat_buf;
1394 int count = 0;
1395 char *shell_working_directory = OsShellGetWorkingDirectory();//获取进程当前工作目录
1396 if (shell_working_directory == NULL)
1397 {
1398 return -1;
1399 }
1400
1401 ERROR_OUT_IF(argc < 2, PRINTK("cp [SOURCEFILE] [DESTFILE]\n"), return -1);//参数必须要两个
1402
1403 src = argv[0];
1404 dst = argv[1];
1405
1406 /* Get source fullpath. */
1407
1408 ret = vfs_normalize_path(shell_working_directory, src, &src_fullpath);//获取源路径的全路径
1409 if (ret < 0)
1410 {
1411 set_errno(-ret);
1412 PRINTK("cp error:%s\n", strerror(errno));
1413 return -1;
1414 }
1415
1416 if (src[strlen(src) - 1] == '/')//如果src最后一个字符是 '/'说明是个目录,src必须是个文件,目前只支持文件,不支持目录
1417 {
1418 PRINTK("cp %s error: Source file can't be a directory.\n", src);
1419 goto errout_with_srcpath;
1420 }
1421
1422 /* Get dest fullpath. */
1423
1424 ret = vfs_normalize_path(shell_working_directory, dst, &dst_fullpath);
1425 if (ret < 0)
1426 {
1427 set_errno(-ret);
1428 PRINTK("cp error: can't open %s. %s\n", dst, strerror(errno));
1429 goto errout_with_srcpath;
1430 }
1431
1432 /* Is dest path exist? *///目标路径是个目录吗?
1433
1434 ret = stat(dst_fullpath, &stat_buf);//判断目标路径存不存在
1435 if (ret < 0)
1436 {
1437 /* Is dest path a directory? */
1438
1439 if (dst[strlen(dst) - 1] == '/')
1440 {
1441 PRINTK("cp error: %s, %s.\n", dst_fullpath, strerror(errno));
1442 goto errout_with_path;
1443 }
1444 }
1445 else
1446 {
1447 if ((S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)) && dst[strlen(dst) - 1] == '/')
1448 {
1449 PRINTK("cp error: %s is not a directory.\n", dst_fullpath);
1450 goto errout_with_path;
1451 }
1452 }
1453
1454 if (os_is_containers_wildcard(src_fullpath))
1455 {
1456 if (ret < 0 || S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))
1457 {
1458 char *src_copy = strdup(src_fullpath);
1459 if (src_copy == NULL)
1460 {
1461 PRINTK("cp error : Out of memory.\n");
1462 goto errout_with_path;
1463 }
1464 (void)os_wildcard_extract_directory(src_copy, &count, CP_COUNT);
1465 free(src_copy);
1466 if (count > 1)
1467 {
1468 PRINTK("cp error : %s is not a directory.\n", dst_fullpath);
1469 goto errout_with_path;
1470 }
1471 }
1472 ret = os_wildcard_extract_directory(src_fullpath, dst_fullpath, CP_FILE);
1473 }
1474 else
1475 {
1476 ret = os_shell_cmd_do_cp(src_fullpath, dst_fullpath);
1477 }
1478 free(dst_fullpath);
1479 free(src_fullpath);
1480 return ret;
1481
1482errout_with_path:
1483 free(dst_fullpath);
1484errout_with_srcpath:
1485 free(src_fullpath);
1486 return VFS_ERROR;
1487}
1488
1489static inline void print_rm_usage(void)
1490{
1491 PRINTK("rm [FILE] or rm [-r/-R] [FILE]\n");
1492}
1493
1494/**
1495 * @brief
1496 * @verbatim rm命令用来删除文件或文件夹。rm [-r] [dirname / filename]
1497 rm命令一次只能删除一个文件或文件夹。
1498 rm -r命令可以删除非空目录。
1499 rm log1.txt ; rm -r sd
1500 @endverbatim
1501 * @param argc
1502 * @param argv
1503 * @return int
1504 */
1505int osShellCmdRm(int argc, const char **argv)
1506{
1507 int ret = 0;
1508 char *fullpath = NULL;
1509 const char *filename = NULL;
1510 char *shell_working_directory = OsShellGetWorkingDirectory();
1511 if (shell_working_directory == NULL)
1512 {
1513 return -1;
1514 }
1515
1516 ERROR_OUT_IF(argc != 1 && argc != 2, print_rm_usage(), return -1);
1517
1518 if (argc == 2)
1519 {
1520 ERROR_OUT_IF(strcmp(argv[0], "-r") != 0 && strcmp(argv[0], "-R") != 0, print_rm_usage(), return -1);
1521
1522 filename = argv[1];
1523 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1524 ERROR_OUT_IF(ret < 0, set_err(-ret, "rm error"), return -1);
1525
1526 if (os_is_containers_wildcard(fullpath))
1527 {
1528 ret = os_wildcard_extract_directory(fullpath, NULL, RM_RECURSIVER);
1529 }
1530 else
1531 {
1532 ret = os_shell_cmd_do_rmdir(fullpath);
1533 }
1534 }
1535 else
1536 {
1537 filename = argv[0];
1538 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1539 ERROR_OUT_IF(ret < 0, set_err(-ret, "rm error"), return -1);
1540
1541 if (os_is_containers_wildcard(fullpath))
1542 {
1543 ret = os_wildcard_extract_directory(fullpath, NULL, RM_FILE);
1544 }
1545 else
1546 {
1547 ret = unlink(fullpath);
1548 }
1549 }
1550 if (ret == -1)
1551 {
1552 perror("rm error");
1553 }
1554 free(fullpath);
1555 return 0;
1556}
1557
1558/**
1559 * @brief
1560 * @verbatim
1561 命令功能
1562 rmdir命令用来删除一个目录。
1563
1564 命令格式
1565 rmdir [dir]
1566
1567 参数说明
1568 参数 参数说明 取值范围
1569 dir 需要删除目录的名称,删除目录必须为空,支持输入路径。N/A
1570
1571 使用指南
1572 rmdir命令只能用来删除目录。
1573 rmdir一次只能删除一个目录。
1574 rmdir只能删除空目录。
1575 使用实例
1576 举例:输入rmdir dir
1577 * @endverbatim
1578 * @param argc
1579 * @param argv
1580 * @return int
1581 */
1582int osShellCmdRmdir(int argc, const char **argv)
1583{
1584 int ret;
1585 char *fullpath = NULL;
1586 const char *filename = NULL;
1587 char *shell_working_directory = OsShellGetWorkingDirectory();
1588 if (shell_working_directory == NULL)
1589 {
1590 return -1;
1591 }
1592
1593 ERROR_OUT_IF(argc == 0, PRINTK("rmdir [DIRECTORY]\n"), return -1);
1594
1595 filename = argv[0];
1596 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1597 ERROR_OUT_IF(ret < 0, set_err(-ret, "rmdir error"), return -1);
1598
1599 if (os_is_containers_wildcard(fullpath))
1600 {
1601 ret = os_wildcard_extract_directory(fullpath, NULL, RM_DIR);
1602 }
1603 else
1604 {
1605 ret = rmdir(fullpath);
1606 }
1607 if (ret == -1)
1608 {
1609 PRINTK("rmdir %s failed. Error: %s.\n", fullpath, strerror(errno));
1610 }
1611 free(fullpath);
1612
1613 return 0;
1614}
1615
1616/**
1617 * @brief
1618 * @verbatim
1619 命令功能
1620 sync命令用于同步缓存数据(文件系统的数据)到sd卡。
1621
1622 命令格式
1623 sync
1624
1625 参数说明
1626 无。
1627
1628 使用指南
1629 sync命令用来刷新缓存,当没有sd卡插入时不进行操作。
1630 有sd卡插入时缓存信息会同步到sd卡,成功返回时无显示。
1631 使用实例
1632 举例:输入sync,有sd卡时同步到sd卡,无sd卡时不操作。
1633 * @endverbatim
1634 * @param argc
1635 * @param argv
1636 * @return int
1637 */
1638int osShellCmdSync(int argc, const char **argv)
1639{
1640 ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: sync\n"), return -1);
1641
1642 sync();
1643 return 0;
1644}
1645
1646/**
1647 * @brief
1648 * @verbatim
1649 命令功能
1650 lsfd命令用来显示当前已经打开的系统文件描述符及对应的文件名。
1651
1652 命令格式
1653 lsfd
1654
1655 使用指南
1656 lsfd命令显示当前已经打开文件的fd号以及文件的名字。
1657
1658 使用实例
1659 举例:输入lsfd,注意这里并不显示 (0 ~ 2)号
1660 OHOS #lsfd
1661 fd filename
1662 3 /dev/console1
1663 4 /dev/spidev1.0
1664 5 /bin/init
1665 6 /bin/shell
1666 * @endverbatim
1667 * @param argc
1668 * @param argv
1669 * @return int
1670 */
1671int osShellCmdLsfd(int argc, const char **argv)
1672{
1673 ERROR_OUT_IF(argc > 0, PRINTK("\nUsage: lsfd\n"), return -1);
1674
1675 lsfd();
1676
1677 return 0;
1678}
1679
1680int checkNum(const char *arg)
1681{
1682 int i = 0;
1683 if (arg == NULL)
1684 {
1685 return -1;
1686 }
1687 if (arg[0] == '-')
1688 {
1689 /* exclude the '-' */
1690
1691 i = 1;
1692 }
1693 for (; arg[i] != 0; i++)
1694 {
1695 if (!isdigit(arg[i]))
1696 {
1697 return -1;
1698 }
1699 }
1700 return 0;
1701}
1702
1703#ifdef LOSCFG_KERNEL_SYSCALL
1704
1705/**
1706 * @brief
1707 * @verbatim
1708 shell su 用于变更为其他使用者的身份
1709 su [uid] [gid]
1710 su命令缺省切换到root用户,uid默认为0,gid为0。
1711 在su命令后的输入参数uid和gid就可以切换到该uid和gid的用户。
1712 输入参数超出范围时,会打印提醒输入正确范围参数。
1713 * @endverbatim
1714 * @param argc
1715 * @param argv
1716 * @return int
1717 */
1718int osShellCmdSu(int argc, const char **argv)
1719{
1720 int su_uid;
1721 int su_gid;
1722
1723 if (argc == 0)//无参时切换到root用户
1724 {
1725 /* for su root */
1726
1727 su_uid = 0;
1728 su_gid = 0;
1729 }
1730 else
1731 {
1732 ERROR_OUT_IF((argc != 2), PRINTK("su [uid_num] [gid_num]\n"), return -1);
1733 ERROR_OUT_IF((checkNum(argv[0]) != 0) || (checkNum(argv[1]) != 0), /* check argv is digit */
1734 PRINTK("check uid_num and gid_num is digit\n"), return -1);
1735
1736 su_uid = atoi(argv[0]);//标准musl C库函数 字符串转数字
1737 su_gid = atoi(argv[1]);
1738
1739 ERROR_OUT_IF((su_uid < 0) || (su_uid > 60000) || (su_gid < 0) ||
1740 (su_gid > 60000), PRINTK("uid_num or gid_num out of range!they should be [0~60000]\n"), return -1);
1741 }
1742
1743 SysSetUserID(su_uid);
1744 SysSetGroupID(su_gid);
1745 return 0;
1746}
1747#endif
1748
1749/**
1750 * @brief
1751 * @verbatim
1752 shell chmod 用于修改文件操作权限。chmod [mode] [pathname]
1753 mode 文件或文件夹权限,用8进制表示对应User、Group、及Other(拥有者、群组、其他组)的权限。[0,777]
1754 pathname 文件路径。已存在的文件。
1755 chmod 777 weharmony.txt 暂不支持 chmod ugo+r file1.txt这种写法
1756 * @endverbatim
1757 * @param pathname
1758 * @return int
1759 */
1760int osShellCmdChmod(int argc, const char **argv)
1761{
1762 int i = 0;
1763 int mode = 0;
1764 int ret;
1765 char *fullpath = NULL;
1766 const char *filename = NULL;
1767 struct IATTR attr = {0};//IATTR是用来inode的属性 见于 ..\third_party\NuttX\include\nuttx\fs\fs.h
1768 char *shell_working_directory = NULL;
1769 const char *p = NULL;
1770#define MODE_BIT 3 /* 3 bits express 1 mode */
1771
1772 ERROR_OUT_IF((argc != 2), PRINTK("Usage: chmod <MODE> [FILE]\n"), return -1);
1773
1774 p = argv[0];
1775 while (p[i])
1776 {
1777 if ((p[i] <= '7') && (p[i] >= '0'))// 参数只能在 000 - 777 之间
1778 {
1779 mode = ((uint)mode << MODE_BIT) | (uint)(p[i] - '0');
1780 }
1781 else
1782 {
1783 PRINTK("check the input <MODE>\n");//例如: chmod 807 是错误的
1784 return -1;
1785 }
1786 i++;
1787 }
1788 filename = argv[1];
1789
1790 shell_working_directory = OsShellGetWorkingDirectory();
1791 if (shell_working_directory == NULL)
1792 {
1793 return -1;
1794 }
1795 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1796 ERROR_OUT_IF(ret < 0, set_err(-ret, "chmod error\n"), return -1);
1797
1798 attr.attr_chg_mode = mode;
1799 attr.attr_chg_valid = CHG_MODE; /* change mode */
1800 ret = chattr(fullpath, &attr);
1801 if (ret < 0)
1802 {
1803 free(fullpath);
1804 PRINTK("chmod error! %s\n", strerror(errno));
1805 return ret;
1806 }
1807
1808 free(fullpath);
1809 return 0;
1810}
1811/****************************************************************
1812shell chown 用于将指定文件的拥有者改为指定的用户或组。chown [owner] [group] [pathname]
1813owner 文件拥有者。[0,0xFFFFFFFF]
1814group 文件群组。1、为空。2、[0,0xFFFFFFFF]
1815pathname 文件路径。已存在的文件。
1816在需要修改的文件名前加上文件拥有者和文件群组就可以分别修改该文件的拥有者和群组。
1817当owner或group值为-1时则表示对应的owner或group不修改。
1818group参数可以为空。
1819举例:chown 100 200 weharmony.txt
1820****************************************************************/
1821int osShellCmdChown(int argc, const char **argv)
1822{
1823 int ret;
1824 char *fullpath = NULL;
1825 const char *filename = NULL;
1826 struct IATTR attr;
1827 uid_t owner = -1;
1828 gid_t group = -1;
1829 attr.attr_chg_valid = 0;
1830
1831 ERROR_OUT_IF(((argc != 2) && (argc != 3)), PRINTK("Usage: chown [OWNER] [GROUP] FILE\n"), return -1);
1832 if (argc == 2)//只有二个参数解析 chown 100 weharmony.txt
1833 {
1834 ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check OWNER is digit\n"), return -1);
1835 owner = atoi(argv[0]);
1836 filename = argv[1];
1837 }
1838 if (argc == 3)//有三个参数解析 chown 100 200 weharmony.txt
1839 {
1840 ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check OWNER is digit\n"), return -1);
1841 ERROR_OUT_IF((checkNum(argv[1]) != 0), PRINTK("check GROUP is digit\n"), return -1);
1842 owner = atoi(argv[0]);//第一个参数用于修改拥有者指定用户
1843 group = atoi(argv[1]);//第二个参数用于修改拥有者指定组
1844 filename = argv[2];
1845 }
1846
1847 if (group != -1)//-1代表不需要处理
1848 {
1849 attr.attr_chg_gid = group;
1850 attr.attr_chg_valid |= CHG_GID;//贴上拥有组被修改过的标签
1851 }
1852 if (owner != -1)
1853 {
1854 attr.attr_chg_uid = owner;
1855 attr.attr_chg_valid |= CHG_UID;//贴上拥有者被修改过的标签
1856 }
1857
1858 char *shell_working_directory = OsShellGetWorkingDirectory();
1859 if (shell_working_directory == NULL)
1860 {
1861 return -1;
1862 }
1863 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1864 ERROR_OUT_IF(ret < 0, set_err(-ret, "chown error\n"), return -1);
1865
1866 ret = chattr(fullpath, &attr);//修改属性,在chattr中,参数attr将会和fullpath原有attr->attr_chg_valid 按|运算
1867 if (ret < 0)
1868 {
1869 free(fullpath);
1870 PRINTK("chown error! %s\n", strerror(errno));
1871 return ret;
1872 }
1873
1874 free(fullpath);
1875 return 0;
1876}
1877
1878/**
1879 * @brief
1880 * @verbatim
1881 chgrp用于修改文件的群组。chgrp [group] [pathname]
1882 group 文件群组。[0,0xFFFFFFFF]
1883 pathname 文件路径。 已存在的文件。
1884 在需要修改的文件名前加上文件群组值就可以修改该文件的所属组。
1885 举例:chgrp 100 weharmony.txt
1886 * @endverbatim
1887 * @param pathname
1888 * @return int
1889 */
1890int osShellCmdChgrp(int argc, const char **argv)
1891{
1892 int ret;
1893 char *fullpath = NULL;
1894 const char *filename = NULL;
1895 struct IATTR attr;
1896 gid_t group;
1897 attr.attr_chg_valid = 0;
1898 ERROR_OUT_IF((argc != 2), PRINTK("Usage: chgrp GROUP FILE\n"), return -1);
1899 ERROR_OUT_IF((checkNum(argv[0]) != 0), PRINTK("check GROUP is digit\n"), return -1);
1900 group = atoi(argv[0]);
1901 filename = argv[1];
1902
1903 if (group != -1) {//可以看出 chgrp 是 chown 命令的裁剪版
1904 attr.attr_chg_gid = group;
1905 attr.attr_chg_valid |= CHG_GID;
1906 }
1907
1908 char *shell_working_directory = OsShellGetWorkingDirectory();
1909 if (shell_working_directory == NULL) {
1910 return -1;
1911 }
1912 ret = vfs_normalize_path(shell_working_directory, filename, &fullpath);
1913 ERROR_OUT_IF(ret < 0, set_err(-ret, "chmod error"), return -1);
1914
1915 ret = chattr(fullpath, &attr);//修改属性
1916 if (ret < 0) {
1917 free(fullpath);
1918 PRINTK("chgrp error! %s\n", strerror(errno));
1919 return ret;
1920 }
1921
1922 free(fullpath);
1923 return 0;
1924}
1925
1926#ifdef LOSCFG_SHELL_CMD_DEBUG
1928SHELLCMD_ENTRY(statfs_shellcmd, CMD_TYPE_EX, "statfs", XARGS, (CmdCallBackFunc)osShellCmdStatfs);
1930#ifdef LOSCFG_KERNEL_SYSCALL
1932#endif
1933#endif
1935SHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CmdCallBackFunc)osShellCmdLs);
1937SHELLCMD_ENTRY(cd_shellcmd, CMD_TYPE_EX, "cd", XARGS, (CmdCallBackFunc)osShellCmdCd);
1945SHELLCMD_ENTRY(mount_shellcmd, CMD_TYPE_EX, "mount", XARGS, (CmdCallBackFunc)osShellCmdMount);//#mount 命令静态注册方式
1946SHELLCMD_ENTRY(umount_shellcmd, CMD_TYPE_EX, "umount", XARGS, (CmdCallBackFunc)osShellCmdUmount);
1948#endif
@ CMD_TYPE_EX
不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。
Definition: shell.h:91
char * OsShellGetWorkingDirectory(void)
Definition: shcmd.c:94
void ls(const char *pathname)
list directory contents.
Definition: vfs_other.c:600
int chattr(const char *pathname, struct IATTR *attr)
Definition: vfs_chattr.c:58
int vfs_normalize_path(const char *directory, const char *filename, char **pathname)
Definition: fullpath.c:245
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
Unlock the task scheduling.
Definition: los_task.c:1148
struct tagTskInitParam TSK_INIT_PARAM_S
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID)
Lock the task scheduling.
Definition: los_task.c:1139
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务
Definition: los_task.c:718
LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态
Definition: los_task.c:1020
VOID *(* TSK_ENTRY_FUNC)(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4)
Define the type of a task entrance function.
Definition: los_task.h:480
__attribute__((aligned(MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS)))
Definition: los_arch_mmu.c:98
int SysSetUserID(int uid)
INT64 ssize_t
Definition: los_typedef.h:79
unsigned long UINTPTR
Definition: los_typedef.h:68
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
int pthread_mutex_lock(pthread_mutex_t *mutex)
互斥锁加锁操作
int pthread_mutex_unlock(pthread_mutex_t *mutex)
解锁互斥锁
此结构用于记录 vnode 的属性
Definition: vnode.h:81
unsigned attr_chg_uid
用户ID
Definition: vnode.h:86
unsigned attr_chg_mode
确定了文件的类型,以及它的所有者、它的group、其它用户访问此文件的权限 (S_IWUSR | ...)
Definition: vnode.h:85
unsigned attr_chg_gid
组ID
Definition: vnode.h:87
unsigned int attr_chg_valid
节点改变有效性 (CHG_MODE | CHG_UID | ... )
Definition: vnode.h:83
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
Definition: vnode.h:164
uint gid
Definition: vnode.h:169
enum VnodeType type
Definition: vnode.h:165
void * data
Definition: vnode.h:176
uint uid
Definition: vnode.h:168
UINT16 usTaskPrio
Definition: los_task.h:505
UINTPTR auwArgs[4]
Definition: los_task.h:507
UINT32 uwStackSize
Definition: los_task.h:508
CHAR * pcName
Definition: los_task.h:509
UINT32 processID
进程ID
Definition: los_task.h:516
TSK_ENTRY_FUNC pfnTaskEntry
Definition: los_task.h:504
UINT32 uwResved
Definition: los_task.h:513
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 ARG_NUM_0 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_6 ARG_NUM_3 ARG_NUM_5 ARG_NUM_7 ARG_NUM_1 ARG_NUM_4 ARG_NUM_5 ARG_NUM_4 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_7 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_7 ARG_NUM_3 ARG_NUM_2 char ARG_NUM_2 ARG_NUM_1 ARG_NUM_0 ARG_NUM_0 ARG_NUM_3 void ARG_NUM_1 ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_5 ARG_NUM_3 ARG_NUM_3 ARG_NUM_4 ARG_NUM_1 ARG_NUM_1 ARG_NUM_3 ARG_NUM_2 ARG_NUM_1 ARG_NUM_4 ARG_NUM_4 ARG_NUM_5 ARG_NUM_3 ARG_NUM_2 void ARG_NUM_6 unsigned ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_3 ARG_NUM_3 ARG_NUM_2 ARG_NUM_2 SysSetGroupID
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 ARG_NUM_0 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_6 ARG_NUM_3 ARG_NUM_5 ARG_NUM_7 ARG_NUM_1 ARG_NUM_4 ARG_NUM_5 ARG_NUM_4 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_7 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_7 ARG_NUM_3 ARG_NUM_2 char ARG_NUM_2 ARG_NUM_1 ARG_NUM_0 ARG_NUM_0 ARG_NUM_3 void ARG_NUM_1 ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_5 ARG_NUM_3 ARG_NUM_3 ARG_NUM_4 ARG_NUM_1 ARG_NUM_1 ARG_NUM_3 ARG_NUM_2 ARG_NUM_1 ARG_NUM_4 ARG_NUM_4 ARG_NUM_5 ARG_NUM_3 ARG_NUM_2 void ARG_NUM_6 unsigned ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_3 ARG_NUM_3 ARG_NUM_2 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_1 char ARG_NUM_0 ARG_NUM_4 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_2 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_6 ARG_NUM_6 ARG_NUM_5 ARG_NUM_3 void ARG_NUM_3 ARG_NUM_3 ARG_NUM_5 ARG_NUM_1 unsigned ARG_NUM_3 long
ARG_NUM_3 int
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 ARG_NUM_0 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_6 ARG_NUM_3 ARG_NUM_5 ARG_NUM_7 ARG_NUM_1 ARG_NUM_4 ARG_NUM_5 ARG_NUM_4 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_7 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_7 ARG_NUM_3 ARG_NUM_2 char ARG_NUM_2 ARG_NUM_1 ARG_NUM_0 ARG_NUM_0 ARG_NUM_3 void ARG_NUM_1 ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_5 ARG_NUM_3 ARG_NUM_3 ARG_NUM_4 ARG_NUM_1 ARG_NUM_1 ARG_NUM_3 ARG_NUM_2 mode_t
u32_t(* CmdCallBackFunc)(u32_t argc, const char **argv)
Definition: types_adapt.h:86
int VnodeDrop(void)
归还锁
Definition: vnode.c:292
@ VNODE_TYPE_REG
Definition: vnode.h:136
int VnodeHold(void)
拿锁,封装互斥量
Definition: vnode.c:283
int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags)
通过路径查询vnode节点
Definition: vnode.c:491
int chdir(const char *path)
Definition: vfs_other.c:150
void lsfd(void)
查看FD
Definition: vfs_other.c:689
static void print_mount_usage(void)
Definition: vfs_shellcmd.c:380
static int os_wildcard_extract_directory(char *fullpath, void *dst, wildcard_type mark)
int osShellCmdPwd(int argc, const char **argv)
Definition: vfs_shellcmd.c:666
wildcard_type
Definition: vfs_shellcmd.c:57
@ CP_FILE
Definition: vfs_shellcmd.c:61
@ RM_DIR
Definition: vfs_shellcmd.c:60
@ RM_FILE
Definition: vfs_shellcmd.c:59
@ CP_COUNT
Definition: vfs_shellcmd.c:62
@ RM_RECURSIVER
Definition: vfs_shellcmd.c:58
static int os_wildcard_delete_file_or_dir(const char *fullpath, wildcard_type mark)
static int os_shell_cmd_do_cp(const char *src_filepath, const char *dst_filename)
Definition: vfs_shellcmd.c:833
int osShellCmdChown(int argc, const char **argv)
static int os_shell_cmd_do_rmdir(const char *pathname)
SHELLCMD_ENTRY(lsfd_shellcmd, CMD_TYPE_EX, "lsfd", XARGS,(CmdCallBackFunc) osShellCmdLsfd)
int osShellCmdRmdir(int argc, const char **argv)
int osShellCmdChgrp(int argc, const char **argv)
static unsigned long get_mountflags(const char *options)
Definition: vfs_shellcmd.c:360
int osShellCmdSu(int argc, const char **argv)
static void print_rm_usage(void)
int osShellCmdChmod(int argc, const char **argv)
int osShellCmdDoCatShow(UINTPTR arg)
Definition: vfs_shellcmd.c:240
static void print_statfs_usage(void)
Definition: vfs_shellcmd.c:700
static int os_is_containers_wildcard(const char *filename)
int osShellCmdLsfd(int argc, const char **argv)
int osShellCmdSync(int argc, const char **argv)
static int nfs_mount_ref(const char *server_ip_and_path, const char *mount_path, unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount")))
static char * os_wildcard_split_path(char *fullpath, char **handle, char **wait)
pthread_mutex_t g_mutex_cp
Definition: vfs_shellcmd.c:811
int osShellCmdTouch(int argc, const char **argv)
Definition: vfs_shellcmd.c:780
int checkNum(const char *arg)
int osShellCmdUmount(int argc, const char **argv)
Definition: vfs_shellcmd.c:557
int osShellCmdMkdir(int argc, const char **argv)
Definition: vfs_shellcmd.c:625
static int os_wildcard_match(const char *src, const char *filename)
int osShellCmdStatfs(int argc, const char **argv)
Definition: vfs_shellcmd.c:726
int osShellCmdMount(int argc, const char **argv)
Definition: vfs_shellcmd.c:406
int osShellCmdCat(int argc, const char **argv)
Definition: vfs_shellcmd.c:301
int osShellCmdRm(int argc, const char **argv)
int osShellCmdCp(int argc, const char **argv)