los_fs.c 16.8 KB
Newer Older
L
likailong 已提交
1
/*
M
mamingshuai 已提交
2 3
 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
L
likailong 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 *    conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 *    of conditions and the following disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 *    to endorse or promote products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
A
arvinzzz 已提交
31 32

#include "los_fs.h"
33
#include "los_config.h"
A
arvinzzz 已提交
34
#include "fs_operations.h"
35
#if (LOSCFG_SUPPORT_FATFS == 1)
M
mamingshuai 已提交
36
#include "fatfs.h"
37
#endif
M
mamingshuai 已提交
38 39 40 41 42 43 44 45 46 47 48
#include "dirent.h"
#include "errno.h"
#include "fcntl.h"
#include "securec.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/mount.h"
#include "sys/statfs.h"
#include "sys/stat.h"
#include "unistd.h"
L
likailong 已提交
49

50
#ifdef LOSCFG_NET_LWIP_SACK
C
Caoruihong 已提交
51
#define _BSD_SOURCE
Y
YOUR_NAME 已提交
52
#include "lwip/sockets.h"
53 54
#endif

C
Caoruihong 已提交
55
#include "vfs_config.h"
M
mamingshuai 已提交
56 57 58 59

#ifdef LOSCFG_RANDOM_DEV
#include "hks_client.h"
#define RANDOM_DEV_FD  CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS
L
likailong 已提交
60
#define RANDOM_DEV_PATH  "/dev/random"
M
mamingshuai 已提交
61
#endif
L
likailong 已提交
62

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#if (LOSCFG_POSIX_PIPE_API == 1)
#include "pipe_impl.h"
#ifdef LOSCFG_RANDOM_DEV
#define PIPE_DEV_FD (RANDOM_DEV_FD + 1)
#else
#define PIPE_DEV_FD (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)
#endif

int PollQueryFd(int fd, struct PollTable *table)
{
    if (fd >= PIPE_DEV_FD) {
        return PipePoll(fd, table);
    }

    return -ENODEV;
}
#endif

81 82 83 84 85
#define FREE_AND_SET_NULL(ptr) do { \
    free(ptr);                      \
    ptr = NULL;                     \
} while (0)

M
mamingshuai 已提交
86
#ifdef LOSCFG_RANDOM_DEV
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
/**
 * @brief Get canonical form of a given path based on cwd(Current working directory).
 *
 * @param cwd Indicates the current working directory.
 * @param path Indicates the path to be canonicalization.
 * @param buf Indicates the pointer to the buffer where the result will be return.
 * @param bufSize Indicates the size of the buffer.
 * @return Returns the length of the canonical path.
 *
 * @attention if path is an absolute path, cwd is ignored. if cwd if not specified, it is assumed to be root('/').
 *            if the buffer is not big enough the result will be truncated, but the return value will always be the
 *            length of the canonical path.
 */
static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, size_t bufSize)
{
M
mamingshuai 已提交
102
    size_t offset;
103 104 105 106 107 108 109 110
    if (!path) {
        path = "";
    }

    if (!cwd || path[0] == '/') {
        cwd = "";
    }

M
mamingshuai 已提交
111 112
    offset = strlen("///") + 1; // three '/' and one '\0'
    size_t tmpLen = strlen(cwd) + strlen(path) + offset;
113 114
    char *tmpBuf = (char *)malloc(tmpLen);
    if (tmpBuf == NULL) {
C
chenjing 已提交
115
        return FS_SUCCESS;
116 117 118 119
    }

    if (-1 == sprintf_s(tmpBuf, tmpLen, "/%s/%s/", cwd, path)) {
        free(tmpBuf);
C
chenjing 已提交
120
        return FS_SUCCESS;
121 122 123 124
    }

    char *p;
    /* replace /./ to / */
M
mamingshuai 已提交
125
    offset = strlen("/./") - 1;
126
    while ((p = strstr(tmpBuf, "/./")) != NULL) {
M
mamingshuai 已提交
127
        if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) {
128
            free(tmpBuf);
C
chenjing 已提交
129
            return FS_SUCCESS;
130 131 132 133 134 135 136
        }
    }

    /* replace // to / */
    while ((p = strstr(tmpBuf, "//")) != NULL) {
        if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + 1, tmpLen - (p - tmpBuf) - 1)) {
            free(tmpBuf);
C
chenjing 已提交
137
            return FS_SUCCESS;
138 139 140 141
        }
    }

    /* handle /../ (e.g., replace /aa/bb/../ to /aa/) */
