• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"
55 #include "los_strncpy_from_user.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 
CheckNewAttrTime(struct IATTR * attr,struct timespec times[TIMESPEC_TIMES_NUM])63 static 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 
GetFullpathNull(int fd,const char * path,char ** filePath)110 static 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 
UserIovItemCheck(const struct iovec * iov,const int iovcnt)137 static 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 
UserIovCopy(struct iovec ** iovBuf,const struct iovec * iov,const int iovcnt,int * valid_iovcnt)152 static 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 
PollfdToSystem(struct pollfd * fds,nfds_t nfds,int ** pollFdsBak)180 static 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 
RestorePollfd(struct pollfd * fds,nfds_t nfds,const int * pollFds)208 static 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 
UserPoll(struct pollfd * fds,nfds_t nfds,int timeout)219 static 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 
SysClose(int fd)235 int SysClose(int fd)
236 {
237     int ret;
238 
239     /* Process fd convert to system global fd */
240     int sysfd = DisassociateProcessFd(fd);
241 
242     ret = close(sysfd);
243     if (ret < 0) {
244         AssociateSystemFd(fd, sysfd);
245         return -get_errno();
246     }
247     FreeProcessFd(fd);
248     return ret;
249 }
250 
SysRead(int fd,void * buf,size_t nbytes)251 ssize_t SysRead(int fd, void *buf, size_t nbytes)
252 {
253     int ret;
254 
255     if (nbytes == 0) {
256         return 0;
257     }
258 
259     if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, nbytes)) {
260         return -EFAULT;
261     }
262 
263     /* Process fd convert to system global fd */
264     fd = GetAssociatedSystemFd(fd);
265 
266     ret = read(fd, buf, nbytes);
267     if (ret < 0) {
268         return -get_errno();
269     }
270     return ret;
271 }
272 
SysWrite(int fd,const void * buf,size_t nbytes)273 ssize_t SysWrite(int fd, const void *buf, size_t nbytes)
274 {
275     int ret;
276 
277     if (nbytes == 0) {
278         return 0;
279     }
280 
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 
294 // int vfs_normalize_path(const char *directory, const char *filename, char **pathname)
295 #ifdef LOSCFG_PID_CONTAINER
296 #ifdef LOSCFG_PROC_PROCESS_DIR
297 #define PROCESS_DIR_ROOT   "/proc"
NextName(char * pos,uint8_t * len)298 static char *NextName(char *pos, uint8_t *len)
299 {
300     char *name = NULL;
301     while (*pos != 0 && *pos == '/') {
302         pos++;
303     }
304     if (*pos == '\0') {
305         return NULL;
306     }
307     name = (char *)pos;
308     while (*pos != '\0' && *pos != '/') {
309         pos++;
310     }
311     *len = pos - name;
312     return name;
313 }
314 
ProcRealProcessIDGet(unsigned int pid)315 static unsigned int ProcRealProcessIDGet(unsigned int pid)
316 {
317     unsigned int intSave;
318     if (OS_PID_CHECK_INVALID(pid)) {
319         return 0;
320     }
321 
322     SCHEDULER_LOCK(intSave);
323     LosProcessCB *pcb = OsGetPCBFromVpid(pid);
324     if (OsProcessIsInactive(pcb)) {
325         SCHEDULER_UNLOCK(intSave);
326         return 0;
327     }
328 
329     int rootPid = OsGetRootPid(pcb);
330     SCHEDULER_UNLOCK(intSave);
331     if ((rootPid == OS_INVALID_VALUE) || (rootPid == pid)) {
332         return 0;
333     }
334 
335     return rootPid;
336 }
337 
ProcRealProcessDirGet(char * path)338 static int ProcRealProcessDirGet(char *path)
339 {
340     char pidBuf[PATH_MAX] = {0};
341     char *fullPath = NULL;
342     uint8_t strLen = 0;
343     int pid, rootPid;
344     int ret = vfs_normalize_path(NULL, path, &fullPath);
345     if (ret < 0) {
346         return ret;
347     }
348 
349     int procLen = strlen(PROCESS_DIR_ROOT);
350     if (strncmp(fullPath, PROCESS_DIR_ROOT, procLen) != 0) {
351         free(fullPath);
352         return 0;
353     }
354 
355     char *pidStr = NextName(fullPath + procLen, &strLen);
356     if (pidStr == NULL) {
357         free(fullPath);
358         return 0;
359     }
360 
361     if ((*pidStr <= '0') || (*pidStr > '9')) {
362         free(fullPath);
363         return 0;
364     }
365 
366     if (memcpy_s(pidBuf, PATH_MAX, pidStr, strLen) != EOK) {
367         free(fullPath);
368         return 0;
369     }
370     pidBuf[strLen] = '\0';
371 
372     pid = atoi(pidBuf);
373     if (pid == 0) {
374         free(fullPath);
375         return 0;
376     }
377 
378     rootPid = ProcRealProcessIDGet((unsigned)pid);
379     if (rootPid == 0) {
380         free(fullPath);
381         return 0;
382     }
383 
384     if (snprintf_s(path, PATH_MAX + 1, PATH_MAX, "/proc/%d%s", rootPid, (pidStr + strLen)) < 0) {
385         free(fullPath);
386         return -EFAULT;
387     }
388 
389     free(fullPath);
390     return 0;
391 }
392 #endif
393 #endif
394 
GetPath(const char * path,char ** pathRet)395 static int GetPath(const char *path, char **pathRet)
396 {
397     int ret = UserPathCopy(path, pathRet);
398     if (ret != 0) {
399         return ret;
400     }
401 #ifdef LOSCFG_PID_CONTAINER
402 #ifdef LOSCFG_PROC_PROCESS_DIR
403     ret = ProcRealProcessDirGet(*pathRet);
404     if (ret != 0) {
405         return ret;
406     }
407 #endif
408 #endif
409     return 0;
410 }
411 
SysOpen(const char * path,int oflags,...)412 int SysOpen(const char *path, int oflags, ...)
413 {
414     int ret;
415     int procFd = -1;
416     mode_t mode = DEFAULT_FILE_MODE; /* 0666: File read-write properties. */
417     char *pathRet = NULL;
418 
419     if (path != NULL) {
420         ret = GetPath(path, &pathRet);
421         if (ret != 0) {
422             goto ERROUT;
423         }
424     }
425 
426     procFd = AllocProcessFd();
427     if (procFd < 0) {
428         ret = -EMFILE;
429         goto ERROUT;
430     }
431 
432     if (oflags & O_CLOEXEC) {
433         SetCloexecFlag(procFd);
434     }
435 
436     if ((unsigned int)oflags & O_DIRECTORY) {
437         ret = do_opendir(pathRet, oflags);
438     } else {
439 #ifdef LOSCFG_FILE_MODE
440         va_list ap;
441         va_start(ap, oflags);
442         mode = va_arg(ap, int);
443         va_end(ap);
444 #endif
445 
446         ret = do_open(AT_FDCWD, pathRet, oflags, mode);
447     }
448 
449     if (ret < 0) {
450         ret = -get_errno();
451         goto ERROUT;
452     }
453 
454     AssociateSystemFd(procFd, ret);
455     if (pathRet != NULL) {
456         LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
457     }
458     return procFd;
459 
460 ERROUT:
461     if (pathRet != NULL) {
462         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
463     }
464     if (procFd >= 0) {
465         FreeProcessFd(procFd);
466     }
467     return ret;
468 }
469 
SysCreat(const char * pathname,mode_t mode)470 int SysCreat(const char *pathname, mode_t mode)
471 {
472     int ret = 0;
473     char *pathRet = NULL;
474 
475     if (pathname != NULL) {
476         ret = UserPathCopy(pathname, &pathRet);
477         if (ret != 0) {
478             goto OUT;
479         }
480     }
481 
482     int procFd = AllocProcessFd();
483     if (procFd  < 0) {
484         ret = -EMFILE;
485         goto OUT;
486     }
487 
488     ret = open((pathname ? pathRet : NULL), O_CREAT | O_TRUNC | O_WRONLY, mode);
489     if (ret < 0) {
490         FreeProcessFd(procFd);
491         ret = -get_errno();
492     } else {
493         AssociateSystemFd(procFd, ret);
494         ret = procFd;
495     }
496 
497 OUT:
498     if (pathRet != NULL) {
499         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
500     }
501     return ret;
502 }
503 
SysLink(const char * oldpath,const char * newpath)504 int SysLink(const char *oldpath, const char *newpath)
505 {
506     int ret;
507     char *oldpathRet = NULL;
508     char *newpathRet = NULL;
509 
510     if (oldpath != NULL) {
511         ret = UserPathCopy(oldpath, &oldpathRet);
512         if (ret != 0) {
513             goto OUT;
514         }
515     }
516 
517     if (newpath != NULL) {
518         ret = UserPathCopy(newpath, &newpathRet);
519         if (ret != 0) {
520             goto OUT;
521         }
522     }
523 
524     ret = link(oldpathRet, newpathRet);
525     if (ret < 0) {
526         ret = -get_errno();
527     }
528 
529 OUT:
530     if (oldpathRet != NULL) {
531         (void)LOS_MemFree(OS_SYS_MEM_ADDR, oldpathRet);
532     }
533     if (newpathRet != NULL) {
534         (void)LOS_MemFree(OS_SYS_MEM_ADDR, newpathRet);
535     }
536     return ret;
537 }
538 
SysReadlink(const char * pathname,char * buf,size_t bufsize)539 ssize_t SysReadlink(const char *pathname, char *buf, size_t bufsize)
540 {
541     ssize_t ret;
542     char *pathRet = NULL;
543 
544     if (bufsize == 0) {
545         return -EINVAL;
546     }
547 
548     if (pathname != NULL) {
549         ret = UserPathCopy(pathname, &pathRet);
550         if (ret != 0) {
551             goto OUT;
552         }
553 
554 #ifdef LOSCFG_PID_CONTAINER
555 #ifdef LOSCFG_PROC_PROCESS_DIR
556         ret = ProcRealProcessDirGet(pathRet);
557         if (ret != 0) {
558             goto OUT;
559         }
560 #endif
561 #endif
562     }
563 
564     if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) {
565         ret = -EFAULT;
566         goto OUT;
567     }
568 
569     ret = readlink(pathRet, buf, bufsize);
570     if (ret < 0) {
571         ret = -get_errno();
572     }
573 
574 OUT:
575     if (pathRet != NULL) {
576         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
577     }
578     return ret;
579 }
580 
SysSymlink(const char * target,const char * linkpath)581 int SysSymlink(const char *target, const char *linkpath)
582 {
583     int ret;
584     char *targetRet = NULL;
585     char *pathRet = NULL;
586 
587     if (target != NULL) {
588         ret = UserPathCopy(target, &targetRet);
589         if (ret != 0) {
590             goto OUT;
591         }
592     }
593 
594     if (linkpath != NULL) {
595         ret = UserPathCopy(linkpath, &pathRet);
596         if (ret != 0) {
597             goto OUT;
598         }
599     }
600 
601     ret = symlink(targetRet, pathRet);
602     if (ret < 0) {
603         ret = -get_errno();
604     }
605 
606 OUT:
607     if (pathRet != NULL) {
608         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
609     }
610 
611     if (targetRet != NULL) {
612         (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
613     }
614     return ret;
615 }
616 
SysUnlink(const char * pathname)617 int SysUnlink(const char *pathname)
618 {
619     int ret;
620     char *pathRet = NULL;
621 
622     if (pathname != NULL) {
623         ret = UserPathCopy(pathname, &pathRet);
624         if (ret != 0) {
625             goto OUT;
626         }
627     }
628 
629     ret = do_unlink(AT_FDCWD, (pathname ? pathRet : NULL));
630     if (ret < 0) {
631         ret = -get_errno();
632     }
633 
634 OUT:
635     if (pathRet != NULL) {
636         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
637     }
638     return ret;
639 }
640 
641 #ifdef LOSCFG_KERNEL_DYNLOAD
SysExecve(const char * fileName,char * const * argv,char * const * envp)642 int SysExecve(const char *fileName, char *const *argv, char *const *envp)
643 {
644     return LOS_DoExecveFile(fileName, argv, envp);
645 }
646 #endif
647 
SysFchdir(int fd)648 int SysFchdir(int fd)
649 {
650     int ret;
651     int sysFd;
652     struct file *file = NULL;
653 
654     sysFd = GetAssociatedSystemFd(fd);
655     if (sysFd < 0) {
656         return -EBADF;
657     }
658 
659     ret = fs_getfilep(sysFd, &file);
660     if (ret < 0) {
661         return -get_errno();
662     }
663 
664     ret = chdir(file->f_path);
665     if (ret < 0) {
666         ret = -get_errno();
667     }
668 
669     return ret;
670 }
671 
SysChdir(const char * path)672 int SysChdir(const char *path)
673 {
674     int ret;
675     char *pathRet = NULL;
676 
677     if (path != NULL) {
678         ret = UserPathCopy(path, &pathRet);
679         if (ret != 0) {
680             goto OUT;
681         }
682     }
683 
684     ret = chdir(path ? pathRet : NULL);
685     if (ret < 0) {
686         ret = -get_errno();
687     }
688 
689 OUT:
690     if (pathRet != NULL) {
691         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
692     }
693     return ret;
694 }
695 
SysLseek(int fd,off_t offset,int whence)696 off_t SysLseek(int fd, off_t offset, int whence)
697 {
698     /* Process fd convert to system global fd */
699     fd = GetAssociatedSystemFd(fd);
700 
701     return _lseek(fd, offset, whence);
702 }
703 
SysLseek64(int fd,int offsetHigh,int offsetLow,off64_t * result,int whence)704 off64_t SysLseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence)
705 {
706     off64_t ret;
707     off64_t res;
708     int retVal;
709 
710     /* Process fd convert to system global fd */
711     fd = GetAssociatedSystemFd(fd);
712 
713     ret = _lseek64(fd, offsetHigh, offsetLow, &res, whence);
714     if (ret != 0) {
715         return ret;
716     }
717 
718     retVal = LOS_ArchCopyToUser(result, &res, sizeof(off64_t));
719     if (retVal != 0) {
720         return -EFAULT;
721     }
722 
723     return 0;
724 }
725 
726 #ifdef LOSCFG_FS_NFS
727 static int NfsMountRef(const char *serverIpAndPath, const char *mountPath,
728                        unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount")));
729 
NfsMount(const char * serverIpAndPath,const char * mountPath,unsigned int uid,unsigned int gid)730 static int NfsMount(const char *serverIpAndPath, const char *mountPath,
731                     unsigned int uid, unsigned int gid)
732 {
733     int ret;
734 
735     if ((serverIpAndPath == NULL) || (mountPath == NULL)) {
736         return -EINVAL;
737     }
738     ret = NfsMountRef(serverIpAndPath, mountPath, uid, gid);
739     if (ret < 0) {
740         ret = -get_errno();
741     }
742     return ret;
743 }
744 #endif
745 
SysMount(const char * source,const char * target,const char * filesystemtype,unsigned long mountflags,const void * data)746 int SysMount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags,
747              const void *data)
748 {
749     int ret;
750     char *sourceRet = NULL;
751     char *targetRet = NULL;
752     char *dataRet = NULL;
753     char fstypeRet[FILESYSTEM_TYPE_MAX + 1] = {0};
754 
755     if (!IsCapPermit(CAP_FS_MOUNT)) {
756         return -EPERM;
757     }
758 
759     if (target != NULL) {
760         ret = UserPathCopy(target, &targetRet);
761         if (ret != 0) {
762             goto OUT;
763         }
764     }
765 
766     if (filesystemtype != NULL) {
767         ret = LOS_StrncpyFromUser(fstypeRet, filesystemtype, FILESYSTEM_TYPE_MAX + 1);
768         if (ret < 0) {
769             goto OUT;
770         } else if (ret > FILESYSTEM_TYPE_MAX) {
771             ret = -ENODEV;
772             goto OUT;
773         }
774 
775         if (strcmp(fstypeRet, "ramfs") && (source != NULL)) {
776             ret = UserPathCopy(source, &sourceRet);
777             if (ret != 0) {
778                 goto OUT;
779             }
780         }
781 #ifdef LOSCFG_FS_NFS
782         if (strcmp(fstypeRet, "nfs") == 0) {
783             ret = NfsMount(sourceRet, targetRet, 0, 0);
784             goto OUT;
785         }
786 #endif
787     }
788 
789     if (data != NULL) {
790         ret = UserPathCopy(data, &dataRet);
791         if (ret != 0) {
792             goto OUT;
793         }
794     }
795 
796     ret = mount(sourceRet, targetRet, (filesystemtype ? fstypeRet : NULL), mountflags, dataRet);
797     if (ret < 0) {
798         ret = -get_errno();
799     }
800 
801 OUT:
802     if (sourceRet != NULL) {
803         (void)LOS_MemFree(OS_SYS_MEM_ADDR, sourceRet);
804     }
805     if (targetRet != NULL) {
806         (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
807     }
808     if (dataRet != NULL) {
809         (void)LOS_MemFree(OS_SYS_MEM_ADDR, dataRet);
810     }
811     return ret;
812 }
813 
SysUmount(const char * target)814 int SysUmount(const char *target)
815 {
816     int ret;
817     char *pathRet = NULL;
818 
819     if (!IsCapPermit(CAP_FS_MOUNT)) {
820         return -EPERM;
821     }
822 
823     if (target != NULL) {
824         ret = UserPathCopy(target, &pathRet);
825         if (ret != 0) {
826             goto OUT;
827         }
828     }
829 
830     ret = umount(target ? pathRet : NULL);
831     if (ret < 0) {
832         ret = -get_errno();
833     }
834 
835 OUT:
836     if (pathRet != NULL) {
837         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
838     }
839     return ret;
840 }
841 
SysAccess(const char * path,int amode)842 int SysAccess(const char *path, int amode)
843 {
844     int ret;
845     char *pathRet = NULL;
846 
847     if (path != NULL) {
848         ret = UserPathCopy(path, &pathRet);
849         if (ret != 0) {
850             goto OUT;
851         }
852     }
853 
854     ret = access(pathRet, amode);
855     if (ret < 0) {
856         ret = -get_errno();
857     }
858 
859 OUT:
860     if (pathRet != NULL) {
861         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
862     }
863 
864     return ret;
865 }
866 
SysRename(const char * oldpath,const char * newpath)867 int SysRename(const char *oldpath, const char *newpath)
868 {
869     int ret;
870     char *pathOldRet = NULL;
871     char *pathNewRet = NULL;
872 
873     if (oldpath != NULL) {
874         ret = UserPathCopy(oldpath, &pathOldRet);
875         if (ret != 0) {
876             goto OUT;
877         }
878     }
879 
880     if (newpath != NULL) {
881         ret = UserPathCopy(newpath, &pathNewRet);
882         if (ret != 0) {
883             goto OUT;
884         }
885     }
886 
887     ret = do_rename(AT_FDCWD, (oldpath ? pathOldRet : NULL), AT_FDCWD,
888                     (newpath ? pathNewRet : NULL));
889     if (ret < 0) {
890         ret = -get_errno();
891     }
892 
893 OUT:
894     if (pathOldRet != NULL) {
895         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet);
896     }
897     if (pathNewRet != NULL) {
898         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet);
899     }
900     return ret;
901 }
902 
SysMkdir(const char * pathname,mode_t mode)903 int SysMkdir(const char *pathname, mode_t mode)
904 {
905     int ret;
906     char *pathRet = NULL;
907 
908     if (pathname != NULL) {
909         ret = UserPathCopy(pathname, &pathRet);
910         if (ret != 0) {
911             goto OUT;
912         }
913     }
914 
915     ret = do_mkdir(AT_FDCWD, (pathname ? pathRet : NULL), mode);
916     if (ret < 0) {
917         ret = -get_errno();
918     }
919 
920 OUT:
921     if (pathRet != NULL) {
922         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
923     }
924     return ret;
925 }
926 
SysRmdir(const char * pathname)927 int SysRmdir(const char *pathname)
928 {
929     int ret;
930     char *pathRet = NULL;
931 
932     if (pathname != NULL) {
933         ret = UserPathCopy(pathname, &pathRet);
934         if (ret != 0) {
935             goto OUT;
936         }
937     }
938 
939     ret = do_rmdir(AT_FDCWD, (pathname ? pathRet : NULL));
940     if (ret < 0) {
941         ret = -get_errno();
942     }
943 
944 OUT:
945     if (pathRet != NULL) {
946         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
947     }
948     return ret;
949 }
950 
SysDup(int fd)951 int SysDup(int fd)
952 {
953     int sysfd = GetAssociatedSystemFd(fd);
954     /* Check if the param is valid, note that: socket fd is not support dup2 */
955     if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) {
956         return -EBADF;
957     }
958 
959     int dupfd = AllocProcessFd();
960     if (dupfd < 0) {
961         return -EMFILE;
962     }
963 
964     files_refer(sysfd);
965     AssociateSystemFd(dupfd, sysfd);
966     return dupfd;
967 }
968 
SysSync(void)969 void SysSync(void)
970 {
971     sync();
972 }
973 
SysUmount2(const char * target,int flags)974 int SysUmount2(const char *target, int flags)
975 {
976     if (flags != 0) {
977         return -EINVAL;
978     }
979     return SysUmount(target);
980 }
981 
SysIoctl(int fd,int req,void * arg)982 int SysIoctl(int fd, int req, void *arg)
983 {
984     int ret;
985     unsigned int size = _IOC_SIZE((unsigned int)req);
986     unsigned int dir = _IOC_DIR((unsigned int)req);
987     if ((size == 0) && (dir != _IOC_NONE)) {
988         return -EINVAL;
989     }
990 
991     if ((dir != _IOC_NONE) && (((void *)(uintptr_t)arg) == NULL)) {
992         return -EINVAL;
993     }
994 
995     if ((dir & _IOC_READ) || (dir & _IOC_WRITE)) {
996         if (!LOS_IsUserAddressRange((uintptr_t)arg, size)) {
997             return -EFAULT;
998         }
999     }
1000 
1001     /* Process fd convert to system global fd */
1002     fd = GetAssociatedSystemFd(fd);
1003 
1004     ret = ioctl(fd, req, arg);
1005     if (ret < 0) {
1006         return -get_errno();
1007     }
1008     return ret;
1009 }
1010 
SysFcntl(int fd,int cmd,void * arg)1011 int SysFcntl(int fd, int cmd, void *arg)
1012 {
1013     /* Process fd convert to system global fd */
1014     int sysfd = GetAssociatedSystemFd(fd);
1015 
1016     int ret = VfsFcntl(fd, cmd, arg);
1017     if (ret == CONTINE_NUTTX_FCNTL) {
1018         ret = fcntl(sysfd, cmd, arg);
1019     }
1020 
1021     if (ret < 0) {
1022         return -get_errno();
1023     }
1024     return ret;
1025 }
1026 
1027 #ifdef LOSCFG_KERNEL_PIPE
SysPipe(int pipefd[2])1028 int SysPipe(int pipefd[2]) /* 2 : pipe fds for read and write */
1029 {
1030     int ret;
1031     int pipeFdIntr[2] = {0}; /* 2 : pipe fds for read and write */
1032 
1033     int procFd0 = AllocProcessFd();
1034     if (procFd0 < 0) {
1035         return -EMFILE;
1036     }
1037     int procFd1 = AllocProcessFd();
1038     if (procFd1 < 0) {
1039         FreeProcessFd(procFd0);
1040         return -EMFILE;
1041     }
1042 
1043     ret = pipe(pipeFdIntr);
1044     if (ret < 0) {
1045         FreeProcessFd(procFd0);
1046         FreeProcessFd(procFd1);
1047         return -get_errno();
1048     }
1049     int sysPipeFd0 = pipeFdIntr[0];
1050     int sysPipeFd1 = pipeFdIntr[1];
1051 
1052     AssociateSystemFd(procFd0, sysPipeFd0);
1053     AssociateSystemFd(procFd1, sysPipeFd1);
1054 
1055     pipeFdIntr[0] = procFd0;
1056     pipeFdIntr[1] = procFd1;
1057 
1058     ret = LOS_ArchCopyToUser(pipefd, pipeFdIntr, sizeof(pipeFdIntr));
1059     if (ret != 0) {
1060         FreeProcessFd(procFd0);
1061         FreeProcessFd(procFd1);
1062         close(sysPipeFd0);
1063         close(sysPipeFd1);
1064         return -EFAULT;
1065     }
1066     return ret;
1067 }
1068 #endif
1069 
SysDup2(int fd1,int fd2)1070 int SysDup2(int fd1, int fd2)
1071 {
1072     int ret;
1073     int sysfd1 = GetAssociatedSystemFd(fd1);
1074     int sysfd2 = GetAssociatedSystemFd(fd2);
1075 
1076     /* Check if the param is valid, note that: socket fd is not support dup2 */
1077     if ((sysfd1 < 0) || (sysfd1 >= CONFIG_NFILE_DESCRIPTORS) || (CheckProcessFd(fd2) != OK)) {
1078         return -EBADF;
1079     }
1080 
1081     /* Handle special circumstances */
1082     if (fd1 == fd2) {
1083         return fd2;
1084     }
1085 
1086     ret = AllocSpecifiedProcessFd(fd2);
1087     if (ret != OK) {
1088         return ret;
1089     }
1090 
1091     /* close the sysfd2 in need */
1092     if (sysfd2 >= 0) {
1093         ret = close(sysfd2);
1094         if (ret < 0) {
1095             AssociateSystemFd(fd2, sysfd2);
1096             return -get_errno();
1097         }
1098     }
1099 
1100     files_refer(sysfd1);
1101     AssociateSystemFd(fd2, sysfd1);
1102 
1103     /* if fd1 is not equal to fd2, the FD_CLOEXEC flag associated with fd2 shall be cleared */
1104     ClearCloexecFlag(fd2);
1105     return fd2;
1106 }
1107 
SelectParamCheckCopy(fd_set * readfds,fd_set * writefds,fd_set * exceptfds,fd_set ** fdsBuf)1108 static int SelectParamCheckCopy(fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fd_set **fdsBuf)
1109 {
1110     fd_set *readfdsRet = NULL;
1111     fd_set *writefdsRet = NULL;
1112     fd_set *exceptfdsRet = NULL;
1113 
1114     *fdsBuf = (fd_set *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(fd_set) * 3); /* 3: three param need check and copy */
1115     if (*fdsBuf == NULL) {
1116         return -ENOMEM;
1117     }
1118 
1119     readfdsRet = *fdsBuf;        /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */
1120     writefdsRet = *fdsBuf + 1;   /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */
1121     exceptfdsRet = *fdsBuf + 2;  /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */
1122 
1123     if (readfds != NULL) {
1124         if (LOS_ArchCopyFromUser(readfdsRet, readfds, sizeof(fd_set)) != 0) {
1125             (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1126             return -EFAULT;
1127         }
1128     }
1129 
1130     if (writefds != NULL) {
1131         if (LOS_ArchCopyFromUser(writefdsRet, writefds, sizeof(fd_set)) != 0) {
1132             (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1133             return -EFAULT;
1134         }
1135     }
1136 
1137     if (exceptfds != NULL) {
1138         if (LOS_ArchCopyFromUser(exceptfdsRet, exceptfds, sizeof(fd_set)) != 0) {
1139             (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1140             return -EFAULT;
1141         }
1142     }
1143 
1144     return 0;
1145 }
1146 
SysSelect(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout)1147 int SysSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
1148 {
1149     int ret;
1150     fd_set *fdsRet = NULL;
1151     fd_set *readfdsRet = NULL;
1152     fd_set *writefdsRet = NULL;
1153     fd_set *exceptfdsRet = NULL;
1154     struct timeval timeoutRet = {0};
1155 
1156     ret = SelectParamCheckCopy(readfds, writefds, exceptfds, &fdsRet);
1157     if (ret != 0) {
1158         return ret;
1159     }
1160 
1161     readfdsRet = fdsRet;        /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */
1162     writefdsRet = fdsRet + 1;   /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */
1163     exceptfdsRet = fdsRet + 2;  /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */
1164 
1165     if (timeout != NULL) {
1166         if (LOS_ArchCopyFromUser(&timeoutRet, timeout, sizeof(struct timeval)) != 0) {
1167             goto ERROUT;
1168         }
1169     }
1170 
1171     ret = do_select(nfds, (readfds ? readfdsRet : NULL), (writefds ? writefdsRet : NULL),
1172                  (exceptfds ? exceptfdsRet : NULL), (timeout ? (&timeoutRet) : NULL), UserPoll);
1173     if (ret < 0) {
1174         (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1175         return -get_errno();
1176     }
1177 
1178     if (readfds != NULL) {
1179         if (LOS_ArchCopyToUser(readfds, readfdsRet, sizeof(fd_set)) != 0) {
1180             goto ERROUT;
1181         }
1182     }
1183 
1184     if (writefds != NULL) {
1185         if (LOS_ArchCopyToUser(writefds, writefdsRet, sizeof(fd_set)) != 0) {
1186             goto ERROUT;
1187         }
1188     }
1189 
1190     if (exceptfds != 0) {
1191         if (LOS_ArchCopyToUser(exceptfds, exceptfdsRet, sizeof(fd_set)) != 0) {
1192             goto ERROUT;
1193         }
1194     }
1195 
1196     (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1197     return ret;
1198 
1199 ERROUT:
1200     (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1201     return -EFAULT;
1202 }
1203 
SysTruncate(const char * path,off_t length)1204 int SysTruncate(const char *path, off_t length)
1205 {
1206     int ret;
1207     int fd = -1;
1208     char *pathRet = NULL;
1209 
1210     if (path != NULL) {
1211         ret = UserPathCopy(path, &pathRet);
1212         if (ret != 0) {
1213             goto OUT;
1214         }
1215     }
1216 
1217     fd = open((path ? pathRet : NULL), O_RDWR);
1218     if (fd < 0) {
1219         /* The errno value has already been set */
1220         ret = -get_errno();
1221         goto OUT;
1222     }
1223 
1224     ret = ftruncate(fd, length);
1225     close(fd);
1226     if (ret < 0) {
1227         ret = -get_errno();
1228     }
1229 
1230 OUT:
1231     if (pathRet != NULL) {
1232         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1233     }
1234     return ret;
1235 }
1236 
SysTruncate64(const char * path,off64_t length)1237 int SysTruncate64(const char *path, off64_t length)
1238 {
1239     int ret;
1240     int fd = -1;
1241     char *pathRet = NULL;
1242 
1243     if (path != NULL) {
1244         ret = UserPathCopy(path, &pathRet);
1245         if (ret != 0) {
1246             goto OUT;
1247         }
1248     }
1249 
1250     fd = open((path ? pathRet : NULL), O_RDWR);
1251     if (fd < 0) {
1252         /* The errno value has already been set */
1253         ret = -get_errno();
1254         goto OUT;
1255     }
1256 
1257     ret = ftruncate64(fd, length);
1258     close(fd);
1259     if (ret < 0) {
1260         ret = -get_errno();
1261     }
1262 
1263 OUT:
1264     if (pathRet != NULL) {
1265         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1266     }
1267     return ret;
1268 }
1269 
SysFtruncate(int fd,off_t length)1270 int SysFtruncate(int fd, off_t length)
1271 {
1272     int ret;
1273 
1274     /* Process fd convert to system global fd */
1275     fd = GetAssociatedSystemFd(fd);
1276 
1277     ret = ftruncate(fd, length);
1278     if (ret < 0) {
1279         return -get_errno();
1280     }
1281     return ret;
1282 }
1283 
SysStatfs(const char * path,struct statfs * buf)1284 int SysStatfs(const char *path, struct statfs *buf)
1285 {
1286     int ret;
1287     char *pathRet = NULL;
1288     struct statfs bufRet = {0};
1289 
1290     if (path != NULL) {
1291         ret = UserPathCopy(path, &pathRet);
1292         if (ret != 0) {
1293             goto OUT;
1294         }
1295     }
1296 
1297     ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1298     if (ret < 0) {
1299         ret = -get_errno();
1300         goto OUT;
1301     }
1302 
1303     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
1304     if (ret != 0) {
1305         ret = -EFAULT;
1306     }
1307 
1308 OUT:
1309     if (pathRet != NULL) {
1310         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1311     }
1312     return ret;
1313 }
1314 
SysStatfs64(const char * path,size_t sz,struct statfs * buf)1315 int SysStatfs64(const char *path, size_t sz, struct statfs *buf)
1316 {
1317     int ret;
1318     char *pathRet = NULL;
1319     struct statfs bufRet = {0};
1320 
1321     if (path != NULL) {
1322         ret = UserPathCopy(path, &pathRet);
1323         if (ret != 0) {
1324             goto OUT;
1325         }
1326     }
1327 
1328     if (sz != sizeof(*buf)) {
1329         ret = -EINVAL;
1330         goto OUT;
1331     }
1332 
1333     ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1334     if (ret < 0) {
1335         ret = -get_errno();
1336         goto OUT;
1337     }
1338 
1339     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
1340     if (ret != 0) {
1341         ret = -EFAULT;
1342     }
1343 
1344 OUT:
1345     if (pathRet != NULL) {
1346         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1347     }
1348     return ret;
1349 }
1350 
SysStat(const char * path,struct kstat * buf)1351 int SysStat(const char *path, struct kstat *buf)
1352 {
1353     int ret;
1354     char *pathRet = NULL;
1355     struct stat bufRet = {0};
1356 
1357     if (path != NULL) {
1358         ret = UserPathCopy(path, &pathRet);
1359         if (ret != 0) {
1360             goto OUT;
1361         }
1362     }
1363 
1364     ret = stat((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1365     if (ret < 0) {
1366         ret = -get_errno();
1367         goto OUT;
1368     }
1369 
1370     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
1371     if (ret != 0) {
1372         ret = -EFAULT;
1373     }
1374 
1375 OUT:
1376     if (pathRet != NULL) {
1377         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1378     }
1379     return ret;
1380 }
1381 
SysLstat(const char * path,struct kstat * buffer)1382 int SysLstat(const char *path, struct kstat *buffer)
1383 {
1384     int ret;
1385     char *pathRet = NULL;
1386     struct stat bufRet = {0};
1387 
1388     if (path != NULL) {
1389         ret = UserPathCopy(path, &pathRet);
1390         if (ret != 0) {
1391             goto OUT;
1392         }
1393     }
1394 
1395     ret = stat((path ? pathRet : NULL), (buffer ? (&bufRet) : NULL));
1396     if (ret < 0) {
1397         ret = -get_errno();
1398         goto OUT;
1399     }
1400 
1401     ret = LOS_ArchCopyToUser(buffer, &bufRet, sizeof(struct kstat));
1402     if (ret != 0) {
1403         ret = -EFAULT;
1404     }
1405 
1406 OUT:
1407     if (pathRet != NULL) {
1408         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1409     }
1410     return ret;
1411 }
1412 
SysFstat(int fd,struct kstat * buf)1413 int SysFstat(int fd, struct kstat *buf)
1414 {
1415     int ret;
1416     struct stat bufRet = {0};
1417     struct file *filep = NULL;
1418 
1419     /* Process fd convert to system global fd */
1420     fd = GetAssociatedSystemFd(fd);
1421 
1422     ret = fs_getfilep(fd, &filep);
1423     if (ret < 0) {
1424         return -get_errno();
1425     }
1426 
1427     if (filep->f_oflags & O_DIRECTORY) {
1428         return -EBADF;
1429     }
1430 
1431     ret = stat(filep->f_path, (buf ? (&bufRet) : NULL));
1432     if (ret < 0) {
1433         return -get_errno();
1434     }
1435 
1436     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
1437     if (ret != 0) {
1438         return -EFAULT;
1439     }
1440 
1441     return ret;
1442 }
1443 
SysStatx(int fd,const char * restrict path,int flag,unsigned mask,struct statx * restrict stx)1444 int SysStatx(int fd, const char *restrict path, int flag, unsigned mask, struct statx *restrict stx)
1445 {
1446     return -ENOSYS;
1447 }
1448 
SysFsync(int fd)1449 int SysFsync(int fd)
1450 {
1451     int ret;
1452     struct file *filep = NULL;
1453 
1454     /* Process fd convert to system global fd */
1455     fd = GetAssociatedSystemFd(fd);
1456 
1457     /* Get the file structure corresponding to the file descriptor. */
1458     ret = fs_getfilep(fd, &filep);
1459     if (ret < 0) {
1460         /* The errno value has already been set */
1461         return -get_errno();
1462     }
1463 
1464     if (filep->f_oflags & O_DIRECTORY) {
1465         return -EBADF;
1466     }
1467 
1468     /* Perform the fsync operation */
1469     ret = file_fsync(filep);
1470     if (ret < 0) {
1471         return -get_errno();
1472     }
1473     return ret;
1474 }
1475 
SysReadv(int fd,const struct iovec * iov,int iovcnt)1476 ssize_t SysReadv(int fd, const struct iovec *iov, int iovcnt)
1477 {
1478     int ret;
1479     int valid_iovcnt = -1;
1480     struct iovec *iovRet = NULL;
1481 
1482     /* Process fd convert to system global fd */
1483     fd = GetAssociatedSystemFd(fd);
1484     if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
1485         return -EINVAL;
1486     }
1487 
1488     if (iovcnt == 0) {
1489         return 0;
1490     }
1491 
1492     ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
1493     if (ret != 0) {
1494         return ret;
1495     }
1496 
1497     if (valid_iovcnt <= 0) {
1498         ret = -EFAULT;
1499         goto OUT;
1500     }
1501 
1502     ret = vfs_readv(fd, iovRet, valid_iovcnt, NULL);
1503     if (ret < 0) {
1504         ret = -get_errno();
1505     }
1506 
1507 OUT:
1508     (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
1509     return ret;
1510 }
1511 
SysWritev(int fd,const struct iovec * iov,int iovcnt)1512 ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt)
1513 {
1514     int ret;
1515     int valid_iovcnt = -1;
1516     struct iovec *iovRet = NULL;
1517 
1518     /* Process fd convert to system global fd */
1519     int sysfd = GetAssociatedSystemFd(fd);
1520     if ((iovcnt < 0) || (iovcnt > IOV_MAX)) {
1521         return -EINVAL;
1522     }
1523 
1524     if (iovcnt == 0) {
1525         return 0;
1526     }
1527 
1528     if (iov == NULL) {
1529         return -EFAULT;
1530     }
1531 
1532     ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
1533     if (ret != 0) {
1534         return ret;
1535     }
1536 
1537     if (valid_iovcnt != iovcnt) {
1538         ret = -EFAULT;
1539         goto OUT_FREE;
1540     }
1541 
1542     ret = writev(sysfd, iovRet, valid_iovcnt);
1543     if (ret < 0) {
1544         ret = -get_errno();
1545     }
1546 
1547 OUT_FREE:
1548     (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
1549     return ret;
1550 }
1551 
SysPoll(struct pollfd * fds,nfds_t nfds,int timeout)1552 int 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 
1590 OUT:
1591     free(pollFds);
1592 OUT_KFD:
1593     free(kfds);
1594     return ret;
1595 }
1596 
SysPrctl(int option,...)1597 int 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 
1624 ERROR:
1625     va_end(ap);
1626     return -err;
1627 }
1628 
SysPread64(int fd,void * buf,size_t nbytes,off64_t offset)1629 ssize_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     (void)memset_s(bufRet, nbytes, 0, nbytes);
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 
SysPwrite64(int fd,const void * buf,size_t nbytes,off64_t offset)1667 ssize_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 
SysGetcwd(char * buf,size_t n)1706 char *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 
SysSendFile(int outfd,int infd,off_t * offset,size_t count)1740 ssize_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 
SysFtruncate64(int fd,off64_t length)1767 int 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 
SysOpenat(int dirfd,const char * path,int oflags,...)1781 int 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 
1831 ERROUT:
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 
SysMkdirat(int dirfd,const char * pathname,mode_t mode)1841 int 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 
1863 OUT:
1864     if (pathRet != NULL) {
1865         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1866     }
1867     return ret;
1868 }
1869 
SysLinkat(int olddirfd,const char * oldpath,int newdirfd,const char * newpath,int flags)1870 int 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 
1905 OUT:
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 
SysSymlinkat(const char * target,int dirfd,const char * linkpath)1915 int 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 
1945 OUT:
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 
SysReadlinkat(int dirfd,const char * pathname,char * buf,size_t bufsize)1956 ssize_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 #ifdef LOSCFG_PID_CONTAINER
1972 #ifdef LOSCFG_PROC_PROCESS_DIR
1973         ret = ProcRealProcessDirGet(pathRet);
1974         if (ret != 0) {
1975             goto OUT;
1976         }
1977 #endif
1978 #endif
1979     }
1980 
1981     if (dirfd != AT_FDCWD) {
1982         /* Process fd convert to system global fd */
1983         dirfd = GetAssociatedSystemFd(dirfd);
1984     }
1985 
1986     if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) {
1987         ret = -EFAULT;
1988         goto OUT;
1989     }
1990 
1991     ret = readlinkat(dirfd, pathRet, buf, bufsize);
1992     if (ret < 0) {
1993         ret = -get_errno();
1994     }
1995 
1996 OUT:
1997     if (pathRet != NULL) {
1998         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1999     }
2000     return ret;
2001 }
2002 
SysUnlinkat(int dirfd,const char * pathname,int flag)2003 int SysUnlinkat(int dirfd, const char *pathname, int flag)
2004 {
2005     int ret;
2006     char *pathRet = NULL;
2007 
2008     if (pathname != NULL) {
2009         ret = UserPathCopy(pathname, &pathRet);
2010         if (ret != 0) {
2011             goto OUT;
2012         }
2013     }
2014 
2015     if (dirfd != AT_FDCWD) {
2016         /* Process fd convert to system global fd */
2017         dirfd = GetAssociatedSystemFd(dirfd);
2018     }
2019 
2020     ret = unlinkat(dirfd, (pathname ? pathRet : NULL), flag);
2021     if (ret < 0) {
2022         ret = -get_errno();
2023     }
2024 
2025 OUT:
2026     if (pathRet != NULL) {
2027         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2028     }
2029     return ret;
2030 }
2031 
SysRenameat(int oldfd,const char * oldpath,int newdfd,const char * newpath)2032 int SysRenameat(int oldfd, const char *oldpath, int newdfd, const char *newpath)
2033 {
2034     int ret;
2035     char *pathOldRet = NULL;
2036     char *pathNewRet = NULL;
2037 
2038     if (oldpath != NULL) {
2039         ret = UserPathCopy(oldpath, &pathOldRet);
2040         if (ret != 0) {
2041             goto OUT;
2042         }
2043     }
2044 
2045     if (newpath != NULL) {
2046         ret = UserPathCopy(newpath, &pathNewRet);
2047         if (ret != 0) {
2048             goto OUT;
2049         }
2050     }
2051 
2052     if (oldfd != AT_FDCWD) {
2053         /* Process fd convert to system global fd */
2054         oldfd = GetAssociatedSystemFd(oldfd);
2055     }
2056     if (newdfd != AT_FDCWD) {
2057         /* Process fd convert to system global fd */
2058         newdfd = GetAssociatedSystemFd(newdfd);
2059     }
2060 
2061     ret = do_rename(oldfd, (oldpath ? pathOldRet : NULL), newdfd, (newpath ? pathNewRet : NULL));
2062     if (ret < 0) {
2063         ret = -get_errno();
2064     }
2065 
2066 OUT:
2067     if (pathOldRet != NULL) {
2068         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet);
2069     }
2070     if (pathNewRet != NULL) {
2071         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet);
2072     }
2073     return ret;
2074 }
2075 
SysFallocate(int fd,int mode,off_t offset,off_t len)2076 int SysFallocate(int fd, int mode, off_t offset, off_t len)
2077 {
2078     int ret;
2079 
2080     /* Process fd convert to system global fd */
2081     fd = GetAssociatedSystemFd(fd);
2082 
2083     ret = fallocate(fd, mode, offset, len);
2084     if (ret < 0) {
2085         return -get_errno();
2086     }
2087     return ret;
2088 }
2089 
SysFallocate64(int fd,int mode,off64_t offset,off64_t len)2090 int SysFallocate64(int fd, int mode, off64_t offset, off64_t len)
2091 {
2092     int ret;
2093 
2094     /* Process fd convert to system global fd */
2095     fd = GetAssociatedSystemFd(fd);
2096 
2097     ret = fallocate64(fd, mode, offset, len);
2098     if (ret < 0) {
2099         return -get_errno();
2100     }
2101     return ret;
2102 }
2103 
SysPreadv(int fd,const struct iovec * iov,int iovcnt,long loffset,long hoffset)2104 ssize_t SysPreadv(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
2105 {
2106     off_t offsetflag;
2107     offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT));
2108 
2109     int ret;
2110     int valid_iovcnt = -1;
2111     struct iovec *iovRet = NULL;
2112 
2113     /* Process fd convert to system global fd */
2114     fd = GetAssociatedSystemFd(fd);
2115     if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
2116         return -EINVAL;
2117     }
2118 
2119     if (iovcnt == 0) {
2120         return 0;
2121     }
2122 
2123     ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
2124     if (ret != 0) {
2125         return ret;
2126     }
2127 
2128     if (valid_iovcnt <= 0) {
2129         ret = -EFAULT;
2130         goto OUT_FREE;
2131     }
2132 
2133     ret = preadv(fd, iovRet, valid_iovcnt, offsetflag);
2134     if (ret < 0) {
2135         ret = -get_errno();
2136     }
2137 
2138 OUT_FREE:
2139     (void)(void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
2140     return ret;
2141 }
2142 
SysPwritev(int fd,const struct iovec * iov,int iovcnt,long loffset,long hoffset)2143 ssize_t SysPwritev(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
2144 {
2145     off_t offsetflag;
2146     offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT));
2147     int ret;
2148     int valid_iovcnt = -1;
2149     struct iovec *iovRet = NULL;
2150 
2151     /* Process fd convert to system global fd */
2152     fd = GetAssociatedSystemFd(fd);
2153     if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
2154         return -EINVAL;
2155     }
2156 
2157     if (iovcnt == 0) {
2158         return 0;
2159     }
2160 
2161     ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
2162     if (ret != 0) {
2163         return ret;
2164     }
2165 
2166     if (valid_iovcnt != iovcnt) {
2167         ret = -EFAULT;
2168         goto OUT_FREE;
2169     }
2170 
2171     ret = pwritev(fd, iovRet, valid_iovcnt, offsetflag);
2172     if (ret < 0) {
2173         ret = -get_errno();
2174     }
2175 
2176 OUT_FREE:
2177     (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
2178     return ret;
2179 }
2180 
2181 #ifdef LOSCFG_FS_FAT
SysFormat(const char * dev,int sectors,int option)2182 int SysFormat(const char *dev, int sectors, int option)
2183 {
2184     int ret;
2185     char *devRet = NULL;
2186 
2187     if (!IsCapPermit(CAP_FS_FORMAT)) {
2188         return -EPERM;
2189     }
2190 
2191     if (dev != NULL) {
2192         ret = UserPathCopy(dev, &devRet);
2193         if (ret != 0) {
2194             goto OUT;
2195         }
2196     }
2197 
2198     ret = format((dev ? devRet : NULL), sectors, option);
2199     if (ret < 0) {
2200         ret = -get_errno();
2201     }
2202 
2203 OUT:
2204     if (devRet != NULL) {
2205         (void)LOS_MemFree(OS_SYS_MEM_ADDR, devRet);
2206     }
2207     return ret;
2208 }
2209 #endif
2210 
SysFstat64(int fd,struct kstat * buf)2211 int SysFstat64(int fd, struct kstat *buf)
2212 {
2213     int ret;
2214     struct stat64 bufRet = {0};
2215 
2216     /* Process fd convert to system global fd */
2217     fd = GetAssociatedSystemFd(fd);
2218 
2219     ret = fstat64(fd, (buf ? (&bufRet) : NULL));
2220     if (ret < 0) {
2221         return -get_errno();
2222     }
2223 
2224     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
2225     if (ret != 0) {
2226         return -EFAULT;
2227     }
2228 
2229     return ret;
2230 }
2231 
SysFcntl64(int fd,int cmd,void * arg)2232 int SysFcntl64(int fd, int cmd, void *arg)
2233 {
2234     /* Process fd convert to system global fd */
2235     int sysfd = GetAssociatedSystemFd(fd);
2236 
2237     int ret = VfsFcntl(fd, cmd, arg);
2238     if (ret == CONTINE_NUTTX_FCNTL) {
2239         ret = fcntl64(sysfd, cmd, arg);
2240     }
2241 
2242     if (ret < 0) {
2243         return -get_errno();
2244     }
2245     return ret;
2246 }
2247 
SysGetdents64(int fd,struct dirent * de_user,unsigned int count)2248 int SysGetdents64(int fd, struct dirent *de_user, unsigned int count)
2249 {
2250     if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)de_user, count)) {
2251         return -EFAULT;
2252     }
2253 
2254     struct dirent *de_knl = NULL;
2255 
2256     /* Process fd convert to system global fd */
2257     fd = GetAssociatedSystemFd(fd);
2258 
2259     int ret = do_readdir(fd, &de_knl, count);
2260     if (ret < 0) {
2261         return ret;
2262     }
2263     if (de_knl != NULL) {
2264         int cpy_ret = LOS_ArchCopyToUser(de_user, de_knl, ret);
2265         if (cpy_ret != 0)
2266         {
2267             return -EFAULT;
2268         }
2269     }
2270     return ret;
2271 }
2272 
SysRealpath(const char * path,char * resolved_path)2273 char *SysRealpath(const char *path, char *resolved_path)
2274 {
2275     char *pathRet = NULL;
2276     char *resolved_pathRet = NULL;
2277     char *result = NULL;
2278     int ret;
2279 
2280     if (resolved_path == NULL) {
2281         return (char *)(intptr_t)-EINVAL;
2282     }
2283 
2284     if (path != NULL) {
2285         ret = UserPathCopy(path, &pathRet);
2286         if (ret != 0) {
2287             result = (char *)(intptr_t)ret;
2288             goto OUT;
2289         }
2290     }
2291 
2292     resolved_pathRet = realpath((path ? pathRet : NULL), NULL);
2293     if (resolved_pathRet == NULL) {
2294         result = (char *)(intptr_t)-get_errno();
2295         goto OUT;
2296     }
2297 
2298     ret = LOS_ArchCopyToUser(resolved_path, resolved_pathRet, strlen(resolved_pathRet) + 1);
2299     if (ret != 0) {
2300         result = (char *)(intptr_t)-EFAULT;
2301         goto OUT;
2302     }
2303     result = resolved_path;
2304 
2305 OUT:
2306     if (pathRet != NULL) {
2307         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2308     }
2309     if (resolved_pathRet != NULL) {
2310         (void)LOS_MemFree(OS_SYS_MEM_ADDR, resolved_pathRet);
2311     }
2312     return result;
2313 }
2314 
SysUtimensat(int fd,const char * path,struct timespec times[TIMESPEC_TIMES_NUM],int flag)2315 int SysUtimensat(int fd, const char *path, struct timespec times[TIMESPEC_TIMES_NUM], int flag)
2316 {
2317     int ret;
2318     int timeLen;
2319     struct IATTR attr = {0};
2320     char *filePath = NULL;
2321 
2322     timeLen = TIMESPEC_TIMES_NUM * sizeof(struct timespec);
2323     CHECK_ASPACE(times, timeLen);
2324     DUP_FROM_USER(times, timeLen);
2325     ret = CheckNewAttrTime(&attr, times);
2326     FREE_DUP(times);
2327     if (ret < 0) {
2328         goto OUT;
2329     }
2330 
2331     ret = GetFullpathNull(fd, path, &filePath);
2332     if (ret < 0) {
2333         goto OUT;
2334     }
2335 
2336     ret = chattr(filePath, &attr);
2337     if (ret < 0) {
2338         ret = -get_errno();
2339     }
2340 
2341 OUT:
2342     PointerFree(filePath);
2343     return ret;
2344 }
2345 
SysChmod(const char * pathname,mode_t mode)2346 int SysChmod(const char *pathname, mode_t mode)
2347 {
2348     int ret;
2349     char *pathRet = NULL;
2350 
2351     if (pathname != NULL) {
2352         ret = UserPathCopy(pathname, &pathRet);
2353         if (ret != 0) {
2354             goto OUT;
2355         }
2356     }
2357 
2358     ret = chmod(pathRet, mode);
2359     if (ret < 0) {
2360         ret = -get_errno();
2361     }
2362 
2363 OUT:
2364     if (pathRet != NULL) {
2365         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2366     }
2367     return ret;
2368 }
2369 
SysFchmodat(int fd,const char * path,mode_t mode,int flag)2370 int SysFchmodat(int fd, const char *path, mode_t mode, int flag)
2371 {
2372     int ret;
2373     char *pathRet = NULL;
2374     char *fullpath = NULL;
2375     struct IATTR attr = {
2376         .attr_chg_mode = mode,
2377         .attr_chg_valid = CHG_MODE,
2378     };
2379 
2380     if (path != NULL) {
2381         ret = UserPathCopy(path, &pathRet);
2382         if (ret != 0) {
2383             goto OUT;
2384         }
2385     }
2386 
2387     if (fd != AT_FDCWD) {
2388         /* Process fd convert to system global fd */
2389         fd = GetAssociatedSystemFd(fd);
2390     }
2391 
2392     ret = vfs_normalize_pathat(fd, pathRet, &fullpath);
2393     if (ret < 0) {
2394         goto OUT;
2395     }
2396 
2397     ret = chattr(fullpath, &attr);
2398     if (ret < 0) {
2399         ret = -get_errno();
2400     }
2401 
2402 OUT:
2403     PointerFree(pathRet);
2404     PointerFree(fullpath);
2405 
2406     return ret;
2407 }
2408 
SysFchmod(int fd,mode_t mode)2409 int SysFchmod(int fd, mode_t mode)
2410 {
2411     int ret;
2412     int sysFd;
2413     struct IATTR attr = {
2414         .attr_chg_mode = mode,
2415         .attr_chg_valid = CHG_MODE, /* change mode */
2416     };
2417     struct file *file = NULL;
2418 
2419     sysFd = GetAssociatedSystemFd(fd);
2420     if (sysFd < 0) {
2421         return -EBADF;
2422     }
2423 
2424     ret = fs_getfilep(sysFd, &file);
2425     if (ret < 0) {
2426         return -get_errno();
2427     }
2428 
2429     ret = chattr(file->f_path, &attr);
2430     if (ret < 0) {
2431         return -get_errno();
2432     }
2433 
2434     return ret;
2435 }
2436 
SysFchownat(int fd,const char * path,uid_t owner,gid_t group,int flag)2437 int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
2438 {
2439     int ret;
2440     char *fullpath = NULL;
2441     struct IATTR attr = {
2442         .attr_chg_valid = 0,
2443     };
2444 
2445     ret = GetFullpath(fd, path, &fullpath);
2446     if (ret < 0) {
2447         goto OUT;
2448     }
2449 
2450     if (owner != (uid_t)-1) {
2451         attr.attr_chg_uid = owner;
2452         attr.attr_chg_valid |= CHG_UID;
2453     }
2454     if (group != (gid_t)-1) {
2455         attr.attr_chg_gid = group;
2456         attr.attr_chg_valid |= CHG_GID;
2457     }
2458 
2459     ret = chattr(fullpath, &attr);
2460     if (ret < 0) {
2461         ret = -get_errno();
2462     }
2463 
2464 OUT:
2465     PointerFree(fullpath);
2466 
2467     return ret;
2468 }
2469 
SysFchown(int fd,uid_t owner,gid_t group)2470 int SysFchown(int fd, uid_t owner, gid_t group)
2471 {
2472     int ret;
2473     int sysFd;
2474     struct IATTR attr = {0};
2475     attr.attr_chg_valid = 0;
2476     struct file *file = NULL;
2477 
2478     sysFd = GetAssociatedSystemFd(fd);
2479     if (sysFd < 0) {
2480         return -EBADF;
2481     }
2482 
2483     ret = fs_getfilep(sysFd, &file);
2484     if (ret < 0) {
2485         return -get_errno();
2486     }
2487 
2488     if (owner != (uid_t)-1) {
2489         attr.attr_chg_uid = owner;
2490         attr.attr_chg_valid |= CHG_UID;
2491     }
2492     if (group != (gid_t)-1) {
2493         attr.attr_chg_gid = group;
2494         attr.attr_chg_valid |= CHG_GID;
2495     }
2496     ret = chattr(file->f_path, &attr);
2497     if (ret < 0) {
2498         ret = -get_errno();
2499     }
2500 
2501     return ret;
2502 }
2503 
SysChown(const char * pathname,uid_t owner,gid_t group)2504 int SysChown(const char *pathname, uid_t owner, gid_t group)
2505 {
2506     int ret;
2507     char *pathRet = NULL;
2508 
2509     if (pathname != NULL) {
2510         ret = UserPathCopy(pathname, &pathRet);
2511         if (ret != 0) {
2512             goto OUT;
2513         }
2514     }
2515 
2516     ret = chown(pathRet, owner, group);
2517     if (ret < 0) {
2518         ret = -get_errno();
2519     }
2520 
2521 OUT:
2522     if (pathRet != NULL) {
2523         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2524     }
2525     return ret;
2526 }
2527 
SysFstatat64(int dirfd,const char * restrict path,struct kstat * restrict buf,int flag)2528 int SysFstatat64(int dirfd, const char *restrict path, struct kstat *restrict buf, int flag)
2529 {
2530     int ret;
2531     struct stat bufRet = {0};
2532     char *pathRet = NULL;
2533     char *fullpath = NULL;
2534 
2535     if (path != NULL) {
2536         ret = UserPathCopy(path, &pathRet);
2537         if (ret != 0) {
2538             goto OUT;
2539         }
2540     }
2541 
2542     if (dirfd != AT_FDCWD) {
2543         /* Process fd convert to system global fd */
2544         dirfd = GetAssociatedSystemFd(dirfd);
2545     }
2546 
2547     ret = vfs_normalize_pathat(dirfd, pathRet, &fullpath);
2548     if (ret < 0) {
2549         goto OUT;
2550     }
2551 
2552     ret = stat(fullpath, &bufRet);
2553     if (ret < 0) {
2554         ret = -get_errno();
2555         goto OUT;
2556     }
2557 
2558     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
2559     if (ret != 0) {
2560         ret = -EFAULT;
2561         goto OUT;
2562     }
2563 
2564 OUT:
2565     if (pathRet != NULL) {
2566         LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2567     }
2568 
2569     if (fullpath != NULL) {
2570         free(fullpath);
2571     }
2572     return ret;
2573 }
2574 
SysFaccessat(int fd,const char * filename,int amode,int flag)2575 int SysFaccessat(int fd, const char *filename, int amode, int flag)
2576 {
2577     int ret;
2578     struct stat buf;
2579     struct statfs fsBuf;
2580     char *fullDirectory = NULL;
2581 
2582     ret = GetFullpath(fd, filename, &fullDirectory);
2583     if (ret < 0) {
2584         goto OUT;
2585     }
2586 
2587     ret = statfs(fullDirectory, &fsBuf);
2588     if (ret != 0) {
2589         ret = -get_errno();
2590         goto OUT;
2591     }
2592 
2593     if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) {
2594         ret = -EROFS;
2595         goto OUT;
2596     }
2597 
2598     ret = stat(fullDirectory, &buf);
2599     if (ret != 0) {
2600         ret = -get_errno();
2601         goto OUT;
2602     }
2603 
2604     if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) {
2605         ret = -EACCES;
2606     }
2607 
2608 OUT:
2609     PointerFree(fullDirectory);
2610 
2611     return ret;
2612 }
2613 
SysFstatfs(int fd,struct statfs * buf)2614 int SysFstatfs(int fd, struct statfs *buf)
2615 {
2616     int ret;
2617     struct file *filep = NULL;
2618     struct statfs bufRet = {0};
2619 
2620     /* Process fd convert to system global fd */
2621     fd = GetAssociatedSystemFd(fd);
2622 
2623     ret = fs_getfilep(fd, &filep);
2624     if (ret < 0) {
2625         ret = -get_errno();
2626         return ret;
2627     }
2628 
2629     ret = statfs(filep->f_path, &bufRet);
2630     if (ret < 0) {
2631         ret = -get_errno();
2632         return ret;
2633     }
2634 
2635     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
2636     if (ret != 0) {
2637         ret = -EFAULT;
2638     }
2639 
2640     return ret;
2641 }
2642 
SysFstatfs64(int fd,size_t sz,struct statfs * buf)2643 int SysFstatfs64(int fd, size_t sz, struct statfs *buf)
2644 {
2645     int ret;
2646 
2647     if (sz != sizeof(struct statfs)) {
2648         ret = -EINVAL;
2649         return ret;
2650     }
2651 
2652     ret = SysFstatfs(fd, buf);
2653 
2654     return ret;
2655 }
2656 
SysPpoll(struct pollfd * fds,nfds_t nfds,const struct timespec * tmo_p,const sigset_t * sigMask,int nsig)2657 int SysPpoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigMask, int nsig)
2658 {
2659     int timeout, retVal;
2660     sigset_t_l origMask = {0};
2661     sigset_t_l set = {0};
2662 
2663     CHECK_ASPACE(tmo_p, sizeof(struct timespec));
2664     CPY_FROM_USER(tmo_p);
2665 
2666     if (tmo_p != NULL) {
2667         timeout = tmo_p->tv_sec * OS_SYS_US_PER_MS + tmo_p->tv_nsec / OS_SYS_NS_PER_MS;
2668         if (timeout < 0) {
2669             return -EINVAL;
2670         }
2671     } else {
2672         timeout = -1;
2673     }
2674 
2675     if (sigMask != NULL) {
2676         retVal = LOS_ArchCopyFromUser(&set, sigMask, sizeof(sigset_t));
2677         if (retVal != 0) {
2678             return -EFAULT;
2679         }
2680         (VOID)OsSigprocMask(SIG_SETMASK, &set, &origMask);
2681     } else {
2682         (VOID)OsSigprocMask(SIG_SETMASK, NULL, &origMask);
2683     }
2684 
2685     retVal = SysPoll(fds, nfds, timeout);
2686     (VOID)OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2687 
2688     return retVal;
2689 }
2690 
SysPselect6(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,const struct timespec * timeout,const long data[2])2691 int SysPselect6(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
2692     const struct timespec *timeout, const long data[2])
2693 {
2694     int ret;
2695     int retVal;
2696     sigset_t_l origMask;
2697     sigset_t_l setl;
2698 
2699     CHECK_ASPACE(readfds, sizeof(fd_set));
2700     CHECK_ASPACE(writefds, sizeof(fd_set));
2701     CHECK_ASPACE(exceptfds, sizeof(fd_set));
2702     CHECK_ASPACE(timeout, sizeof(struct timeval));
2703 
2704     CPY_FROM_USER(readfds);
2705     CPY_FROM_USER(writefds);
2706     CPY_FROM_USER(exceptfds);
2707     DUP_FROM_USER(timeout, sizeof(struct timeval));
2708 
2709     if (timeout != NULL) {
2710         ((struct timeval *)timeout)->tv_usec = timeout->tv_nsec / 1000; /* 1000, convert ns to us */
2711     }
2712 
2713     if (data != NULL) {
2714         retVal = LOS_ArchCopyFromUser(&(setl.sig[0]), (int *)((UINTPTR)data[0]), sizeof(sigset_t));
2715         if (retVal != 0) {
2716             ret = -EFAULT;
2717             FREE_DUP(timeout);
2718             return ret;
2719         }
2720     }
2721 
2722     OsSigprocMask(SIG_SETMASK, &setl, &origMask);
2723     ret = do_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout, UserPoll);
2724     if (ret < 0) {
2725         /* do not copy parameter back to user mode if do_select failed */
2726         ret = -get_errno();
2727         FREE_DUP(timeout);
2728         return ret;
2729     }
2730     OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2731 
2732     CPY_TO_USER(readfds);
2733     CPY_TO_USER(writefds);
2734     CPY_TO_USER(exceptfds);
2735     FREE_DUP(timeout);
2736 
2737     return ret;
2738 }
2739 
DoEpollCreate1(int flags)2740 static int DoEpollCreate1(int flags)
2741 {
2742     int ret;
2743     int procFd;
2744 
2745     ret = epoll_create1(flags);
2746     if (ret < 0) {
2747         ret = -get_errno();
2748         return ret;
2749     }
2750 
2751     procFd = AllocAndAssocProcessFd((INTPTR)(ret), MIN_START_FD);
2752     if (procFd == -1) {
2753         epoll_close(ret);
2754         return -EMFILE;
2755     }
2756 
2757     return procFd;
2758 }
2759 
SysEpollCreate(int size)2760 int SysEpollCreate(int size)
2761 {
2762     (void)size;
2763     return DoEpollCreate1(0);
2764 }
2765 
SysEpollCreate1(int flags)2766 int SysEpollCreate1(int flags)
2767 {
2768     return DoEpollCreate1(flags);
2769 }
2770 
SysEpollCtl(int epfd,int op,int fd,struct epoll_event * ev)2771 int SysEpollCtl(int epfd, int op, int fd, struct epoll_event *ev)
2772 {
2773     int ret;
2774 
2775     CHECK_ASPACE(ev, sizeof(struct epoll_event));
2776     CPY_FROM_USER(ev);
2777 
2778     fd = GetAssociatedSystemFd(fd);
2779     epfd = GetAssociatedSystemFd(epfd);
2780     if ((fd < 0) || (epfd < 0)) {
2781         ret = -EBADF;
2782         goto OUT;
2783     }
2784 
2785     ret = epoll_ctl(epfd, op, fd, ev);
2786     if (ret < 0) {
2787         ret = -EBADF;
2788         goto OUT;
2789     }
2790 
2791     CPY_TO_USER(ev);
2792 OUT:
2793     return (ret == -1) ? -get_errno() : ret;
2794 }
2795 
SysEpollWait(int epfd,struct epoll_event * evs,int maxevents,int timeout)2796 int SysEpollWait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
2797 {
2798     int ret = 0;
2799 
2800     CHECK_ASPACE(evs, sizeof(struct epoll_event));
2801     CPY_FROM_USER(evs);
2802 
2803     epfd = GetAssociatedSystemFd(epfd);
2804     if  (epfd < 0) {
2805         ret = -EBADF;
2806         goto OUT;
2807     }
2808 
2809     ret = epoll_wait(epfd, evs, maxevents, timeout);
2810     if (ret < 0) {
2811         ret = -get_errno();
2812     }
2813 
2814     CPY_TO_USER(evs);
2815 OUT:
2816     return (ret == -1) ? -get_errno() : ret;
2817 }
2818 
SysEpollPwait(int epfd,struct epoll_event * evs,int maxevents,int timeout,const sigset_t * mask)2819 int SysEpollPwait(int epfd, struct epoll_event *evs, int maxevents, int timeout, const sigset_t *mask)
2820 {
2821     sigset_t_l origMask;
2822     sigset_t_l setl;
2823     int ret = 0;
2824 
2825     CHECK_ASPACE(mask, sizeof(sigset_t));
2826 
2827     if (mask != NULL) {
2828         ret = LOS_ArchCopyFromUser(&setl, mask, sizeof(sigset_t));
2829         if (ret != 0) {
2830             return -EFAULT;
2831         }
2832     }
2833 
2834     CHECK_ASPACE(evs, sizeof(struct epoll_event));
2835     CPY_FROM_USER(evs);
2836 
2837     epfd = GetAssociatedSystemFd(epfd);
2838     if (epfd < 0) {
2839         ret = -EBADF;
2840         goto OUT;
2841     }
2842 
2843     OsSigprocMask(SIG_SETMASK, &setl, &origMask);
2844     ret = epoll_wait(epfd, evs, maxevents, timeout);
2845     if (ret < 0) {
2846         ret = -get_errno();
2847     }
2848 
2849     OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2850 
2851     CPY_TO_USER(evs);
2852 OUT:
2853     return (ret == -1) ? -get_errno() : ret;
2854 }
2855 
2856 #ifdef LOSCFG_CHROOT
SysChroot(const char * path)2857 int SysChroot(const char *path)
2858 {
2859     int ret;
2860     char *pathRet = NULL;
2861 
2862     if (path != NULL) {
2863         ret = UserPathCopy(path, &pathRet);
2864         if (ret != 0) {
2865             goto OUT;
2866         }
2867     }
2868 
2869     ret = chroot(path ? pathRet : NULL);
2870     if (ret < 0) {
2871         ret = -get_errno();
2872     }
2873 OUT:
2874     if (pathRet != NULL) {
2875         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2876     }
2877     return ret;
2878 }
2879 #endif
2880 #endif
2881