更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
fs_syscall.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 "syscall_pub.h"
33#ifdef LOSCFG_FS_VFS
34#include "errno.h"
35#include "unistd.h"
36#include "fs/fd_table.h"
37#include "fs/file.h"
38#include "fs/fs.h"
39#include "fs/fs_operation.h"
40#include "sys/mount.h"
41#include "los_task_pri.h"
42#include "sys/utsname.h"
43#include "sys/uio.h"
44#include "poll.h"
45#include "sys/prctl.h"
46#include "epoll.h"
47#ifdef LOSCFG_KERNEL_DYNLOAD
48#include "los_exec_elf.h"
49#endif
50#include "los_syscall.h"
51#include "dirent.h"
52#include "user_copy.h"
53#include "los_vm_map.h"
54#include "los_memory.h"
56#include "capability_type.h"
57#include "capability_api.h"
58#include "sys/statfs.h"
59//拷贝用户空间路径到内核空间
60#define HIGH_SHIFT_BIT 32
61#define TIMESPEC_TIMES_NUM 2
62
63static int CheckNewAttrTime(struct IATTR *attr, struct timespec times[TIMESPEC_TIMES_NUM])
64{
65 int ret = ENOERR;
66 struct timespec stp = {0};
67
68 if (times) {
69 if (times[0].tv_nsec == UTIME_OMIT) {
70 attr->attr_chg_valid &= ~CHG_ATIME;
71 } else if (times[0].tv_nsec == UTIME_NOW) {
72 ret = clock_gettime(CLOCK_REALTIME, &stp);
73 if (ret < 0) {
74 return -get_errno();
75 }
76 attr->attr_chg_atime = (unsigned int)stp.tv_sec;
77 attr->attr_chg_valid |= CHG_ATIME;
78 } else {
79 attr->attr_chg_atime = (unsigned int)times[0].tv_sec;
80 attr->attr_chg_valid |= CHG_ATIME;
81 }
82
83 if (times[1].tv_nsec == UTIME_OMIT) {
84 attr->attr_chg_valid &= ~CHG_MTIME;
85 } else if (times[1].tv_nsec == UTIME_NOW) {
86 ret = clock_gettime(CLOCK_REALTIME, &stp);
87 if (ret < 0) {
88 return -get_errno();
89 }
90 attr->attr_chg_mtime = (unsigned int)stp.tv_sec;
91 attr->attr_chg_valid |= CHG_MTIME;
92 } else {
93 attr->attr_chg_mtime = (unsigned int)times[1].tv_sec;
94 attr->attr_chg_valid |= CHG_MTIME;
95 }
96 } else {
97 ret = clock_gettime(CLOCK_REALTIME, &stp);
98 if (ret < 0) {
99 return -get_errno();
100 }
101 attr->attr_chg_atime = (unsigned int)stp.tv_sec;
102 attr->attr_chg_mtime = (unsigned int)stp.tv_sec;
103 attr->attr_chg_valid |= CHG_ATIME;
104 attr->attr_chg_valid |= CHG_MTIME;
105 }
106
107 return ret;
108}
109///获取全路径
110static int GetFullpathNull(int fd, const char *path, char **filePath)
111{
112 int ret;
113 char *fullPath = NULL;
114 struct file *file = NULL;
115
116 if ((fd != AT_FDCWD) && (path == NULL)) {
117 fd = GetAssociatedSystemFd(fd);
118 ret = fs_getfilep(fd, &file);
119 if (ret < 0) {
120 return -get_errno();
121 }
122 fullPath = strdup(file->f_path);
123 if (fullPath == NULL) {
124 ret = -ENOMEM;
125 }
126 } else {
127 ret = GetFullpath(fd, path, &fullPath);
128 if (ret < 0) {
129 return ret;
130 }
131 }
132
133 *filePath = fullPath;
134 return ret;
135}
136///用户空间 io向量地址范围检查
137static int UserIovItemCheck(const struct iovec *iov, const int iovcnt)
138{
139 int i;
140 for (i = 0; i < iovcnt; ++i) {
141 if (iov[i].iov_len == 0) {
142 continue;
143 }
144
145 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)iov[i].iov_base, iov[i].iov_len)) {
146 return i;
147 }
148 }
149 return iovcnt;
150}
151
152static int UserIovCopy(struct iovec **iovBuf, const struct iovec *iov, const int iovcnt, int *valid_iovcnt)
153{
154 int ret;
155 int bufLen = iovcnt * sizeof(struct iovec);
156 if (bufLen < 0) {
157 return -EINVAL;
158 }
159
160 *iovBuf = (struct iovec*)LOS_MemAlloc(OS_SYS_MEM_ADDR, bufLen);
161 if (*iovBuf == NULL) {
162 return -ENOMEM;
163 }
164
165 if (LOS_ArchCopyFromUser(*iovBuf, iov, bufLen) != 0) {
166 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *iovBuf);
167 return -EFAULT;
168 }
169
170 ret = UserIovItemCheck(*iovBuf, iovcnt);
171 if (ret == 0) {
172 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *iovBuf);
173 return -EFAULT;
174 }
175
176 *valid_iovcnt = ret;
177 return 0;
178}
179
180static int PollfdToSystem(struct pollfd *fds, nfds_t nfds, int **pollFdsBak)
181{
182 if ((nfds != 0 && fds == NULL) || (pollFdsBak == NULL)) {
183 set_errno(EINVAL);
184 return -1;
185 }
186 if (nfds == 0) {
187 return 0;
188 }
189 int *pollFds = (int *)malloc(sizeof(int) * nfds);
190 if (pollFds == NULL) {
191 set_errno(ENOMEM);
192 return -1;
193 }
194 for (int i = 0; i < nfds; ++i) {
195 struct pollfd *p_fds = &fds[i];
196 pollFds[i] = p_fds->fd;
197 if (p_fds->fd < 0) {
198 set_errno(EBADF);
199 free(pollFds);
200 return -1;
201 }
202 p_fds->fd = GetAssociatedSystemFd(p_fds->fd);
203 }
204 *pollFdsBak = pollFds;
205 return 0;
206}
207
208static void RestorePollfd(struct pollfd *fds, nfds_t nfds, const int *pollFds)
209{
210 if ((fds == NULL) || (pollFds == NULL)) {
211 return;
212 }
213 for (int i = 0; i < nfds; ++i) {
214 struct pollfd *p_fds = &fds[i];
215 p_fds->fd = pollFds[i];
216 }
217}
218///使用poll方式 实现IO多路复用的机制
219static int UserPoll(struct pollfd *fds, nfds_t nfds, int timeout)
220{
221 int *pollFds = NULL;
222 int ret = PollfdToSystem(fds, nfds, &pollFds);
223 if (ret < 0) {
224 return -1;
225 }
226
227 ret = poll(fds, nfds, timeout);
228
229 RestorePollfd(fds, nfds, pollFds);
230
231 free(pollFds);
232 return ret;
233}
234
235//关闭文件句柄
236int SysClose(int fd)
237{
238 int ret;
239
240 /* Process fd convert to system global fd */
241 int sysfd = DisassociateProcessFd(fd);//先解除关联
242
243 ret = close(sysfd);//关闭文件,个人认为应该先 close - > DisassociateProcessFd
244 if (ret < 0) {//关闭失败时
245 AssociateSystemFd(fd, sysfd);//继续关联
246 return -get_errno();
247 }
248 FreeProcessFd(fd);//释放进程fd
249 return ret;
250}
251///系统调用|读文件:从文件中读取nbytes长度的内容到buf中(用户空间)
252ssize_t SysRead(int fd, void *buf, size_t nbytes)
253{
254 int ret;
255
256 if (nbytes == 0) {
257 return 0;
258 }
259 //[buf,buf+nbytes]地址必须在用户空间
260 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, nbytes)) {
261 return -EFAULT;
262 }
263
264 /* Process fd convert to system global fd */
265 fd = GetAssociatedSystemFd(fd);//获得关联的系统fd,因为真正的read,write是需要sysFd的
266 ret = read(fd, buf, nbytes);
267 if (ret < 0) {
268 return -get_errno();
269 }
270 return ret;
271}
272///系统调用|写文件:将buf中(用户空间)nbytes长度的内容写到文件中
273ssize_t SysWrite(int fd, const void *buf, size_t nbytes)
274{
275 int ret;
276
277 if (nbytes == 0) {
278 return 0;
279 }
280 //[buf,buf+nbytes]地址必须在用户空间
281 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, nbytes)) {
282 return -EFAULT;
283 }
284
285 /* Process fd convert to system global fd */
286 int sysfd = GetAssociatedSystemFd(fd);
287 ret = write(sysfd, buf, nbytes);
288 if (ret < 0) {
289 return -get_errno();
290 }
291 return ret;
292}
293///系统调用|打开文件, 正常情况下返回进程的FD值
294int SysOpen(const char *path, int oflags, ...)
295{
296 int ret;
297 int procFd;
298 mode_t mode = DEFAULT_FILE_MODE; /* 0666: File read-write properties. */
299 char *pathRet = NULL;
300
301 if (path != NULL) {
302 ret = UserPathCopy(path, &pathRet);
303 if (ret != 0) {
304 return ret;
305 }
306 }
307
308 procFd = AllocProcessFd();//分配进程描述符
309 if (procFd < 0) {
310 ret = -EMFILE;
311 goto ERROUT;
312 }
313
314 if (oflags & O_CLOEXEC) {
315 SetCloexecFlag(procFd);
316 }
317
318 if ((unsigned int)oflags & O_DIRECTORY) {//目录标签
319 ret = do_opendir(pathRet, oflags);//打开目录
320 } else {
321
322#ifdef LOSCFG_FILE_MODE //文件权限开关
323 va_list ap;
324
325 va_start(ap, oflags);
326 mode = va_arg(ap, int);//可变参数读取mode值
327 va_end(ap);
328#endif
329//当fd参数的值是AT_FDCWD,并且path参数是一个相对路径名,fstatat会计算相对于当前目录的path参数。
330//如果path是一个绝对路径,fd参数就会被忽略
331 ret = do_open(AT_FDCWD, pathRet, oflags, mode);//打开文件,返回系统描述符
332 }
333
334 if (ret < 0) {
335 ret = -get_errno();
336 goto ERROUT;
337 }
338
339 AssociateSystemFd(procFd, ret);//进程<->系统描述符 关联/绑定
340 if (pathRet != NULL) {
341 LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
342 }
343 return procFd;//返回进程描述符
344
345ERROUT:
346 if (pathRet != NULL) {
347 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
348 }
349 if (procFd >= 0) {
350 FreeProcessFd(procFd);
351 }
352 return ret;
353}
354
355/*!
356 * @brief 创建文件,从实现看 SysCreat 和 SysOpen 并没有太大的区别,只有打开方式的区别
357 * \n SysCreat函数完全可以被SysOpen函数替代
358 * @param pathname
359 * @param mode
360 * @verbatim 常用标签如下:
361 O_CREAT:若文件存在,此标志无用;若不存在,建新文件
362 O_TRUNC:若文件存在,则长度被截为0,属性不变
363 O_WRONLY:写文件
364 O_RDONLY:读文件
365 O_BINARY:此标志可显示地给出以二进制方式打开文件
366 O_TEXT :此标志可用于显示地给出以文本方式打开文件
367 O_RDWR :即读也写
368 O_APPEND:即读也写,但每次写总是在文件尾添加
369 * @endverbatim
370 * @return int
371 */
372int SysCreat(const char *pathname, mode_t mode)
373{
374 int ret = 0;
375 char *pathRet = NULL;
376
377 if (pathname != NULL) {
378 ret = UserPathCopy(pathname, &pathRet);
379 if (ret != 0) {
380 goto OUT;
381 }
382 }
383
384 int procFd = AllocProcessFd();
385 if (procFd < 0) {
386 ret = -EMFILE;
387 goto OUT;
388 }
389 // 调用关系 open -> do_open chmod 666
390 ret = open((pathname ? pathRet : NULL), O_CREAT | O_TRUNC | O_WRONLY, mode);
391 if (ret < 0) {
392 FreeProcessFd(procFd);
393 ret = -get_errno();
394 } else {
395 AssociateSystemFd(procFd, ret);
396 ret = procFd;
397 }
398
399OUT:
400 if (pathRet != NULL) {
401 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
402 }
403 return ret;
404}
405
406int SysLink(const char *oldpath, const char *newpath)
407{
408 int ret;
409 char *oldpathRet = NULL;
410 char *newpathRet = NULL;
411
412 if (oldpath != NULL) {
413 ret = UserPathCopy(oldpath, &oldpathRet);
414 if (ret != 0) {
415 goto OUT;
416 }
417 }
418
419 if (newpath != NULL) {
420 ret = UserPathCopy(newpath, &newpathRet);
421 if (ret != 0) {
422 goto OUT;
423 }
424 }
425
426 ret = link(oldpathRet, newpathRet);
427 if (ret < 0) {
428 ret = -get_errno();
429 }
430
431OUT:
432 if (oldpathRet != NULL) {
433 (void)LOS_MemFree(OS_SYS_MEM_ADDR, oldpathRet);
434 }
435 if (newpathRet != NULL) {
436 (void)LOS_MemFree(OS_SYS_MEM_ADDR, newpathRet);
437 }
438 return ret;
439}
440
441ssize_t SysReadlink(const char *pathname, char *buf, size_t bufsize)
442{
443 ssize_t ret;
444 char *pathRet = NULL;
445
446 if (bufsize == 0) {
447 return -EINVAL;
448 }
449
450 if (pathname != NULL) {
451 ret = UserPathCopy(pathname, &pathRet);
452 if (ret != 0) {
453 goto OUT;
454 }
455 }
456
457 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) {
458 ret = -EFAULT;
459 goto OUT;
460 }
461
462 ret = readlink(pathRet, buf, bufsize);
463 if (ret < 0) {
464 ret = -get_errno();
465 }
466
467OUT:
468 if (pathRet != NULL) {
469 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
470 }
471 return ret;
472}
473
474int SysSymlink(const char *target, const char *linkpath)
475{
476 int ret;
477 char *targetRet = NULL;
478 char *pathRet = NULL;
479
480 if (target != NULL) {
481 ret = UserPathCopy(target, &targetRet);
482 if (ret != 0) {
483 goto OUT;
484 }
485 }
486
487 if (linkpath != NULL) {
488 ret = UserPathCopy(linkpath, &pathRet);
489 if (ret != 0) {
490 goto OUT;
491 }
492 }
493
494 ret = symlink(targetRet, pathRet);
495 if (ret < 0) {
496 ret = -get_errno();
497 }
498
499OUT:
500 if (pathRet != NULL) {
501 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
502 }
503
504 if (targetRet != NULL) {
505 (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
506 }
507 return ret;
508}
509
510/**
511 * @brief 删除链:删除由装入点管理的文件
512 * @verbatim
513 执行unlink()函数并不一定会真正的删除文件,它先会检查文件系统中此文件的连接数是否为1,
514 如果不是1说明此文件还有其他链接对象,因此只对此文件的连接数进行减1操作。若连接数为1,
515 并且在此时没有任何进程打开该文件,此内容才会真正地被删除掉。在有进程打开此文件的情况下,
516 则暂时不会删除,直到所有打开该文件的进程都结束时文件就会被删除。
517 * @endverbatim
518 */
519int SysUnlink(const char *pathname)
520{
521 int ret;
522 char *pathRet = NULL;
523
524 if (pathname != NULL) {
525 ret = UserPathCopy(pathname, &pathRet);
526 if (ret != 0) {
527 goto OUT;
528 }
529 }
530 //删除由装入点管理的文件
531 ret = do_unlink(AT_FDCWD, (pathname ? pathRet : NULL));
532 if (ret < 0) {
533 ret = -get_errno();
534 }
535
536OUT:
537 if (pathRet != NULL) {
538 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
539 }
540 return ret;
541}
542///动态加载程序过程
543#ifdef LOSCFG_KERNEL_DYNLOAD
544/*
545argv :参数数组 {"ls", "-al", "/etc/passwd", NULL};
546envp :环境变量数组 {"PATH=/bin", NULL}
547*/
548int SysExecve(const char *fileName, char *const *argv, char *const *envp)
549{
550 return LOS_DoExecveFile(fileName, argv, envp);
551}
552#endif
553
554int SysFchdir(int fd)
555{
556 int ret;
557 int sysFd;
558 struct file *file = NULL;
559
560 sysFd = GetAssociatedSystemFd(fd);
561 if (sysFd < 0) {
562 return -EBADF;
563 }
564
565 ret = fs_getfilep(sysFd, &file);
566 if (ret < 0) {
567 return -get_errno();
568 }
569
570 ret = chdir(file->f_path);
571 if (ret < 0) {
572 ret = -get_errno();
573 }
574
575 return ret;
576}
577
578int SysChdir(const char *path)
579{
580 int ret;
581 char *pathRet = NULL;
582
583 if (path != NULL) {
584 ret = UserPathCopy(path, &pathRet);
585 if (ret != 0) {
586 goto OUT;
587 }
588 }
589
590 ret = chdir(path ? pathRet : NULL);
591 if (ret < 0) {
592 ret = -get_errno();
593 }
594
595OUT:
596 if (pathRet != NULL) {
597 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
598 }
599 return ret;
600}
601///移动文件指针
602off_t SysLseek(int fd, off_t offset, int whence)
603{
604 /* Process fd convert to system global fd */
605 fd = GetAssociatedSystemFd(fd);
606
607 return _lseek(fd, offset, whence);
608}
609
610//移动文件指针
611off64_t SysLseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence)
612{
613 off64_t ret;
614 off64_t res;
615 int retVal;
616
617 /* Process fd convert to system global fd */
618 fd = GetAssociatedSystemFd(fd);
619
620 ret = _lseek64(fd, offsetHigh, offsetLow, &res, whence);
621 if (ret != 0) {
622 return ret;
623 }
624
625 retVal = LOS_ArchCopyToUser(result, &res, sizeof(off64_t));
626 if (retVal != 0) {
627 return -EFAULT;
628 }
629
630 return 0;
631}
632
633#ifdef LOSCFG_FS_NFS
634static int NfsMountRef(const char *serverIpAndPath, const char *mountPath,
635 unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount")));
636
637static int NfsMount(const char *serverIpAndPath, const char *mountPath,
638 unsigned int uid, unsigned int gid)
639{
640 int ret;
641
642 if ((serverIpAndPath == NULL) || (mountPath == NULL)) {
643 return -EINVAL;
644 }
645 ret = NfsMountRef(serverIpAndPath, mountPath, uid, gid);
646 if (ret < 0) {
647 ret = -get_errno();
648 }
649 return ret;
650}
651#endif
652
653/*!
654 * @brief SysMount 挂载文件系统
655 * 挂载是指将一个存储设备挂接到一个已存在的路径上。我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的路径上,
656 * 然后通过这个路径来访问存储设备。如果只有一个存储设备,则可以直接挂载到根目录 / 上,变成根文件系统
657 * @param data 特定文件系统的私有数据
658 * @param filesystemtype 挂载的文件系统类型
659 * @param mountflags 读写标志位
660 * @param source 已经格式化的块设备名称
661 * @param target 挂载路径,即挂载点
662 * @return
663 *
664 * @see
665 */
666int SysMount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags,
667 const void *data)
668{
669 int ret;
670 char *sourceRet = NULL;
671 char *targetRet = NULL;
672 char *dataRet = NULL;
673 char fstypeRet[FILESYSTEM_TYPE_MAX + 1] = {0};
674
675 if (!IsCapPermit(CAP_FS_MOUNT)) {
676 return -EPERM;
677 }
678
679 if (target != NULL) {
680 ret = UserPathCopy(target, &targetRet);
681 if (ret != 0) {
682 goto OUT;
683 }
684 }
685
686 if (filesystemtype != NULL) {
687 ret = LOS_StrncpyFromUser(fstypeRet, filesystemtype, FILESYSTEM_TYPE_MAX + 1);
688 if (ret < 0) {
689 goto OUT;
690 } else if (ret > FILESYSTEM_TYPE_MAX) {
691 ret = -ENODEV;
692 goto OUT;
693 }
694
695 if (strcmp(fstypeRet, "ramfs") && (source != NULL)) {
696 ret = UserPathCopy(source, &sourceRet);
697 if (ret != 0) {
698 goto OUT;
699 }
700 }
701#ifdef LOSCFG_FS_NFS
702 if (strcmp(fstypeRet, "nfs") == 0) {
703 ret = NfsMount(sourceRet, targetRet, 0, 0);
704 goto OUT;
705 }
706#endif
707 }
708
709 if (data != NULL) {
710 ret = UserPathCopy(data, &dataRet);
711 if (ret != 0) {
712 goto OUT;
713 }
714 }
715
716 ret = mount(sourceRet, targetRet, (filesystemtype ? fstypeRet : NULL), mountflags, dataRet);
717 if (ret < 0) {
718 ret = -get_errno();
719 }
720
721OUT:
722 if (sourceRet != NULL) {
723 (void)LOS_MemFree(OS_SYS_MEM_ADDR, sourceRet);
724 }
725 if (targetRet != NULL) {
726 (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
727 }
728 if (dataRet != NULL) {
729 (void)LOS_MemFree(OS_SYS_MEM_ADDR, dataRet);
730 }
731 return ret;
732}
733///卸载文件系统,当某个文件系统不需要再使用了,那么可以将它卸载掉。
734int SysUmount(const char *target)
735{
736 int ret;
737 char *pathRet = NULL;
738
739 if (!IsCapPermit(CAP_FS_MOUNT)) {
740 return -EPERM;
741 }
742
743 if (target != NULL) {
744 ret = UserPathCopy(target, &pathRet);
745 if (ret != 0) {
746 goto OUT;
747 }
748 }
749
750 ret = umount(target ? pathRet : NULL);
751 if (ret < 0) {
752 ret = -get_errno();
753 }
754
755OUT:
756 if (pathRet != NULL) {
757 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
758 }
759 return ret;
760}
761///确定文件的可存取性
762int SysAccess(const char *path, int amode)
763{
764 int ret;
765 char *pathRet = NULL;
766
767 if (path != NULL) {
768 ret = UserPathCopy(path, &pathRet);
769 if (ret != 0) {
770 goto OUT;
771 }
772 }
773
774 ret = access(pathRet, amode);
775 if (ret < 0) {
776 ret = -get_errno();
777 }
778
779OUT:
780 if (pathRet != NULL) {
781 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
782 }
783
784 return ret;
785}
786///重命名文件
787int SysRename(const char *oldpath, const char *newpath)
788{
789 int ret;
790 char *pathOldRet = NULL;
791 char *pathNewRet = NULL;
792
793 if (oldpath != NULL) {
794 ret = UserPathCopy(oldpath, &pathOldRet);
795 if (ret != 0) {
796 goto OUT;
797 }
798 }
799
800 if (newpath != NULL) {
801 ret = UserPathCopy(newpath, &pathNewRet);
802 if (ret != 0) {
803 goto OUT;
804 }
805 }
806
807 ret = do_rename(AT_FDCWD, (oldpath ? pathOldRet : NULL), AT_FDCWD,
808 (newpath ? pathNewRet : NULL));
809 if (ret < 0) {
810 ret = -get_errno();
811 }
812
813OUT:
814 if (pathOldRet != NULL) {
815 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet);
816 }
817 if (pathNewRet != NULL) {
818 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet);
819 }
820 return ret;
821}
822///创建目录
823int SysMkdir(const char *pathname, mode_t mode)
824{
825 int ret;
826 char *pathRet = NULL;
827
828 if (pathname != NULL) {
829 ret = UserPathCopy(pathname, &pathRet);
830 if (ret != 0) {
831 goto OUT;
832 }
833 }
834
835 ret = do_mkdir(AT_FDCWD, (pathname ? pathRet : NULL), mode);
836 if (ret < 0) {
837 ret = -get_errno();
838 }
839
840OUT:
841 if (pathRet != NULL) {
842 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
843 }
844 return ret;
845}
846///删除目录
847int SysRmdir(const char *pathname)
848{
849 int ret;
850 char *pathRet = NULL;
851
852 if (pathname != NULL) {
853 ret = UserPathCopy(pathname, &pathRet);
854 if (ret != 0) {
855 goto OUT;
856 }
857 }
858
859 ret = do_rmdir(AT_FDCWD, (pathname ? pathRet : NULL));
860 if (ret < 0) {
861 ret = -get_errno();
862 }
863
864OUT:
865 if (pathRet != NULL) {
866 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
867 }
868 return ret;
869}
870
871int SysDup(int fd)
872{
873 int sysfd = GetAssociatedSystemFd(fd);
874 /* Check if the param is valid, note that: socket fd is not support dup2 */
875 if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) {
876 return -EBADF;
877 }
878
879 int dupfd = AllocProcessFd();
880 if (dupfd < 0) {
881 return -EMFILE;
882 }
883
884 files_refer(sysfd);
885 AssociateSystemFd(dupfd, sysfd);
886 return dupfd;
887}
888///将内存缓冲区数据写回硬盘
889void SysSync(void)
890{
891 sync();
892}
893///卸载文件系统
894int SysUmount2(const char *target, int flags)
895{
896 if (flags != 0) {
897 return -EINVAL;
898 }
899 return SysUmount(target);
900}
901///I/O总控制函数
902int SysIoctl(int fd, int req, void *arg)
903{
904 int ret;
905 unsigned int size = _IOC_SIZE((unsigned int)req);
906 unsigned int dir = _IOC_DIR((unsigned int)req);
907 if ((size == 0) && (dir != _IOC_NONE)) {
908 return -EINVAL;
909 }
910
911 if ((dir != _IOC_NONE) && (((void *)(uintptr_t)arg) == NULL)) {
912 return -EINVAL;
913 }
914
915 if ((dir & _IOC_READ) || (dir & _IOC_WRITE)) {
916 if (!LOS_IsUserAddressRange((uintptr_t)arg, size)) {
917 return -EFAULT;
918 }
919 }
920
921 /* Process fd convert to system global fd */
922 fd = GetAssociatedSystemFd(fd);
923
924 ret = ioctl(fd, req, arg);
925 if (ret < 0) {
926 return -get_errno();
927 }
928 return ret;
929}
930
931/**
932 * @brief
933 * @verbatim
934用来修改已经打开文件的属性的函数包含5个功能:
9351.复制一个已有文件描述符,功能和dup和dup2相同,对应的cmd:F_DUPFD、F_DUPFD_CLOEXEC。
936 当使用这两个cmd时,需要传入第三个参数,fcntl返回复制后的文件描述符,此返回值是之前未被占用的描述符,
937 并且必须一个大于等于第三个参数值。
938 F_DUPFD命令要求返回的文件描述符会清除对应的FD_CLOEXEC
939 F_DUPFD_CLOEXEC要求设置新描述符的FD_CLOEXEC标志。
940
9412.获取、设置文件描述符标志,对应的cmd:F_GETFD、F_SETFD。
942 用于设置FD_CLOEXEC标志,此标志的含义是:当进程执行exec系统调用后此文件描述符会被自动关闭。
943
9443.获取、设置文件访问状态标志,对应的cmd:F_GETFL、F_SETFL。
945 获取当前打开文件的访问标志,设置对应的访问标志,一般常用来设置做非阻塞读写操作。
946
9474.获取、设置记录锁功能,对应的cmd:F_GETLK、F_SETLK、F_SETLKW。
948
9495.获取、设置异步I/O所有权,对应的cmd:F_GETOWN、F_SETOWN。
950 获取和设置用来接收SIGIO/SIGURG信号的进程id或者进程组id。返回对应的进程id或者进程组id取负值。
951 * @endverbatim
952 * @param fd
953 * @param cmd
954 * @param arg
955 * @return int
956 */
957int SysFcntl(int fd, int cmd, void *arg)
958{
959 /* Process fd convert to system global fd */
960 int sysfd = GetAssociatedSystemFd(fd);
961
962 int ret = VfsFcntl(fd, cmd, arg);
963 if (ret == CONTINE_NUTTX_FCNTL) {
964 ret = fcntl(sysfd, cmd, arg);
965 }
966
967 if (ret < 0) {
968 return -get_errno();
969 }
970 return ret;
971}
972
973#ifdef LOSCFG_KERNEL_PIPE
974/**
975 * @brief
976 * @verbatim
977 管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。
978 调用pipe系统函数即可创建一个管道。有如下特质:
979
980 1. 其本质是一个伪文件(实为内核缓冲区)
981 2. 由两个文件描述符引用,一个表示读端,一个表示写端。
982 3. 规定数据从管道的写端流入管道,从读端流出。
983
984 管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。
985 管道的局限性:
986 ① 数据自己读不能自己写。
987 ② 数据一旦被读走,便不在管道中存在,不可反复读取。
988 ③ 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。
989 ④ 只能在有公共祖先的进程间使用管道。
990 常见的通信方式有,单工通信、半双工通信、全双工通信。
991 * @endverbatim
992 * @param pipefd
993 * @return int
994 */
995int SysPipe(int pipefd[2]) /* 2 : pipe fds for read and write */
996{
997 int ret;
998 int pipeFdIntr[2] = {0}; /* 2 : pipe fds for read and write */
999
1000 int procFd0 = AllocProcessFd();//读端管道,像 stdin对应标准输入
1001 if (procFd0 < 0) {
1002 return -EMFILE;
1003 }
1004 int procFd1 = AllocProcessFd();//写端管道,像 stdout对应标准输出
1005 if (procFd1 < 0) {
1006 FreeProcessFd(procFd0);
1007 return -EMFILE;
1008 }
1009
1010 ret = pipe(pipeFdIntr);//创建管道
1011 if (ret < 0) {
1012 FreeProcessFd(procFd0);
1013 FreeProcessFd(procFd1);
1014 return -get_errno();
1015 }
1016 int sysPipeFd0 = pipeFdIntr[0];
1017 int sysPipeFd1 = pipeFdIntr[1];
1018
1019 AssociateSystemFd(procFd0, sysPipeFd0);//进程FD和系统FD绑定
1020 AssociateSystemFd(procFd1, sysPipeFd1);
1021
1022 pipeFdIntr[0] = procFd0;
1023 pipeFdIntr[1] = procFd1;
1024
1025 ret = LOS_ArchCopyToUser(pipefd, pipeFdIntr, sizeof(pipeFdIntr));//参数都走两个进程FD
1026 if (ret != 0) {
1027 FreeProcessFd(procFd0);
1028 FreeProcessFd(procFd1);
1029 close(sysPipeFd0);
1030 close(sysPipeFd1);
1031 return -EFAULT;
1032 }
1033 return ret;
1034}
1035#endif
1036
1037/// 复制文件描述符
1038int SysDup2(int fd1, int fd2)
1039{
1040 int ret;
1041 int sysfd1 = GetAssociatedSystemFd(fd1);
1042 int sysfd2 = GetAssociatedSystemFd(fd2);
1043 //检查参数是否有效,注意:socket fd不支持dup2
1044 /* Check if the param is valid, note that: socket fd is not support dup2 */
1045 if ((sysfd1 < 0) || (sysfd1 >= CONFIG_NFILE_DESCRIPTORS) || (CheckProcessFd(fd2) != OK)) {//socket的fd必大于CONFIG_NFILE_DESCRIPTORS
1046 return -EBADF;
1047 }
1048
1049 /* Handle special circumstances */
1050 if (fd1 == fd2) {
1051 return fd2;
1052 }
1053
1054 ret = AllocSpecifiedProcessFd(fd2);
1055 if (ret != OK) {
1056 return ret;
1057 }
1058
1059 /* close the sysfd2 in need */
1060 if (sysfd2 >= 0) {
1061 ret = close(sysfd2);
1062 if (ret < 0) {
1063 AssociateSystemFd(fd2, sysfd2);
1064 return -get_errno();
1065 }
1066 }
1067
1068 files_refer(sysfd1);
1069 AssociateSystemFd(fd2, sysfd1);
1070
1071 /* if fd1 is not equal to fd2, the FD_CLOEXEC flag associated with fd2 shall be cleared */
1072 ClearCloexecFlag(fd2);
1073 return fd2;
1074}
1075///select()参数检查
1076static int SelectParamCheckCopy(fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fd_set **fdsBuf)
1077{
1078 fd_set *readfdsRet = NULL;
1079 fd_set *writefdsRet = NULL;
1080 fd_set *exceptfdsRet = NULL;
1081
1082 *fdsBuf = (fd_set *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(fd_set) * 3); /* 3: three param need check and copy */
1083 if (*fdsBuf == NULL) {
1084 return -ENOMEM;
1085 }
1086
1087 readfdsRet = *fdsBuf; /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */
1088 writefdsRet = *fdsBuf + 1; /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */
1089 exceptfdsRet = *fdsBuf + 2; /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */
1090
1091 if (readfds != NULL) {
1092 if (LOS_ArchCopyFromUser(readfdsRet, readfds, sizeof(fd_set)) != 0) {
1093 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1094 return -EFAULT;
1095 }
1096 }
1097
1098 if (writefds != NULL) {
1099 if (LOS_ArchCopyFromUser(writefdsRet, writefds, sizeof(fd_set)) != 0) {
1100 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1101 return -EFAULT;
1102 }
1103 }
1104
1105 if (exceptfds != NULL) {
1106 if (LOS_ArchCopyFromUser(exceptfdsRet, exceptfds, sizeof(fd_set)) != 0) {
1107 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1108 return -EFAULT;
1109 }
1110 }
1111
1112 return 0;
1113}
1114
1115/*!
1116 * @brief SysSelect 系统调用|文件系统|select .鸿蒙liteos目前也支持epoll方式
1117 *
1118 * @param exceptfds 文件集将监视文件集中的任何文件是否发生错误,可用于其他的用途,
1119 * 例如,监视带外数据OOB,带外数据使用MSG_OOB标志发送到套接字上。当select函数返回的时候,
1120 * exceptfds将清除其中的其他文件描述符,只留下标记有OOB数据的文件描述符。
1121 * @param nfds select监视的文件句柄数,一般设为要监视各文件中的最大文件描述符值加1。
1122 * @param readfds 文件描述符集合监视文件集中的任何文件是否有数据可读,当select函数返回的时候,
1123 * readfds将清除其中不可读的文件描述符,只留下可读的文件描述符。
1124 * @param timeout 参数是一个指向 struct timeval 类型的指针,它可以使 select()在等待 timeout 时间后
1125 * 若没有文件描述符准备好则返回。其timeval结构用于指定这段时间的秒数和微秒数。它可以使select处于三种状态:
1126 * (1) 若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;
1127 * (2) 若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;
1128 * (3) timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。
1129 * @param writefds 文件描述符集合监视文件集中的任何文件是否有数据可写,当select函数返回的时候,
1130 * writefds将清除其中不可写的文件描述符,只留下可写的文件描述符。
1131 * @return
1132 *
1133 * @see
1134 */
1135int SysSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
1136{
1137 int ret;
1138 fd_set *fdsRet = NULL;
1139 fd_set *readfdsRet = NULL;
1140 fd_set *writefdsRet = NULL;
1141 fd_set *exceptfdsRet = NULL;
1142 struct timeval timeoutRet = {0};
1143
1144 ret = SelectParamCheckCopy(readfds, writefds, exceptfds, &fdsRet);//检查参数
1145 if (ret != 0) {
1146 return ret;
1147 }
1148
1149 readfdsRet = fdsRet; /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */
1150 writefdsRet = fdsRet + 1; /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */
1151 exceptfdsRet = fdsRet + 2; /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */
1152
1153 if (timeout != NULL) {
1154 if (LOS_ArchCopyFromUser(&timeoutRet, timeout, sizeof(struct timeval)) != 0) {
1155 goto ERROUT;
1156 }
1157 }
1158 //poll()是在NuttX下执行此类监视操作的基本API
1159 ret = do_select(nfds, (readfds ? readfdsRet : NULL), (writefds ? writefdsRet : NULL),
1160 (exceptfds ? exceptfdsRet : NULL), (timeout ? (&timeoutRet) : NULL), UserPoll);
1161 if (ret < 0) {
1162 (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1163 return -get_errno();
1164 }
1165
1166 if (readfds != NULL) {
1167 if (LOS_ArchCopyToUser(readfds, readfdsRet, sizeof(fd_set)) != 0) {
1168 goto ERROUT;
1169 }
1170 }
1171
1172 if (writefds != NULL) {
1173 if (LOS_ArchCopyToUser(writefds, writefdsRet, sizeof(fd_set)) != 0) {
1174 goto ERROUT;
1175 }
1176 }
1177
1178 if (exceptfds != 0) {
1179 if (LOS_ArchCopyToUser(exceptfds, exceptfdsRet, sizeof(fd_set)) != 0) {
1180 goto ERROUT;
1181 }
1182 }
1183
1184 (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1185 return ret;
1186
1187ERROUT:
1188 (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1189 return -EFAULT;
1190}
1191///系统调用|文件系统|截断功能
1192int SysTruncate(const char *path, off_t length)
1193{
1194 int ret;
1195 int fd = -1;
1196 char *pathRet = NULL;
1197
1198 if (path != NULL) {
1199 ret = UserPathCopy(path, &pathRet);
1200 if (ret != 0) {
1201 goto OUT;
1202 }
1203 }
1204
1205 fd = open((path ? pathRet : NULL), O_RDWR);
1206 if (fd < 0) {
1207 /* The errno value has already been set */
1208 ret = -get_errno();
1209 goto OUT;
1210 }
1211
1212 ret = ftruncate(fd, length);
1213 close(fd);
1214 if (ret < 0) {
1215 ret = -get_errno();
1216 }
1217
1218OUT:
1219 if (pathRet != NULL) {
1220 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1221 }
1222 return ret;
1223}
1224///系统调用|文件系统|截断功能
1225int SysTruncate64(const char *path, off64_t length)
1226{
1227 int ret;
1228 int fd = -1;
1229 char *pathRet = NULL;
1230
1231 if (path != NULL) {
1232 ret = UserPathCopy(path, &pathRet);
1233 if (ret != 0) {
1234 goto OUT;
1235 }
1236 }
1237
1238 fd = open((path ? pathRet : NULL), O_RDWR);
1239 if (fd < 0) {
1240 /* The errno value has already been set */
1241 ret = -get_errno();
1242 goto OUT;
1243 }
1244
1245 ret = ftruncate64(fd, length);
1246 close(fd);
1247 if (ret < 0) {
1248 ret = -get_errno();
1249 }
1250
1251OUT:
1252 if (pathRet != NULL) {
1253 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1254 }
1255 return ret;
1256}
1257///系统调用|文件系统|截断功能
1258int SysFtruncate(int fd, off_t length)
1259{
1260 int ret;
1261
1262 /* Process fd convert to system global fd */
1263 fd = GetAssociatedSystemFd(fd);
1264
1265 ret = ftruncate(fd, length);
1266 if (ret < 0) {
1267 return -get_errno();
1268 }
1269 return ret;
1270}
1271///获取指定路径下文件的文件系统信息
1272int SysStatfs(const char *path, struct statfs *buf)
1273{
1274 int ret;
1275 char *pathRet = NULL;
1276 struct statfs bufRet = {0};
1277
1278 if (path != NULL) {
1279 ret = UserPathCopy(path, &pathRet);
1280 if (ret != 0) {
1281 goto OUT;
1282 }
1283 }
1284
1285 ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1286 if (ret < 0) {
1287 ret = -get_errno();
1288 goto OUT;
1289 }
1290
1291 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
1292 if (ret != 0) {
1293 ret = -EFAULT;
1294 }
1295
1296OUT:
1297 if (pathRet != NULL) {
1298 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1299 }
1300 return ret;
1301}
1302///获取文件系统信息
1303int SysStatfs64(const char *path, size_t sz, struct statfs *buf)
1304{
1305 int ret;
1306 char *pathRet = NULL;
1307 struct statfs bufRet = {0};
1308
1309 if (path != NULL) {
1310 ret = UserPathCopy(path, &pathRet);
1311 if (ret != 0) {
1312 goto OUT;
1313 }
1314 }
1315
1316 if (sz != sizeof(*buf)) {
1317 ret = -EINVAL;
1318 goto OUT;
1319 }
1320
1321 ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1322 if (ret < 0) {
1323 ret = -get_errno();
1324 goto OUT;
1325 }
1326
1327 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
1328 if (ret != 0) {
1329 ret = -EFAULT;
1330 }
1331
1332OUT:
1333 if (pathRet != NULL) {
1334 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1335 }
1336 return ret;
1337}
1338///获取文件状态信息
1339int SysStat(const char *path, struct kstat *buf)
1340{
1341 int ret;
1342 char *pathRet = NULL;
1343 struct stat bufRet = {0};
1344
1345 if (path != NULL) {
1346 ret = UserPathCopy(path, &pathRet);
1347 if (ret != 0) {
1348 goto OUT;
1349 }
1350 }
1351
1352 ret = stat((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1353 if (ret < 0) {
1354 ret = -get_errno();
1355 goto OUT;
1356 }
1357
1358 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
1359 if (ret != 0) {
1360 ret = -EFAULT;
1361 }
1362
1363OUT:
1364 if (pathRet != NULL) {
1365 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1366 }
1367 return ret;
1368}
1369///参见SysStat
1370int SysLstat(const char *path, struct kstat *buffer)
1371{
1372 int ret;
1373 char *pathRet = NULL;
1374 struct stat bufRet = {0};
1375
1376 if (path != NULL) {
1377 ret = UserPathCopy(path, &pathRet);
1378 if (ret != 0) {
1379 goto OUT;
1380 }
1381 }
1382
1383 ret = stat((path ? pathRet : NULL), (buffer ? (&bufRet) : NULL));
1384 if (ret < 0) {
1385 ret = -get_errno();
1386 goto OUT;
1387 }
1388
1389 ret = LOS_ArchCopyToUser(buffer, &bufRet, sizeof(struct kstat));
1390 if (ret != 0) {
1391 ret = -EFAULT;
1392 }
1393
1394OUT:
1395 if (pathRet != NULL) {
1396 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1397 }
1398 return ret;
1399}
1400///参见SysStat
1401int SysFstat(int fd, struct kstat *buf)
1402{
1403 int ret;
1404 struct stat bufRet = {0};
1405 struct file *filep = NULL;
1406
1407 /* Process fd convert to system global fd */
1408 fd = GetAssociatedSystemFd(fd);
1409
1410 ret = fs_getfilep(fd, &filep);
1411 if (ret < 0) {
1412 return -get_errno();
1413 }
1414
1415 if (filep->f_oflags & O_DIRECTORY) {
1416 return -EBADF;
1417 }
1418
1419 ret = stat(filep->f_path, (buf ? (&bufRet) : NULL));
1420 if (ret < 0) {
1421 return -get_errno();
1422 }
1423
1424 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
1425 if (ret != 0) {
1426 return -EFAULT;
1427 }
1428
1429 return ret;
1430}
1431
1432int SysStatx(int fd, const char *restrict path, int flag, unsigned mask, struct statx *restrict stx)
1433{
1434 return -ENOSYS;
1435}
1436///把文件在内存中的部分写回磁盘
1437int SysFsync(int fd)
1438{
1439 int ret;
1440 struct file *filep = NULL;
1441
1442 /* Process fd convert to system global fd */
1443 fd = GetAssociatedSystemFd(fd);
1444
1445 /* Get the file structure corresponding to the file descriptor. */
1446 ret = fs_getfilep(fd, &filep);
1447 if (ret < 0) {
1448 /* The errno value has already been set */
1449 return -get_errno();
1450 }
1451
1452 if (filep->f_oflags & O_DIRECTORY) {
1453 return -EBADF;
1454 }
1455
1456 /* Perform the fsync operation */
1457 ret = file_fsync(filep);
1458 if (ret < 0) {
1459 return -get_errno();
1460 }
1461 return ret;
1462}
1463///通过FD读入数据到缓冲数组中,fd为进程描述符
1464ssize_t SysReadv(int fd, const struct iovec *iov, int iovcnt)
1465{
1466 int ret;
1467 int valid_iovcnt = -1;
1468 struct iovec *iovRet = NULL;
1469
1470 /* Process fd convert to system global fd */
1471 fd = GetAssociatedSystemFd(fd);//进程FD转成系统FD
1472 if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
1473 return -EINVAL;
1474 }
1475
1476 if (iovcnt == 0) {
1477 return 0;
1478 }
1479
1480 ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
1481 if (ret != 0) {
1482 return ret;
1483 }
1484
1485 if (valid_iovcnt <= 0) {
1486 ret = -EFAULT;
1487 goto OUT;
1488 }
1489
1490 ret = vfs_readv(fd, iovRet, valid_iovcnt, NULL);
1491 if (ret < 0) {
1492 ret = -get_errno();
1493 }
1494
1495OUT:
1496 (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
1497 return ret;
1498}
1499///将缓冲数组里的数据写入文件
1500ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt)
1501{
1502 int ret;
1503 int valid_iovcnt = -1;
1504 struct iovec *iovRet = NULL;
1505
1506 /* Process fd convert to system global fd */
1507 int sysfd = GetAssociatedSystemFd(fd);
1508 if ((iovcnt < 0) || (iovcnt > IOV_MAX)) {
1509 return -EINVAL;
1510 }
1511
1512 if (iovcnt == 0) {
1513 return 0;
1514 }
1515
1516 if (iov == NULL) {
1517 return -EFAULT;
1518 }
1519
1520 ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
1521 if (ret != 0) {
1522 return ret;
1523 }
1524
1525 if (valid_iovcnt != iovcnt) {
1526 ret = -EFAULT;
1527 goto OUT_FREE;
1528 }
1529
1530 ret = writev(sysfd, iovRet, valid_iovcnt);
1531 if (ret < 0) {
1532 ret = -get_errno();
1533 }
1534
1535OUT_FREE:
1536 (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
1537 return ret;
1538}
1539
1540/*!
1541 * @brief SysPoll I/O多路转换
1542 *
1543 * @param fds fds是一个struct pollfd类型的数组,用于存放需要检测其状态的socket描述符,并且调用poll函数之后fds数组不会被清空;
1544 * 一个pollfd结构体表示一个被监视的文件描述符,通过传递fds指示 poll() 监视多个文件描述符。
1545 * @param nfds 记录数组fds中描述符的总数量。
1546 * @param timeout 指定等待的毫秒数,无论 I/O 是否准备好,poll() 都会返回,和select函数是类似的。
1547 * @return 函数返回fds集合中就绪的读、写,或出错的描述符数量,返回0表示超时,返回-1表示出错;
1548 * poll改变了文件描述符集合的描述方式,使用了pollfd结构而不是select的fd_set结构,使得poll支持的文件描述符集合限制远大于select的1024。
1549 * 这也是和select不同的地方。
1550 * @see
1551 */
1552int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout)
1553{
1554 int ret;
1555 struct pollfd *kfds = NULL;
1556
1557 if ((nfds >= MAX_POLL_NFDS) || (nfds == 0) || (fds == NULL)) {
1558 return -EINVAL;
1559 }
1560
1561 kfds = (struct pollfd *)malloc(sizeof(struct pollfd) * nfds);
1562 if (kfds != NULL) {
1563 if (LOS_ArchCopyFromUser(kfds, fds, sizeof(struct pollfd) * nfds) != 0) {
1564 ret = -EFAULT;
1565 goto OUT_KFD;
1566 }
1567 }
1568
1569 int *pollFds = NULL;
1570 ret = PollfdToSystem(kfds, nfds, &pollFds);
1571 if (ret < 0) {
1572 ret = -get_errno();
1573 goto OUT_KFD;
1574 }
1575
1576 ret = poll(kfds, nfds, timeout);
1577 if (ret < 0) {
1578 ret = -get_errno();
1579 goto OUT;
1580 }
1581
1582 if (kfds != NULL) {
1583 RestorePollfd(kfds, nfds, pollFds);
1584 if (LOS_ArchCopyToUser(fds, kfds, sizeof(struct pollfd) * nfds) != 0) {
1585 ret = -EFAULT;
1586 goto OUT;
1587 }
1588 }
1589
1590OUT:
1591 free(pollFds);
1592OUT_KFD:
1593 free(kfds);
1594 return ret;
1595}
1596///对进程进行特定操作
1597int SysPrctl(int option, ...)
1598{
1599 unsigned long name;
1600 va_list ap;
1601 errno_t err;
1602
1603 va_start(ap, option);
1604 if (option != PR_SET_NAME) {
1605 PRINT_ERR("%s: %d, no support option : 0x%x\n", __FUNCTION__, __LINE__, option);
1606 err = EOPNOTSUPP;
1607 goto ERROR;
1608 }
1609
1610 name = va_arg(ap, unsigned long);
1611 if (!LOS_IsUserAddress(name)) {
1612 err = EFAULT;
1613 goto ERROR;
1614 }
1615
1616 err = OsSetTaskName(OsCurrTaskGet(), (const char *)(uintptr_t)name, TRUE);
1617 if (err != LOS_OK) {
1618 goto ERROR;
1619 }
1620
1621 va_end(ap);
1622 return ENOERR;
1623
1624ERROR:
1625 va_end(ap);
1626 return -err;
1627}
1628///对进程进行特定操作
1629ssize_t SysPread64(int fd, void *buf, size_t nbytes, off64_t offset)
1630{
1631 int ret, retVal;
1632 char *bufRet = NULL;
1633
1634 /* Process fd convert to system global fd */
1635 fd = GetAssociatedSystemFd(fd);
1636
1637 if (nbytes == 0) {
1638 ret = pread64(fd, buf, nbytes, offset);
1639 if (ret < 0) {
1640 return -get_errno();
1641 } else {
1642 return ret;
1643 }
1644 }
1645
1646 bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nbytes);
1647 if (bufRet == NULL) {
1648 return -ENOMEM;
1649 }
1650
1651 ret = pread64(fd, (buf ? bufRet : NULL), nbytes, offset);
1652 if (ret < 0) {
1653 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1654 return -get_errno();
1655 }
1656
1657 retVal = LOS_ArchCopyToUser(buf, bufRet, ret);
1658 if (retVal != 0) {
1659 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1660 return -EFAULT;
1661 }
1662
1663 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1664 return ret;
1665}
1666
1667ssize_t SysPwrite64(int fd, const void *buf, size_t nbytes, off64_t offset)
1668{
1669 int ret;
1670 char *bufRet = NULL;
1671
1672 /* Process fd convert to system global fd */
1673 fd = GetAssociatedSystemFd(fd);
1674
1675 if (nbytes == 0) {
1676 ret = pwrite64(fd, buf, nbytes, offset);
1677 if (ret < 0) {
1678 return -get_errno();
1679 }
1680 return ret;
1681 }
1682
1683 bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nbytes);
1684 if (bufRet == NULL) {
1685 return -ENOMEM;
1686 }
1687
1688 if (buf != NULL) {
1689 ret = LOS_ArchCopyFromUser(bufRet, buf, nbytes);
1690 if (ret != 0) {
1691 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1692 return -EFAULT;
1693 }
1694 }
1695
1696 ret = pwrite64(fd, (buf ? bufRet : NULL), nbytes, offset);
1697 if (ret < 0) {
1698 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1699 return -get_errno();
1700 }
1701
1702 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1703 return ret;
1704}
1705
1706char *SysGetcwd(char *buf, size_t n)
1707{
1708 char *ret = NULL;
1709 char *bufRet = NULL;
1710 size_t bufLen = n;
1711 int retVal;
1712
1713 if (bufLen > PATH_MAX) {
1714 bufLen = PATH_MAX;
1715 }
1716
1717 bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, bufLen);
1718 if (bufRet == NULL) {
1719 return (char *)(intptr_t)-ENOMEM;
1720 }
1721 (void)memset_s(bufRet, bufLen, 0, bufLen);
1722
1723 ret = getcwd((buf ? bufRet : NULL), bufLen);
1724 if (ret == NULL) {
1725 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1726 return (char *)(intptr_t)-get_errno();
1727 }
1728
1729 retVal = LOS_ArchCopyToUser(buf, bufRet, bufLen);
1730 if (retVal != 0) {
1731 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1732 return (char *)(intptr_t)-EFAULT;
1733 }
1734 ret = buf;
1735
1736 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1737 return ret;
1738}
1739
1740ssize_t SysSendFile(int outfd, int infd, off_t *offset, size_t count)
1741{
1742 int ret, retVal;
1743 off_t offsetRet;
1744
1745 retVal = LOS_ArchCopyFromUser(&offsetRet, offset, sizeof(off_t));
1746 if (retVal != 0) {
1747 return -EFAULT;
1748 }
1749
1750 /* Process fd convert to system global fd */
1751 outfd = GetAssociatedSystemFd(outfd);
1752 infd = GetAssociatedSystemFd(infd);
1753
1754 ret = sendfile(outfd, infd, (offset ? (&offsetRet) : NULL), count);
1755 if (ret < 0) {
1756 return -get_errno();
1757 }
1758
1759 retVal = LOS_ArchCopyToUser(offset, &offsetRet, sizeof(off_t));
1760 if (retVal != 0) {
1761 return -EFAULT;
1762 }
1763
1764 return ret;
1765}
1766
1767int SysFtruncate64(int fd, off64_t length)
1768{
1769 int ret;
1770
1771 /* Process fd convert to system global fd */
1772 fd = GetAssociatedSystemFd(fd);
1773
1774 ret = ftruncate64(fd, length);
1775 if (ret < 0) {
1776 return -get_errno();
1777 }
1778 return ret;
1779}
1780
1781int SysOpenat(int dirfd, const char *path, int oflags, ...)
1782{
1783 int ret;
1784 int procFd;
1785 char *pathRet = NULL;
1786 mode_t mode;
1787#ifdef LOSCFG_FILE_MODE
1788 va_list ap;
1789
1790 va_start(ap, oflags);
1791 mode = va_arg(ap, int);
1792 va_end(ap);
1793#else
1794 mode = 0666; /* 0666: File read-write properties. */
1795#endif
1796
1797 if (path != NULL) {
1798 ret = UserPathCopy(path, &pathRet);
1799 if (ret != 0) {
1800 return ret;
1801 }
1802 }
1803
1804 procFd = AllocProcessFd();
1805 if (procFd < 0) {
1806 ret = -EMFILE;
1807 goto ERROUT;
1808 }
1809
1810 if (oflags & O_CLOEXEC) {
1811 SetCloexecFlag(procFd);
1812 }
1813
1814 if (dirfd != AT_FDCWD) {
1815 /* Process fd convert to system global fd */
1816 dirfd = GetAssociatedSystemFd(dirfd);
1817 }
1818
1819 ret = do_open(dirfd, (path ? pathRet : NULL), oflags, mode);
1820 if (ret < 0) {
1821 ret = -get_errno();
1822 goto ERROUT;
1823 }
1824
1825 AssociateSystemFd(procFd, ret);
1826 if (pathRet != NULL) {
1827 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1828 }
1829 return procFd;
1830
1831ERROUT:
1832 if (pathRet != NULL) {
1833 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1834 }
1835 if (procFd >= 0) {
1836 FreeProcessFd(procFd);
1837 }
1838 return ret;
1839}
1840
1841int SysMkdirat(int dirfd, const char *pathname, mode_t mode)
1842{
1843 int ret;
1844 char *pathRet = NULL;
1845
1846 if (pathname != NULL) {
1847 ret = UserPathCopy(pathname, &pathRet);
1848 if (ret != 0) {
1849 goto OUT;
1850 }
1851 }
1852
1853 if (dirfd != AT_FDCWD) {
1854 /* Process fd convert to system global fd */
1855 dirfd = GetAssociatedSystemFd(dirfd);
1856 }
1857
1858 ret = do_mkdir(dirfd, (pathname ? pathRet : NULL), mode);
1859 if (ret < 0) {
1860 ret = -get_errno();
1861 }
1862
1863OUT:
1864 if (pathRet != NULL) {
1865 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1866 }
1867 return ret;
1868}
1869
1870int SysLinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags)
1871{
1872 int ret;
1873 char *oldpathRet = NULL;
1874 char *newpathRet = NULL;
1875
1876 if (oldpath != NULL) {
1877 ret = UserPathCopy(oldpath, &oldpathRet);
1878 if (ret != 0) {
1879 goto OUT;
1880 }
1881 }
1882
1883 if (newpath != NULL) {
1884 ret = UserPathCopy(newpath, &newpathRet);
1885 if (ret != 0) {
1886 goto OUT;
1887 }
1888 }
1889
1890 if (olddirfd != AT_FDCWD) {
1891 /* Process fd convert to system global fd */
1892 olddirfd = GetAssociatedSystemFd(olddirfd);
1893 }
1894
1895 if (newdirfd != AT_FDCWD) {
1896 /* Process fd convert to system global fd */
1897 newdirfd = GetAssociatedSystemFd(newdirfd);
1898 }
1899
1900 ret = linkat(olddirfd, oldpathRet, newdirfd, newpathRet, flags);
1901 if (ret < 0) {
1902 ret = -get_errno();
1903 }
1904
1905OUT:
1906 if (oldpathRet != NULL) {
1907 (void)LOS_MemFree(OS_SYS_MEM_ADDR, oldpathRet);
1908 }
1909 if (newpathRet != NULL) {
1910 (void)LOS_MemFree(OS_SYS_MEM_ADDR, newpathRet);
1911 }
1912 return ret;
1913}
1914
1915int SysSymlinkat(const char *target, int dirfd, const char *linkpath)
1916{
1917 int ret;
1918 char *pathRet = NULL;
1919 char *targetRet = NULL;
1920
1921 if (target != NULL) {
1922 ret = UserPathCopy(target, &targetRet);
1923 if (ret != 0) {
1924 goto OUT;
1925 }
1926 }
1927
1928 if (linkpath != NULL) {
1929 ret = UserPathCopy(linkpath, &pathRet);
1930 if (ret != 0) {
1931 goto OUT;
1932 }
1933 }
1934
1935 if (dirfd != AT_FDCWD) {
1936 /* Process fd convert to system global fd */
1937 dirfd = GetAssociatedSystemFd(dirfd);
1938 }
1939
1940 ret = symlinkat(targetRet, dirfd, pathRet);
1941 if (ret < 0) {
1942 ret = -get_errno();
1943 }
1944
1945OUT:
1946 if (pathRet != NULL) {
1947 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1948 }
1949
1950 if (targetRet != NULL) {
1951 (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
1952 }
1953 return ret;
1954}
1955
1956ssize_t SysReadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize)
1957{
1958 ssize_t ret;
1959 char *pathRet = NULL;
1960
1961 if (bufsize == 0) {
1962 return -EINVAL;
1963 }
1964
1965 if (pathname != NULL) {
1966 ret = UserPathCopy(pathname, &pathRet);
1967 if (ret != 0) {
1968 goto OUT;
1969 }
1970 }
1971
1972 if (dirfd != AT_FDCWD) {
1973 /* Process fd convert to system global fd */
1974 dirfd = GetAssociatedSystemFd(dirfd);
1975 }
1976
1977 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) {
1978 ret = -EFAULT;
1979 goto OUT;
1980 }
1981
1982 ret = readlinkat(dirfd, pathRet, buf, bufsize);
1983 if (ret < 0) {
1984 ret = -get_errno();
1985 }
1986
1987OUT:
1988 if (pathRet != NULL) {
1989 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1990 }
1991 return ret;
1992}
1993
1994int SysUnlinkat(int dirfd, const char *pathname, int flag)
1995{
1996 int ret;
1997 char *pathRet = NULL;
1998
1999 if (pathname != NULL) {
2000 ret = UserPathCopy(pathname, &pathRet);
2001 if (ret != 0) {
2002 goto OUT;
2003 }
2004 }
2005
2006 if (dirfd != AT_FDCWD) {
2007 /* Process fd convert to system global fd */
2008 dirfd = GetAssociatedSystemFd(dirfd);
2009 }
2010
2011 ret = unlinkat(dirfd, (pathname ? pathRet : NULL), flag);
2012 if (ret < 0) {
2013 ret = -get_errno();
2014 }
2015
2016OUT:
2017 if (pathRet != NULL) {
2018 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2019 }
2020 return ret;
2021}
2022
2023int SysRenameat(int oldfd, const char *oldpath, int newdfd, const char *newpath)
2024{
2025 int ret;
2026 char *pathOldRet = NULL;
2027 char *pathNewRet = NULL;
2028
2029 if (oldpath != NULL) {
2030 ret = UserPathCopy(oldpath, &pathOldRet);
2031 if (ret != 0) {
2032 goto OUT;
2033 }
2034 }
2035
2036 if (newpath != NULL) {
2037 ret = UserPathCopy(newpath, &pathNewRet);
2038 if (ret != 0) {
2039 goto OUT;
2040 }
2041 }
2042
2043 if (oldfd != AT_FDCWD) {
2044 /* Process fd convert to system global fd */
2045 oldfd = GetAssociatedSystemFd(oldfd);
2046 }
2047 if (newdfd != AT_FDCWD) {
2048 /* Process fd convert to system global fd */
2049 newdfd = GetAssociatedSystemFd(newdfd);
2050 }
2051
2052 ret = do_rename(oldfd, (oldpath ? pathOldRet : NULL), newdfd, (newpath ? pathNewRet : NULL));
2053 if (ret < 0) {
2054 ret = -get_errno();
2055 }
2056
2057OUT:
2058 if (pathOldRet != NULL) {
2059 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet);
2060 }
2061 if (pathNewRet != NULL) {
2062 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet);
2063 }
2064 return ret;
2065}
2066
2067int SysFallocate(int fd, int mode, off_t offset, off_t len)
2068{
2069 int ret;
2070
2071 /* Process fd convert to system global fd */
2072 fd = GetAssociatedSystemFd(fd);
2073
2074 ret = fallocate(fd, mode, offset, len);
2075 if (ret < 0) {
2076 return -get_errno();
2077 }
2078 return ret;
2079}
2080
2081int SysFallocate64(int fd, int mode, off64_t offset, off64_t len)
2082{
2083 int ret;
2084
2085 /* Process fd convert to system global fd */
2086 fd = GetAssociatedSystemFd(fd);
2087
2088 ret = fallocate64(fd, mode, offset, len);
2089 if (ret < 0) {
2090 return -get_errno();
2091 }
2092 return ret;
2093}
2094
2095ssize_t SysPreadv(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
2096{
2097 off_t offsetflag;
2098 offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT));
2099
2100 int ret;
2101 int valid_iovcnt = -1;
2102 struct iovec *iovRet = NULL;
2103
2104 /* Process fd convert to system global fd */
2105 fd = GetAssociatedSystemFd(fd);
2106 if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
2107 return -EINVAL;
2108 }
2109
2110 if (iovcnt == 0) {
2111 return 0;
2112 }
2113
2114 ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
2115 if (ret != 0) {
2116 return ret;
2117 }
2118
2119 if (valid_iovcnt <= 0) {
2120 ret = -EFAULT;
2121 goto OUT_FREE;
2122 }
2123
2124 ret = preadv(fd, iovRet, valid_iovcnt, offsetflag);
2125 if (ret < 0) {
2126 ret = -get_errno();
2127 }
2128
2129OUT_FREE:
2130 (void)(void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
2131 return ret;
2132}
2133
2134ssize_t SysPwritev(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
2135{
2136 off_t offsetflag;
2137 offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT));
2138 int ret;
2139 int valid_iovcnt = -1;
2140 struct iovec *iovRet = NULL;
2141
2142 /* Process fd convert to system global fd */
2143 fd = GetAssociatedSystemFd(fd);
2144 if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
2145 return -EINVAL;
2146 }
2147
2148 if (iovcnt == 0) {
2149 return 0;
2150 }
2151
2152 ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
2153 if (ret != 0) {
2154 return ret;
2155 }
2156
2157 if (valid_iovcnt != iovcnt) {
2158 ret = -EFAULT;
2159 goto OUT_FREE;
2160 }
2161
2162 ret = pwritev(fd, iovRet, valid_iovcnt, offsetflag);
2163 if (ret < 0) {
2164 ret = -get_errno();
2165 }
2166
2167OUT_FREE:
2168 (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
2169 return ret;
2170}
2171
2172#ifdef LOSCFG_FS_FAT
2173int SysFormat(const char *dev, int sectors, int option)
2174{
2175 int ret;
2176 char *devRet = NULL;
2177
2178 if (!IsCapPermit(CAP_FS_FORMAT)) {
2179 return -EPERM;
2180 }
2181
2182 if (dev != NULL) {
2183 ret = UserPathCopy(dev, &devRet);
2184 if (ret != 0) {
2185 goto OUT;
2186 }
2187 }
2188
2189 ret = format((dev ? devRet : NULL), sectors, option);
2190 if (ret < 0) {
2191 ret = -get_errno();
2192 }
2193
2194OUT:
2195 if (devRet != NULL) {
2196 (void)LOS_MemFree(OS_SYS_MEM_ADDR, devRet);
2197 }
2198 return ret;
2199}
2200#endif
2201
2202int SysFstat64(int fd, struct kstat *buf)
2203{
2204 int ret;
2205 struct stat64 bufRet = {0};
2206
2207 /* Process fd convert to system global fd */
2208 fd = GetAssociatedSystemFd(fd);
2209
2210 ret = fstat64(fd, (buf ? (&bufRet) : NULL));
2211 if (ret < 0) {
2212 return -get_errno();
2213 }
2214
2215 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
2216 if (ret != 0) {
2217 return -EFAULT;
2218 }
2219
2220 return ret;
2221}
2222
2223int SysFcntl64(int fd, int cmd, void *arg)
2224{
2225 /* Process fd convert to system global fd */
2226 int sysfd = GetAssociatedSystemFd(fd);
2227
2228 int ret = VfsFcntl(fd, cmd, arg);
2229 if (ret == CONTINE_NUTTX_FCNTL) {
2230 ret = fcntl64(sysfd, cmd, arg);
2231 }
2232
2233 if (ret < 0) {
2234 return -get_errno();
2235 }
2236 return ret;
2237}
2238
2239int SysGetdents64(int fd, struct dirent *de_user, unsigned int count)
2240{
2241 if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)de_user, count)) {
2242 return -EFAULT;
2243 }
2244
2245 struct dirent *de_knl = NULL;
2246
2247 /* Process fd convert to system global fd */
2248 fd = GetAssociatedSystemFd(fd);
2249
2250 int ret = do_readdir(fd, &de_knl, count);
2251 if (ret < 0) {
2252 return ret;
2253 }
2254 if (de_knl != NULL) {
2255 int cpy_ret = LOS_ArchCopyToUser(de_user, de_knl, ret);
2256 if (cpy_ret != 0)
2257 {
2258 return -EFAULT;
2259 }
2260 }
2261 return ret;
2262}
2263
2264char *SysRealpath(const char *path, char *resolved_path)
2265{
2266 char *pathRet = NULL;
2267 char *resolved_pathRet = NULL;
2268 char *result = NULL;
2269 int ret;
2270
2271 if (resolved_path == NULL) {
2272 return (char *)(intptr_t)-EINVAL;
2273 }
2274
2275 if (path != NULL) {
2276 ret = UserPathCopy(path, &pathRet);
2277 if (ret != 0) {
2278 result = (char *)(intptr_t)ret;
2279 goto OUT;
2280 }
2281 }
2282
2283 resolved_pathRet = realpath((path ? pathRet : NULL), NULL);
2284 if (resolved_pathRet == NULL) {
2285 result = (char *)(intptr_t)-get_errno();
2286 goto OUT;
2287 }
2288
2289 ret = LOS_ArchCopyToUser(resolved_path, resolved_pathRet, strlen(resolved_pathRet) + 1);
2290 if (ret != 0) {
2291 result = (char *)(intptr_t)-EFAULT;
2292 goto OUT;
2293 }
2294 result = resolved_path;
2295
2296OUT:
2297 if (pathRet != NULL) {
2298 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2299 }
2300 if (resolved_pathRet != NULL) {
2301 (void)LOS_MemFree(OS_SYS_MEM_ADDR, resolved_pathRet);
2302 }
2303 return result;
2304}
2305
2306int SysUtimensat(int fd, const char *path, struct timespec times[TIMESPEC_TIMES_NUM], int flag)
2307{
2308 int ret;
2309 int timeLen;
2310 struct IATTR attr = {0};
2311 char *filePath = NULL;
2312
2313 timeLen = TIMESPEC_TIMES_NUM * sizeof(struct timespec);
2314 CHECK_ASPACE(times, timeLen);
2315 DUP_FROM_USER(times, timeLen);
2316 ret = CheckNewAttrTime(&attr, times);
2317 FREE_DUP(times);
2318 if (ret < 0) {
2319 goto OUT;
2320 }
2321
2322 ret = GetFullpathNull(fd, path, &filePath);
2323 if (ret < 0) {
2324 goto OUT;
2325 }
2326
2327 ret = chattr(filePath, &attr);
2328 if (ret < 0) {
2329 ret = -get_errno();
2330 }
2331
2332OUT:
2333 PointerFree(filePath);
2334 return ret;
2335}
2336
2337int SysChmod(const char *pathname, mode_t mode)
2338{
2339 int ret;
2340 char *pathRet = NULL;
2341
2342 if (pathname != NULL) {
2343 ret = UserPathCopy(pathname, &pathRet);
2344 if (ret != 0) {
2345 goto OUT;
2346 }
2347 }
2348
2349 ret = chmod(pathRet, mode);
2350 if (ret < 0) {
2351 ret = -get_errno();
2352 }
2353
2354OUT:
2355 if (pathRet != NULL) {
2356 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2357 }
2358 return ret;
2359}
2360
2361int SysFchmodat(int fd, const char *path, mode_t mode, int flag)
2362{
2363 int ret;
2364 char *pathRet = NULL;
2365 char *fullpath = NULL;
2366 struct IATTR attr = {
2367 .attr_chg_mode = mode,
2368 .attr_chg_valid = CHG_MODE,
2369 };
2370
2371 if (path != NULL) {
2372 ret = UserPathCopy(path, &pathRet);
2373 if (ret != 0) {
2374 goto OUT;
2375 }
2376 }
2377
2378 if (fd != AT_FDCWD) {
2379 /* Process fd convert to system global fd */
2380 fd = GetAssociatedSystemFd(fd);
2381 }
2382
2383 ret = vfs_normalize_pathat(fd, pathRet, &fullpath);
2384 if (ret < 0) {
2385 goto OUT;
2386 }
2387
2388 ret = chattr(fullpath, &attr);
2389 if (ret < 0) {
2390 ret = -get_errno();
2391 }
2392
2393OUT:
2394 PointerFree(pathRet);
2395 PointerFree(fullpath);
2396
2397 return ret;
2398}
2399
2400int SysFchmod(int fd, mode_t mode)
2401{
2402 int ret;
2403 int sysFd;
2404 struct IATTR attr = {
2405 .attr_chg_mode = mode,
2406 .attr_chg_valid = CHG_MODE, /* change mode */
2407 };
2408 struct file *file = NULL;
2409
2410 sysFd = GetAssociatedSystemFd(fd);
2411 if (sysFd < 0) {
2412 return -EBADF;
2413 }
2414
2415 ret = fs_getfilep(sysFd, &file);
2416 if (ret < 0) {
2417 return -get_errno();
2418 }
2419
2420 ret = chattr(file->f_path, &attr);
2421 if (ret < 0) {
2422 return -get_errno();
2423 }
2424
2425 return ret;
2426}
2427
2428int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
2429{
2430 int ret;
2431 char *fullpath = NULL;
2432 struct IATTR attr = {
2433 .attr_chg_valid = 0,
2434 };
2435
2436 ret = GetFullpath(fd, path, &fullpath);
2437 if (ret < 0) {
2438 goto OUT;
2439 }
2440
2441 if (owner != (uid_t)-1) {
2442 attr.attr_chg_uid = owner;
2443 attr.attr_chg_valid |= CHG_UID;
2444 }
2445 if (group != (gid_t)-1) {
2446 attr.attr_chg_gid = group;
2447 attr.attr_chg_valid |= CHG_GID;
2448 }
2449
2450 ret = chattr(fullpath, &attr);
2451 if (ret < 0) {
2452 ret = -get_errno();
2453 }
2454
2455OUT:
2456 PointerFree(fullpath);
2457
2458 return ret;
2459}
2460
2461int SysFchown(int fd, uid_t owner, gid_t group)
2462{
2463 int ret;
2464 int sysFd;
2465 struct IATTR attr = {0};
2466 attr.attr_chg_valid = 0;
2467 struct file *file = NULL;
2468
2469 sysFd = GetAssociatedSystemFd(fd);
2470 if (sysFd < 0) {
2471 return -EBADF;
2472 }
2473
2474 ret = fs_getfilep(sysFd, &file);
2475 if (ret < 0) {
2476 return -get_errno();
2477 }
2478
2479 if (owner != (uid_t)-1) {
2480 attr.attr_chg_uid = owner;
2481 attr.attr_chg_valid |= CHG_UID;
2482 }
2483 if (group != (gid_t)-1) {
2484 attr.attr_chg_gid = group;
2485 attr.attr_chg_valid |= CHG_GID;
2486 }
2487 ret = chattr(file->f_path, &attr);
2488 if (ret < 0) {
2489 ret = -get_errno();
2490 }
2491
2492 return ret;
2493}
2494
2495int SysChown(const char *pathname, uid_t owner, gid_t group)
2496{
2497 int ret;
2498 char *pathRet = NULL;
2499
2500 if (pathname != NULL) {
2501 ret = UserPathCopy(pathname, &pathRet);
2502 if (ret != 0) {
2503 goto OUT;
2504 }
2505 }
2506
2507 ret = chown(pathRet, owner, group);
2508 if (ret < 0) {
2509 ret = -get_errno();
2510 }
2511
2512OUT:
2513 if (pathRet != NULL) {
2514 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2515 }
2516 return ret;
2517}
2518
2519int SysFstatat64(int dirfd, const char *restrict path, struct kstat *restrict buf, int flag)
2520{
2521 int ret;
2522 struct stat bufRet = {0};
2523 char *pathRet = NULL;
2524 char *fullpath = NULL;
2525
2526 if (path != NULL) {
2527 ret = UserPathCopy(path, &pathRet);
2528 if (ret != 0) {
2529 goto OUT;
2530 }
2531 }
2532
2533 if (dirfd != AT_FDCWD) {
2534 /* Process fd convert to system global fd */
2535 dirfd = GetAssociatedSystemFd(dirfd);
2536 }
2537
2538 ret = vfs_normalize_pathat(dirfd, pathRet, &fullpath);
2539 if (ret < 0) {
2540 goto OUT;
2541 }
2542
2543 ret = stat(fullpath, &bufRet);
2544 if (ret < 0) {
2545 ret = -get_errno();
2546 goto OUT;
2547 }
2548
2549 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
2550 if (ret != 0) {
2551 ret = -EFAULT;
2552 goto OUT;
2553 }
2554
2555OUT:
2556 if (pathRet != NULL) {
2557 LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2558 }
2559
2560 if (fullpath != NULL) {
2561 free(fullpath);
2562 }
2563 return ret;
2564}
2565
2566int SysFaccessat(int fd, const char *filename, int amode, int flag)
2567{
2568 int ret;
2569 struct stat buf;
2570 struct statfs fsBuf;
2571 char *fullDirectory = NULL;
2572
2573 ret = GetFullpath(fd, filename, &fullDirectory);
2574 if (ret < 0) {
2575 goto OUT;
2576 }
2577
2578 ret = statfs(fullDirectory, &fsBuf);
2579 if (ret != 0) {
2580 ret = -get_errno();
2581 goto OUT;
2582 }
2583
2584 if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) {
2585 ret = -EROFS;
2586 goto OUT;
2587 }
2588
2589 ret = stat(fullDirectory, &buf);
2590 if (ret != 0) {
2591 ret = -get_errno();
2592 goto OUT;
2593 }
2594
2595 if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) {
2596 ret = -EACCES;
2597 }
2598
2599OUT:
2600 PointerFree(fullDirectory);
2601
2602 return ret;
2603}
2604
2605int SysFstatfs(int fd, struct statfs *buf)
2606{
2607 int ret;
2608 struct file *filep = NULL;
2609 struct statfs bufRet = {0};
2610
2611 /* Process fd convert to system global fd */
2612 fd = GetAssociatedSystemFd(fd);
2613
2614 ret = fs_getfilep(fd, &filep);
2615 if (ret < 0) {
2616 ret = -get_errno();
2617 return ret;
2618 }
2619
2620 ret = statfs(filep->f_path, &bufRet);
2621 if (ret < 0) {
2622 ret = -get_errno();
2623 return ret;
2624 }
2625
2626 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
2627 if (ret != 0) {
2628 ret = -EFAULT;
2629 }
2630
2631 return ret;
2632}
2633
2634int SysFstatfs64(int fd, size_t sz, struct statfs *buf)
2635{
2636 int ret;
2637
2638 if (sz != sizeof(struct statfs)) {
2639 ret = -EINVAL;
2640 return ret;
2641 }
2642
2643 ret = SysFstatfs(fd, buf);
2644
2645 return ret;
2646}
2647
2648int SysPpoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigMask, int nsig)
2649{
2650 int timeout, retVal;
2651 sigset_t_l origMask = {0};
2652 sigset_t_l set = {0};
2653
2654 CHECK_ASPACE(tmo_p, sizeof(struct timespec));
2655 CPY_FROM_USER(tmo_p);
2656
2657 if (tmo_p != NULL) {
2658 timeout = tmo_p->tv_sec * OS_SYS_US_PER_MS + tmo_p->tv_nsec / OS_SYS_NS_PER_MS;
2659 if (timeout < 0) {
2660 return -EINVAL;
2661 }
2662 } else {
2663 timeout = -1;
2664 }
2665
2666 if (sigMask != NULL) {
2667 retVal = LOS_ArchCopyFromUser(&set, sigMask, sizeof(sigset_t));
2668 if (retVal != 0) {
2669 return -EFAULT;
2670 }
2671 (VOID)OsSigprocMask(SIG_SETMASK, &set, &origMask);
2672 } else {
2673 (VOID)OsSigprocMask(SIG_SETMASK, NULL, &origMask);
2674 }
2675
2676 retVal = SysPoll(fds, nfds, timeout);
2677 (VOID)OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2678
2679 return retVal;
2680}
2681
2682int SysPselect6(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
2683 const struct timespec *timeout, const long data[2])
2684{
2685 int ret;
2686 int retVal;
2687 sigset_t_l origMask;
2688 sigset_t_l setl;
2689
2690 CHECK_ASPACE(readfds, sizeof(fd_set));
2691 CHECK_ASPACE(writefds, sizeof(fd_set));
2692 CHECK_ASPACE(exceptfds, sizeof(fd_set));
2693 CHECK_ASPACE(timeout, sizeof(struct timeval));
2694
2695 CPY_FROM_USER(readfds);
2696 CPY_FROM_USER(writefds);
2697 CPY_FROM_USER(exceptfds);
2698 DUP_FROM_USER(timeout, sizeof(struct timeval));
2699
2700 if (timeout != NULL) {
2701 ((struct timeval *)timeout)->tv_usec = timeout->tv_nsec / 1000; /* 1000, convert ns to us */
2702 }
2703
2704 if (data != NULL) {
2705 retVal = LOS_ArchCopyFromUser(&(setl.sig[0]), (int *)((UINTPTR)data[0]), sizeof(sigset_t));
2706 if (retVal != 0) {
2707 ret = -EFAULT;
2708 FREE_DUP(timeout);
2709 return ret;
2710 }
2711 }
2712
2713 OsSigprocMask(SIG_SETMASK, &setl, &origMask);
2714 ret = do_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout, UserPoll);
2715 if (ret < 0) {
2716 /* do not copy parameter back to user mode if do_select failed */
2717 ret = -get_errno();
2718 FREE_DUP(timeout);
2719 return ret;
2720 }
2721 OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2722
2723 CPY_TO_USER(readfds);
2724 CPY_TO_USER(writefds);
2725 CPY_TO_USER(exceptfds);
2726 FREE_DUP(timeout);
2727
2728 return ret;
2729}
2730
2731static int DoEpollCreate1(int flags)
2732{
2733 int ret;
2734 int procFd;
2735
2736 ret = epoll_create1(flags);
2737 if (ret < 0) {
2738 ret = -get_errno();
2739 return ret;
2740 }
2741
2742 procFd = AllocAndAssocProcessFd((INTPTR)(ret), MIN_START_FD);
2743 if (procFd == -1) {
2744 epoll_close(ret);
2745 return -EMFILE;
2746 }
2747
2748 return procFd;
2749}
2750
2751int SysEpollCreate(int size)
2752{
2753 (void)size;
2754 return DoEpollCreate1(0);
2755}
2756
2757int SysEpollCreate1(int flags)
2758{
2759 return DoEpollCreate1(flags);
2760}
2761
2762int SysEpollCtl(int epfd, int op, int fd, struct epoll_event *ev)
2763{
2764 int ret;
2765
2766 CHECK_ASPACE(ev, sizeof(struct epoll_event));
2767 CPY_FROM_USER(ev);
2768
2769 fd = GetAssociatedSystemFd(fd);
2770 epfd = GetAssociatedSystemFd(epfd);
2771 if ((fd < 0) || (epfd < 0)) {
2772 ret = -EBADF;
2773 goto OUT;
2774 }
2775
2776 ret = epoll_ctl(epfd, op, fd, ev);
2777 if (ret < 0) {
2778 ret = -EBADF;
2779 goto OUT;
2780 }
2781
2782 CPY_TO_USER(ev);
2783OUT:
2784 return (ret == -1) ? -get_errno() : ret;
2785}
2786
2787int SysEpollWait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
2788{
2789 int ret = 0;
2790
2791 CHECK_ASPACE(evs, sizeof(struct epoll_event));
2792 CPY_FROM_USER(evs);
2793
2794 epfd = GetAssociatedSystemFd(epfd);
2795 if (epfd < 0) {
2796 ret = -EBADF;
2797 goto OUT;
2798 }
2799
2800 ret = epoll_wait(epfd, evs, maxevents, timeout);
2801 if (ret < 0) {
2802 ret = -get_errno();
2803 }
2804
2805 CPY_TO_USER(evs);
2806OUT:
2807 return (ret == -1) ? -get_errno() : ret;
2808}
2809
2810int SysEpollPwait(int epfd, struct epoll_event *evs, int maxevents, int timeout, const sigset_t *mask)
2811{
2812 sigset_t_l origMask;
2813 sigset_t_l setl;
2814 int ret = 0;
2815
2816 CHECK_ASPACE(mask, sizeof(sigset_t));
2817
2818 if (mask != NULL) {
2819 ret = LOS_ArchCopyFromUser(&setl, mask, sizeof(sigset_t));
2820 if (ret != 0) {
2821 return -EFAULT;
2822 }
2823 }
2824
2825 CHECK_ASPACE(evs, sizeof(struct epoll_event));
2826 CPY_FROM_USER(evs);
2827
2828 epfd = GetAssociatedSystemFd(epfd);
2829 if (epfd < 0) {
2830 ret = -EBADF;
2831 goto OUT;
2832 }
2833
2834 OsSigprocMask(SIG_SETMASK, &setl, &origMask);
2835 ret = epoll_wait(epfd, evs, maxevents, timeout);
2836 if (ret < 0) {
2837 ret = -get_errno();
2838 }
2839
2840 OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2841
2842 CPY_TO_USER(evs);
2843OUT:
2844 return (ret == -1) ? -get_errno() : ret;
2845}
2846
2847#endif
BOOL IsCapPermit(UINT32 capIndex)
Definition: capability.c:43
void files_refer(int fd)
int format(const char *dev, int sectors, int option)
formatting sd card
Definition: format.c:44
int epoll_close(int epfd)
Definition: fs_epoll.c:219
int epoll_wait(int epfd, FAR struct epoll_event *evs, int maxevents, int timeout)
Definition: fs_epoll.c:297
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev)
Definition: fs_epoll.c:233
int epoll_create1(int flags)
Definition: fs_epoll.c:179
int VfsFcntl(int fd, int cmd,...)
Definition: vfs_fcntl.c:68
void SetCloexecFlag(int procFd)
Definition: vfs_cloexec.c:62
int chattr(const char *pathname, struct IATTR *attr)
Definition: vfs_chattr.c:58
void ClearCloexecFlag(int procFd)
Definition: vfs_cloexec.c:89
off64_t SysLseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence)
Definition: fs_syscall.c:611
ssize_t SysWrite(int fd, const void *buf, size_t nbytes)
系统调用|写文件:将buf中(用户空间)nbytes长度的内容写到文件中
Definition: fs_syscall.c:273
ssize_t SysReadlink(const char *pathname, char *buf, size_t bufsize)
Definition: fs_syscall.c:441
int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout)
SysPoll I/O多路转换
Definition: fs_syscall.c:1552
int SysRename(const char *oldpath, const char *newpath)
重命名文件
Definition: fs_syscall.c:787
static int CheckNewAttrTime(struct IATTR *attr, struct timespec times[TIMESPEC_TIMES_NUM])
Definition: fs_syscall.c:63
int SysRmdir(const char *pathname)
删除目录
Definition: fs_syscall.c:847
int SysLstat(const char *path, struct kstat *buffer)
参见SysStat
Definition: fs_syscall.c:1370
int SysFallocate(int fd, int mode, off_t offset, off_t len)
Definition: fs_syscall.c:2067
int SysFsync(int fd)
把文件在内存中的部分写回磁盘
Definition: fs_syscall.c:1437
static int PollfdToSystem(struct pollfd *fds, nfds_t nfds, int **pollFdsBak)
Definition: fs_syscall.c:180
int SysFstatfs64(int fd, size_t sz, struct statfs *buf)
Definition: fs_syscall.c:2634
static void RestorePollfd(struct pollfd *fds, nfds_t nfds, const int *pollFds)
Definition: fs_syscall.c:208
int SysFchdir(int fd)
Definition: fs_syscall.c:554
int SysStat(const char *path, struct kstat *buf)
获取文件状态信息
Definition: fs_syscall.c:1339
int SysPselect6(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const long data[2])
Definition: fs_syscall.c:2682
int SysStatfs64(const char *path, size_t sz, struct statfs *buf)
获取文件系统信息
Definition: fs_syscall.c:1303
int SysTruncate(const char *path, off_t length)
系统调用|文件系统|截断功能
Definition: fs_syscall.c:1192
static int SelectParamCheckCopy(fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fd_set **fdsBuf)
select()参数检查
Definition: fs_syscall.c:1076
int SysSymlinkat(const char *target, int dirfd, const char *linkpath)
Definition: fs_syscall.c:1915
int SysEpollCreate(int size)
Definition: fs_syscall.c:2751
int SysFchown(int fd, uid_t owner, gid_t group)
Definition: fs_syscall.c:2461
int SysLink(const char *oldpath, const char *newpath)
Definition: fs_syscall.c:406
int SysEpollCreate1(int flags)
Definition: fs_syscall.c:2757
char * SysGetcwd(char *buf, size_t n)
Definition: fs_syscall.c:1706
int SysFaccessat(int fd, const char *filename, int amode, int flag)
Definition: fs_syscall.c:2566
int SysEpollWait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
Definition: fs_syscall.c:2787
int SysIoctl(int fd, int req, void *arg)
I/O总控制函数
Definition: fs_syscall.c:902
int SysFtruncate(int fd, off_t length)
系统调用|文件系统|截断功能
Definition: fs_syscall.c:1258
ssize_t SysReadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize)
Definition: fs_syscall.c:1956
int SysStatx(int fd, const char *restrict path, int flag, unsigned mask, struct statx *restrict stx)
Definition: fs_syscall.c:1432
ssize_t SysPwrite64(int fd, const void *buf, size_t nbytes, off64_t offset)
Definition: fs_syscall.c:1667
int SysDup2(int fd1, int fd2)
复制文件描述符
Definition: fs_syscall.c:1038
int SysFallocate64(int fd, int mode, off64_t offset, off64_t len)
Definition: fs_syscall.c:2081
int SysFstatfs(int fd, struct statfs *buf)
Definition: fs_syscall.c:2605
int SysStatfs(const char *path, struct statfs *buf)
获取指定路径下文件的文件系统信息
Definition: fs_syscall.c:1272
ssize_t SysReadv(int fd, const struct iovec *iov, int iovcnt)
通过FD读入数据到缓冲数组中,fd为进程描述符
Definition: fs_syscall.c:1464
int SysFcntl(int fd, int cmd, void *arg)
Definition: fs_syscall.c:957
int SysOpen(const char *path, int oflags,...)
系统调用|打开文件, 正常情况下返回进程的FD值
Definition: fs_syscall.c:294
ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt)
将缓冲数组里的数据写入文件
Definition: fs_syscall.c:1500
int SysFchmod(int fd, mode_t mode)
Definition: fs_syscall.c:2400
int SysChown(const char *pathname, uid_t owner, gid_t group)
Definition: fs_syscall.c:2495
static int NfsMount(const char *serverIpAndPath, const char *mountPath, unsigned int uid, unsigned int gid)
Definition: fs_syscall.c:637
ssize_t SysSendFile(int outfd, int infd, off_t *offset, size_t count)
Definition: fs_syscall.c:1740
static int DoEpollCreate1(int flags)
Definition: fs_syscall.c:2731
int SysFchmodat(int fd, const char *path, mode_t mode, int flag)
Definition: fs_syscall.c:2361
int SysSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
SysSelect 系统调用|文件系统|select .鸿蒙liteos目前也支持epoll方式
Definition: fs_syscall.c:1135
static int GetFullpathNull(int fd, const char *path, char **filePath)
获取全路径
Definition: fs_syscall.c:110
int SysFstat64(int fd, struct kstat *buf)
Definition: fs_syscall.c:2202
void SysSync(void)
将内存缓冲区数据写回硬盘
Definition: fs_syscall.c:889
int SysUtimensat(int fd, const char *path, struct timespec times[TIMESPEC_TIMES_NUM], int flag)
Definition: fs_syscall.c:2306
int SysSymlink(const char *target, const char *linkpath)
Definition: fs_syscall.c:474
int SysExecve(const char *fileName, char *const *argv, char *const *envp)
动态加载程序过程
Definition: fs_syscall.c:548
int SysClose(int fd)
Definition: fs_syscall.c:236
int SysUmount2(const char *target, int flags)
卸载文件系统
Definition: fs_syscall.c:894
int SysRenameat(int oldfd, const char *oldpath, int newdfd, const char *newpath)
Definition: fs_syscall.c:2023
off_t SysLseek(int fd, off_t offset, int whence)
移动文件指针
Definition: fs_syscall.c:602
int SysChmod(const char *pathname, mode_t mode)
Definition: fs_syscall.c:2337
int SysPpoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigMask, int nsig)
Definition: fs_syscall.c:2648
char * SysRealpath(const char *path, char *resolved_path)
Definition: fs_syscall.c:2264
ssize_t SysPread64(int fd, void *buf, size_t nbytes, off64_t offset)
对进程进行特定操作
Definition: fs_syscall.c:1629
ssize_t SysPwritev(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
Definition: fs_syscall.c:2134
int SysFtruncate64(int fd, off64_t length)
Definition: fs_syscall.c:1767
ssize_t SysRead(int fd, void *buf, size_t nbytes)
系统调用|读文件:从文件中读取nbytes长度的内容到buf中(用户空间)
Definition: fs_syscall.c:252
static int UserIovCopy(struct iovec **iovBuf, const struct iovec *iov, const int iovcnt, int *valid_iovcnt)
Definition: fs_syscall.c:152
int SysFstatat64(int dirfd, const char *restrict path, struct kstat *restrict buf, int flag)
Definition: fs_syscall.c:2519
int SysLinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags)
Definition: fs_syscall.c:1870
int SysAccess(const char *path, int amode)
确定文件的可存取性
Definition: fs_syscall.c:762
int SysUnlinkat(int dirfd, const char *pathname, int flag)
Definition: fs_syscall.c:1994
int SysUnlink(const char *pathname)
删除链:删除由装入点管理的文件
Definition: fs_syscall.c:519
int SysCreat(const char *pathname, mode_t mode)
创建文件,从实现看 SysCreat 和 SysOpen 并没有太大的区别,只有打开方式的区别 SysCreat函数完全可以被SysOpen函数替代
Definition: fs_syscall.c:372
int SysMkdirat(int dirfd, const char *pathname, mode_t mode)
Definition: fs_syscall.c:1841
int SysTruncate64(const char *path, off64_t length)
系统调用|文件系统|截断功能
Definition: fs_syscall.c:1225
int SysFstat(int fd, struct kstat *buf)
参见SysStat
Definition: fs_syscall.c:1401
int SysGetdents64(int fd, struct dirent *de_user, unsigned int count)
Definition: fs_syscall.c:2239
int SysEpollPwait(int epfd, struct epoll_event *evs, int maxevents, int timeout, const sigset_t *mask)
Definition: fs_syscall.c:2810
int SysUmount(const char *target)
卸载文件系统,当某个文件系统不需要再使用了,那么可以将它卸载掉。
Definition: fs_syscall.c:734
int SysDup(int fd)
Definition: fs_syscall.c:871
int SysOpenat(int dirfd, const char *path, int oflags,...)
Definition: fs_syscall.c:1781
int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
Definition: fs_syscall.c:2428
int SysEpollCtl(int epfd, int op, int fd, struct epoll_event *ev)
Definition: fs_syscall.c:2762
int SysFormat(const char *dev, int sectors, int option)
Definition: fs_syscall.c:2173
static int UserPoll(struct pollfd *fds, nfds_t nfds, int timeout)
使用poll方式 实现IO多路复用的机制
Definition: fs_syscall.c:219
int SysMkdir(const char *pathname, mode_t mode)
创建目录
Definition: fs_syscall.c:823
int SysChdir(const char *path)
Definition: fs_syscall.c:578
int SysFcntl64(int fd, int cmd, void *arg)
Definition: fs_syscall.c:2223
int SysMount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data)
SysMount 挂载文件系统 挂载是指将一个存储设备挂接到一个已存在的路径上。我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的路径上, 然后通过这个路径来访问存储设备。如果只有一个存...
Definition: fs_syscall.c:666
int SysPrctl(int option,...)
对进程进行特定操作
Definition: fs_syscall.c:1597
static int UserIovItemCheck(const struct iovec *iov, const int iovcnt)
用户空间 io向量地址范围检查
Definition: fs_syscall.c:137
ssize_t SysPreadv(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
Definition: fs_syscall.c:2095
int SysPipe(int pipefd[2])
Definition: fs_syscall.c:995
static int NfsMountRef(const char *serverIpAndPath, const char *mountPath, unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount")))
int vfs_normalize_pathat(int dirfd, const char *filename, char **pathname)
Definition: fullpath.c:309
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
__attribute__((aligned(MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS)))
Definition: los_arch_mmu.c:98
INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR *const *argv, CHAR *const *envp)
LOS_DoExecveFile 根据fileName执行一个新的用户程序 LOS_DoExecveFile接口一般由用户通过execve系列接口利用系统调用机制调用创建新的进程,内核不能直接调用该接口...
Definition: los_exec_elf.c:165
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
int OsSigprocMask(int how, const sigset_t_l *set, sigset_t_l *oldset)
Definition: los_signal.c:233
int do_open(int dirfd, const char *path, int oflags, mode_t mode)
int do_mkdir(int dirfd, const char *pathname, mode_t mode)
int do_rename(int oldfd, const char *oldpath, int newfd, const char *newpath)
int do_unlink(int dirfd, const char *pathname)
int do_readdir(int fd, struct dirent **de, unsigned int count)
int do_rmdir(int dirfd, const char *pathname)
int do_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout, PollFun poll)
int do_opendir(const char *path, int oflags)
LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName)
Definition: los_task.c:1337
unsigned long vaddr_t
Definition: los_typedef.h:206
unsigned long VADDR_T
Definition: los_typedef.h:208
INT64 ssize_t
Definition: los_typedef.h:79
unsigned long UINTPTR
Definition: los_typedef.h:68
signed long INTPTR
Definition: los_typedef.h:69
STATIC INLINE BOOL LOS_IsUserAddressRange(VADDR_T vaddr, size_t len)
虚拟地址[vaddr,vaddr + len]是否在用户空间
Definition: los_vm_map.h:281
STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr)
虚拟地址是否在用户空间
Definition: los_vm_map.h:275
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
off64_t _lseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence)
Definition: stdio.c:77
off_t _lseek(int fd, off_t offset, int whence)
Definition: stdio.c:38
INT32 LOS_StrncpyFromUser(CHAR *dst, const CHAR *src, INT32 count)
此结构用于记录 vnode 的属性
Definition: vnode.h:81
unsigned attr_chg_uid
用户ID
Definition: vnode.h:86
unsigned attr_chg_atime
节点最近访问时间
Definition: vnode.h:89
unsigned attr_chg_mode
确定了文件的类型,以及它的所有者、它的group、其它用户访问此文件的权限 (S_IWUSR | ...)
Definition: vnode.h:85
unsigned attr_chg_gid
组ID
Definition: vnode.h:87
unsigned attr_chg_mtime
节点对应的文件内容被修改时间
Definition: vnode.h:90
unsigned int attr_chg_valid
节点改变有效性 (CHG_MODE | CHG_UID | ... )
Definition: vnode.h:83
char * f_path
int f_oflags
unsigned long sig[MAX_SIG_ARRAY_IN_MUSL/sizeof(unsigned long)]
Definition: los_signal.h:166
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 off64_t
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
int GetFullpath(int fd, const char *path, char **fullpath)
Definition: syscall_pub.c:64
int UserPathCopy(const char *userPath, char **pathBuf)
Definition: syscall_pub.c:105
tv tv_sec
Definition: time.c:439
clock_t times(struct tms *buf)
Definition: time.c:1107
int clock_gettime(clockid_t clockID, struct timespec *tp)
当用户程序进行特定系统调用时(例如clock_gettime(CLOCK_REALTIME_COARSE, &ts)),VDSO代码页会将其拦截;
Definition: time.c:614
size_t LOS_ArchCopyToUser(void *dst, const void *src, size_t len)
从内核空间拷贝到用户空间
Definition: user_copy.c:79
size_t LOS_ArchCopyFromUser(void *dst, const void *src, size_t len)
Definition: user_copy.c:58
int VfsPermissionCheck(uint fuid, uint fgid, mode_t fileMode, int accMode)
int fallocate64(int fd, int mode, off64_t offset, off64_t len)
int fallocate(int fd, int mode, off_t offset, off_t len)
char * realpath(const char *path, char *resolved_path)
Definition: vfs_other.c:651
int chdir(const char *path)
Definition: vfs_other.c:150
int fstat64(int fd, struct stat64 *buf)
Definition: vfs_other.c:63
char * getcwd(char *buf, size_t n)
Definition: vfs_other.c:222
int chown(const char *pathname, uid_t owner, gid_t group)
Definition: vfs_other.c:271
int access(const char *path, int amode)
Definition: vfs_other.c:293
int chmod(const char *path, mode_t mode)
Definition: vfs_other.c:256
ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: vfs_preadv.c:47
int AllocAndAssocProcessFd(int sysFd, int minFd)
分配和绑定进程描述符
Definition: vfs_procfd.c:261
int CheckProcessFd(int procFd)
Definition: vfs_procfd.c:122
void AssociateSystemFd(int procFd, int sysFd)
参数进程FD和参数系统FD进行绑定(关联)
Definition: vfs_procfd.c:105
void FreeProcessFd(int procFd)
释放进程文件描述符
Definition: vfs_procfd.c:191
int DisassociateProcessFd(int procFd)
解绑系统文件描述符,返回系统文件描述符
Definition: vfs_procfd.c:206
int AllocProcessFd(void)
分配文件描述符
Definition: vfs_procfd.c:228
int AllocSpecifiedProcessFd(int procFd)
Definition: vfs_procfd.c:162
int GetAssociatedSystemFd(int procFd)
获取绑定的系统描述符
Definition: vfs_procfd.c:133
ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: vfs_pwritev.c:47
ssize_t vfs_readv(int fd, const struct iovec *iov, int iovcnt, off_t *offset)
供系统调用
Definition: vfs_readv.c:91
ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
Definition: vfs_writev.c:136