M
mamingshuai 已提交
142
    offset = strlen("/../") - 1;
143 144
    while ((p = strstr(tmpBuf, "/../")) != NULL) {
        char *start = p;
M
mamingshuai 已提交
145 146
        while (start > tmpBuf && *(start - 1) != '/') {
            --start;
147
        }
M
mamingshuai 已提交
148
        if (EOK != memmove_s(start, tmpLen - (start - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) {
149
            free(tmpBuf);
C
chenjing 已提交
150
            return FS_SUCCESS;
151 152 153 154 155 156 157 158 159 160 161 162 163 164
        }
    }

    size_t totalLen = strlen(tmpBuf);
    /* strip the last / */
    if (totalLen > 1 && tmpBuf[totalLen - 1] == '/') {
        tmpBuf[--totalLen] = 0;
    }

    if (!buf || bufSize == 0) {
        free(tmpBuf);
        return totalLen;
    }

M
mamingshuai 已提交
165
    if (EOK != memcpy_s(buf, bufSize, tmpBuf, (((totalLen + 1) > bufSize) ? bufSize : (totalLen + 1)))) {
166
        free(tmpBuf);
C
chenjing 已提交
167
        return FS_SUCCESS;
168 169 170 171 172 173
    }

    buf[bufSize - 1] = 0;
    free(tmpBuf);
    return totalLen;
}
M
mamingshuai 已提交
174 175
#endif

C
Caoruihong 已提交
176 177 178
static struct FsMap g_fsmap[MAX_FILESYSTEM_LEN] = {0};
static struct FsMap *g_fs = NULL;

C
chenjing 已提交
179 180
static void InitMountInfo(void)
{
181
#if (LOSCFG_SUPPORT_FATFS == 1)
C
chenjing 已提交
182 183 184 185 186
    extern struct MountOps g_fatfsMnt;
    extern struct FileOps g_fatfsFops;
    g_fsmap[0].fileSystemtype = strdup("fat");
    g_fsmap[0].fsMops = &g_fatfsMnt;
    g_fsmap[0].fsFops = &g_fatfsFops;
187 188
#endif
#if (LOSCFG_SUPPORT_LITTLEFS == 1)
C
chenjing 已提交
189 190 191 192 193
    extern struct MountOps g_lfsMnt;
    extern struct FileOps g_lfsFops;
    g_fsmap[1].fileSystemtype = strdup("littlefs");
    g_fsmap[1].fsMops = &g_lfsMnt;
    g_fsmap[1].fsFops = &g_lfsFops;
194
#endif
C
chenjing 已提交
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
}

static struct FsMap *MountFindfs(const char *fileSystemtype)
{
    struct FsMap *m = NULL;

    for (int i = 0; i < MAX_FILESYSTEM_LEN; i++) {
        m = &(g_fsmap[i]);
        if (m->fileSystemtype && strcmp(fileSystemtype, m->fileSystemtype) == 0) {
            return m;
        }
    }

    return NULL;
}

A
arvinzzz 已提交
211 212 213
int LOS_FsMount(const char *source, const char *target,
                const char *filesystemtype, unsigned long mountflags,
                const void *data)
M
mamingshuai 已提交
214
{
C
chenjing 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
    static int initFlag = 0;

    if (initFlag == 0) {
        InitMountInfo();
        initFlag = 1;
    }

    g_fs = MountFindfs(filesystemtype);
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }

    if (g_fs->fsMops == NULL || g_fs->fsMops->Mount == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }

    return g_fs->fsMops->Mount(source, target, filesystemtype, mountflags, data);
M
mamingshuai 已提交
234 235
}

A
arvinzzz 已提交
236
int LOS_FsUmount(const char *target)
M
mamingshuai 已提交
237
{
C
chenjing 已提交
238 239 240 241 242 243 244 245 246
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsMops == NULL || g_fs->fsMops->Umount == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsMops->Umount(target);
M
mamingshuai 已提交
247 248
}

A
arvinzzz 已提交
249
int LOS_FsUmount2(const char *target, int flag)
M
mamingshuai 已提交
250
{
C
chenjing 已提交
251 252 253 254 255 256 257 258 259
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsMops == NULL || g_fs->fsMops->Umount2 == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsMops->Umount2(target, flag);
M
mamingshuai 已提交
260
}
261

