• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #define _GNU_SOURCE 1
32 #include "los_fs.h"
33 #include <stdint.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <stdbool.h>
38 #include <unistd.h>
39 #include <sys/uio.h>
40 #include "errno.h"
41 #include "fcntl.h"
42 #include "los_mux.h"
43 #include "los_debug.h"
44 #include "los_sched.h"
45 #include "limits.h"
46 #include "securec.h"
47 #include "vfs_config.h"
48 #include "vfs_files.h"
49 #include "vfs_maps.h"
50 #include "vfs_mount.h"
51 #include "vfs_operations.h"
52 
53 #ifdef LOSCFG_NET_LWIP_SACK
54 #include "lwipopts.h"
55 #include "lwip/sockets.h"
56 #define CONFIG_NSOCKET_DESCRIPTORS  LWIP_CONFIG_NUM_SOCKETS
57 #else
58 #define CONFIG_NSOCKET_DESCRIPTORS  0
59 #endif
60 
61 #ifdef LOSCFG_RANDOM_DEV
62 #include "hks_client.h"
63 #define RANDOM_DEV_FD  CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS
64 #define RANDOM_DEV_PATH  "/dev/random"
65 #endif
66 
67 #if (LOSCFG_POSIX_PIPE_API == 1)
68 #include "pipe_impl.h"
69 #ifdef LOSCFG_RANDOM_DEV
70 #define PIPE_DEV_FD (RANDOM_DEV_FD + 1)
71 #else
72 #define PIPE_DEV_FD (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)
73 #endif
74 
PollQueryFd(int fd,struct PollTable * table)75 int PollQueryFd(int fd, struct PollTable *table)
76 {
77     if (fd >= PIPE_DEV_FD) {
78         return PipePoll(fd, table);
79     }
80 
81     return -ENODEV;
82 }
83 #endif
84 
85 #define FREE_AND_SET_NULL(ptr) do { \
86     LOSCFG_FS_FREE_HOOK(ptr);       \
87     ptr = NULL;                     \
88 } while (0)
89 
90 #define LOS_FCNTL   (O_NONBLOCK | O_NDELAY | O_APPEND | O_SYNC)
91 #define IOV_MAX_CNT 4
92 
93 UINT32 g_fsMutex;
94 static UINT32 g_dirNum = 0;
95 
LOS_FsLock(void)96 int LOS_FsLock(void)
97 {
98     if (!OsCheckKernelRunning()) {
99         return LOS_OK;
100     }
101     if (LOS_MuxPend(g_fsMutex, (UINT32)LOSCFG_FS_LOCK_TIMEOUT) != LOS_OK) {
102         PRINT_ERR("LOS_FsLock failed!");
103         return (int)LOS_NOK;
104     }
105 
106     return LOS_OK;
107 }
108 
LOS_FsUnlock(void)109 void LOS_FsUnlock(void)
110 {
111     if (!OsCheckKernelRunning()) {
112         return;
113     }
114     (void)LOS_MuxPost(g_fsMutex);
115 }
116 
117 #ifdef LOSCFG_RANDOM_DEV
118 /**
119  * @brief Get canonical form of a given path based on cwd(Current working directory).
120  *
121  * @param cwd Indicates the current working directory.
122  * @param path Indicates the path to be canonicalization.
123  * @param buf Indicates the pointer to the buffer where the result will be return.
124  * @param bufSize Indicates the size of the buffer.
125  * @return Returns the length of the canonical path.
126  *
127  * @attention if path is an absolute path, cwd is ignored. if cwd if not specified, it is assumed to be root('/').
128  *            if the buffer is not big enough the result will be truncated, but the return value will always be the
129  *            length of the canonical path.
130  */
GetCanonicalPath(const char * cwd,const char * path,char * buf,size_t bufSize)131 static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, size_t bufSize)
132 {
133     size_t offset;
134     if (!path) {
135         path = "";
136     }
137 
138     if ((!cwd) || (path[0] == '/')) {
139         cwd = "";
140     }
141 
142     offset = strlen("///") + 1; // three '/' and one '\0'
143     size_t tmpLen = strlen(cwd) + strlen(path) + offset;
144     char *tmpBuf = (char *)LOSCFG_FS_MALLOC_HOOK(tmpLen);
145     if (tmpBuf == NULL) {
146         return LOS_OK;
147     }
148 
149     if (-1 == sprintf_s(tmpBuf, tmpLen, "/%s/%s/", cwd, path)) {
150         LOSCFG_FS_FREE_HOOK(tmpBuf);
151         return LOS_OK;
152     }
153 
154     char *p;
155     /* replace /./ to / */
156     offset = strlen("/./") - 1;
157     while ((p = strstr(tmpBuf, "/./")) != NULL) {
158         if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) {
159             LOSCFG_FS_FREE_HOOK(tmpBuf);
160             return LOS_OK;
161         }
162     }
163 
164     /* replace // to / */
165     while ((p = strstr(tmpBuf, "//")) != NULL) {
166         if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + 1, tmpLen - (p - tmpBuf) - 1)) {
167             LOSCFG_FS_FREE_HOOK(tmpBuf);
168             return LOS_OK;
169         }
170     }
171 
172     /* handle /../ (e.g., replace /aa/bb/../ to /aa/) */
173     offset = strlen("/../") - 1;
174     while ((p = strstr(tmpBuf, "/../")) != NULL) {
175         char *start = p;
176         while (start > tmpBuf && *(start - 1) != '/') {
177             --start;
178         }
179         if (EOK != memmove_s(start, tmpLen - (start - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) {
180             LOSCFG_FS_FREE_HOOK(tmpBuf);
181             return LOS_OK;
182         }
183     }
184 
185     size_t totalLen = strlen(tmpBuf);
186     /* strip the last / */
187     if (totalLen > 1 && tmpBuf[totalLen - 1] == '/') {
188         tmpBuf[--totalLen] = 0;
189     }
190 
191     if ((!buf) || (bufSize == 0)) {
192         LOSCFG_FS_FREE_HOOK(tmpBuf);
193         return totalLen;
194     }
195 
196     if (EOK != memcpy_s(buf, bufSize, tmpBuf, (((totalLen + 1) > bufSize) ? bufSize : (totalLen + 1)))) {
197         LOSCFG_FS_FREE_HOOK(tmpBuf);
198         return LOS_OK;
199     }
200 
201     buf[bufSize - 1] = 0;
202     LOSCFG_FS_FREE_HOOK(tmpBuf);
203     return totalLen;
204 }
205 #endif
206 
VfsPathCheck(const char * path,bool isFile)207 static int VfsPathCheck(const char *path, bool isFile)
208 {
209     size_t len;
210     if ((path == NULL) || (path[0] == '\0')) {
211         VFS_ERRNO_SET(EINVAL);
212         return (int)LOS_NOK;
213     }
214 
215     len = strlen(path);
216     if (len >= PATH_MAX) {
217         VFS_ERRNO_SET(ENAMETOOLONG);
218         return (int)LOS_NOK;
219     }
220 
221     if (isFile && path[len - 1] == '/') {
222         VFS_ERRNO_SET(EINVAL);
223         return (int)LOS_NOK;
224     }
225 
226     return LOS_OK;
227 }
228 
VfsOpen(const char * path,int flags)229 static int VfsOpen(const char *path, int flags)
230 {
231     size_t len;
232     struct File *file = NULL;
233     int fd = -1;
234     const char *pathInMp = NULL;
235     struct MountPoint *mp = NULL;
236 
237     if (VfsPathCheck(path, TRUE) != LOS_OK) {
238         return fd;
239     }
240 
241     if (LOS_FsLock() != LOS_OK) {
242         VFS_ERRNO_SET(EAGAIN);
243         return fd;
244     }
245 
246     mp = VfsMpFind(path, &pathInMp);
247     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0') ||
248         (mp->mFs->fsFops == NULL) || (mp->mFs->fsFops->open == NULL)) {
249         /* path is not in any mountpoint */
250         VFS_ERRNO_SET(ENOENT);
251         LOS_FsUnlock();
252         return fd;
253     }
254 
255     if ((mp->mWriteEnable == FALSE) &&
256         (flags & (O_CREAT | O_WRONLY | O_RDWR))) {
257         /* can't create file in read only mp */
258         VFS_ERRNO_SET(EACCES);
259         LOS_FsUnlock();
260         return fd;
261     }
262 
263     file = VfsFileGet();
264     if (file == NULL) {
265         VFS_ERRNO_SET(ENFILE);
266         LOS_FsUnlock();
267         return fd;
268     }
269 
270     len = strlen(path) + 1;
271     file->fullPath = LOSCFG_FS_MALLOC_HOOK(len);
272     if (file->fullPath == NULL) {
273         VFS_ERRNO_SET(ENOMEM);
274         VfsFilePut(file);
275         LOS_FsUnlock();
276         return (int)LOS_NOK;
277     }
278     (void)strcpy_s((char *)file->fullPath, len, path);
279 
280     file->fFlags = (UINT32)flags;
281     file->fOffset = 0;
282     file->fData = NULL;
283     file->fFops = mp->mFs->fsFops;
284     file->fMp = mp;
285     file->fOwner = LOS_CurTaskIDGet();
286 
287     if (file->fFops->open(file, pathInMp, flags) == 0) {
288         mp->mRefs++;
289         fd = FileToFd(file);
290         file->fStatus = FILE_STATUS_READY; /* file now ready to use */
291     } else {
292         LOSCFG_FS_FREE_HOOK((void *)file->fullPath);
293         VfsFilePut(file);
294     }
295 
296     LOS_FsUnlock();
297     return fd;
298 }
299 
300 /* attach to a file and then set new status */
301 
VfsAttachFile(int fd,UINT32 status)302 static struct File *VfsAttachFile(int fd, UINT32 status)
303 {
304     struct File *file = NULL;
305 
306     if ((fd < MIN_START_FD) || (fd >= CONFIG_NFILE_DESCRIPTORS)) {
307         VFS_ERRNO_SET(EBADF);
308         return NULL;
309     }
310 
311     if (LOS_FsLock() != LOS_OK) {
312         VFS_ERRNO_SET(EFAULT);
313         return NULL;
314     }
315 
316     file = FdToFile(fd);
317     if ((file == NULL) || (file->fMp == NULL)) {
318         VFS_ERRNO_SET(EBADF);
319         LOS_FsUnlock();
320         return NULL;
321     }
322 
323     if (file->fStatus != FILE_STATUS_READY) {
324         VFS_ERRNO_SET(EBADF);
325         LOS_FsUnlock();
326         return NULL;
327     }
328 
329     file->fStatus = status;
330     return file;
331 }
332 
VfsAttachFileReady(int fd)333 static struct File *VfsAttachFileReady(int fd)
334 {
335     return VfsAttachFile(fd, FILE_STATUS_READY);
336 }
337 
VfsAttachFileWithStatus(int fd,int status)338 static struct File *VfsAttachFileWithStatus(int fd, int status)
339 {
340     return VfsAttachFile(fd, (UINT32)status);
341 }
342 
VfsDetachFile(const struct File * file)343 static void VfsDetachFile(const struct File *file)
344 {
345     (void)file;
346     LOS_FsUnlock();
347 }
348 
VfsClose(int fd)349 static int VfsClose(int fd)
350 {
351     struct File *file = NULL;
352     int ret = (int)LOS_NOK;
353 
354     file = VfsAttachFileWithStatus(fd, FILE_STATUS_CLOSING);
355     if (file == NULL) {
356         return ret;
357     }
358 
359     if ((file->fFops != NULL) && (file->fFops->close != NULL)) {
360         ret = file->fFops->close(file);
361     } else {
362         VFS_ERRNO_SET(ENOTSUP);
363     }
364 
365     if ((ret == 0) && (file->fMp != NULL)) {
366         file->fMp->mRefs--;
367     }
368 
369     if (file->fullPath != NULL) {
370         LOSCFG_FS_FREE_HOOK((void *)file->fullPath);
371     }
372 
373     VfsFilePut(file);
374 
375     VfsDetachFile(file);
376 
377     return ret;
378 }
379 
VfsRead(int fd,char * buff,size_t bytes)380 static ssize_t VfsRead(int fd, char *buff, size_t bytes)
381 {
382     struct File *file = NULL;
383     ssize_t ret = (ssize_t)-1;
384 
385     if (buff == NULL) {
386         VFS_ERRNO_SET(EFAULT);
387         return ret;
388     }
389 
390     if (bytes == 0) {
391         return 0;
392     }
393 
394     file = VfsAttachFileReady(fd);
395     if (file == NULL) {
396         return ret;
397     }
398 
399     if ((file->fFlags & O_ACCMODE) == O_WRONLY) {
400         VFS_ERRNO_SET(EACCES);
401     } else if ((file->fFops != NULL) && (file->fFops->read != NULL)) {
402         ret = file->fFops->read(file, buff, bytes);
403     } else {
404         VFS_ERRNO_SET(ENOTSUP);
405     }
406 
407     /* else ret will be -1 */
408     VfsDetachFile(file);
409 
410     return ret;
411 }
412 
VfsWrite(int fd,const void * buff,size_t bytes)413 static ssize_t VfsWrite(int fd, const void *buff, size_t bytes)
414 {
415     struct File *file = NULL;
416     ssize_t ret = (ssize_t)LOS_NOK;
417 
418     if ((buff == NULL) || (bytes == 0)) {
419         VFS_ERRNO_SET(EINVAL);
420         return ret;
421     }
422 
423     file = VfsAttachFileReady(fd);
424     if (file == NULL) {
425         return ret;
426     }
427 
428     if ((file->fFlags & O_ACCMODE) == O_RDONLY) {
429         VFS_ERRNO_SET(EACCES);
430     } else if ((file->fFops != NULL) && (file->fFops->write != NULL)) {
431         ret = file->fFops->write(file, buff, bytes);
432     } else {
433         VFS_ERRNO_SET(ENOTSUP);
434     }
435 
436     /* else ret will be -1 */
437     VfsDetachFile(file);
438 
439     return ret;
440 }
441 
VfsIoctl(int fd,int func,va_list ap)442 static int VfsIoctl(int fd, int func, va_list ap)
443 {
444     unsigned long arg;
445     struct File *file = NULL;
446     int ret = (int)LOS_NOK;
447 
448     arg = va_arg(ap, unsigned long);
449     file = VfsAttachFileReady(fd);
450     if (file == NULL) {
451         return ret;
452     }
453 
454     if ((file->fFops != NULL) && (file->fFops->ioctl != NULL)) {
455         ret = file->fFops->ioctl(file, func, arg);
456     } else {
457         VFS_ERRNO_SET(ENOTSUP);
458     }
459 
460     VfsDetachFile(file);
461 
462     return ret;
463 }
464 
VfsVfcntl(struct File * filep,int cmd,va_list ap)465 static int VfsVfcntl(struct File *filep, int cmd, va_list ap)
466 {
467     int ret;
468     UINT32 flags;
469 
470     if ((filep == NULL) || (filep->fFops == NULL)) {
471         return -EBADF;
472     }
473 
474     if (cmd == F_GETFL) {
475         ret = (int)(filep->fFlags);
476     } else if (cmd == F_SETFL) {
477         flags = (UINT32)va_arg(ap, int);
478         flags &= LOS_FCNTL;
479         filep->fFlags &= ~LOS_FCNTL;
480         filep->fFlags |= flags;
481         ret = LOS_OK;
482     } else {
483         ret = -ENOSYS;
484     }
485     return ret;
486 }
487 
MapToPosixRet(int ret)488 static int MapToPosixRet(int ret)
489 {
490     return ((ret) < 0 ? -1 : (ret));
491 }
492 
493 /* POSIX interface */
open(const char * path,int flags,...)494 int open(const char *path, int flags, ...)
495 {
496     if (path == NULL) {
497         errno = EINVAL;
498         return (int)LOS_NOK;
499     }
500 #ifdef LOSCFG_RANDOM_DEV
501     unsigned flagMask = O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_LARGEFILE \
502                         | O_TRUNC | O_EXCL | O_DIRECTORY;
503     if ((unsigned)flags & ~flagMask) {
504         errno = EINVAL;
505         return (int)LOS_NOK;
506     }
507 
508     size_t pathLen = strlen(path) + 1;
509     if ((unsigned)pathLen > PATH_MAX) {
510         errno = EINVAL;
511         return (int)LOS_NOK;
512     }
513 
514     char *canonicalPath = (char *)LOSCFG_FS_MALLOC_HOOK(pathLen);
515     if (!canonicalPath) {
516         errno = ENOMEM;
517         return (int)LOS_NOK;
518     }
519     if (GetCanonicalPath(NULL, path, canonicalPath, pathLen) == 0) {
520         FREE_AND_SET_NULL(canonicalPath);
521         errno = ENOMEM;
522         return (int)LOS_NOK;
523     }
524 
525     if (strcmp(canonicalPath, RANDOM_DEV_PATH) == 0) {
526         FREE_AND_SET_NULL(canonicalPath);
527         if ((O_ACCMODE & (unsigned)flags) != O_RDONLY) {
528             errno = EPERM;
529             return (int)LOS_NOK;
530         }
531         if ((unsigned)flags & O_DIRECTORY) {
532             errno = ENOTDIR;
533             return (int)LOS_NOK;
534         }
535         return RANDOM_DEV_FD;
536     }
537     if ((strcmp(canonicalPath, "/") == 0) ||
538         (strcmp(canonicalPath, "/dev") == 0)) {
539         FREE_AND_SET_NULL(canonicalPath);
540         if ((unsigned)flags & O_DIRECTORY) {
541             errno = EPERM;
542             return (int)LOS_NOK;
543         }
544         errno = EISDIR;
545         return (int)LOS_NOK;
546     }
547     FREE_AND_SET_NULL(canonicalPath);
548 #endif
549 #if (LOSCFG_POSIX_PIPE_API == 1)
550     if (!strncmp(path, PIPE_DEV_PATH, strlen(PIPE_DEV_PATH))) {
551         return PipeOpen(path, flags, PIPE_DEV_FD);
552     }
553 #endif
554 
555     int ret = VfsOpen(path, flags);
556     return MapToPosixRet(ret);
557 }
558 #if (LOSCFG_LIBC_NEWLIB == 1)
559 FUNC_ALIAS(open, _open, (const char *path, int flags, ...), int);
560 #endif
561 
close(int fd)562 int close(int fd)
563 {
564 #ifdef LOSCFG_RANDOM_DEV
565     if (fd == RANDOM_DEV_FD) {
566         return LOS_OK;
567     }
568 #endif
569 #ifdef LOSCFG_NET_LWIP_SACK
570     if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
571         return closesocket(fd);
572     }
573 #endif /* LOSCFG_NET_LWIP_SACK */
574 #if (LOSCFG_POSIX_PIPE_API == 1)
575     if (fd >= PIPE_DEV_FD) {
576         return PipeClose(fd);
577     }
578 #endif
579 
580     int ret = (int)LOS_NOK;
581     if (fd >= MIN_START_FD && fd < CONFIG_NFILE_DESCRIPTORS) {
582         ret = VfsClose(fd);
583     }
584     return MapToPosixRet(ret);
585 }
586 #if (LOSCFG_LIBC_NEWLIB == 1)
587 FUNC_ALIAS(close, _close, (int fd), int);
588 #endif
589 
read(int fd,void * buff,size_t bytes)590 ssize_t read(int fd, void *buff, size_t bytes)
591 {
592 #ifdef LOSCFG_RANDOM_DEV
593     if (fd == RANDOM_DEV_FD) {
594         if (nbyte == 0) {
595             return FS_SUCCESS;
596         }
597         if (buf == NULL) {
598             errno = EINVAL;
599             return FS_FAILURE;
600         }
601         if (nbyte > 1024) { /* 1024, max random_size */
602             nbyte = 1024; /* hks_generate_random: random_size must <= 1024 */
603         }
604         struct hks_blob key = {HKS_BLOB_TYPE_RAW, (uint8_t *)buf, nbyte};
605         if (hks_generate_random(&key) != 0) {
606             errno = EIO;
607             return FS_FAILURE;
608         }
609         return (ssize_t)nbyte;
610     }
611 #endif
612 #ifdef LOSCFG_NET_LWIP_SACK
613     if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
614         return recv(fd, buff, bytes, 0);
615     }
616 #endif /* LOSCFG_NET_LWIP_SACK */
617 
618 #if (LOSCFG_POSIX_PIPE_API == 1)
619     if (fd >= PIPE_DEV_FD) {
620         return PipeRead(fd, buff, bytes);
621     }
622 #endif
623 
624     ssize_t ret = (ssize_t)LOS_NOK;
625     if (fd >= MIN_START_FD && fd < CONFIG_NFILE_DESCRIPTORS) {
626         ret = VfsRead(fd, buff, bytes);
627     }
628 
629     return MapToPosixRet(ret);
630 }
631 #if (LOSCFG_LIBC_NEWLIB == 1)
632 FUNC_ALIAS(read, _read, (int fd, void *buff, size_t bytes), ssize_t);
633 #endif
634 
write(int fd,const void * buff,size_t bytes)635 ssize_t write(int fd, const void *buff, size_t bytes)
636 {
637 #ifdef LOSCFG_RANDOM_DEV
638     if (fd == RANDOM_DEV_FD) {
639         errno = EBADF; /* "/dev/random" is readonly */
640         return (ssize_t)LOS_NOK;
641     }
642 #endif
643 #ifdef LOSCFG_NET_LWIP_SACK
644     if (fd >= CONFIG_NFILE_DESCRIPTORS &&
645         fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
646         return send(fd, buff, bytes, 0);
647     }
648 #endif /* LOSCFG_NET_LWIP_SACK */
649 
650 #if (LOSCFG_POSIX_PIPE_API == 1)
651     if (fd >= PIPE_DEV_FD) {
652         return PipeWrite(fd, buff, bytes);
653     }
654 #endif
655 
656     ssize_t ret = (ssize_t)LOS_NOK;
657     if (fd >= MIN_START_FD && fd < CONFIG_NFILE_DESCRIPTORS) {
658         ret = VfsWrite(fd, buff, bytes);
659     }
660 
661     return MapToPosixRet(ret);
662 }
663 #if (LOSCFG_LIBC_NEWLIB == 1)
664 FUNC_ALIAS(write, _write, (int fd, const void *buff, size_t bytes), ssize_t);
665 #endif
666 
lseek(int fd,off_t off,int whence)667 off_t lseek(int fd, off_t off, int whence)
668 {
669     struct File *file;
670     off_t ret = (off_t)LOS_NOK;
671 
672     file = VfsAttachFileReady(fd);
673     if (file == NULL) {
674         return ret;
675     }
676 
677     if ((file->fFops == NULL) || (file->fFops->lseek == NULL)) {
678         ret = file->fOffset;
679     } else {
680         ret = file->fFops->lseek(file, off, whence);
681     }
682 
683     VfsDetachFile(file);
684     return ret;
685 }
686 #if (LOSCFG_LIBC_NEWLIB == 1)
687 FUNC_ALIAS(lseek, _lseek, (int fd, off_t off, int whence), off_t);
688 #endif
689 
stat(const char * path,struct stat * stat)690 int stat(const char *path, struct stat *stat)
691 {
692     struct MountPoint *mp = NULL;
693     const char *pathInMp = NULL;
694     int ret = (int)LOS_NOK;
695 
696     if (VfsPathCheck(path, FALSE) != LOS_OK) {
697         return MapToPosixRet(ret);
698     }
699 
700     if (stat == NULL) {
701         VFS_ERRNO_SET(EINVAL);
702         return MapToPosixRet(ret);
703     }
704 
705     if (LOS_FsLock() != LOS_OK) {
706         VFS_ERRNO_SET(EAGAIN);
707         return MapToPosixRet(ret);
708     }
709 
710     mp = VfsMpFind(path, &pathInMp);
711     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0')) {
712         VFS_ERRNO_SET(ENOENT);
713         LOS_FsUnlock();
714         return MapToPosixRet(ret);
715     }
716 
717     if (mp->mFs->fsFops->stat != NULL) {
718         ret = mp->mFs->fsFops->stat(mp, pathInMp, stat);
719     } else {
720         VFS_ERRNO_SET(ENOTSUP);
721     }
722 
723     LOS_FsUnlock();
724     return MapToPosixRet(ret);
725 }
726 #if (LOSCFG_LIBC_NEWLIB == 1)
727 FUNC_ALIAS(stat, _stat, (const char *path, struct stat *stat), int);
728 #endif
729 
statfs(const char * path,struct statfs * buf)730 int statfs(const char *path, struct statfs *buf)
731 {
732     struct MountPoint *mp = NULL;
733     const char *pathInMp = NULL;
734     int ret = (int)LOS_NOK;
735 
736     if (VfsPathCheck(path, FALSE) != LOS_OK) {
737         return MapToPosixRet(ret);
738     }
739 
740     if (buf == NULL) {
741         VFS_ERRNO_SET(EINVAL);
742         return MapToPosixRet(ret);
743     }
744 
745     if (LOS_FsLock() != LOS_OK) {
746         VFS_ERRNO_SET(EAGAIN);
747         return MapToPosixRet(ret);
748     }
749 
750     mp = VfsMpFind(path, &pathInMp);
751     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0')) {
752         VFS_ERRNO_SET(ENOENT);
753         LOS_FsUnlock();
754         return MapToPosixRet(ret);
755     }
756 
757     if (mp->mFs->fsMops->statfs != NULL) {
758         ret = mp->mFs->fsMops->statfs(pathInMp, buf);
759     } else {
760         VFS_ERRNO_SET(ENOTSUP);
761     }
762 
763     LOS_FsUnlock();
764     return MapToPosixRet(ret);
765 }
766 
unlink(const char * path)767 int unlink(const char *path)
768 {
769     struct MountPoint *mp = NULL;
770     const char *pathInMp = NULL;
771     int ret = (int)LOS_NOK;
772 
773     if (VfsPathCheck(path, FALSE) != LOS_OK) {
774         return MapToPosixRet(ret);
775     }
776 
777     if (LOS_FsLock() != LOS_OK) {
778         VFS_ERRNO_SET(EAGAIN);
779         return MapToPosixRet(ret);
780     }
781 
782     mp = VfsMpFind(path, &pathInMp);
783     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0') ||
784         (mp->mFs->fsFops->unlink == NULL)) {
785         VFS_ERRNO_SET(ENOENT);
786         LOS_FsUnlock();
787         return MapToPosixRet(ret);
788     }
789 
790     ret = mp->mFs->fsFops->unlink(mp, pathInMp);
791 
792     LOS_FsUnlock();
793     return MapToPosixRet(ret);
794 }
795 #if (LOSCFG_LIBC_NEWLIB == 1)
796 FUNC_ALIAS(unlink, _unlink, (const char *path), int);
797 #endif
798 
rename(const char * oldpath,const char * newpath)799 int rename(const char *oldpath, const char *newpath)
800 {
801     struct MountPoint *mpOld = NULL;
802     struct MountPoint *mpNew = NULL;
803     const char *pathInMpOld = NULL;
804     const char *pathInMpNew = NULL;
805     int ret = (int)LOS_NOK;
806 
807     if (VfsPathCheck(oldpath, FALSE) != LOS_OK) {
808         return MapToPosixRet(ret);
809     }
810     if (VfsPathCheck(newpath, FALSE) != LOS_OK) {
811         return MapToPosixRet(ret);
812     }
813 
814     if (LOS_FsLock() != LOS_OK) {
815         VFS_ERRNO_SET(EAGAIN);
816         return MapToPosixRet(ret);
817     }
818 
819     mpOld = VfsMpFind(oldpath, &pathInMpOld);
820 
821     if (pathInMpOld == NULL) {
822         VFS_ERRNO_SET(EINVAL);
823         LOS_FsUnlock();
824         return MapToPosixRet(ret);
825     }
826 
827     if ((mpOld == NULL) || (*pathInMpOld == '\0') ||
828         (mpOld->mFs->fsFops->unlink == NULL)) {
829         VFS_ERRNO_SET(EINVAL);
830         LOS_FsUnlock();
831         return MapToPosixRet(ret);
832     }
833 
834     mpNew = VfsMpFind(newpath, &pathInMpNew);
835     if ((mpNew == NULL) || (pathInMpNew == NULL) || (*pathInMpNew == '\0') || (mpNew->mFs->fsFops->unlink == NULL)) {
836         VFS_ERRNO_SET(EINVAL);
837         LOS_FsUnlock();
838         return MapToPosixRet(ret);
839     }
840 
841     if (mpOld != mpNew) {
842         VFS_ERRNO_SET(EXDEV);
843         LOS_FsUnlock();
844         return MapToPosixRet(ret);
845     }
846 
847     if (mpOld->mFs->fsFops->rename != NULL) {
848         ret = mpOld->mFs->fsFops->rename(mpOld, pathInMpOld, pathInMpNew);
849     } else {
850         VFS_ERRNO_SET(ENOTSUP);
851     }
852 
853     LOS_FsUnlock();
854     return MapToPosixRet(ret);
855 }
856 
fsync(int fd)857 int fsync(int fd)
858 {
859     struct File *file;
860     int ret = (int)LOS_NOK;
861 
862     file = VfsAttachFileReady(fd);
863     if (file == NULL) {
864         return MapToPosixRet(ret);
865     }
866 
867     if (file->fMp->mWriteEnable == FALSE) {
868         VFS_ERRNO_SET(EACCES);
869         VfsDetachFile(file);
870         return MapToPosixRet(ret);
871     }
872 
873     if ((file->fFops != NULL) && (file->fFops->sync != NULL)) {
874         ret = file->fFops->sync(file);
875     } else {
876         VFS_ERRNO_SET(ENOTSUP);
877     }
878 
879     VfsDetachFile(file);
880     return MapToPosixRet(ret);
881 }
882 
opendir(const char * path)883 DIR *opendir(const char *path)
884 {
885     struct MountPoint *mp = NULL;
886     const char *pathInMp = NULL;
887     struct Dir *dir = NULL;
888     UINT32 ret;
889 
890     if (VfsPathCheck(path, FALSE) != LOS_OK) {
891         return NULL;
892     }
893 
894     dir = (struct Dir *)LOSCFG_FS_MALLOC_HOOK(sizeof(struct Dir));
895     if (dir == NULL) {
896         VFS_ERRNO_SET(ENOMEM);
897         return NULL;
898     }
899 
900     if (LOS_FsLock() != LOS_OK) {
901         VFS_ERRNO_SET(EAGAIN);
902         LOSCFG_FS_FREE_HOOK(dir);
903         return NULL;
904     }
905 
906     if (g_dirNum >= LOSCFG_MAX_OPEN_DIRS) {
907         VFS_ERRNO_SET(ENFILE);
908         LOS_FsUnlock();
909         LOSCFG_FS_FREE_HOOK(dir);
910         return NULL;
911     }
912 
913     mp = VfsMpFind(path, &pathInMp);
914     if ((mp == NULL) || (pathInMp == NULL)) {
915         VFS_ERRNO_SET(ENOENT);
916         LOS_FsUnlock();
917         LOSCFG_FS_FREE_HOOK(dir);
918         return NULL;
919     }
920 
921     if (mp->mFs->fsFops->opendir == NULL) {
922         VFS_ERRNO_SET(ENOTSUP);
923         LOS_FsUnlock();
924         LOSCFG_FS_FREE_HOOK(dir);
925         return NULL;
926     }
927 
928     dir->dMp = mp;
929     dir->dOffset = 0;
930 
931     ret = (UINT32)mp->mFs->fsFops->opendir(dir, pathInMp);
932     if (ret == 0) {
933         mp->mRefs++;
934         g_dirNum++;
935     } else {
936         LOSCFG_FS_FREE_HOOK(dir);
937         dir = NULL;
938     }
939 
940     LOS_FsUnlock();
941     return (DIR *)dir;
942 }
943 
readdir(DIR * dir)944 struct dirent *readdir(DIR *dir)
945 {
946     struct dirent *ret = NULL;
947     struct Dir *d = (struct Dir *)dir;
948 
949     if ((dir == NULL) || (d->dMp == NULL)) {
950         VFS_ERRNO_SET(EINVAL);
951         return NULL;
952     }
953 
954     if (LOS_FsLock() != LOS_OK) {
955         VFS_ERRNO_SET(EAGAIN);
956         return NULL;
957     }
958 
959     if ((d->dMp->mFs != NULL) && (d->dMp->mFs->fsFops != NULL) &&
960         (d->dMp->mFs->fsFops->readdir != NULL)) {
961         if (d->dMp->mFs->fsFops->readdir(d, &d->dDent) == 0) {
962             ret = &d->dDent;
963         }
964     } else {
965         VFS_ERRNO_SET(ENOTSUP);
966     }
967 
968     LOS_FsUnlock();
969 
970     return ret;
971 }
972 
closedir(DIR * dir)973 int closedir(DIR *dir)
974 {
975     struct MountPoint *mp = NULL;
976     int ret = (int)LOS_NOK;
977     struct Dir *d = (struct Dir *)dir;
978 
979     if ((d == NULL) || (d->dMp == NULL)) {
980         VFS_ERRNO_SET(EBADF);
981         return MapToPosixRet(ret);
982     }
983 
984     mp = d->dMp;
985 
986     if (LOS_FsLock() != LOS_OK) {
987         VFS_ERRNO_SET(EAGAIN);
988         return MapToPosixRet(ret);
989     }
990 
991     if ((d->dMp->mFs != NULL) && (d->dMp->mFs->fsFops != NULL) &&
992         (d->dMp->mFs->fsFops->closedir != NULL)) {
993         ret = d->dMp->mFs->fsFops->closedir(d);
994     } else {
995         VFS_ERRNO_SET(ENOTSUP);
996     }
997 
998     if (ret == 0) {
999         mp->mRefs--;
1000         g_dirNum--;
1001     } else {
1002         VFS_ERRNO_SET(EBADF);
1003     }
1004 
1005     LOS_FsUnlock();
1006     LOSCFG_FS_FREE_HOOK(d);
1007     d = NULL;
1008     return MapToPosixRet(ret);
1009 }
1010 
mkdir(const char * path,mode_t mode)1011 int mkdir(const char *path, mode_t mode)
1012 {
1013     struct MountPoint *mp = NULL;
1014     const char *pathInMp = NULL;
1015     int ret = (int)LOS_NOK;
1016     (void)mode;
1017 
1018     if (VfsPathCheck(path, FALSE) != LOS_OK) {
1019         return MapToPosixRet(ret);
1020     }
1021 
1022     if (LOS_FsLock() != LOS_OK) {
1023         VFS_ERRNO_SET(EAGAIN);
1024         return MapToPosixRet(ret);
1025     }
1026 
1027     mp = VfsMpFind(path, &pathInMp);
1028     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0')) {
1029         VFS_ERRNO_SET(ENOENT);
1030         LOS_FsUnlock();
1031         return MapToPosixRet(ret);
1032     }
1033 
1034     if (mp->mFs->fsFops->mkdir != NULL) {
1035         ret = mp->mFs->fsFops->mkdir(mp, pathInMp);
1036     } else {
1037         VFS_ERRNO_SET(ENOTSUP);
1038     }
1039 
1040     LOS_FsUnlock();
1041     return MapToPosixRet(ret);
1042 }
1043 
rmdir(const char * path)1044 int rmdir(const char *path)
1045 {
1046     struct MountPoint *mp = NULL;
1047     const char *pathInMp = NULL;
1048     int ret = (int)LOS_NOK;
1049 
1050     if (path == NULL) {
1051         VFS_ERRNO_SET(EINVAL);
1052         return MapToPosixRet(ret);
1053     }
1054 
1055     if (LOS_FsLock() != LOS_OK) {
1056         VFS_ERRNO_SET(EAGAIN);
1057         return MapToPosixRet(ret);
1058     }
1059 
1060     mp = VfsMpFind(path, &pathInMp);
1061     if ((mp == NULL) || (pathInMp == NULL) || (*pathInMp == '\0') ||
1062         (mp->mFs->fsFops->rmdir == NULL)) {
1063         VFS_ERRNO_SET(ENOENT);
1064         LOS_FsUnlock();
1065         return MapToPosixRet(ret);
1066     }
1067 
1068     ret = mp->mFs->fsFops->rmdir(mp, pathInMp);
1069 
1070     LOS_FsUnlock();
1071     return MapToPosixRet(ret);
1072 }
1073 
lstat(const char * path,struct stat * buffer)1074 int lstat(const char *path, struct stat *buffer)
1075 {
1076     return stat(path, buffer);
1077 }
1078 
fstat(int fd,struct stat * buf)1079 int fstat(int fd, struct stat *buf)
1080 {
1081     struct File *filep;
1082     int ret;
1083     filep = VfsAttachFileReady(fd);
1084     if ((filep == NULL) || (filep->fMp == NULL) || filep->fullPath == NULL) {
1085         return (int)LOS_NOK;
1086     }
1087     ret = stat(filep->fullPath, buf);
1088     VfsDetachFile(filep);
1089     return ret;
1090 }
1091 #if (LOSCFG_LIBC_NEWLIB == 1)
1092 FUNC_ALIAS(fstat, _fstat, (int fd, struct stat *buf), int);
1093 #endif
1094 
fcntl(int fd,int cmd,...)1095 int fcntl(int fd, int cmd, ...)
1096 {
1097     struct File *filep = NULL;
1098     int ret;
1099     va_list ap;
1100 
1101     va_start(ap, cmd);
1102     if (fd < CONFIG_NFILE_DESCRIPTORS) {
1103         filep = VfsAttachFileReady(fd);
1104         ret = VfsVfcntl(filep, cmd, ap);
1105         VfsDetachFile(filep);
1106     } else {
1107 #ifndef LOSCFG_NET_LWIP_SACK
1108         ret = -EBADF;
1109 #else
1110         int arg = va_arg(ap, int);
1111         ret = lwip_fcntl(fd, (long)cmd, arg);
1112         va_end(ap);
1113         return ret;
1114 #endif /* LOSCFG_NET_LWIP_SACK */
1115     }
1116 
1117     if (ret < 0) {
1118         VFS_ERRNO_SET(-ret);
1119         ret = (int)LOS_NOK;
1120     }
1121     va_end(ap);
1122     return ret;
1123 }
1124 
ioctl(int fd,int req,...)1125 int ioctl(int fd, int req, ...)
1126 {
1127     int ret;
1128     va_list ap;
1129 
1130     va_start(ap, req);
1131     if (fd < CONFIG_NFILE_DESCRIPTORS) {
1132         ret = VfsIoctl(fd, req, ap);
1133     } else {
1134 #ifndef LOSCFG_NET_LWIP_SACK
1135         ret = -EBADF;
1136 #else
1137         UINTPTR arg = va_arg(ap, UINTPTR);
1138         ret = lwip_ioctl(fd, (long)req, (void *)arg);
1139 #endif /* LOSCFG_NET_LWIP_SACK */
1140     }
1141 
1142     va_end(ap);
1143     return ret;
1144 }
1145 
readv(int fd,const struct iovec * iovBuf,int iovcnt)1146 ssize_t readv(int fd, const struct iovec *iovBuf, int iovcnt)
1147 {
1148     int i;
1149     errno_t ret;
1150     char *buf = NULL;
1151     char *curBuf = NULL;
1152     char *readBuf = NULL;
1153     size_t bufLen = 0;
1154     size_t bytesToRead;
1155     ssize_t totalBytesRead;
1156     size_t totalLen;
1157     const struct iovec *iov = (const struct iovec *)iovBuf;
1158 
1159     if ((iov == NULL) || (iovcnt <= 0) || (iovcnt > IOV_MAX_CNT)) {
1160         return (ssize_t)LOS_NOK;
1161     }
1162 
1163     for (i = 0; i < iovcnt; ++i) {
1164         if ((SSIZE_MAX - bufLen) < iov[i].iov_len) {
1165             return (ssize_t)LOS_NOK;
1166         }
1167         bufLen += iov[i].iov_len;
1168     }
1169     if (bufLen == 0) {
1170         return (ssize_t)LOS_NOK;
1171     }
1172     totalLen = bufLen * sizeof(char);
1173     buf = (char *)LOSCFG_FS_MALLOC_HOOK(totalLen);
1174     if (buf == NULL) {
1175         return (ssize_t)LOS_NOK;
1176     }
1177 
1178     totalBytesRead = read(fd, buf, bufLen);
1179     if ((size_t)totalBytesRead < totalLen) {
1180         totalLen = (size_t)totalBytesRead;
1181     }
1182     curBuf = buf;
1183     for (i = 0; i < iovcnt; ++i) {
1184         readBuf = (char *)iov[i].iov_base;
1185         bytesToRead = iov[i].iov_len;
1186 
1187         size_t lenToRead = totalLen < bytesToRead ? totalLen : bytesToRead;
1188         ret = memcpy_s(readBuf, bytesToRead, curBuf, lenToRead);
1189         if (ret != EOK) {
1190             LOSCFG_FS_FREE_HOOK(buf);
1191             return (ssize_t)LOS_NOK;
1192         }
1193         if (totalLen < (size_t)bytesToRead) {
1194             break;
1195         }
1196         curBuf += bytesToRead;
1197         totalLen -= bytesToRead;
1198     }
1199     LOSCFG_FS_FREE_HOOK(buf);
1200     return totalBytesRead;
1201 }
1202 
writev(int fd,const struct iovec * iovBuf,int iovcnt)1203 ssize_t writev(int fd, const struct iovec *iovBuf, int iovcnt)
1204 {
1205     int i;
1206     errno_t ret;
1207     char *buf = NULL;
1208     char *curBuf = NULL;
1209     char *writeBuf = NULL;
1210     size_t bufLen = 0;
1211     size_t bytesToWrite;
1212     ssize_t totalBytesWritten;
1213     size_t totalLen;
1214     const struct iovec *iov = iovBuf;
1215 
1216     if ((iov == NULL) || (iovcnt <= 0) || (iovcnt > IOV_MAX_CNT)) {
1217         return (ssize_t)LOS_NOK;
1218     }
1219 
1220     for (i = 0; i < iovcnt; ++i) {
1221         if ((SSIZE_MAX - bufLen) < iov[i].iov_len) {
1222             VFS_ERRNO_SET(EINVAL);
1223             return (ssize_t)LOS_NOK;
1224         }
1225         bufLen += iov[i].iov_len;
1226     }
1227     if (bufLen == 0) {
1228         return (ssize_t)LOS_NOK;
1229     }
1230     totalLen = bufLen * sizeof(char);
1231     buf = (char *)LOSCFG_FS_MALLOC_HOOK(totalLen);
1232     if (buf == NULL) {
1233         return (ssize_t)LOS_NOK;
1234     }
1235     curBuf = buf;
1236     for (i = 0; i < iovcnt; ++i) {
1237         writeBuf = (char *)iov[i].iov_base;
1238         bytesToWrite = iov[i].iov_len;
1239         if (((ssize_t)totalLen <= 0) || ((ssize_t)bytesToWrite <= 0)) {
1240             continue;
1241         }
1242         ret = memcpy_s(curBuf, totalLen, writeBuf, bytesToWrite);
1243         if (ret != EOK) {
1244             LOSCFG_FS_FREE_HOOK(buf);
1245             return (ssize_t)LOS_NOK;
1246         }
1247         curBuf += bytesToWrite;
1248         totalLen -= bytesToWrite;
1249     }
1250 
1251     totalBytesWritten = write(fd, buf, bufLen);
1252     LOSCFG_FS_FREE_HOOK(buf);
1253 
1254     return totalBytesWritten;
1255 }
1256 
remove(const char * filename)1257 int remove(const char *filename)
1258 {
1259     int ret = unlink(filename);
1260     if (ret == -EISDIR) {
1261         ret = rmdir(filename);
1262     }
1263 
1264     return ret;
1265 }
1266 
access(const char * path,int amode)1267 int access(const char *path, int amode)
1268 {
1269     int result;
1270     mode_t mode;
1271     struct stat buf;
1272 
1273     result = stat(path, &buf);
1274     if (result != 0) {
1275         return (int)LOS_NOK;
1276     }
1277 
1278     mode = buf.st_mode;
1279     if ((unsigned int)amode & R_OK) {
1280         if ((mode & (S_IROTH | S_IRGRP | S_IRUSR)) == 0) {
1281             VFS_ERRNO_SET(EACCES);
1282             return (int)LOS_NOK;
1283         }
1284     }
1285     if ((unsigned int)amode & W_OK) {
1286         if ((mode & (S_IWOTH | S_IWGRP | S_IWUSR)) == 0) {
1287             VFS_ERRNO_SET(EACCES);
1288             return (int)LOS_NOK;
1289         }
1290     }
1291     if ((unsigned int)amode & X_OK) {
1292         if ((mode & (S_IXOTH | S_IXGRP | S_IXUSR)) == 0) {
1293             VFS_ERRNO_SET(EACCES);
1294             return (int)LOS_NOK;
1295         }
1296     }
1297     return 0;
1298 }
1299 
ftruncate(int fd,off_t length)1300 int ftruncate(int fd, off_t length)
1301 {
1302     int ret = (int)LOS_NOK;
1303     struct File *file = NULL;
1304 
1305     if (length <= 0) {
1306         VFS_ERRNO_SET(EINVAL);
1307         return ret;
1308     }
1309 
1310     file = VfsAttachFileReady(fd);
1311     if (file == NULL) {
1312         return ret;
1313     }
1314 
1315     if (file->fMp->mWriteEnable == FALSE) {
1316         VFS_ERRNO_SET(EACCES);
1317         VfsDetachFile(file);
1318         return ret;
1319     }
1320 
1321     if ((file->fFlags & O_ACCMODE) == O_RDONLY) {
1322         VFS_ERRNO_SET(EACCES);
1323     } else if ((file->fFops != NULL) && (file->fFops->truncate != NULL)) {
1324         ret = file->fFops->truncate(file, length);
1325     } else {
1326         VFS_ERRNO_SET(ENOTSUP);
1327     }
1328 
1329     /* else ret will be -1 */
1330     VfsDetachFile(file);
1331     return ret;
1332 }
1333 
pread(int fd,void * buff,size_t bytes,off_t off)1334 ssize_t pread(int fd, void *buff, size_t bytes, off_t off)
1335 {
1336     ssize_t ret = (ssize_t)LOS_NOK;
1337     off_t savepos, pos;
1338 
1339     if (fd < 0 || fd >= CONFIG_NFILE_DESCRIPTORS) {
1340         return MapToPosixRet((int)ret);
1341     }
1342 
1343     if (buff == NULL) {
1344         VFS_ERRNO_SET(EFAULT);
1345         return MapToPosixRet((int)ret);
1346     }
1347 
1348     if (bytes == 0) {
1349         return 0;
1350     }
1351 
1352     if (LOS_FsLock() != LOS_OK) {
1353         VFS_ERRNO_SET(EAGAIN);
1354         return MapToPosixRet((int)ret);
1355     }
1356 
1357     savepos = lseek(fd, 0, SEEK_CUR);
1358     if (savepos == (off_t)-1) {
1359         LOS_FsUnlock();
1360         return MapToPosixRet((int)ret);
1361     }
1362 
1363     pos = lseek(fd, off, SEEK_SET);
1364     if (pos == (off_t)-1) {
1365         LOS_FsUnlock();
1366         return MapToPosixRet((int)ret);
1367     }
1368 
1369     ret = read(fd, buff, bytes);
1370     pos = lseek(fd, savepos, SEEK_SET);
1371     if ((pos == (off_t)-1) && (ret >= 0)) {
1372         LOS_FsUnlock();
1373         return MapToPosixRet((int)LOS_NOK);
1374     }
1375 
1376     LOS_FsUnlock();
1377 
1378     return MapToPosixRet((int)ret);
1379 }
1380 
pwrite(int fd,const void * buff,size_t bytes,off_t off)1381 ssize_t pwrite(int fd, const void *buff, size_t bytes, off_t off)
1382 {
1383     ssize_t ret = (ssize_t)LOS_NOK;
1384     off_t savepos, pos;
1385 
1386     if ((fd < 0) || (fd >= CONFIG_NFILE_DESCRIPTORS)) {
1387         return MapToPosixRet((int)ret);
1388     }
1389 
1390     if (buff == NULL) {
1391         VFS_ERRNO_SET(EFAULT);
1392         return MapToPosixRet((int)ret);
1393     }
1394 
1395     if (bytes == 0) {
1396         return 0;
1397     }
1398 
1399     if (LOS_FsLock() != LOS_OK) {
1400         VFS_ERRNO_SET(EAGAIN);
1401         return MapToPosixRet((int)ret);
1402     }
1403 
1404     savepos = lseek(fd, 0, SEEK_CUR);
1405     if (savepos == (off_t)-1) {
1406         LOS_FsUnlock();
1407         return MapToPosixRet((int)ret);
1408     }
1409 
1410     pos = lseek(fd, off, SEEK_SET);
1411     if (pos == (off_t)-1) {
1412         LOS_FsUnlock();
1413         return MapToPosixRet((int)ret);
1414     }
1415 
1416     ret = write(fd, buff, bytes);
1417     pos = lseek(fd, savepos, SEEK_SET);
1418     if ((pos == (off_t)-1) && (ret >= 0)) {
1419         LOS_FsUnlock();
1420         return MapToPosixRet((int)LOS_NOK);
1421     }
1422 
1423     LOS_FsUnlock();
1424 
1425     return MapToPosixRet((int)ret);
1426 }
1427