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