A
arvinzzz 已提交
262
int LOS_Open(const char *path, int oflag, ...)
L
likailong 已提交
263
{
M
mamingshuai 已提交
264
#ifdef LOSCFG_RANDOM_DEV
265 266 267
    unsigned flags = O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_LARGEFILE | O_TRUNC | O_EXCL | O_DIRECTORY;
    if ((unsigned)oflag & ~flags) {
        errno = EINVAL;
C
chenjing 已提交
268
        return FS_FAILURE;
269
    }
M
mamingshuai 已提交
270 271

    size_t pathLen = strlen(path) + 1;
272 273 274
    char *canonicalPath = (char *)malloc(pathLen);
    if (!canonicalPath) {
        errno = ENOMEM;
C
chenjing 已提交
275
        return FS_FAILURE;
276
    }
M
mamingshuai 已提交
277
    if (GetCanonicalPath(NULL, path, canonicalPath, pathLen) == 0) {
278 279
        FREE_AND_SET_NULL(canonicalPath);
        errno = ENOMEM;
C
chenjing 已提交
280
        return FS_FAILURE;
281
    }
M
mamingshuai 已提交
282

283 284 285 286
    if (strcmp(canonicalPath, RANDOM_DEV_PATH) == 0) {
        FREE_AND_SET_NULL(canonicalPath);
        if ((O_ACCMODE & (unsigned)oflag) != O_RDONLY) {
            errno = EPERM;
C
chenjing 已提交
287
            return FS_FAILURE;
288 289 290
        }
        if ((unsigned)oflag & O_DIRECTORY) {
            errno = ENOTDIR;
C
chenjing 已提交
291
            return FS_FAILURE;
L
likailong 已提交
292 293 294
        }
        return RANDOM_DEV_FD;
    }
295 296 297 298
    if (strcmp(canonicalPath, "/") == 0 || strcmp(canonicalPath, "/dev") == 0) {
        FREE_AND_SET_NULL(canonicalPath);
        if ((unsigned)oflag & O_DIRECTORY) {
            errno = EPERM;
C
chenjing 已提交
299
            return FS_FAILURE;
300 301
        }
        errno = EISDIR;
C
chenjing 已提交
302
        return FS_FAILURE;
303 304
    }
    FREE_AND_SET_NULL(canonicalPath);
M
mamingshuai 已提交
305
#endif
306 307 308 309 310 311 312

#if (LOSCFG_POSIX_PIPE_API == 1)
    if ((path != NULL) && !strncmp(path, PIPE_DEV_PATH, strlen(PIPE_DEV_PATH))) {
        return PipeOpen(path, oflag, PIPE_DEV_FD);
    }
#endif

C
chenjing 已提交
313 314 315 316 317 318 319 320 321
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Open == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Open(path, oflag);
L
likailong 已提交
322 323
}

A
arvinzzz 已提交
324
int LOS_Close(int fd)
L
likailong 已提交
325
{
M
mamingshuai 已提交
326
#ifdef LOSCFG_RANDOM_DEV
L
likailong 已提交
327
    if (fd == RANDOM_DEV_FD) {
C
chenjing 已提交
328
        return FS_SUCCESS;
L
likailong 已提交
329
    }
M
mamingshuai 已提交
330
#endif
331 332 333 334 335
#ifdef LOSCFG_NET_LWIP_SACK
    if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
        return closesocket(fd);
    }
#endif
336 337 338 339 340 341 342

#if (LOSCFG_POSIX_PIPE_API == 1)
    if (fd >= PIPE_DEV_FD) {
        return PipeClose(fd);
    }
#endif

C
chenjing 已提交
343 344 345 346 347 348 349 350 351
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Close == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Close(fd);
L
likailong 已提交
352 353
}

