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