• 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 
SysOpen(const char * path,int oflags,...)294 int 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 #ifdef LOSCFG_FILE_MODE
322         va_list ap;
323         va_start(ap, oflags);
324         mode = va_arg(ap, int);
325         va_end(ap);
326 #endif
327 
328         ret = do_open(AT_FDCWD, pathRet, oflags, mode);
329     }
330 
331     if (ret < 0) {
332         ret = -get_errno();
333         goto ERROUT;
334     }
335 
336     AssociateSystemFd(procFd, ret);
337     if (pathRet != NULL) {
338         LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
339     }
340     return procFd;
341 
342 ERROUT:
343     if (pathRet != NULL) {
344         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
345     }
346     if (procFd >= 0) {
347         FreeProcessFd(procFd);
348     }
349     return ret;
350 }
351 
SysCreat(const char * pathname,mode_t mode)352 int SysCreat(const char *pathname, mode_t mode)
353 {
354     int ret = 0;
355     char *pathRet = NULL;
356 
357     if (pathname != NULL) {
358         ret = UserPathCopy(pathname, &pathRet);
359         if (ret != 0) {
360             goto OUT;
361         }
362     }
363 
364     int procFd = AllocProcessFd();
365     if (procFd  < 0) {
366         ret = -EMFILE;
367         goto OUT;
368     }
369 
370     ret = open((pathname ? pathRet : NULL), O_CREAT | O_TRUNC | O_WRONLY, mode);
371     if (ret < 0) {
372         FreeProcessFd(procFd);
373         ret = -get_errno();
374     } else {
375         AssociateSystemFd(procFd, ret);
376         ret = procFd;
377     }
378 
379 OUT:
380     if (pathRet != NULL) {
381         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
382     }
383     return ret;
384 }
385 
SysLink(const char * oldpath,const char * newpath)386 int SysLink(const char *oldpath, const char *newpath)
387 {
388     int ret;
389     char *oldpathRet = NULL;
390     char *newpathRet = NULL;
391 
392     if (oldpath != NULL) {
393         ret = UserPathCopy(oldpath, &oldpathRet);
394         if (ret != 0) {
395             goto OUT;
396         }
397     }
398 
399     if (newpath != NULL) {
400         ret = UserPathCopy(newpath, &newpathRet);
401         if (ret != 0) {
402             goto OUT;
403         }
404     }
405 
406     ret = link(oldpathRet, newpathRet);
407     if (ret < 0) {
408         ret = -get_errno();
409     }
410 
411 OUT:
412     if (oldpathRet != NULL) {
413         (void)LOS_MemFree(OS_SYS_MEM_ADDR, oldpathRet);
414     }
415     if (newpathRet != NULL) {
416         (void)LOS_MemFree(OS_SYS_MEM_ADDR, newpathRet);
417     }
418     return ret;
419 }
420 
SysReadlink(const char * pathname,char * buf,size_t bufsize)421 ssize_t SysReadlink(const char *pathname, char *buf, size_t bufsize)
422 {
423     ssize_t ret;
424     char *pathRet = NULL;
425 
426     if (bufsize == 0) {
427         return -EINVAL;
428     }
429 
430     if (pathname != NULL) {
431         ret = UserPathCopy(pathname, &pathRet);
432         if (ret != 0) {
433             goto OUT;
434         }
435     }
436 
437     if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) {
438         ret = -EFAULT;
439         goto OUT;
440     }
441 
442     ret = readlink(pathRet, buf, bufsize);
443     if (ret < 0) {
444         ret = -get_errno();
445     }
446 
447 OUT:
448     if (pathRet != NULL) {
449         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
450     }
451     return ret;
452 }
453 
SysSymlink(const char * target,const char * linkpath)454 int SysSymlink(const char *target, const char *linkpath)
455 {
456     int ret;
457     char *targetRet = NULL;
458     char *pathRet = NULL;
459 
460     if (target != NULL) {
461         ret = UserPathCopy(target, &targetRet);
462         if (ret != 0) {
463             goto OUT;
464         }
465     }
466 
467     if (linkpath != NULL) {
468         ret = UserPathCopy(linkpath, &pathRet);
469         if (ret != 0) {
470             goto OUT;
471         }
472     }
473 
474     ret = symlink(targetRet, pathRet);
475     if (ret < 0) {
476         ret = -get_errno();
477     }
478 
479 OUT:
480     if (pathRet != NULL) {
481         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
482     }
483 
484     if (targetRet != NULL) {
485         (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
486     }
487     return ret;
488 }
489 
SysUnlink(const char * pathname)490 int SysUnlink(const char *pathname)
491 {
492     int ret;
493     char *pathRet = NULL;
494 
495     if (pathname != NULL) {
496         ret = UserPathCopy(pathname, &pathRet);
497         if (ret != 0) {
498             goto OUT;
499         }
500     }
501 
502     ret = do_unlink(AT_FDCWD, (pathname ? pathRet : NULL));
503     if (ret < 0) {
504         ret = -get_errno();
505     }
506 
507 OUT:
508     if (pathRet != NULL) {
509         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
510     }
511     return ret;
512 }
513 
514 #ifdef LOSCFG_KERNEL_DYNLOAD
SysExecve(const char * fileName,char * const * argv,char * const * envp)515 int SysExecve(const char *fileName, char *const *argv, char *const *envp)
516 {
517     return LOS_DoExecveFile(fileName, argv, envp);
518 }
519 #endif
520 
SysFchdir(int fd)521 int SysFchdir(int fd)
522 {
523     int ret;
524     int sysFd;
525     struct file *file = NULL;
526 
527     sysFd = GetAssociatedSystemFd(fd);
528     if (sysFd < 0) {
529         return -EBADF;
530     }
531 
532     ret = fs_getfilep(sysFd, &file);
533     if (ret < 0) {
534         return -get_errno();
535     }
536 
537     ret = chdir(file->f_path);
538     if (ret < 0) {
539         ret = -get_errno();
540     }
541 
542     return ret;
543 }
544 
SysChdir(const char * path)545 int SysChdir(const char *path)
546 {
547     int ret;
548     char *pathRet = NULL;
549 
550     if (path != NULL) {
551         ret = UserPathCopy(path, &pathRet);
552         if (ret != 0) {
553             goto OUT;
554         }
555     }
556 
557     ret = chdir(path ? pathRet : NULL);
558     if (ret < 0) {
559         ret = -get_errno();
560     }
561 
562 OUT:
563     if (pathRet != NULL) {
564         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
565     }
566     return ret;
567 }
568 
SysLseek(int fd,off_t offset,int whence)569 off_t SysLseek(int fd, off_t offset, int whence)
570 {
571     /* Process fd convert to system global fd */
572     fd = GetAssociatedSystemFd(fd);
573 
574     return _lseek(fd, offset, whence);
575 }
576 
SysLseek64(int fd,int offsetHigh,int offsetLow,off64_t * result,int whence)577 off64_t SysLseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence)
578 {
579     off64_t ret;
580     off64_t res;
581     int retVal;
582 
583     /* Process fd convert to system global fd */
584     fd = GetAssociatedSystemFd(fd);
585 
586     ret = _lseek64(fd, offsetHigh, offsetLow, &res, whence);
587     if (ret != 0) {
588         return ret;
589     }
590 
591     retVal = LOS_ArchCopyToUser(result, &res, sizeof(off64_t));
592     if (retVal != 0) {
593         return -EFAULT;
594     }
595 
596     return 0;
597 }
598 
599 #ifdef LOSCFG_FS_NFS
600 static int NfsMountRef(const char *serverIpAndPath, const char *mountPath,
601                        unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount")));
602 
NfsMount(const char * serverIpAndPath,const char * mountPath,unsigned int uid,unsigned int gid)603 static int NfsMount(const char *serverIpAndPath, const char *mountPath,
604                     unsigned int uid, unsigned int gid)
605 {
606     int ret;
607 
608     if ((serverIpAndPath == NULL) || (mountPath == NULL)) {
609         return -EINVAL;
610     }
611     ret = NfsMountRef(serverIpAndPath, mountPath, uid, gid);
612     if (ret < 0) {
613         ret = -get_errno();
614     }
615     return ret;
616 }
617 #endif
618 
SysMount(const char * source,const char * target,const char * filesystemtype,unsigned long mountflags,const void * data)619 int SysMount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags,
620              const void *data)
621 {
622     int ret;
623     char *sourceRet = NULL;
624     char *targetRet = NULL;
625     char *dataRet = NULL;
626     char fstypeRet[FILESYSTEM_TYPE_MAX + 1] = {0};
627 
628     if (!IsCapPermit(CAP_FS_MOUNT)) {
629         return -EPERM;
630     }
631 
632     if (target != NULL) {
633         ret = UserPathCopy(target, &targetRet);
634         if (ret != 0) {
635             goto OUT;
636         }
637     }
638 
639     if (filesystemtype != NULL) {
640         ret = LOS_StrncpyFromUser(fstypeRet, filesystemtype, FILESYSTEM_TYPE_MAX + 1);
641         if (ret < 0) {
642             goto OUT;
643         } else if (ret > FILESYSTEM_TYPE_MAX) {
644             ret = -ENODEV;
645             goto OUT;
646         }
647 
648         if (strcmp(fstypeRet, "ramfs") && (source != NULL)) {
649             ret = UserPathCopy(source, &sourceRet);
650             if (ret != 0) {
651                 goto OUT;
652             }
653         }
654 #ifdef LOSCFG_FS_NFS
655         if (strcmp(fstypeRet, "nfs") == 0) {
656             ret = NfsMount(sourceRet, targetRet, 0, 0);
657             goto OUT;
658         }
659 #endif
660     }
661 
662     if (data != NULL) {
663         ret = UserPathCopy(data, &dataRet);
664         if (ret != 0) {
665             goto OUT;
666         }
667     }
668 
669     ret = mount(sourceRet, targetRet, (filesystemtype ? fstypeRet : NULL), mountflags, dataRet);
670     if (ret < 0) {
671         ret = -get_errno();
672     }
673 
674 OUT:
675     if (sourceRet != NULL) {
676         (void)LOS_MemFree(OS_SYS_MEM_ADDR, sourceRet);
677     }
678     if (targetRet != NULL) {
679         (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
680     }
681     if (dataRet != NULL) {
682         (void)LOS_MemFree(OS_SYS_MEM_ADDR, dataRet);
683     }
684     return ret;
685 }
686 
SysUmount(const char * target)687 int SysUmount(const char *target)
688 {
689     int ret;
690     char *pathRet = NULL;
691 
692     if (!IsCapPermit(CAP_FS_MOUNT)) {
693         return -EPERM;
694     }
695 
696     if (target != NULL) {
697         ret = UserPathCopy(target, &pathRet);
698         if (ret != 0) {
699             goto OUT;
700         }
701     }
702 
703     ret = umount(target ? pathRet : NULL);
704     if (ret < 0) {
705         ret = -get_errno();
706     }
707 
708 OUT:
709     if (pathRet != NULL) {
710         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
711     }
712     return ret;
713 }
714 
SysAccess(const char * path,int amode)715 int SysAccess(const char *path, int amode)
716 {
717     int ret;
718     char *pathRet = NULL;
719 
720     if (path != NULL) {
721         ret = UserPathCopy(path, &pathRet);
722         if (ret != 0) {
723             goto OUT;
724         }
725     }
726 
727     ret = access(pathRet, amode);
728     if (ret < 0) {
729         ret = -get_errno();
730     }
731 
732 OUT:
733     if (pathRet != NULL) {
734         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
735     }
736 
737     return ret;
738 }
739 
SysRename(const char * oldpath,const char * newpath)740 int SysRename(const char *oldpath, const char *newpath)
741 {
742     int ret;
743     char *pathOldRet = NULL;
744     char *pathNewRet = NULL;
745 
746     if (oldpath != NULL) {
747         ret = UserPathCopy(oldpath, &pathOldRet);
748         if (ret != 0) {
749             goto OUT;
750         }
751     }
752 
753     if (newpath != NULL) {
754         ret = UserPathCopy(newpath, &pathNewRet);
755         if (ret != 0) {
756             goto OUT;
757         }
758     }
759 
760     ret = do_rename(AT_FDCWD, (oldpath ? pathOldRet : NULL), AT_FDCWD,
761                     (newpath ? pathNewRet : NULL));
762     if (ret < 0) {
763         ret = -get_errno();
764     }
765 
766 OUT:
767     if (pathOldRet != NULL) {
768         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet);
769     }
770     if (pathNewRet != NULL) {
771         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet);
772     }
773     return ret;
774 }
775 
SysMkdir(const char * pathname,mode_t mode)776 int SysMkdir(const char *pathname, mode_t mode)
777 {
778     int ret;
779     char *pathRet = NULL;
780 
781     if (pathname != NULL) {
782         ret = UserPathCopy(pathname, &pathRet);
783         if (ret != 0) {
784             goto OUT;
785         }
786     }
787 
788     ret = do_mkdir(AT_FDCWD, (pathname ? pathRet : NULL), mode);
789     if (ret < 0) {
790         ret = -get_errno();
791     }
792 
793 OUT:
794     if (pathRet != NULL) {
795         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
796     }
797     return ret;
798 }
799 
SysRmdir(const char * pathname)800 int SysRmdir(const char *pathname)
801 {
802     int ret;
803     char *pathRet = NULL;
804 
805     if (pathname != NULL) {
806         ret = UserPathCopy(pathname, &pathRet);
807         if (ret != 0) {
808             goto OUT;
809         }
810     }
811 
812     ret = do_rmdir(AT_FDCWD, (pathname ? pathRet : NULL));
813     if (ret < 0) {
814         ret = -get_errno();
815     }
816 
817 OUT:
818     if (pathRet != NULL) {
819         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
820     }
821     return ret;
822 }
823 
SysDup(int fd)824 int SysDup(int fd)
825 {
826     int sysfd = GetAssociatedSystemFd(fd);
827     /* Check if the param is valid, note that: socket fd is not support dup2 */
828     if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) {
829         return -EBADF;
830     }
831 
832     int dupfd = AllocProcessFd();
833     if (dupfd < 0) {
834         return -EMFILE;
835     }
836 
837     files_refer(sysfd);
838     AssociateSystemFd(dupfd, sysfd);
839     return dupfd;
840 }
841 
SysSync(void)842 void SysSync(void)
843 {
844     sync();
845 }
846 
SysUmount2(const char * target,int flags)847 int SysUmount2(const char *target, int flags)
848 {
849     if (flags != 0) {
850         return -EINVAL;
851     }
852     return SysUmount(target);
853 }
854 
SysIoctl(int fd,int req,void * arg)855 int SysIoctl(int fd, int req, void *arg)
856 {
857     int ret;
858     unsigned int size = _IOC_SIZE((unsigned int)req);
859     unsigned int dir = _IOC_DIR((unsigned int)req);
860     if ((size == 0) && (dir != _IOC_NONE)) {
861         return -EINVAL;
862     }
863 
864     if ((dir != _IOC_NONE) && (((void *)(uintptr_t)arg) == NULL)) {
865         return -EINVAL;
866     }
867 
868     if ((dir & _IOC_READ) || (dir & _IOC_WRITE)) {
869         if (!LOS_IsUserAddressRange((uintptr_t)arg, size)) {
870             return -EFAULT;
871         }
872     }
873 
874     /* Process fd convert to system global fd */
875     fd = GetAssociatedSystemFd(fd);
876 
877     ret = ioctl(fd, req, arg);
878     if (ret < 0) {
879         return -get_errno();
880     }
881     return ret;
882 }
883 
SysFcntl(int fd,int cmd,void * arg)884 int SysFcntl(int fd, int cmd, void *arg)
885 {
886     /* Process fd convert to system global fd */
887     int sysfd = GetAssociatedSystemFd(fd);
888 
889     int ret = VfsFcntl(fd, cmd, arg);
890     if (ret == CONTINE_NUTTX_FCNTL) {
891         ret = fcntl(sysfd, cmd, arg);
892     }
893 
894     if (ret < 0) {
895         return -get_errno();
896     }
897     return ret;
898 }
899 
900 #ifdef LOSCFG_KERNEL_PIPE
SysPipe(int pipefd[2])901 int SysPipe(int pipefd[2]) /* 2 : pipe fds for read and write */
902 {
903     int ret;
904     int pipeFdIntr[2] = {0}; /* 2 : pipe fds for read and write */
905 
906     int procFd0 = AllocProcessFd();
907     if (procFd0 < 0) {
908         return -EMFILE;
909     }
910     int procFd1 = AllocProcessFd();
911     if (procFd1 < 0) {
912         FreeProcessFd(procFd0);
913         return -EMFILE;
914     }
915 
916     ret = pipe(pipeFdIntr);
917     if (ret < 0) {
918         FreeProcessFd(procFd0);
919         FreeProcessFd(procFd1);
920         return -get_errno();
921     }
922     int sysPipeFd0 = pipeFdIntr[0];
923     int sysPipeFd1 = pipeFdIntr[1];
924 
925     AssociateSystemFd(procFd0, sysPipeFd0);
926     AssociateSystemFd(procFd1, sysPipeFd1);
927 
928     pipeFdIntr[0] = procFd0;
929     pipeFdIntr[1] = procFd1;
930 
931     ret = LOS_ArchCopyToUser(pipefd, pipeFdIntr, sizeof(pipeFdIntr));
932     if (ret != 0) {
933         FreeProcessFd(procFd0);
934         FreeProcessFd(procFd1);
935         close(sysPipeFd0);
936         close(sysPipeFd1);
937         return -EFAULT;
938     }
939     return ret;
940 }
941 #endif
942 
SysDup2(int fd1,int fd2)943 int SysDup2(int fd1, int fd2)
944 {
945     int ret;
946     int sysfd1 = GetAssociatedSystemFd(fd1);
947     int sysfd2 = GetAssociatedSystemFd(fd2);
948 
949     /* Check if the param is valid, note that: socket fd is not support dup2 */
950     if ((sysfd1 < 0) || (sysfd1 >= CONFIG_NFILE_DESCRIPTORS) || (CheckProcessFd(fd2) != OK)) {
951         return -EBADF;
952     }
953 
954     /* Handle special circumstances */
955     if (fd1 == fd2) {
956         return fd2;
957     }
958 
959     ret = AllocSpecifiedProcessFd(fd2);
960     if (ret != OK) {
961         return ret;
962     }
963 
964     /* close the sysfd2 in need */
965     if (sysfd2 >= 0) {
966         ret = close(sysfd2);
967         if (ret < 0) {
968             AssociateSystemFd(fd2, sysfd2);
969             return -get_errno();
970         }
971     }
972 
973     files_refer(sysfd1);
974     AssociateSystemFd(fd2, sysfd1);
975 
976     /* if fd1 is not equal to fd2, the FD_CLOEXEC flag associated with fd2 shall be cleared */
977     ClearCloexecFlag(fd2);
978     return fd2;
979 }
980 
SelectParamCheckCopy(fd_set * readfds,fd_set * writefds,fd_set * exceptfds,fd_set ** fdsBuf)981 static int SelectParamCheckCopy(fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fd_set **fdsBuf)
982 {
983     fd_set *readfdsRet = NULL;
984     fd_set *writefdsRet = NULL;
985     fd_set *exceptfdsRet = NULL;
986 
987     *fdsBuf = (fd_set *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(fd_set) * 3); /* 3: three param need check and copy */
988     if (*fdsBuf == NULL) {
989         return -ENOMEM;
990     }
991 
992     readfdsRet = *fdsBuf;        /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */
993     writefdsRet = *fdsBuf + 1;   /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */
994     exceptfdsRet = *fdsBuf + 2;  /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */
995 
996     if (readfds != NULL) {
997         if (LOS_ArchCopyFromUser(readfdsRet, readfds, sizeof(fd_set)) != 0) {
998             (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
999             return -EFAULT;
1000         }
1001     }
1002 
1003     if (writefds != NULL) {
1004         if (LOS_ArchCopyFromUser(writefdsRet, writefds, sizeof(fd_set)) != 0) {
1005             (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1006             return -EFAULT;
1007         }
1008     }
1009 
1010     if (exceptfds != NULL) {
1011         if (LOS_ArchCopyFromUser(exceptfdsRet, exceptfds, sizeof(fd_set)) != 0) {
1012             (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1013             return -EFAULT;
1014         }
1015     }
1016 
1017     return 0;
1018 }
1019 
SysSelect(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout)1020 int SysSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
1021 {
1022     int ret;
1023     fd_set *fdsRet = NULL;
1024     fd_set *readfdsRet = NULL;
1025     fd_set *writefdsRet = NULL;
1026     fd_set *exceptfdsRet = NULL;
1027     struct timeval timeoutRet = {0};
1028 
1029     ret = SelectParamCheckCopy(readfds, writefds, exceptfds, &fdsRet);
1030     if (ret != 0) {
1031         return ret;
1032     }
1033 
1034     readfdsRet = fdsRet;        /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */
1035     writefdsRet = fdsRet + 1;   /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */
1036     exceptfdsRet = fdsRet + 2;  /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */
1037 
1038     if (timeout != NULL) {
1039         if (LOS_ArchCopyFromUser(&timeoutRet, timeout, sizeof(struct timeval)) != 0) {
1040             goto ERROUT;
1041         }
1042     }
1043 
1044     ret = do_select(nfds, (readfds ? readfdsRet : NULL), (writefds ? writefdsRet : NULL),
1045                  (exceptfds ? exceptfdsRet : NULL), (timeout ? (&timeoutRet) : NULL), UserPoll);
1046     if (ret < 0) {
1047         (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1048         return -get_errno();
1049     }
1050 
1051     if (readfds != NULL) {
1052         if (LOS_ArchCopyToUser(readfds, readfdsRet, sizeof(fd_set)) != 0) {
1053             goto ERROUT;
1054         }
1055     }
1056 
1057     if (writefds != NULL) {
1058         if (LOS_ArchCopyToUser(writefds, writefdsRet, sizeof(fd_set)) != 0) {
1059             goto ERROUT;
1060         }
1061     }
1062 
1063     if (exceptfds != 0) {
1064         if (LOS_ArchCopyToUser(exceptfds, exceptfdsRet, sizeof(fd_set)) != 0) {
1065             goto ERROUT;
1066         }
1067     }
1068 
1069     (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1070     return ret;
1071 
1072 ERROUT:
1073     (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1074     return -EFAULT;
1075 }
1076 
SysTruncate(const char * path,off_t length)1077 int SysTruncate(const char *path, off_t length)
1078 {
1079     int ret;
1080     int fd = -1;
1081     char *pathRet = NULL;
1082 
1083     if (path != NULL) {
1084         ret = UserPathCopy(path, &pathRet);
1085         if (ret != 0) {
1086             goto OUT;
1087         }
1088     }
1089 
1090     fd = open((path ? pathRet : NULL), O_RDWR);
1091     if (fd < 0) {
1092         /* The errno value has already been set */
1093         ret = -get_errno();
1094         goto OUT;
1095     }
1096 
1097     ret = ftruncate(fd, length);
1098     close(fd);
1099     if (ret < 0) {
1100         ret = -get_errno();
1101     }
1102 
1103 OUT:
1104     if (pathRet != NULL) {
1105         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1106     }
1107     return ret;
1108 }
1109 
SysTruncate64(const char * path,off64_t length)1110 int SysTruncate64(const char *path, off64_t length)
1111 {
1112     int ret;
1113     int fd = -1;
1114     char *pathRet = NULL;
1115 
1116     if (path != NULL) {
1117         ret = UserPathCopy(path, &pathRet);
1118         if (ret != 0) {
1119             goto OUT;
1120         }
1121     }
1122 
1123     fd = open((path ? pathRet : NULL), O_RDWR);
1124     if (fd < 0) {
1125         /* The errno value has already been set */
1126         ret = -get_errno();
1127         goto OUT;
1128     }
1129 
1130     ret = ftruncate64(fd, length);
1131     close(fd);
1132     if (ret < 0) {
1133         ret = -get_errno();
1134     }
1135 
1136 OUT:
1137     if (pathRet != NULL) {
1138         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1139     }
1140     return ret;
1141 }
1142 
SysFtruncate(int fd,off_t length)1143 int SysFtruncate(int fd, off_t length)
1144 {
1145     int ret;
1146 
1147     /* Process fd convert to system global fd */
1148     fd = GetAssociatedSystemFd(fd);
1149 
1150     ret = ftruncate(fd, length);
1151     if (ret < 0) {
1152         return -get_errno();
1153     }
1154     return ret;
1155 }
1156 
SysStatfs(const char * path,struct statfs * buf)1157 int SysStatfs(const char *path, struct statfs *buf)
1158 {
1159     int ret;
1160     char *pathRet = NULL;
1161     struct statfs bufRet = {0};
1162 
1163     if (path != NULL) {
1164         ret = UserPathCopy(path, &pathRet);
1165         if (ret != 0) {
1166             goto OUT;
1167         }
1168     }
1169 
1170     ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1171     if (ret < 0) {
1172         ret = -get_errno();
1173         goto OUT;
1174     }
1175 
1176     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
1177     if (ret != 0) {
1178         ret = -EFAULT;
1179     }
1180 
1181 OUT:
1182     if (pathRet != NULL) {
1183         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1184     }
1185     return ret;
1186 }
1187 
SysStatfs64(const char * path,size_t sz,struct statfs * buf)1188 int SysStatfs64(const char *path, size_t sz, struct statfs *buf)
1189 {
1190     int ret;
1191     char *pathRet = NULL;
1192     struct statfs bufRet = {0};
1193 
1194     if (path != NULL) {
1195         ret = UserPathCopy(path, &pathRet);
1196         if (ret != 0) {
1197             goto OUT;
1198         }
1199     }
1200 
1201     if (sz != sizeof(*buf)) {
1202         ret = -EINVAL;
1203         goto OUT;
1204     }
1205 
1206     ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1207     if (ret < 0) {
1208         ret = -get_errno();
1209         goto OUT;
1210     }
1211 
1212     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
1213     if (ret != 0) {
1214         ret = -EFAULT;
1215     }
1216 
1217 OUT:
1218     if (pathRet != NULL) {
1219         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1220     }
1221     return ret;
1222 }
1223 
SysStat(const char * path,struct kstat * buf)1224 int SysStat(const char *path, struct kstat *buf)
1225 {
1226     int ret;
1227     char *pathRet = NULL;
1228     struct stat bufRet = {0};
1229 
1230     if (path != NULL) {
1231         ret = UserPathCopy(path, &pathRet);
1232         if (ret != 0) {
1233             goto OUT;
1234         }
1235     }
1236 
1237     ret = stat((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1238     if (ret < 0) {
1239         ret = -get_errno();
1240         goto OUT;
1241     }
1242 
1243     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
1244     if (ret != 0) {
1245         ret = -EFAULT;
1246     }
1247 
1248 OUT:
1249     if (pathRet != NULL) {
1250         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1251     }
1252     return ret;
1253 }
1254 
SysLstat(const char * path,struct kstat * buffer)1255 int SysLstat(const char *path, struct kstat *buffer)
1256 {
1257     int ret;
1258     char *pathRet = NULL;
1259     struct stat bufRet = {0};
1260 
1261     if (path != NULL) {
1262         ret = UserPathCopy(path, &pathRet);
1263         if (ret != 0) {
1264             goto OUT;
1265         }
1266     }
1267 
1268     ret = stat((path ? pathRet : NULL), (buffer ? (&bufRet) : NULL));
1269     if (ret < 0) {
1270         ret = -get_errno();
1271         goto OUT;
1272     }
1273 
1274     ret = LOS_ArchCopyToUser(buffer, &bufRet, sizeof(struct kstat));
1275     if (ret != 0) {
1276         ret = -EFAULT;
1277     }
1278 
1279 OUT:
1280     if (pathRet != NULL) {
1281         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1282     }
1283     return ret;
1284 }
1285 
SysFstat(int fd,struct kstat * buf)1286 int SysFstat(int fd, struct kstat *buf)
1287 {
1288     int ret;
1289     struct stat bufRet = {0};
1290     struct file *filep = NULL;
1291 
1292     /* Process fd convert to system global fd */
1293     fd = GetAssociatedSystemFd(fd);
1294 
1295     ret = fs_getfilep(fd, &filep);
1296     if (ret < 0) {
1297         return -get_errno();
1298     }
1299 
1300     if (filep->f_oflags & O_DIRECTORY) {
1301         return -EBADF;
1302     }
1303 
1304     ret = stat(filep->f_path, (buf ? (&bufRet) : NULL));
1305     if (ret < 0) {
1306         return -get_errno();
1307     }
1308 
1309     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
1310     if (ret != 0) {
1311         return -EFAULT;
1312     }
1313 
1314     return ret;
1315 }
1316 
SysStatx(int fd,const char * restrict path,int flag,unsigned mask,struct statx * restrict stx)1317 int SysStatx(int fd, const char *restrict path, int flag, unsigned mask, struct statx *restrict stx)
1318 {
1319     return -ENOSYS;
1320 }
1321 
SysFsync(int fd)1322 int SysFsync(int fd)
1323 {
1324     int ret;
1325     struct file *filep = NULL;
1326 
1327     /* Process fd convert to system global fd */
1328     fd = GetAssociatedSystemFd(fd);
1329 
1330     /* Get the file structure corresponding to the file descriptor. */
1331     ret = fs_getfilep(fd, &filep);
1332     if (ret < 0) {
1333         /* The errno value has already been set */
1334         return -get_errno();
1335     }
1336 
1337     if (filep->f_oflags & O_DIRECTORY) {
1338         return -EBADF;
1339     }
1340 
1341     /* Perform the fsync operation */
1342     ret = file_fsync(filep);
1343     if (ret < 0) {
1344         return -get_errno();
1345     }
1346     return ret;
1347 }
1348 
SysReadv(int fd,const struct iovec * iov,int iovcnt)1349 ssize_t SysReadv(int fd, const struct iovec *iov, int iovcnt)
1350 {
1351     int ret;
1352     int valid_iovcnt = -1;
1353     struct iovec *iovRet = NULL;
1354 
1355     /* Process fd convert to system global fd */
1356     fd = GetAssociatedSystemFd(fd);
1357     if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
1358         return -EINVAL;
1359     }
1360 
1361     if (iovcnt == 0) {
1362         return 0;
1363     }
1364 
1365     ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
1366     if (ret != 0) {
1367         return ret;
1368     }
1369 
1370     if (valid_iovcnt <= 0) {
1371         ret = -EFAULT;
1372         goto OUT;
1373     }
1374 
1375     ret = vfs_readv(fd, iovRet, valid_iovcnt, NULL);
1376     if (ret < 0) {
1377         ret = -get_errno();
1378     }
1379 
1380 OUT:
1381     (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
1382     return ret;
1383 }
1384 
SysWritev(int fd,const struct iovec * iov,int iovcnt)1385 ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt)
1386 {
1387     int ret;
1388     int valid_iovcnt = -1;
1389     struct iovec *iovRet = NULL;
1390 
1391     /* Process fd convert to system global fd */
1392     int sysfd = GetAssociatedSystemFd(fd);
1393     if ((iovcnt < 0) || (iovcnt > IOV_MAX)) {
1394         return -EINVAL;
1395     }
1396 
1397     if (iovcnt == 0) {
1398         return 0;
1399     }
1400 
1401     if (iov == NULL) {
1402         return -EFAULT;
1403     }
1404 
1405     ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
1406     if (ret != 0) {
1407         return ret;
1408     }
1409 
1410     if (valid_iovcnt != iovcnt) {
1411         ret = -EFAULT;
1412         goto OUT_FREE;
1413     }
1414 
1415     ret = writev(sysfd, iovRet, valid_iovcnt);
1416     if (ret < 0) {
1417         ret = -get_errno();
1418     }
1419 
1420 OUT_FREE:
1421     (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
1422     return ret;
1423 }
1424 
SysPoll(struct pollfd * fds,nfds_t nfds,int timeout)1425 int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout)
1426 {
1427     int ret;
1428     struct pollfd *kfds = NULL;
1429 
1430     if ((nfds >= MAX_POLL_NFDS) || (nfds == 0) || (fds == NULL)) {
1431         return -EINVAL;
1432     }
1433 
1434     kfds = (struct pollfd *)malloc(sizeof(struct pollfd) * nfds);
1435     if (kfds != NULL) {
1436         if (LOS_ArchCopyFromUser(kfds, fds, sizeof(struct pollfd) * nfds) != 0) {
1437             ret = -EFAULT;
1438             goto OUT_KFD;
1439         }
1440     }
1441 
1442     int *pollFds = NULL;
1443     ret = PollfdToSystem(kfds, nfds, &pollFds);
1444     if (ret < 0) {
1445         ret = -get_errno();
1446         goto OUT_KFD;
1447     }
1448 
1449     ret = poll(kfds, nfds, timeout);
1450     if (ret < 0) {
1451         ret = -get_errno();
1452         goto OUT;
1453     }
1454 
1455     if (kfds != NULL) {
1456         RestorePollfd(kfds, nfds, pollFds);
1457         if (LOS_ArchCopyToUser(fds, kfds, sizeof(struct pollfd) * nfds) != 0) {
1458             ret = -EFAULT;
1459             goto OUT;
1460         }
1461     }
1462 
1463 OUT:
1464     free(pollFds);
1465 OUT_KFD:
1466     free(kfds);
1467     return ret;
1468 }
1469 
SysPrctl(int option,...)1470 int SysPrctl(int option, ...)
1471 {
1472     unsigned long name;
1473     va_list ap;
1474     errno_t err;
1475 
1476     va_start(ap, option);
1477     if (option != PR_SET_NAME) {
1478         PRINT_ERR("%s: %d, no support option : 0x%x\n", __FUNCTION__, __LINE__, option);
1479         err = EOPNOTSUPP;
1480         goto ERROR;
1481     }
1482 
1483     name = va_arg(ap, unsigned long);
1484     if (!LOS_IsUserAddress(name)) {
1485         err = EFAULT;
1486         goto ERROR;
1487     }
1488 
1489     err = OsSetTaskName(OsCurrTaskGet(), (const char *)(uintptr_t)name, TRUE);
1490     if (err != LOS_OK) {
1491         goto ERROR;
1492     }
1493 
1494     va_end(ap);
1495     return ENOERR;
1496 
1497 ERROR:
1498     va_end(ap);
1499     return -err;
1500 }
1501 
SysPread64(int fd,void * buf,size_t nbytes,off64_t offset)1502 ssize_t SysPread64(int fd, void *buf, size_t nbytes, off64_t offset)
1503 {
1504     int ret, retVal;
1505     char *bufRet = NULL;
1506 
1507     /* Process fd convert to system global fd */
1508     fd = GetAssociatedSystemFd(fd);
1509 
1510     if (nbytes == 0) {
1511         ret = pread64(fd, buf, nbytes, offset);
1512         if (ret < 0) {
1513             return -get_errno();
1514         } else {
1515             return ret;
1516         }
1517     }
1518 
1519     bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nbytes);
1520     if (bufRet == NULL) {
1521         return -ENOMEM;
1522     }
1523 
1524     ret = pread64(fd, (buf ? bufRet : NULL), nbytes, offset);
1525     if (ret < 0) {
1526         (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1527         return -get_errno();
1528     }
1529 
1530     retVal = LOS_ArchCopyToUser(buf, bufRet, ret);
1531     if (retVal != 0) {
1532         (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1533         return -EFAULT;
1534     }
1535 
1536     (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1537     return ret;
1538 }
1539 
SysPwrite64(int fd,const void * buf,size_t nbytes,off64_t offset)1540 ssize_t SysPwrite64(int fd, const void *buf, size_t nbytes, off64_t offset)
1541 {
1542     int ret;
1543     char *bufRet = NULL;
1544 
1545     /* Process fd convert to system global fd */
1546     fd = GetAssociatedSystemFd(fd);
1547 
1548     if (nbytes == 0) {
1549         ret = pwrite64(fd, buf, nbytes, offset);
1550         if (ret < 0) {
1551             return -get_errno();
1552         }
1553         return ret;
1554     }
1555 
1556     bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nbytes);
1557     if (bufRet == NULL) {
1558         return -ENOMEM;
1559     }
1560 
1561     if (buf != NULL) {
1562         ret = LOS_ArchCopyFromUser(bufRet, buf, nbytes);
1563         if (ret != 0) {
1564             (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1565             return -EFAULT;
1566         }
1567     }
1568 
1569     ret = pwrite64(fd, (buf ? bufRet : NULL), nbytes, offset);
1570     if (ret < 0) {
1571         (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1572         return -get_errno();
1573     }
1574 
1575     (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1576     return ret;
1577 }
1578 
SysGetcwd(char * buf,size_t n)1579 char *SysGetcwd(char *buf, size_t n)
1580 {
1581     char *ret = NULL;
1582     char *bufRet = NULL;
1583     size_t bufLen = n;
1584     int retVal;
1585 
1586     if (bufLen > PATH_MAX) {
1587         bufLen = PATH_MAX;
1588     }
1589 
1590     bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, bufLen);
1591     if (bufRet == NULL) {
1592         return (char *)(intptr_t)-ENOMEM;
1593     }
1594     (void)memset_s(bufRet, bufLen, 0, bufLen);
1595 
1596     ret = getcwd((buf ? bufRet : NULL), bufLen);
1597     if (ret == NULL) {
1598         (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1599         return (char *)(intptr_t)-get_errno();
1600     }
1601 
1602     retVal = LOS_ArchCopyToUser(buf, bufRet, bufLen);
1603     if (retVal != 0) {
1604         (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1605         return (char *)(intptr_t)-EFAULT;
1606     }
1607     ret = buf;
1608 
1609     (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1610     return ret;
1611 }
1612 
SysSendFile(int outfd,int infd,off_t * offset,size_t count)1613 ssize_t SysSendFile(int outfd, int infd, off_t *offset, size_t count)
1614 {
1615     int ret, retVal;
1616     off_t offsetRet;
1617 
1618     retVal = LOS_ArchCopyFromUser(&offsetRet, offset, sizeof(off_t));
1619     if (retVal != 0) {
1620         return -EFAULT;
1621     }
1622 
1623     /* Process fd convert to system global fd */
1624     outfd = GetAssociatedSystemFd(outfd);
1625     infd = GetAssociatedSystemFd(infd);
1626 
1627     ret = sendfile(outfd, infd, (offset ? (&offsetRet) : NULL), count);
1628     if (ret < 0) {
1629         return -get_errno();
1630     }
1631 
1632     retVal = LOS_ArchCopyToUser(offset, &offsetRet, sizeof(off_t));
1633     if (retVal != 0) {
1634         return -EFAULT;
1635     }
1636 
1637     return ret;
1638 }
1639 
SysFtruncate64(int fd,off64_t length)1640 int SysFtruncate64(int fd, off64_t length)
1641 {
1642     int ret;
1643 
1644     /* Process fd convert to system global fd */
1645     fd = GetAssociatedSystemFd(fd);
1646 
1647     ret = ftruncate64(fd, length);
1648     if (ret < 0) {
1649         return -get_errno();
1650     }
1651     return ret;
1652 }
1653 
SysOpenat(int dirfd,const char * path,int oflags,...)1654 int SysOpenat(int dirfd, const char *path, int oflags, ...)
1655 {
1656     int ret;
1657     int procFd;
1658     char *pathRet = NULL;
1659     mode_t mode;
1660 #ifdef LOSCFG_FILE_MODE
1661     va_list ap;
1662 
1663     va_start(ap, oflags);
1664     mode = va_arg(ap, int);
1665     va_end(ap);
1666 #else
1667     mode = 0666; /* 0666: File read-write properties. */
1668 #endif
1669 
1670     if (path != NULL) {
1671         ret = UserPathCopy(path, &pathRet);
1672         if (ret != 0) {
1673             return ret;
1674         }
1675     }
1676 
1677     procFd = AllocProcessFd();
1678     if (procFd < 0) {
1679         ret = -EMFILE;
1680         goto ERROUT;
1681     }
1682 
1683     if (oflags & O_CLOEXEC) {
1684         SetCloexecFlag(procFd);
1685     }
1686 
1687     if (dirfd != AT_FDCWD) {
1688         /* Process fd convert to system global fd */
1689         dirfd = GetAssociatedSystemFd(dirfd);
1690     }
1691 
1692     ret = do_open(dirfd, (path ? pathRet : NULL), oflags, mode);
1693     if (ret < 0) {
1694         ret = -get_errno();
1695         goto ERROUT;
1696     }
1697 
1698     AssociateSystemFd(procFd, ret);
1699     if (pathRet != NULL) {
1700         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1701     }
1702     return procFd;
1703 
1704 ERROUT:
1705     if (pathRet != NULL) {
1706         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1707     }
1708     if (procFd >= 0) {
1709         FreeProcessFd(procFd);
1710     }
1711     return ret;
1712 }
1713 
SysMkdirat(int dirfd,const char * pathname,mode_t mode)1714 int SysMkdirat(int dirfd, const char *pathname, mode_t mode)
1715 {
1716     int ret;
1717     char *pathRet = NULL;
1718 
1719     if (pathname != NULL) {
1720         ret = UserPathCopy(pathname, &pathRet);
1721         if (ret != 0) {
1722             goto OUT;
1723         }
1724     }
1725 
1726     if (dirfd != AT_FDCWD) {
1727         /* Process fd convert to system global fd */
1728         dirfd = GetAssociatedSystemFd(dirfd);
1729     }
1730 
1731     ret = do_mkdir(dirfd, (pathname ? pathRet : NULL), mode);
1732     if (ret < 0) {
1733         ret = -get_errno();
1734     }
1735 
1736 OUT:
1737     if (pathRet != NULL) {
1738         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1739     }
1740     return ret;
1741 }
1742 
SysLinkat(int olddirfd,const char * oldpath,int newdirfd,const char * newpath,int flags)1743 int SysLinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags)
1744 {
1745     int ret;
1746     char *oldpathRet = NULL;
1747     char *newpathRet = NULL;
1748 
1749     if (oldpath != NULL) {
1750         ret = UserPathCopy(oldpath, &oldpathRet);
1751         if (ret != 0) {
1752             goto OUT;
1753         }
1754     }
1755 
1756     if (newpath != NULL) {
1757         ret = UserPathCopy(newpath, &newpathRet);
1758         if (ret != 0) {
1759             goto OUT;
1760         }
1761     }
1762 
1763     if (olddirfd != AT_FDCWD) {
1764         /* Process fd convert to system global fd */
1765         olddirfd = GetAssociatedSystemFd(olddirfd);
1766     }
1767 
1768     if (newdirfd != AT_FDCWD) {
1769         /* Process fd convert to system global fd */
1770         newdirfd = GetAssociatedSystemFd(newdirfd);
1771     }
1772 
1773     ret = linkat(olddirfd, oldpathRet, newdirfd, newpathRet, flags);
1774     if (ret < 0) {
1775         ret = -get_errno();
1776     }
1777 
1778 OUT:
1779     if (oldpathRet != NULL) {
1780         (void)LOS_MemFree(OS_SYS_MEM_ADDR, oldpathRet);
1781     }
1782     if (newpathRet != NULL) {
1783         (void)LOS_MemFree(OS_SYS_MEM_ADDR, newpathRet);
1784     }
1785     return ret;
1786 }
1787 
SysSymlinkat(const char * target,int dirfd,const char * linkpath)1788 int SysSymlinkat(const char *target, int dirfd, const char *linkpath)
1789 {
1790     int ret;
1791     char *pathRet = NULL;
1792     char *targetRet = NULL;
1793 
1794     if (target != NULL) {
1795         ret = UserPathCopy(target, &targetRet);
1796         if (ret != 0) {
1797             goto OUT;
1798         }
1799     }
1800 
1801     if (linkpath != NULL) {
1802         ret = UserPathCopy(linkpath, &pathRet);
1803         if (ret != 0) {
1804             goto OUT;
1805         }
1806     }
1807 
1808     if (dirfd != AT_FDCWD) {
1809         /* Process fd convert to system global fd */
1810         dirfd = GetAssociatedSystemFd(dirfd);
1811     }
1812 
1813     ret = symlinkat(targetRet, dirfd, pathRet);
1814     if (ret < 0) {
1815         ret = -get_errno();
1816     }
1817 
1818 OUT:
1819     if (pathRet != NULL) {
1820         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1821     }
1822 
1823     if (targetRet != NULL) {
1824         (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
1825     }
1826     return ret;
1827 }
1828 
SysReadlinkat(int dirfd,const char * pathname,char * buf,size_t bufsize)1829 ssize_t SysReadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize)
1830 {
1831     ssize_t ret;
1832     char *pathRet = NULL;
1833 
1834     if (bufsize == 0) {
1835         return -EINVAL;
1836     }
1837 
1838     if (pathname != NULL) {
1839         ret = UserPathCopy(pathname, &pathRet);
1840         if (ret != 0) {
1841             goto OUT;
1842         }
1843     }
1844 
1845     if (dirfd != AT_FDCWD) {
1846         /* Process fd convert to system global fd */
1847         dirfd = GetAssociatedSystemFd(dirfd);
1848     }
1849 
1850     if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) {
1851         ret = -EFAULT;
1852         goto OUT;
1853     }
1854 
1855     ret = readlinkat(dirfd, pathRet, buf, bufsize);
1856     if (ret < 0) {
1857         ret = -get_errno();
1858     }
1859 
1860 OUT:
1861     if (pathRet != NULL) {
1862         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1863     }
1864     return ret;
1865 }
1866 
SysUnlinkat(int dirfd,const char * pathname,int flag)1867 int SysUnlinkat(int dirfd, const char *pathname, int flag)
1868 {
1869     int ret;
1870     char *pathRet = NULL;
1871 
1872     if (pathname != NULL) {
1873         ret = UserPathCopy(pathname, &pathRet);
1874         if (ret != 0) {
1875             goto OUT;
1876         }
1877     }
1878 
1879     if (dirfd != AT_FDCWD) {
1880         /* Process fd convert to system global fd */
1881         dirfd = GetAssociatedSystemFd(dirfd);
1882     }
1883 
1884     ret = unlinkat(dirfd, (pathname ? pathRet : NULL), flag);
1885     if (ret < 0) {
1886         ret = -get_errno();
1887     }
1888 
1889 OUT:
1890     if (pathRet != NULL) {
1891         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1892     }
1893     return ret;
1894 }
1895 
SysRenameat(int oldfd,const char * oldpath,int newdfd,const char * newpath)1896 int SysRenameat(int oldfd, const char *oldpath, int newdfd, const char *newpath)
1897 {
1898     int ret;
1899     char *pathOldRet = NULL;
1900     char *pathNewRet = NULL;
1901 
1902     if (oldpath != NULL) {
1903         ret = UserPathCopy(oldpath, &pathOldRet);
1904         if (ret != 0) {
1905             goto OUT;
1906         }
1907     }
1908 
1909     if (newpath != NULL) {
1910         ret = UserPathCopy(newpath, &pathNewRet);
1911         if (ret != 0) {
1912             goto OUT;
1913         }
1914     }
1915 
1916     if (oldfd != AT_FDCWD) {
1917         /* Process fd convert to system global fd */
1918         oldfd = GetAssociatedSystemFd(oldfd);
1919     }
1920     if (newdfd != AT_FDCWD) {
1921         /* Process fd convert to system global fd */
1922         newdfd = GetAssociatedSystemFd(newdfd);
1923     }
1924 
1925     ret = do_rename(oldfd, (oldpath ? pathOldRet : NULL), newdfd, (newpath ? pathNewRet : NULL));
1926     if (ret < 0) {
1927         ret = -get_errno();
1928     }
1929 
1930 OUT:
1931     if (pathOldRet != NULL) {
1932         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet);
1933     }
1934     if (pathNewRet != NULL) {
1935         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet);
1936     }
1937     return ret;
1938 }
1939 
SysFallocate(int fd,int mode,off_t offset,off_t len)1940 int SysFallocate(int fd, int mode, off_t offset, off_t len)
1941 {
1942     int ret;
1943 
1944     /* Process fd convert to system global fd */
1945     fd = GetAssociatedSystemFd(fd);
1946 
1947     ret = fallocate(fd, mode, offset, len);
1948     if (ret < 0) {
1949         return -get_errno();
1950     }
1951     return ret;
1952 }
1953 
SysFallocate64(int fd,int mode,off64_t offset,off64_t len)1954 int SysFallocate64(int fd, int mode, off64_t offset, off64_t len)
1955 {
1956     int ret;
1957 
1958     /* Process fd convert to system global fd */
1959     fd = GetAssociatedSystemFd(fd);
1960 
1961     ret = fallocate64(fd, mode, offset, len);
1962     if (ret < 0) {
1963         return -get_errno();
1964     }
1965     return ret;
1966 }
1967 
SysPreadv(int fd,const struct iovec * iov,int iovcnt,long loffset,long hoffset)1968 ssize_t SysPreadv(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
1969 {
1970     off_t offsetflag;
1971     offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT));
1972 
1973     int ret;
1974     int valid_iovcnt = -1;
1975     struct iovec *iovRet = NULL;
1976 
1977     /* Process fd convert to system global fd */
1978     fd = GetAssociatedSystemFd(fd);
1979     if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
1980         return -EINVAL;
1981     }
1982 
1983     if (iovcnt == 0) {
1984         return 0;
1985     }
1986 
1987     ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
1988     if (ret != 0) {
1989         return ret;
1990     }
1991 
1992     if (valid_iovcnt <= 0) {
1993         ret = -EFAULT;
1994         goto OUT_FREE;
1995     }
1996 
1997     ret = preadv(fd, iovRet, valid_iovcnt, offsetflag);
1998     if (ret < 0) {
1999         ret = -get_errno();
2000     }
2001 
2002 OUT_FREE:
2003     (void)(void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
2004     return ret;
2005 }
2006 
SysPwritev(int fd,const struct iovec * iov,int iovcnt,long loffset,long hoffset)2007 ssize_t SysPwritev(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
2008 {
2009     off_t offsetflag;
2010     offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT));
2011     int ret;
2012     int valid_iovcnt = -1;
2013     struct iovec *iovRet = NULL;
2014 
2015     /* Process fd convert to system global fd */
2016     fd = GetAssociatedSystemFd(fd);
2017     if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
2018         return -EINVAL;
2019     }
2020 
2021     if (iovcnt == 0) {
2022         return 0;
2023     }
2024 
2025     ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
2026     if (ret != 0) {
2027         return ret;
2028     }
2029 
2030     if (valid_iovcnt != iovcnt) {
2031         ret = -EFAULT;
2032         goto OUT_FREE;
2033     }
2034 
2035     ret = pwritev(fd, iovRet, valid_iovcnt, offsetflag);
2036     if (ret < 0) {
2037         ret = -get_errno();
2038     }
2039 
2040 OUT_FREE:
2041     (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
2042     return ret;
2043 }
2044 
2045 #ifdef LOSCFG_FS_FAT
SysFormat(const char * dev,int sectors,int option)2046 int SysFormat(const char *dev, int sectors, int option)
2047 {
2048     int ret;
2049     char *devRet = NULL;
2050 
2051     if (!IsCapPermit(CAP_FS_FORMAT)) {
2052         return -EPERM;
2053     }
2054 
2055     if (dev != NULL) {
2056         ret = UserPathCopy(dev, &devRet);
2057         if (ret != 0) {
2058             goto OUT;
2059         }
2060     }
2061 
2062     ret = format((dev ? devRet : NULL), sectors, option);
2063     if (ret < 0) {
2064         ret = -get_errno();
2065     }
2066 
2067 OUT:
2068     if (devRet != NULL) {
2069         (void)LOS_MemFree(OS_SYS_MEM_ADDR, devRet);
2070     }
2071     return ret;
2072 }
2073 #endif
2074 
SysFstat64(int fd,struct kstat * buf)2075 int SysFstat64(int fd, struct kstat *buf)
2076 {
2077     int ret;
2078     struct stat64 bufRet = {0};
2079 
2080     /* Process fd convert to system global fd */
2081     fd = GetAssociatedSystemFd(fd);
2082 
2083     ret = fstat64(fd, (buf ? (&bufRet) : NULL));
2084     if (ret < 0) {
2085         return -get_errno();
2086     }
2087 
2088     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
2089     if (ret != 0) {
2090         return -EFAULT;
2091     }
2092 
2093     return ret;
2094 }
2095 
SysFcntl64(int fd,int cmd,void * arg)2096 int SysFcntl64(int fd, int cmd, void *arg)
2097 {
2098     /* Process fd convert to system global fd */
2099     int sysfd = GetAssociatedSystemFd(fd);
2100 
2101     int ret = VfsFcntl(fd, cmd, arg);
2102     if (ret == CONTINE_NUTTX_FCNTL) {
2103         ret = fcntl64(sysfd, cmd, arg);
2104     }
2105 
2106     if (ret < 0) {
2107         return -get_errno();
2108     }
2109     return ret;
2110 }
2111 
SysGetdents64(int fd,struct dirent * de_user,unsigned int count)2112 int SysGetdents64(int fd, struct dirent *de_user, unsigned int count)
2113 {
2114     if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)de_user, count)) {
2115         return -EFAULT;
2116     }
2117 
2118     struct dirent *de_knl = NULL;
2119 
2120     /* Process fd convert to system global fd */
2121     fd = GetAssociatedSystemFd(fd);
2122 
2123     int ret = do_readdir(fd, &de_knl, count);
2124     if (ret < 0) {
2125         return ret;
2126     }
2127     if (de_knl != NULL) {
2128         int cpy_ret = LOS_ArchCopyToUser(de_user, de_knl, ret);
2129         if (cpy_ret != 0)
2130         {
2131             return -EFAULT;
2132         }
2133     }
2134     return ret;
2135 }
2136 
SysRealpath(const char * path,char * resolved_path)2137 char *SysRealpath(const char *path, char *resolved_path)
2138 {
2139     char *pathRet = NULL;
2140     char *resolved_pathRet = NULL;
2141     char *result = NULL;
2142     int ret;
2143 
2144     if (resolved_path == NULL) {
2145         return (char *)(intptr_t)-EINVAL;
2146     }
2147 
2148     if (path != NULL) {
2149         ret = UserPathCopy(path, &pathRet);
2150         if (ret != 0) {
2151             result = (char *)(intptr_t)ret;
2152             goto OUT;
2153         }
2154     }
2155 
2156     resolved_pathRet = realpath((path ? pathRet : NULL), NULL);
2157     if (resolved_pathRet == NULL) {
2158         result = (char *)(intptr_t)-get_errno();
2159         goto OUT;
2160     }
2161 
2162     ret = LOS_ArchCopyToUser(resolved_path, resolved_pathRet, strlen(resolved_pathRet) + 1);
2163     if (ret != 0) {
2164         result = (char *)(intptr_t)-EFAULT;
2165         goto OUT;
2166     }
2167     result = resolved_path;
2168 
2169 OUT:
2170     if (pathRet != NULL) {
2171         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2172     }
2173     if (resolved_pathRet != NULL) {
2174         (void)LOS_MemFree(OS_SYS_MEM_ADDR, resolved_pathRet);
2175     }
2176     return result;
2177 }
2178 
SysUtimensat(int fd,const char * path,struct timespec times[TIMESPEC_TIMES_NUM],int flag)2179 int SysUtimensat(int fd, const char *path, struct timespec times[TIMESPEC_TIMES_NUM], int flag)
2180 {
2181     int ret;
2182     int timeLen;
2183     struct IATTR attr = {0};
2184     char *filePath = NULL;
2185 
2186     timeLen = TIMESPEC_TIMES_NUM * sizeof(struct timespec);
2187     CHECK_ASPACE(times, timeLen);
2188     DUP_FROM_USER(times, timeLen);
2189     ret = CheckNewAttrTime(&attr, times);
2190     FREE_DUP(times);
2191     if (ret < 0) {
2192         goto OUT;
2193     }
2194 
2195     ret = GetFullpathNull(fd, path, &filePath);
2196     if (ret < 0) {
2197         goto OUT;
2198     }
2199 
2200     ret = chattr(filePath, &attr);
2201     if (ret < 0) {
2202         ret = -get_errno();
2203     }
2204 
2205 OUT:
2206     PointerFree(filePath);
2207     return ret;
2208 }
2209 
SysChmod(const char * pathname,mode_t mode)2210 int SysChmod(const char *pathname, mode_t mode)
2211 {
2212     int ret;
2213     char *pathRet = NULL;
2214 
2215     if (pathname != NULL) {
2216         ret = UserPathCopy(pathname, &pathRet);
2217         if (ret != 0) {
2218             goto OUT;
2219         }
2220     }
2221 
2222     ret = chmod(pathRet, mode);
2223     if (ret < 0) {
2224         ret = -get_errno();
2225     }
2226 
2227 OUT:
2228     if (pathRet != NULL) {
2229         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2230     }
2231     return ret;
2232 }
2233 
SysFchmodat(int fd,const char * path,mode_t mode,int flag)2234 int SysFchmodat(int fd, const char *path, mode_t mode, int flag)
2235 {
2236     int ret;
2237     char *pathRet = NULL;
2238     char *fullpath = NULL;
2239     struct IATTR attr = {
2240         .attr_chg_mode = mode,
2241         .attr_chg_valid = CHG_MODE,
2242     };
2243 
2244     if (path != NULL) {
2245         ret = UserPathCopy(path, &pathRet);
2246         if (ret != 0) {
2247             goto OUT;
2248         }
2249     }
2250 
2251     if (fd != AT_FDCWD) {
2252         /* Process fd convert to system global fd */
2253         fd = GetAssociatedSystemFd(fd);
2254     }
2255 
2256     ret = vfs_normalize_pathat(fd, pathRet, &fullpath);
2257     if (ret < 0) {
2258         goto OUT;
2259     }
2260 
2261     ret = chattr(fullpath, &attr);
2262     if (ret < 0) {
2263         ret = -get_errno();
2264     }
2265 
2266 OUT:
2267     PointerFree(pathRet);
2268     PointerFree(fullpath);
2269 
2270     return ret;
2271 }
2272 
SysFchmod(int fd,mode_t mode)2273 int SysFchmod(int fd, mode_t mode)
2274 {
2275     int ret;
2276     int sysFd;
2277     struct IATTR attr = {
2278         .attr_chg_mode = mode,
2279         .attr_chg_valid = CHG_MODE, /* change mode */
2280     };
2281     struct file *file = NULL;
2282 
2283     sysFd = GetAssociatedSystemFd(fd);
2284     if (sysFd < 0) {
2285         return -EBADF;
2286     }
2287 
2288     ret = fs_getfilep(sysFd, &file);
2289     if (ret < 0) {
2290         return -get_errno();
2291     }
2292 
2293     ret = chattr(file->f_path, &attr);
2294     if (ret < 0) {
2295         return -get_errno();
2296     }
2297 
2298     return ret;
2299 }
2300 
SysFchownat(int fd,const char * path,uid_t owner,gid_t group,int flag)2301 int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
2302 {
2303     int ret;
2304     char *fullpath = NULL;
2305     struct IATTR attr = {
2306         .attr_chg_valid = 0,
2307     };
2308 
2309     ret = GetFullpath(fd, path, &fullpath);
2310     if (ret < 0) {
2311         goto OUT;
2312     }
2313 
2314     if (owner != (uid_t)-1) {
2315         attr.attr_chg_uid = owner;
2316         attr.attr_chg_valid |= CHG_UID;
2317     }
2318     if (group != (gid_t)-1) {
2319         attr.attr_chg_gid = group;
2320         attr.attr_chg_valid |= CHG_GID;
2321     }
2322 
2323     ret = chattr(fullpath, &attr);
2324     if (ret < 0) {
2325         ret = -get_errno();
2326     }
2327 
2328 OUT:
2329     PointerFree(fullpath);
2330 
2331     return ret;
2332 }
2333 
SysFchown(int fd,uid_t owner,gid_t group)2334 int SysFchown(int fd, uid_t owner, gid_t group)
2335 {
2336     int ret;
2337     int sysFd;
2338     struct IATTR attr = {0};
2339     attr.attr_chg_valid = 0;
2340     struct file *file = NULL;
2341 
2342     sysFd = GetAssociatedSystemFd(fd);
2343     if (sysFd < 0) {
2344         return -EBADF;
2345     }
2346 
2347     ret = fs_getfilep(sysFd, &file);
2348     if (ret < 0) {
2349         return -get_errno();
2350     }
2351 
2352     if (owner != (uid_t)-1) {
2353         attr.attr_chg_uid = owner;
2354         attr.attr_chg_valid |= CHG_UID;
2355     }
2356     if (group != (gid_t)-1) {
2357         attr.attr_chg_gid = group;
2358         attr.attr_chg_valid |= CHG_GID;
2359     }
2360     ret = chattr(file->f_path, &attr);
2361     if (ret < 0) {
2362         ret = -get_errno();
2363     }
2364 
2365     return ret;
2366 }
2367 
SysChown(const char * pathname,uid_t owner,gid_t group)2368 int SysChown(const char *pathname, uid_t owner, gid_t group)
2369 {
2370     int ret;
2371     char *pathRet = NULL;
2372 
2373     if (pathname != NULL) {
2374         ret = UserPathCopy(pathname, &pathRet);
2375         if (ret != 0) {
2376             goto OUT;
2377         }
2378     }
2379 
2380     ret = chown(pathRet, owner, group);
2381     if (ret < 0) {
2382         ret = -get_errno();
2383     }
2384 
2385 OUT:
2386     if (pathRet != NULL) {
2387         (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2388     }
2389     return ret;
2390 }
2391 
SysFstatat64(int dirfd,const char * restrict path,struct kstat * restrict buf,int flag)2392 int SysFstatat64(int dirfd, const char *restrict path, struct kstat *restrict buf, int flag)
2393 {
2394     int ret;
2395     struct stat bufRet = {0};
2396     char *pathRet = NULL;
2397     char *fullpath = NULL;
2398 
2399     if (path != NULL) {
2400         ret = UserPathCopy(path, &pathRet);
2401         if (ret != 0) {
2402             goto OUT;
2403         }
2404     }
2405 
2406     if (dirfd != AT_FDCWD) {
2407         /* Process fd convert to system global fd */
2408         dirfd = GetAssociatedSystemFd(dirfd);
2409     }
2410 
2411     ret = vfs_normalize_pathat(dirfd, pathRet, &fullpath);
2412     if (ret < 0) {
2413         goto OUT;
2414     }
2415 
2416     ret = stat(fullpath, &bufRet);
2417     if (ret < 0) {
2418         ret = -get_errno();
2419         goto OUT;
2420     }
2421 
2422     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
2423     if (ret != 0) {
2424         ret = -EFAULT;
2425         goto OUT;
2426     }
2427 
2428 OUT:
2429     if (pathRet != NULL) {
2430         LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2431     }
2432 
2433     if (fullpath != NULL) {
2434         free(fullpath);
2435     }
2436     return ret;
2437 }
2438 
SysFaccessat(int fd,const char * filename,int amode,int flag)2439 int SysFaccessat(int fd, const char *filename, int amode, int flag)
2440 {
2441     int ret;
2442     struct stat buf;
2443     struct statfs fsBuf;
2444     char *fullDirectory = NULL;
2445 
2446     ret = GetFullpath(fd, filename, &fullDirectory);
2447     if (ret < 0) {
2448         goto OUT;
2449     }
2450 
2451     ret = statfs(fullDirectory, &fsBuf);
2452     if (ret != 0) {
2453         ret = -get_errno();
2454         goto OUT;
2455     }
2456 
2457     if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) {
2458         ret = -EROFS;
2459         goto OUT;
2460     }
2461 
2462     ret = stat(fullDirectory, &buf);
2463     if (ret != 0) {
2464         ret = -get_errno();
2465         goto OUT;
2466     }
2467 
2468     if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) {
2469         ret = -EACCES;
2470     }
2471 
2472 OUT:
2473     PointerFree(fullDirectory);
2474 
2475     return ret;
2476 }
2477 
SysFstatfs(int fd,struct statfs * buf)2478 int SysFstatfs(int fd, struct statfs *buf)
2479 {
2480     int ret;
2481     struct file *filep = NULL;
2482     struct statfs bufRet = {0};
2483 
2484     /* Process fd convert to system global fd */
2485     fd = GetAssociatedSystemFd(fd);
2486 
2487     ret = fs_getfilep(fd, &filep);
2488     if (ret < 0) {
2489         ret = -get_errno();
2490         return ret;
2491     }
2492 
2493     ret = statfs(filep->f_path, &bufRet);
2494     if (ret < 0) {
2495         ret = -get_errno();
2496         return ret;
2497     }
2498 
2499     ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
2500     if (ret != 0) {
2501         ret = -EFAULT;
2502     }
2503 
2504     return ret;
2505 }
2506 
SysFstatfs64(int fd,size_t sz,struct statfs * buf)2507 int SysFstatfs64(int fd, size_t sz, struct statfs *buf)
2508 {
2509     int ret;
2510 
2511     if (sz != sizeof(struct statfs)) {
2512         ret = -EINVAL;
2513         return ret;
2514     }
2515 
2516     ret = SysFstatfs(fd, buf);
2517 
2518     return ret;
2519 }
2520 
SysPpoll(struct pollfd * fds,nfds_t nfds,const struct timespec * tmo_p,const sigset_t * sigMask,int nsig)2521 int SysPpoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigMask, int nsig)
2522 {
2523     int timeout, retVal;
2524     sigset_t_l origMask = {0};
2525     sigset_t_l set = {0};
2526 
2527     CHECK_ASPACE(tmo_p, sizeof(struct timespec));
2528     CPY_FROM_USER(tmo_p);
2529 
2530     if (tmo_p != NULL) {
2531         timeout = tmo_p->tv_sec * OS_SYS_US_PER_MS + tmo_p->tv_nsec / OS_SYS_NS_PER_MS;
2532         if (timeout < 0) {
2533             return -EINVAL;
2534         }
2535     } else {
2536         timeout = -1;
2537     }
2538 
2539     if (sigMask != NULL) {
2540         retVal = LOS_ArchCopyFromUser(&set, sigMask, sizeof(sigset_t));
2541         if (retVal != 0) {
2542             return -EFAULT;
2543         }
2544         (VOID)OsSigprocMask(SIG_SETMASK, &set, &origMask);
2545     } else {
2546         (VOID)OsSigprocMask(SIG_SETMASK, NULL, &origMask);
2547     }
2548 
2549     retVal = SysPoll(fds, nfds, timeout);
2550     (VOID)OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2551 
2552     return retVal;
2553 }
2554 
SysPselect6(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,const struct timespec * timeout,const long data[2])2555 int SysPselect6(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
2556     const struct timespec *timeout, const long data[2])
2557 {
2558     int ret;
2559     int retVal;
2560     sigset_t_l origMask;
2561     sigset_t_l setl;
2562 
2563     CHECK_ASPACE(readfds, sizeof(fd_set));
2564     CHECK_ASPACE(writefds, sizeof(fd_set));
2565     CHECK_ASPACE(exceptfds, sizeof(fd_set));
2566     CHECK_ASPACE(timeout, sizeof(struct timeval));
2567 
2568     CPY_FROM_USER(readfds);
2569     CPY_FROM_USER(writefds);
2570     CPY_FROM_USER(exceptfds);
2571     DUP_FROM_USER(timeout, sizeof(struct timeval));
2572 
2573     if (timeout != NULL) {
2574         ((struct timeval *)timeout)->tv_usec = timeout->tv_nsec / 1000; /* 1000, convert ns to us */
2575     }
2576 
2577     if (data != NULL) {
2578         retVal = LOS_ArchCopyFromUser(&(setl.sig[0]), (int *)((UINTPTR)data[0]), sizeof(sigset_t));
2579         if (retVal != 0) {
2580             ret = -EFAULT;
2581             FREE_DUP(timeout);
2582             return ret;
2583         }
2584     }
2585 
2586     OsSigprocMask(SIG_SETMASK, &setl, &origMask);
2587     ret = do_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout, UserPoll);
2588     if (ret < 0) {
2589         /* do not copy parameter back to user mode if do_select failed */
2590         ret = -get_errno();
2591         FREE_DUP(timeout);
2592         return ret;
2593     }
2594     OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2595 
2596     CPY_TO_USER(readfds);
2597     CPY_TO_USER(writefds);
2598     CPY_TO_USER(exceptfds);
2599     FREE_DUP(timeout);
2600 
2601     return ret;
2602 }
2603 
DoEpollCreate1(int flags)2604 static int DoEpollCreate1(int flags)
2605 {
2606     int ret;
2607     int procFd;
2608 
2609     ret = epoll_create1(flags);
2610     if (ret < 0) {
2611         ret = -get_errno();
2612         return ret;
2613     }
2614 
2615     procFd = AllocAndAssocProcessFd((INTPTR)(ret), MIN_START_FD);
2616     if (procFd == -1) {
2617         epoll_close(ret);
2618         return -EMFILE;
2619     }
2620 
2621     return procFd;
2622 }
2623 
SysEpollCreate(int size)2624 int SysEpollCreate(int size)
2625 {
2626     (void)size;
2627     return DoEpollCreate1(0);
2628 }
2629 
SysEpollCreate1(int flags)2630 int SysEpollCreate1(int flags)
2631 {
2632     return DoEpollCreate1(flags);
2633 }
2634 
SysEpollCtl(int epfd,int op,int fd,struct epoll_event * ev)2635 int SysEpollCtl(int epfd, int op, int fd, struct epoll_event *ev)
2636 {
2637     int ret;
2638 
2639     CHECK_ASPACE(ev, sizeof(struct epoll_event));
2640     CPY_FROM_USER(ev);
2641 
2642     fd = GetAssociatedSystemFd(fd);
2643     epfd = GetAssociatedSystemFd(epfd);
2644     if ((fd < 0) || (epfd < 0)) {
2645         ret = -EBADF;
2646         goto OUT;
2647     }
2648 
2649     ret = epoll_ctl(epfd, op, fd, ev);
2650     if (ret < 0) {
2651         ret = -EBADF;
2652         goto OUT;
2653     }
2654 
2655     CPY_TO_USER(ev);
2656 OUT:
2657     return (ret == -1) ? -get_errno() : ret;
2658 }
2659 
SysEpollWait(int epfd,struct epoll_event * evs,int maxevents,int timeout)2660 int SysEpollWait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
2661 {
2662     int ret = 0;
2663 
2664     CHECK_ASPACE(evs, sizeof(struct epoll_event));
2665     CPY_FROM_USER(evs);
2666 
2667     epfd = GetAssociatedSystemFd(epfd);
2668     if  (epfd < 0) {
2669         ret = -EBADF;
2670         goto OUT;
2671     }
2672 
2673     ret = epoll_wait(epfd, evs, maxevents, timeout);
2674     if (ret < 0) {
2675         ret = -get_errno();
2676     }
2677 
2678     CPY_TO_USER(evs);
2679 OUT:
2680     return (ret == -1) ? -get_errno() : ret;
2681 }
2682 
SysEpollPwait(int epfd,struct epoll_event * evs,int maxevents,int timeout,const sigset_t * mask)2683 int SysEpollPwait(int epfd, struct epoll_event *evs, int maxevents, int timeout, const sigset_t *mask)
2684 {
2685     sigset_t_l origMask;
2686     sigset_t_l setl;
2687     int ret = 0;
2688 
2689     CHECK_ASPACE(mask, sizeof(sigset_t));
2690 
2691     if (mask != NULL) {
2692         ret = LOS_ArchCopyFromUser(&setl, mask, sizeof(sigset_t));
2693         if (ret != 0) {
2694             return -EFAULT;
2695         }
2696     }
2697 
2698     CHECK_ASPACE(evs, sizeof(struct epoll_event));
2699     CPY_FROM_USER(evs);
2700 
2701     epfd = GetAssociatedSystemFd(epfd);
2702     if (epfd < 0) {
2703         ret = -EBADF;
2704         goto OUT;
2705     }
2706 
2707     OsSigprocMask(SIG_SETMASK, &setl, &origMask);
2708     ret = epoll_wait(epfd, evs, maxevents, timeout);
2709     if (ret < 0) {
2710         ret = -get_errno();
2711     }
2712 
2713     OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2714 
2715     CPY_TO_USER(evs);
2716 OUT:
2717     return (ret == -1) ? -get_errno() : ret;
2718 }
2719 
2720 #endif
2721