A
arvinzzz 已提交
354
ssize_t LOS_Read(int fd, void *buf, size_t nbyte)
L
likailong 已提交
355
{
M
mamingshuai 已提交
356
#ifdef LOSCFG_RANDOM_DEV
L
likailong 已提交
357
    if (fd == RANDOM_DEV_FD) {
M
mamingshuai 已提交
358
        if (nbyte == 0) {
C
chenjing 已提交
359
            return FS_SUCCESS;
L
likailong 已提交
360 361 362
        }
        if (buf == NULL) {
            errno = EINVAL;
C
chenjing 已提交
363
            return FS_FAILURE;
L
likailong 已提交
364
        }
W
wangchen 已提交
365
        if (nbyte > 1024) { /* 1024, max random_size */
M
mamingshuai 已提交
366
            nbyte = 1024; /* hks_generate_random: random_size must <= 1024 */
L
likailong 已提交
367
        }
M
mamingshuai 已提交
368
        struct hks_blob key = {HKS_BLOB_TYPE_RAW, (uint8_t *)buf, nbyte};
L
likailong 已提交
369 370
        if (hks_generate_random(&key) != 0) {
            errno = EIO;
C
chenjing 已提交
371
            return FS_FAILURE;
L
likailong 已提交
372
        }
M
mamingshuai 已提交
373
        return (ssize_t)nbyte;
L
likailong 已提交
374
    }
M
mamingshuai 已提交
375
#endif
376 377
#ifdef LOSCFG_NET_LWIP_SACK
    if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
M
mamingshuai 已提交
378
        return recv(fd, buf, nbyte, 0);
379 380
    }
#endif
381 382 383 384 385 386 387

#if (LOSCFG_POSIX_PIPE_API == 1)
    if (fd >= PIPE_DEV_FD) {
        return PipeRead(fd, buf, nbyte);
    }
#endif

C
chenjing 已提交
388 389 390 391
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
392 393 394 395
    if (g_fs->fsFops == NULL || g_fs->fsFops->Read == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
C
chenjing 已提交
396
    return g_fs->fsFops->Read(fd, buf, nbyte);
L
likailong 已提交
397 398
}

A
arvinzzz 已提交
399
ssize_t LOS_Write(int fd, const void *buf, size_t nbyte)
L
likailong 已提交
400
{
M
mamingshuai 已提交
401
#ifdef LOSCFG_RANDOM_DEV
L
likailong 已提交
402 403
    if (fd == RANDOM_DEV_FD) {
        errno = EBADF; /* "/dev/random" is readonly */
C
chenjing 已提交
404
        return FS_FAILURE;
L
likailong 已提交
405
    }
M
mamingshuai 已提交
406
#endif
407 408
#ifdef LOSCFG_NET_LWIP_SACK
    if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
M
mamingshuai 已提交
409
        return send(fd, buf, nbyte, 0);
410 411
    }
#endif
412 413 414 415 416 417 418

#if (LOSCFG_POSIX_PIPE_API == 1)
    if (fd >= PIPE_DEV_FD) {
        return PipeWrite(fd, buf, nbyte);
    }
#endif

C
chenjing 已提交
419 420 421 422 423 424 425 426 427
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Write == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Write(fd, buf, nbyte);
M
mamingshuai 已提交
428 429
}

A
arvinzzz 已提交
430
off_t LOS_Lseek(int fd, off_t offset, int whence)
M
mamingshuai 已提交
431
{
C
chenjing 已提交
432 433 434 435 436 437 438 439 440
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Seek == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Seek(fd, offset, whence);
M
mamingshuai 已提交
441 442
}

A
arvinzzz 已提交
443
int LOS_Unlink(const char *path)
M
mamingshuai 已提交
444
{
C
chenjing 已提交
445 446 447 448 449 450 451 452 453
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Unlink == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Unlink(path);
M
mamingshuai 已提交
454 455
}

A
arvinzzz 已提交
456
int LOS_Fstat(int fd, struct stat *buf)
M
mamingshuai 已提交
457
{
C
chenjing 已提交
458 459 460 461 462 463 464 465 466
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Fstat == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Fstat(fd, buf);
M
mamingshuai 已提交
467 468
}

A
arvinzzz 已提交
469
int LOS_Stat(const char *path, struct stat *buf)
M
mamingshuai 已提交
470
{
C
chenjing 已提交
471 472 473 474
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
475
    if (g_fs->fsFops == NULL || g_fs->fsFops->Getattr == NULL) {
C
chenjing 已提交
476 477 478
        errno = ENOSYS;
        return FS_FAILURE;
    }
479
    return g_fs->fsFops->Getattr(path, buf);
M
mamingshuai 已提交
480 481
}

A
arvinzzz 已提交
482
int LOS_Fsync(int fd)
M
mamingshuai 已提交
483
{
C
chenjing 已提交
484 485 486 487 488 489 490 491 492
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Fsync == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Fsync(fd);
M
mamingshuai 已提交
493 494
}

A
arvinzzz 已提交
495
int LOS_Mkdir(const char *path, mode_t mode)
M
mamingshuai 已提交
496
{
C
chenjing 已提交
497 498 499 500 501 502 503 504 505
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Mkdir == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Mkdir(path, mode);
M
mamingshuai 已提交
506 507
}

A
arvinzzz 已提交
508
DIR *LOS_Opendir(const char *dirName)
M
mamingshuai 已提交
509
{
C
chenjing 已提交
510 511 512 513 514 515 516 517 518
    if (g_fs == NULL) {
        errno = ENODEV;
        return NULL;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Opendir == NULL) {
        errno = ENOSYS;
        return NULL;
    }
    return g_fs->fsFops->Opendir(dirName);
M
mamingshuai 已提交
519 520
}

A
arvinzzz 已提交
521
struct dirent *LOS_Readdir(DIR *dir)
M
mamingshuai 已提交
522
{
C
chenjing 已提交
523 524 525 526 527 528 529 530 531
    if (g_fs == NULL) {
        errno = ENODEV;
        return NULL;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Readdir == NULL) {
        errno = ENOSYS;
        return NULL;
    }
    return g_fs->fsFops->Readdir(dir);
M
mamingshuai 已提交
532 533
}

A
arvinzzz 已提交
534
int LOS_Closedir(DIR *dir)
M
mamingshuai 已提交
535
{
C
chenjing 已提交
536 537 538 539 540 541 542 543 544
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Closedir == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Closedir(dir);
M
mamingshuai 已提交
545 546
}

A
arvinzzz 已提交
547
int LOS_Rmdir(const char *path)
M
mamingshuai 已提交
548
{
C
chenjing 已提交
549 550 551 552 553 554 555 556 557
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Rmdir == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Rmdir(path);
M
mamingshuai 已提交
558 559
}

A
arvinzzz 已提交
560
int LOS_Rename(const char *oldName, const char *newName)
M
mamingshuai 已提交
561
{
C
chenjing 已提交
562 563 564 565 566 567 568 569 570
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Rename == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Rename(oldName, newName);
M
mamingshuai 已提交
571 572
}

A
arvinzzz 已提交
573
int LOS_Statfs(const char *path, struct statfs *buf)
M
mamingshuai 已提交
574
{
C
chenjing 已提交
575 576 577 578 579 580 581 582 583
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsMops == NULL || g_fs->fsMops->Statfs == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsMops->Statfs(path, buf);
M
mamingshuai 已提交
584 585
}

A
arvinzzz 已提交
586
int LOS_Ftruncate(int fd, off_t length)
M
mamingshuai 已提交
587
{
C
chenjing 已提交
588 589 590 591 592 593 594 595 596
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Ftruncate == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Ftruncate(fd, length);
L
likailong 已提交
597
}
A
arvinzzz 已提交
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649

ssize_t LOS_Pread(int fd, void *buf, size_t nbyte, off_t offset)
{
#ifdef LOSCFG_RANDOM_DEV
    if (fd == RANDOM_DEV_FD) {
        if (nbyte == 0) {
            return FS_SUCCESS;
        }
        if (buf == NULL) {
            errno = EINVAL;
            return FS_FAILURE;
        }
        if (nbyte > 1024) { /* 1024, max random_size */
            nbyte = 1024; /* hks_generate_random: random_size must <= 1024 */
        }
        struct hks_blob key = {HKS_BLOB_TYPE_RAW, (uint8_t *)buf, nbyte};
        if (hks_generate_random(&key) != 0) {
            errno = EIO;
            return FS_FAILURE;
        }
        return (ssize_t)nbyte;
    }
#endif
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Pread == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Pread(fd, buf, nbyte, offset);
}

ssize_t LOS_Pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
{
#ifdef LOSCFG_RANDOM_DEV
    if (fd == RANDOM_DEV_FD) {
        errno = EBADF; /* "/dev/random" is readonly */
        return FS_FAILURE;
    }
#endif
    if (g_fs == NULL) {
        errno = ENODEV;
        return FS_FAILURE;
    }
    if (g_fs->fsFops == NULL || g_fs->fsFops->Pwrite == NULL) {
        errno = ENOSYS;
        return FS_FAILURE;
    }
    return g_fs->fsFops->Pwrite(fd, buf, nbyte, offset);
}