xref: /kernel/liteos_a/fs/vfs/operation/vfs_other.c (revision 0d163575)
10d163575Sopenharmony_ci/*
20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
30d163575Sopenharmony_ci * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
40d163575Sopenharmony_ci *
50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
60d163575Sopenharmony_ci * are permitted provided that the following conditions are met:
70d163575Sopenharmony_ci *
80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
90d163575Sopenharmony_ci *    conditions and the following disclaimer.
100d163575Sopenharmony_ci *
110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
120d163575Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
130d163575Sopenharmony_ci *    provided with the distribution.
140d163575Sopenharmony_ci *
150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
160d163575Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
170d163575Sopenharmony_ci *    permission.
180d163575Sopenharmony_ci *
190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
300d163575Sopenharmony_ci */
310d163575Sopenharmony_ci
320d163575Sopenharmony_ci#include "errno.h"
330d163575Sopenharmony_ci#include "stdlib.h"
340d163575Sopenharmony_ci#include "string.h"
350d163575Sopenharmony_ci#include "dirent.h"
360d163575Sopenharmony_ci#include "unistd.h"
370d163575Sopenharmony_ci#include "sys/select.h"
380d163575Sopenharmony_ci#include "sys/mount.h"
390d163575Sopenharmony_ci#include "sys/stat.h"
400d163575Sopenharmony_ci#include "sys/statfs.h"
410d163575Sopenharmony_ci#include "sys/prctl.h"
420d163575Sopenharmony_ci#include "fs/fd_table.h"
430d163575Sopenharmony_ci#include "fs/file.h"
440d163575Sopenharmony_ci#include "linux/spinlock.h"
450d163575Sopenharmony_ci#include "los_process_pri.h"
460d163575Sopenharmony_ci#include "los_task_pri.h"
470d163575Sopenharmony_ci#include "capability_api.h"
480d163575Sopenharmony_ci#include "vnode.h"
490d163575Sopenharmony_ci
500d163575Sopenharmony_ci#define MAX_DIR_ENT 1024
510d163575Sopenharmony_ciint fstat(int fd, struct stat *buf)
520d163575Sopenharmony_ci{
530d163575Sopenharmony_ci    struct file *filep = NULL;
540d163575Sopenharmony_ci
550d163575Sopenharmony_ci    int ret = fs_getfilep(fd, &filep);
560d163575Sopenharmony_ci    if (ret < 0) {
570d163575Sopenharmony_ci        return VFS_ERROR;
580d163575Sopenharmony_ci    }
590d163575Sopenharmony_ci
600d163575Sopenharmony_ci    return stat(filep->f_path, buf);
610d163575Sopenharmony_ci}
620d163575Sopenharmony_ci
630d163575Sopenharmony_ciint fstat64(int fd, struct stat64 *buf)
640d163575Sopenharmony_ci{
650d163575Sopenharmony_ci    struct file *filep = NULL;
660d163575Sopenharmony_ci
670d163575Sopenharmony_ci    int ret = fs_getfilep(fd, &filep);
680d163575Sopenharmony_ci    if (ret < 0) {
690d163575Sopenharmony_ci        return VFS_ERROR;
700d163575Sopenharmony_ci    }
710d163575Sopenharmony_ci
720d163575Sopenharmony_ci    return stat64(filep->f_path, buf);
730d163575Sopenharmony_ci}
740d163575Sopenharmony_ci
750d163575Sopenharmony_ciint lstat(const char *path, struct stat *buffer)
760d163575Sopenharmony_ci{
770d163575Sopenharmony_ci    return stat(path, buffer);
780d163575Sopenharmony_ci}
790d163575Sopenharmony_ci
800d163575Sopenharmony_ciint VfsVnodePermissionCheck(const struct Vnode *node, int accMode)
810d163575Sopenharmony_ci{
820d163575Sopenharmony_ci    uint fuid = node->uid;
830d163575Sopenharmony_ci    uint fgid = node->gid;
840d163575Sopenharmony_ci    uint fileMode = node->mode;
850d163575Sopenharmony_ci    return VfsPermissionCheck(fuid, fgid, fileMode, accMode);
860d163575Sopenharmony_ci}
870d163575Sopenharmony_ci
880d163575Sopenharmony_ciint VfsPermissionCheck(uint fuid, uint fgid, uint fileMode, int accMode)
890d163575Sopenharmony_ci{
900d163575Sopenharmony_ci    uint uid = OsCurrUserGet()->effUserID;
910d163575Sopenharmony_ci    mode_t tmpMode = fileMode;
920d163575Sopenharmony_ci
930d163575Sopenharmony_ci    if (uid == fuid) {
940d163575Sopenharmony_ci        tmpMode >>= USER_MODE_SHIFT;
950d163575Sopenharmony_ci    } else if (LOS_CheckInGroups(fgid)) {
960d163575Sopenharmony_ci        tmpMode >>= GROUP_MODE_SHIFT;
970d163575Sopenharmony_ci    }
980d163575Sopenharmony_ci
990d163575Sopenharmony_ci    tmpMode &= (READ_OP | WRITE_OP | EXEC_OP);
1000d163575Sopenharmony_ci
1010d163575Sopenharmony_ci    if (((uint)accMode & tmpMode) == accMode) {
1020d163575Sopenharmony_ci        return 0;
1030d163575Sopenharmony_ci    }
1040d163575Sopenharmony_ci
1050d163575Sopenharmony_ci    tmpMode = 0;
1060d163575Sopenharmony_ci    if (S_ISDIR(fileMode)) {
1070d163575Sopenharmony_ci        if (IsCapPermit(CAP_DAC_EXECUTE)
1080d163575Sopenharmony_ci            || (!((uint)accMode & WRITE_OP) && IsCapPermit(CAP_DAC_READ_SEARCH))) {
1090d163575Sopenharmony_ci            tmpMode |= EXEC_OP;
1100d163575Sopenharmony_ci        }
1110d163575Sopenharmony_ci    } else {
1120d163575Sopenharmony_ci        if (IsCapPermit(CAP_DAC_EXECUTE) && (fileMode & MODE_IXUGO)) {
1130d163575Sopenharmony_ci            tmpMode |= EXEC_OP;
1140d163575Sopenharmony_ci        }
1150d163575Sopenharmony_ci    }
1160d163575Sopenharmony_ci
1170d163575Sopenharmony_ci    if (IsCapPermit(CAP_DAC_WRITE)) {
1180d163575Sopenharmony_ci        tmpMode |= WRITE_OP;
1190d163575Sopenharmony_ci    }
1200d163575Sopenharmony_ci
1210d163575Sopenharmony_ci    if (IsCapPermit(CAP_DAC_READ_SEARCH)) {
1220d163575Sopenharmony_ci        tmpMode |= READ_OP;
1230d163575Sopenharmony_ci    }
1240d163575Sopenharmony_ci
1250d163575Sopenharmony_ci    if (((uint)accMode & tmpMode) == accMode) {
1260d163575Sopenharmony_ci        return 0;
1270d163575Sopenharmony_ci    }
1280d163575Sopenharmony_ci
1290d163575Sopenharmony_ci    return 1;
1300d163575Sopenharmony_ci}
1310d163575Sopenharmony_ci
1320d163575Sopenharmony_ci#ifdef VFS_USING_WORKDIR
1330d163575Sopenharmony_cistatic int SetWorkDir(const char *dir, size_t len)
1340d163575Sopenharmony_ci{
1350d163575Sopenharmony_ci    errno_t ret;
1360d163575Sopenharmony_ci    uint lock_flags;
1370d163575Sopenharmony_ci    LosProcessCB *curr = OsCurrProcessGet();
1380d163575Sopenharmony_ci
1390d163575Sopenharmony_ci    spin_lock_irqsave(&curr->files->workdir_lock, lock_flags);
1400d163575Sopenharmony_ci    ret = strncpy_s(curr->files->workdir, PATH_MAX, dir, len);
1410d163575Sopenharmony_ci    curr->files->workdir[PATH_MAX - 1] = '\0';
1420d163575Sopenharmony_ci    spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
1430d163575Sopenharmony_ci    if (ret != EOK) {
1440d163575Sopenharmony_ci        return -1;
1450d163575Sopenharmony_ci    }
1460d163575Sopenharmony_ci
1470d163575Sopenharmony_ci        return 0;
1480d163575Sopenharmony_ci}
1490d163575Sopenharmony_ci#endif
1500d163575Sopenharmony_ci
1510d163575Sopenharmony_ciint chdir(const char *path)
1520d163575Sopenharmony_ci{
1530d163575Sopenharmony_ci    int ret;
1540d163575Sopenharmony_ci    char *fullpath = NULL;
1550d163575Sopenharmony_ci    char *fullpath_bak = NULL;
1560d163575Sopenharmony_ci    struct stat statBuff;
1570d163575Sopenharmony_ci
1580d163575Sopenharmony_ci    if (!path) {
1590d163575Sopenharmony_ci        set_errno(EFAULT);
1600d163575Sopenharmony_ci        return -1;
1610d163575Sopenharmony_ci    }
1620d163575Sopenharmony_ci
1630d163575Sopenharmony_ci    if (!strlen(path)) {
1640d163575Sopenharmony_ci        set_errno(ENOENT);
1650d163575Sopenharmony_ci        return -1;
1660d163575Sopenharmony_ci    }
1670d163575Sopenharmony_ci
1680d163575Sopenharmony_ci    if (strlen(path) > PATH_MAX) {
1690d163575Sopenharmony_ci        set_errno(ENAMETOOLONG);
1700d163575Sopenharmony_ci        return -1;
1710d163575Sopenharmony_ci    }
1720d163575Sopenharmony_ci
1730d163575Sopenharmony_ci    ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
1740d163575Sopenharmony_ci    if (ret < 0) {
1750d163575Sopenharmony_ci        set_errno(-ret);
1760d163575Sopenharmony_ci        return -1; /* build path failed */
1770d163575Sopenharmony_ci    }
1780d163575Sopenharmony_ci    fullpath_bak = fullpath;
1790d163575Sopenharmony_ci    ret = stat(fullpath, &statBuff);
1800d163575Sopenharmony_ci    if (ret < 0) {
1810d163575Sopenharmony_ci        free(fullpath_bak);
1820d163575Sopenharmony_ci        return -1;
1830d163575Sopenharmony_ci    }
1840d163575Sopenharmony_ci
1850d163575Sopenharmony_ci    if (!S_ISDIR(statBuff.st_mode)) {
1860d163575Sopenharmony_ci        set_errno(ENOTDIR);
1870d163575Sopenharmony_ci        free(fullpath_bak);
1880d163575Sopenharmony_ci        return -1;
1890d163575Sopenharmony_ci    }
1900d163575Sopenharmony_ci
1910d163575Sopenharmony_ci    if (VfsPermissionCheck(statBuff.st_uid, statBuff.st_gid, statBuff.st_mode, EXEC_OP)) {
1920d163575Sopenharmony_ci        set_errno(EACCES);
1930d163575Sopenharmony_ci        free(fullpath_bak);
1940d163575Sopenharmony_ci        return -1;
1950d163575Sopenharmony_ci    }
1960d163575Sopenharmony_ci
1970d163575Sopenharmony_ci#ifdef VFS_USING_WORKDIR
1980d163575Sopenharmony_ci    ret = SetWorkDir(fullpath, strlen(fullpath));
1990d163575Sopenharmony_ci    if (ret != 0) {
2000d163575Sopenharmony_ci        PRINT_ERR("chdir path error!\n");
2010d163575Sopenharmony_ci        ret = -1;
2020d163575Sopenharmony_ci    }
2030d163575Sopenharmony_ci#endif
2040d163575Sopenharmony_ci
2050d163575Sopenharmony_ci    /* release normalize directory path name */
2060d163575Sopenharmony_ci
2070d163575Sopenharmony_ci    free(fullpath_bak);
2080d163575Sopenharmony_ci
2090d163575Sopenharmony_ci    return ret;
2100d163575Sopenharmony_ci}
2110d163575Sopenharmony_ci
2120d163575Sopenharmony_ci/**
2130d163575Sopenharmony_ci * this function is a POSIX compliant version, which will return current
2140d163575Sopenharmony_ci * working directory.
2150d163575Sopenharmony_ci *
2160d163575Sopenharmony_ci * @param buf the returned current directory.
2170d163575Sopenharmony_ci * @param size the buffer size.
2180d163575Sopenharmony_ci *
2190d163575Sopenharmony_ci * @return the returned current directory.
2200d163575Sopenharmony_ci */
2210d163575Sopenharmony_ci
2220d163575Sopenharmony_cichar *getcwd(char *buf, size_t n)
2230d163575Sopenharmony_ci{
2240d163575Sopenharmony_ci#ifdef VFS_USING_WORKDIR
2250d163575Sopenharmony_ci    int ret;
2260d163575Sopenharmony_ci    unsigned int len;
2270d163575Sopenharmony_ci    UINTPTR lock_flags;
2280d163575Sopenharmony_ci    LosProcessCB *curr = OsCurrProcessGet();
2290d163575Sopenharmony_ci#endif
2300d163575Sopenharmony_ci    if (buf == NULL) {
2310d163575Sopenharmony_ci        set_errno(EINVAL);
2320d163575Sopenharmony_ci        return buf;
2330d163575Sopenharmony_ci    }
2340d163575Sopenharmony_ci#ifdef VFS_USING_WORKDIR
2350d163575Sopenharmony_ci    spin_lock_irqsave(&curr->files->workdir_lock, lock_flags);
2360d163575Sopenharmony_ci    len = strlen(curr->files->workdir);
2370d163575Sopenharmony_ci    if (n <= len) {
2380d163575Sopenharmony_ci        set_errno(ERANGE);
2390d163575Sopenharmony_ci        spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
2400d163575Sopenharmony_ci        return NULL;
2410d163575Sopenharmony_ci    }
2420d163575Sopenharmony_ci    ret = memcpy_s(buf, n, curr->files->workdir, len + 1);
2430d163575Sopenharmony_ci    if (ret != EOK) {
2440d163575Sopenharmony_ci        set_errno(ENAMETOOLONG);
2450d163575Sopenharmony_ci        spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
2460d163575Sopenharmony_ci        return NULL;
2470d163575Sopenharmony_ci    }
2480d163575Sopenharmony_ci    spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
2490d163575Sopenharmony_ci#else
2500d163575Sopenharmony_ci    PRINT_ERR("NO_WORKING_DIR\n");
2510d163575Sopenharmony_ci#endif
2520d163575Sopenharmony_ci
2530d163575Sopenharmony_ci    return buf;
2540d163575Sopenharmony_ci}
2550d163575Sopenharmony_ci
2560d163575Sopenharmony_ciint chmod(const char *path, mode_t mode)
2570d163575Sopenharmony_ci{
2580d163575Sopenharmony_ci    struct IATTR attr = {0};
2590d163575Sopenharmony_ci    attr.attr_chg_mode = mode;
2600d163575Sopenharmony_ci    attr.attr_chg_valid = CHG_MODE; /* change mode */
2610d163575Sopenharmony_ci    int ret;
2620d163575Sopenharmony_ci
2630d163575Sopenharmony_ci    ret = chattr(path, &attr);
2640d163575Sopenharmony_ci    if (ret < 0) {
2650d163575Sopenharmony_ci        return VFS_ERROR;
2660d163575Sopenharmony_ci    }
2670d163575Sopenharmony_ci
2680d163575Sopenharmony_ci    return OK;
2690d163575Sopenharmony_ci}
2700d163575Sopenharmony_ci
2710d163575Sopenharmony_ciint chown(const char *pathname, uid_t owner, gid_t group)
2720d163575Sopenharmony_ci{
2730d163575Sopenharmony_ci    struct IATTR attr = {0};
2740d163575Sopenharmony_ci    attr.attr_chg_valid = 0;
2750d163575Sopenharmony_ci    int ret;
2760d163575Sopenharmony_ci
2770d163575Sopenharmony_ci    if (owner != (uid_t)-1) {
2780d163575Sopenharmony_ci        attr.attr_chg_uid = owner;
2790d163575Sopenharmony_ci        attr.attr_chg_valid |= CHG_UID;
2800d163575Sopenharmony_ci    }
2810d163575Sopenharmony_ci    if (group != (gid_t)-1) {
2820d163575Sopenharmony_ci        attr.attr_chg_gid = group;
2830d163575Sopenharmony_ci        attr.attr_chg_valid |= CHG_GID;
2840d163575Sopenharmony_ci    }
2850d163575Sopenharmony_ci    ret = chattr(pathname, &attr);
2860d163575Sopenharmony_ci    if (ret < 0) {
2870d163575Sopenharmony_ci        return VFS_ERROR;
2880d163575Sopenharmony_ci    }
2890d163575Sopenharmony_ci
2900d163575Sopenharmony_ci    return OK;
2910d163575Sopenharmony_ci}
2920d163575Sopenharmony_ci
2930d163575Sopenharmony_ciint access(const char *path, int amode)
2940d163575Sopenharmony_ci{
2950d163575Sopenharmony_ci    int ret;
2960d163575Sopenharmony_ci    struct stat buf;
2970d163575Sopenharmony_ci    struct statfs fsBuf;
2980d163575Sopenharmony_ci
2990d163575Sopenharmony_ci    ret = statfs(path, &fsBuf);
3000d163575Sopenharmony_ci    if (ret != 0) {
3010d163575Sopenharmony_ci        if (get_errno() != ENOSYS) {
3020d163575Sopenharmony_ci            return VFS_ERROR;
3030d163575Sopenharmony_ci        }
3040d163575Sopenharmony_ci        /* dev has no statfs ops, need devfs to handle this in feature */
3050d163575Sopenharmony_ci    }
3060d163575Sopenharmony_ci
3070d163575Sopenharmony_ci    if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) {
3080d163575Sopenharmony_ci        set_errno(EROFS);
3090d163575Sopenharmony_ci        return VFS_ERROR;
3100d163575Sopenharmony_ci    }
3110d163575Sopenharmony_ci
3120d163575Sopenharmony_ci    ret = stat(path, &buf);
3130d163575Sopenharmony_ci    if (ret != 0) {
3140d163575Sopenharmony_ci        return VFS_ERROR;
3150d163575Sopenharmony_ci    }
3160d163575Sopenharmony_ci
3170d163575Sopenharmony_ci    if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) {
3180d163575Sopenharmony_ci        set_errno(EACCES);
3190d163575Sopenharmony_ci        return VFS_ERROR;
3200d163575Sopenharmony_ci    }
3210d163575Sopenharmony_ci
3220d163575Sopenharmony_ci    return OK;
3230d163575Sopenharmony_ci}
3240d163575Sopenharmony_ci
3250d163575Sopenharmony_cistatic struct dirent **scandir_get_file_list(const char *dir, int *num, int(*filter)(const struct dirent *))
3260d163575Sopenharmony_ci{
3270d163575Sopenharmony_ci    DIR *od = NULL;
3280d163575Sopenharmony_ci    int listSize = MAX_DIR_ENT;
3290d163575Sopenharmony_ci    int n = 0;
3300d163575Sopenharmony_ci    struct dirent **list = NULL;
3310d163575Sopenharmony_ci    struct dirent **newList = NULL;
3320d163575Sopenharmony_ci    struct dirent *ent = NULL;
3330d163575Sopenharmony_ci    struct dirent *p = NULL;
3340d163575Sopenharmony_ci    int err;
3350d163575Sopenharmony_ci
3360d163575Sopenharmony_ci    od = opendir(dir);
3370d163575Sopenharmony_ci    if (od == NULL) {
3380d163575Sopenharmony_ci        return NULL;
3390d163575Sopenharmony_ci    }
3400d163575Sopenharmony_ci
3410d163575Sopenharmony_ci    list = (struct dirent **)malloc(listSize * sizeof(struct dirent *));
3420d163575Sopenharmony_ci    if (list == NULL) {
3430d163575Sopenharmony_ci        (void)closedir(od);
3440d163575Sopenharmony_ci        return NULL;
3450d163575Sopenharmony_ci    }
3460d163575Sopenharmony_ci
3470d163575Sopenharmony_ci    for (ent = readdir(od); ent != NULL; ent = readdir(od)) {
3480d163575Sopenharmony_ci        if (filter && !filter(ent)) {
3490d163575Sopenharmony_ci            continue;
3500d163575Sopenharmony_ci        }
3510d163575Sopenharmony_ci
3520d163575Sopenharmony_ci        if (n == listSize) {
3530d163575Sopenharmony_ci            listSize += MAX_DIR_ENT;
3540d163575Sopenharmony_ci            newList = (struct dirent **)malloc(listSize * sizeof(struct dirent *));
3550d163575Sopenharmony_ci            if (newList == NULL) {
3560d163575Sopenharmony_ci                break;
3570d163575Sopenharmony_ci            }
3580d163575Sopenharmony_ci
3590d163575Sopenharmony_ci            err = memcpy_s(newList, listSize * sizeof(struct dirent *), list, n * sizeof(struct dirent *));
3600d163575Sopenharmony_ci            if (err != EOK) {
3610d163575Sopenharmony_ci                free(newList);
3620d163575Sopenharmony_ci                break;
3630d163575Sopenharmony_ci            }
3640d163575Sopenharmony_ci            free(list);
3650d163575Sopenharmony_ci            list = newList;
3660d163575Sopenharmony_ci        }
3670d163575Sopenharmony_ci
3680d163575Sopenharmony_ci        p = (struct dirent *)malloc(sizeof(struct dirent));
3690d163575Sopenharmony_ci        if (p == NULL) {
3700d163575Sopenharmony_ci            break;
3710d163575Sopenharmony_ci        }
3720d163575Sopenharmony_ci
3730d163575Sopenharmony_ci        (void)memcpy_s((void *)p, sizeof(struct dirent), (void *)ent, sizeof(struct dirent));
3740d163575Sopenharmony_ci        list[n] = p;
3750d163575Sopenharmony_ci
3760d163575Sopenharmony_ci        n++;
3770d163575Sopenharmony_ci    }
3780d163575Sopenharmony_ci
3790d163575Sopenharmony_ci    if (closedir(od) < 0) {
3800d163575Sopenharmony_ci        while (n--) {
3810d163575Sopenharmony_ci            free(list[n]);
3820d163575Sopenharmony_ci        }
3830d163575Sopenharmony_ci        free(list);
3840d163575Sopenharmony_ci        return NULL;
3850d163575Sopenharmony_ci    }
3860d163575Sopenharmony_ci
3870d163575Sopenharmony_ci    *num = n;
3880d163575Sopenharmony_ci    return list;
3890d163575Sopenharmony_ci}
3900d163575Sopenharmony_ci
3910d163575Sopenharmony_ciint scandir(const char *dir, struct dirent ***namelist,
3920d163575Sopenharmony_ci            int(*filter)(const struct dirent *),
3930d163575Sopenharmony_ci            int(*compar)(const struct dirent **, const struct dirent **))
3940d163575Sopenharmony_ci{
3950d163575Sopenharmony_ci    int n = 0;
3960d163575Sopenharmony_ci    struct dirent **list = NULL;
3970d163575Sopenharmony_ci
3980d163575Sopenharmony_ci    if ((dir == NULL) || (namelist == NULL)) {
3990d163575Sopenharmony_ci        return -1;
4000d163575Sopenharmony_ci    }
4010d163575Sopenharmony_ci
4020d163575Sopenharmony_ci    list = scandir_get_file_list(dir, &n, filter);
4030d163575Sopenharmony_ci    if (list == NULL) {
4040d163575Sopenharmony_ci        return -1;
4050d163575Sopenharmony_ci    }
4060d163575Sopenharmony_ci
4070d163575Sopenharmony_ci    /* Change to return to the array size */
4080d163575Sopenharmony_ci    *namelist = (struct dirent **)malloc(n * sizeof(struct dirent *));
4090d163575Sopenharmony_ci    if (*namelist == NULL && n > 0) {
4100d163575Sopenharmony_ci        *namelist = list;
4110d163575Sopenharmony_ci    } else if (*namelist != NULL) {
4120d163575Sopenharmony_ci        (void)memcpy_s(*namelist, n * sizeof(struct dirent *), list, n * sizeof(struct dirent *));
4130d163575Sopenharmony_ci        free(list);
4140d163575Sopenharmony_ci    } else {
4150d163575Sopenharmony_ci        free(list);
4160d163575Sopenharmony_ci    }
4170d163575Sopenharmony_ci
4180d163575Sopenharmony_ci    /* Sort array */
4190d163575Sopenharmony_ci
4200d163575Sopenharmony_ci    if (compar && *namelist) {
4210d163575Sopenharmony_ci        qsort((void *)*namelist, (size_t)n, sizeof(struct dirent *), (int (*)(const void *, const void *))*compar);
4220d163575Sopenharmony_ci    }
4230d163575Sopenharmony_ci
4240d163575Sopenharmony_ci    return n;
4250d163575Sopenharmony_ci}
4260d163575Sopenharmony_ci
4270d163575Sopenharmony_ciint alphasort(const struct dirent **a, const struct dirent **b)
4280d163575Sopenharmony_ci{
4290d163575Sopenharmony_ci    return strcoll((*a)->d_name, (*b)->d_name);
4300d163575Sopenharmony_ci}
4310d163575Sopenharmony_ci
4320d163575Sopenharmony_cichar *rindex(const char *s, int c)
4330d163575Sopenharmony_ci{
4340d163575Sopenharmony_ci    if (s == NULL) {
4350d163575Sopenharmony_ci        return NULL;
4360d163575Sopenharmony_ci    }
4370d163575Sopenharmony_ci
4380d163575Sopenharmony_ci    /* Don't bother tracing - strrchr can do that */
4390d163575Sopenharmony_ci    return (char *)strrchr(s, c);
4400d163575Sopenharmony_ci}
4410d163575Sopenharmony_ci
4420d163575Sopenharmony_cistatic char *ls_get_fullpath(const char *path, struct dirent *pdirent)
4430d163575Sopenharmony_ci{
4440d163575Sopenharmony_ci    char *fullpath = NULL;
4450d163575Sopenharmony_ci    int ret;
4460d163575Sopenharmony_ci
4470d163575Sopenharmony_ci    if (path[1] != '\0') {
4480d163575Sopenharmony_ci        /* 2, The position of the path character: / and the end character '/0' */
4490d163575Sopenharmony_ci        fullpath = (char *)malloc(strlen(path) + strlen(pdirent->d_name) + 2);
4500d163575Sopenharmony_ci        if (fullpath == NULL) {
4510d163575Sopenharmony_ci            goto exit_with_nomem;
4520d163575Sopenharmony_ci        }
4530d163575Sopenharmony_ci
4540d163575Sopenharmony_ci        /* 2, The position of the path character: / and the end character '/0' */
4550d163575Sopenharmony_ci        ret = snprintf_s(fullpath, strlen(path) + strlen(pdirent->d_name) + 2,
4560d163575Sopenharmony_ci                         strlen(path) + strlen(pdirent->d_name) + 1, "%s/%s", path, pdirent->d_name);
4570d163575Sopenharmony_ci        if (ret < 0) {
4580d163575Sopenharmony_ci            free(fullpath);
4590d163575Sopenharmony_ci            set_errno(ENAMETOOLONG);
4600d163575Sopenharmony_ci            return NULL;
4610d163575Sopenharmony_ci        }
4620d163575Sopenharmony_ci    } else {
4630d163575Sopenharmony_ci        /* 2, The position of the path character: / and the end character '/0' */
4640d163575Sopenharmony_ci        fullpath = (char *)malloc(strlen(pdirent->d_name) + 2);
4650d163575Sopenharmony_ci        if (fullpath == NULL) {
4660d163575Sopenharmony_ci            goto exit_with_nomem;
4670d163575Sopenharmony_ci        }
4680d163575Sopenharmony_ci
4690d163575Sopenharmony_ci        /* 2, The position of the path character: / and the end character '/0' */
4700d163575Sopenharmony_ci        ret = snprintf_s(fullpath, strlen(pdirent->d_name) + 2, strlen(pdirent->d_name) + 1,
4710d163575Sopenharmony_ci                         "/%s", pdirent->d_name);
4720d163575Sopenharmony_ci        if (ret < 0) {
4730d163575Sopenharmony_ci            free(fullpath);
4740d163575Sopenharmony_ci            set_errno(ENAMETOOLONG);
4750d163575Sopenharmony_ci            return NULL;
4760d163575Sopenharmony_ci        }
4770d163575Sopenharmony_ci    }
4780d163575Sopenharmony_ci    return fullpath;
4790d163575Sopenharmony_ci
4800d163575Sopenharmony_ciexit_with_nomem:
4810d163575Sopenharmony_ci    set_errno(ENOSPC);
4820d163575Sopenharmony_ci    return (char *)NULL;
4830d163575Sopenharmony_ci}
4840d163575Sopenharmony_ci
4850d163575Sopenharmony_cistatic void PrintFileInfo64(const struct stat64 *stat64Info, const char *name, const char *linkName)
4860d163575Sopenharmony_ci{
4870d163575Sopenharmony_ci    mode_t mode;
4880d163575Sopenharmony_ci    char str[UGO_NUMS][UGO_NUMS + 1] = {0};
4890d163575Sopenharmony_ci    char dirFlag;
4900d163575Sopenharmony_ci    int i;
4910d163575Sopenharmony_ci
4920d163575Sopenharmony_ci    for (i = 0; i < UGO_NUMS; i++) {
4930d163575Sopenharmony_ci        mode = stat64Info->st_mode >> (uint)(USER_MODE_SHIFT - i * UGO_NUMS);
4940d163575Sopenharmony_ci        str[i][0] = (mode & READ_OP) ? 'r' : '-';
4950d163575Sopenharmony_ci        str[i][1] = (mode & WRITE_OP) ? 'w' : '-';
4960d163575Sopenharmony_ci        str[i][UGO_NUMS - 1] = (mode & EXEC_OP) ? 'x' : '-';
4970d163575Sopenharmony_ci    }
4980d163575Sopenharmony_ci
4990d163575Sopenharmony_ci    if (S_ISDIR(stat64Info->st_mode)) {
5000d163575Sopenharmony_ci        dirFlag = 'd';
5010d163575Sopenharmony_ci    } else if (S_ISLNK(stat64Info->st_mode)) {
5020d163575Sopenharmony_ci        dirFlag = 'l';
5030d163575Sopenharmony_ci    } else {
5040d163575Sopenharmony_ci        dirFlag = '-';
5050d163575Sopenharmony_ci    }
5060d163575Sopenharmony_ci
5070d163575Sopenharmony_ci    if (S_ISLNK(stat64Info->st_mode)) {
5080d163575Sopenharmony_ci        PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s -> %s\n", dirFlag,
5090d163575Sopenharmony_ci               str[0], str[1], str[UGO_NUMS - 1], stat64Info->st_size,
5100d163575Sopenharmony_ci               stat64Info->st_uid, stat64Info->st_gid, name, linkName);
5110d163575Sopenharmony_ci    } else {
5120d163575Sopenharmony_ci        PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s\n", dirFlag,
5130d163575Sopenharmony_ci               str[0], str[1], str[UGO_NUMS - 1], stat64Info->st_size,
5140d163575Sopenharmony_ci               stat64Info->st_uid, stat64Info->st_gid, name);
5150d163575Sopenharmony_ci    }
5160d163575Sopenharmony_ci}
5170d163575Sopenharmony_ci
5180d163575Sopenharmony_cistatic void PrintFileInfo(const struct stat *statInfo, const char *name, const char *linkName)
5190d163575Sopenharmony_ci{
5200d163575Sopenharmony_ci    mode_t mode;
5210d163575Sopenharmony_ci    char str[UGO_NUMS][UGO_NUMS + 1] = {0};
5220d163575Sopenharmony_ci    char dirFlag;
5230d163575Sopenharmony_ci    int i;
5240d163575Sopenharmony_ci
5250d163575Sopenharmony_ci    for (i = 0; i < UGO_NUMS; i++) {
5260d163575Sopenharmony_ci        mode = statInfo->st_mode >> (uint)(USER_MODE_SHIFT - i * UGO_NUMS);
5270d163575Sopenharmony_ci        str[i][0] = (mode & READ_OP) ? 'r' : '-';
5280d163575Sopenharmony_ci        str[i][1] = (mode & WRITE_OP) ? 'w' : '-';
5290d163575Sopenharmony_ci        str[i][UGO_NUMS - 1] = (mode & EXEC_OP) ? 'x' : '-';
5300d163575Sopenharmony_ci    }
5310d163575Sopenharmony_ci
5320d163575Sopenharmony_ci    if (S_ISDIR(statInfo->st_mode)) {
5330d163575Sopenharmony_ci        dirFlag = 'd';
5340d163575Sopenharmony_ci    } else if (S_ISLNK(statInfo->st_mode)) {
5350d163575Sopenharmony_ci        dirFlag = 'l';
5360d163575Sopenharmony_ci    } else {
5370d163575Sopenharmony_ci        dirFlag = '-';
5380d163575Sopenharmony_ci    }
5390d163575Sopenharmony_ci
5400d163575Sopenharmony_ci    if (S_ISLNK(statInfo->st_mode)) {
5410d163575Sopenharmony_ci        PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s -> %s\n", dirFlag,
5420d163575Sopenharmony_ci               str[0], str[1], str[UGO_NUMS - 1], statInfo->st_size,
5430d163575Sopenharmony_ci               statInfo->st_uid, statInfo->st_gid, name, linkName);
5440d163575Sopenharmony_ci    } else {
5450d163575Sopenharmony_ci        PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s\n", dirFlag,
5460d163575Sopenharmony_ci               str[0], str[1], str[UGO_NUMS - 1], statInfo->st_size,
5470d163575Sopenharmony_ci               statInfo->st_uid, statInfo->st_gid, name);
5480d163575Sopenharmony_ci    }
5490d163575Sopenharmony_ci}
5500d163575Sopenharmony_ci
5510d163575Sopenharmony_ciint LsFile(const char *path)
5520d163575Sopenharmony_ci{
5530d163575Sopenharmony_ci    struct stat64 stat64Info;
5540d163575Sopenharmony_ci    struct stat statInfo;
5550d163575Sopenharmony_ci    char linkName[NAME_MAX] = { 0 };
5560d163575Sopenharmony_ci
5570d163575Sopenharmony_ci    if (stat64(path, &stat64Info) == 0) {
5580d163575Sopenharmony_ci        if (S_ISLNK(stat64Info.st_mode)) {
5590d163575Sopenharmony_ci            readlink(path, linkName, NAME_MAX);
5600d163575Sopenharmony_ci        }
5610d163575Sopenharmony_ci        PrintFileInfo64(&stat64Info, path, (const char *)linkName);
5620d163575Sopenharmony_ci    } else if (stat(path, &statInfo) == 0) {
5630d163575Sopenharmony_ci        if (S_ISLNK(statInfo.st_mode)) {
5640d163575Sopenharmony_ci            readlink(path, linkName, NAME_MAX);
5650d163575Sopenharmony_ci        }
5660d163575Sopenharmony_ci        PrintFileInfo(&statInfo, path, (const char *)linkName);
5670d163575Sopenharmony_ci    } else {
5680d163575Sopenharmony_ci        return -1;
5690d163575Sopenharmony_ci    }
5700d163575Sopenharmony_ci
5710d163575Sopenharmony_ci    return 0;
5720d163575Sopenharmony_ci}
5730d163575Sopenharmony_ci
5740d163575Sopenharmony_ciint LsDir(const char *path)
5750d163575Sopenharmony_ci{
5760d163575Sopenharmony_ci    struct stat statInfo = { 0 };
5770d163575Sopenharmony_ci    struct stat64 stat64Info = { 0 };
5780d163575Sopenharmony_ci    char linkName[NAME_MAX] = { 0 };
5790d163575Sopenharmony_ci    DIR *d = NULL;
5800d163575Sopenharmony_ci    char *fullpath = NULL;
5810d163575Sopenharmony_ci    char *fullpath_bak = NULL;
5820d163575Sopenharmony_ci    struct dirent *pdirent = NULL;
5830d163575Sopenharmony_ci
5840d163575Sopenharmony_ci    d = opendir(path);
5850d163575Sopenharmony_ci    if (d == NULL) {
5860d163575Sopenharmony_ci        return -1;
5870d163575Sopenharmony_ci    }
5880d163575Sopenharmony_ci
5890d163575Sopenharmony_ci    PRINTK("Directory %s:\n", path);
5900d163575Sopenharmony_ci    do {
5910d163575Sopenharmony_ci        pdirent = readdir(d);
5920d163575Sopenharmony_ci        if (pdirent == NULL) {
5930d163575Sopenharmony_ci            break;
5940d163575Sopenharmony_ci        }
5950d163575Sopenharmony_ci        if (!strcmp(pdirent->d_name, ".") || !strcmp(pdirent->d_name, "..")) {
5960d163575Sopenharmony_ci            continue;
5970d163575Sopenharmony_ci        }
5980d163575Sopenharmony_ci        (void)memset_s(&statInfo, sizeof(struct stat), 0, sizeof(struct stat));
5990d163575Sopenharmony_ci        (void)memset_s(&stat64Info, sizeof(struct stat), 0, sizeof(struct stat));
6000d163575Sopenharmony_ci        (void)memset_s(&linkName, sizeof(linkName), 0, sizeof(linkName));
6010d163575Sopenharmony_ci        fullpath = ls_get_fullpath(path, pdirent);
6020d163575Sopenharmony_ci        if (fullpath == NULL) {
6030d163575Sopenharmony_ci            (void)closedir(d);
6040d163575Sopenharmony_ci            return -1;
6050d163575Sopenharmony_ci        }
6060d163575Sopenharmony_ci
6070d163575Sopenharmony_ci        fullpath_bak = fullpath;
6080d163575Sopenharmony_ci        if (stat64(fullpath, &stat64Info) == 0) {
6090d163575Sopenharmony_ci            if (S_ISLNK(stat64Info.st_mode)) {
6100d163575Sopenharmony_ci                readlink(fullpath, linkName, NAME_MAX);
6110d163575Sopenharmony_ci            }
6120d163575Sopenharmony_ci            PrintFileInfo64(&stat64Info, pdirent->d_name, linkName);
6130d163575Sopenharmony_ci        } else if (stat(fullpath, &statInfo) == 0) {
6140d163575Sopenharmony_ci            if (S_ISLNK(statInfo.st_mode)) {
6150d163575Sopenharmony_ci                readlink(fullpath, linkName, NAME_MAX);
6160d163575Sopenharmony_ci            }
6170d163575Sopenharmony_ci            PrintFileInfo(&statInfo, pdirent->d_name, linkName);
6180d163575Sopenharmony_ci        } else {
6190d163575Sopenharmony_ci            PRINTK("BAD file: %s\n", pdirent->d_name);
6200d163575Sopenharmony_ci        }
6210d163575Sopenharmony_ci        free(fullpath_bak);
6220d163575Sopenharmony_ci    } while (1);
6230d163575Sopenharmony_ci    (void)closedir(d);
6240d163575Sopenharmony_ci
6250d163575Sopenharmony_ci    return 0;
6260d163575Sopenharmony_ci}
6270d163575Sopenharmony_ci
6280d163575Sopenharmony_civoid ls(const char *pathname)
6290d163575Sopenharmony_ci{
6300d163575Sopenharmony_ci    struct stat statInfo = { 0 };
6310d163575Sopenharmony_ci    char *path = NULL;
6320d163575Sopenharmony_ci    int ret;
6330d163575Sopenharmony_ci
6340d163575Sopenharmony_ci    if (pathname == NULL) {
6350d163575Sopenharmony_ci#ifdef VFS_USING_WORKDIR
6360d163575Sopenharmony_ci        UINTPTR lock_flags;
6370d163575Sopenharmony_ci        LosProcessCB *curr = OsCurrProcessGet();
6380d163575Sopenharmony_ci
6390d163575Sopenharmony_ci        /* open current working directory */
6400d163575Sopenharmony_ci
6410d163575Sopenharmony_ci        spin_lock_irqsave(&curr->files->workdir_lock, lock_flags);
6420d163575Sopenharmony_ci        path = strdup(curr->files->workdir);
6430d163575Sopenharmony_ci        spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
6440d163575Sopenharmony_ci#else
6450d163575Sopenharmony_ci        path = strdup("/");
6460d163575Sopenharmony_ci#endif
6470d163575Sopenharmony_ci        if (path == NULL) {
6480d163575Sopenharmony_ci            return;
6490d163575Sopenharmony_ci        }
6500d163575Sopenharmony_ci    } else {
6510d163575Sopenharmony_ci        ret = vfs_normalize_path(NULL, pathname, &path);
6520d163575Sopenharmony_ci        if (ret < 0) {
6530d163575Sopenharmony_ci            set_errno(-ret);
6540d163575Sopenharmony_ci            return;
6550d163575Sopenharmony_ci        }
6560d163575Sopenharmony_ci    }
6570d163575Sopenharmony_ci
6580d163575Sopenharmony_ci    ret = stat(path, &statInfo);
6590d163575Sopenharmony_ci    if (ret < 0) {
6600d163575Sopenharmony_ci        perror("ls error");
6610d163575Sopenharmony_ci        free(path);
6620d163575Sopenharmony_ci        return;
6630d163575Sopenharmony_ci    }
6640d163575Sopenharmony_ci
6650d163575Sopenharmony_ci    if (statInfo.st_mode & S_IFDIR) { /* list all directory and file */
6660d163575Sopenharmony_ci        ret = LsDir((pathname == NULL) ? path : pathname);
6670d163575Sopenharmony_ci    } else { /* show the file information */
6680d163575Sopenharmony_ci        ret = LsFile(path);
6690d163575Sopenharmony_ci    }
6700d163575Sopenharmony_ci    if (ret < 0) {
6710d163575Sopenharmony_ci        perror("ls error");
6720d163575Sopenharmony_ci    }
6730d163575Sopenharmony_ci
6740d163575Sopenharmony_ci    free(path);
6750d163575Sopenharmony_ci    return;
6760d163575Sopenharmony_ci}
6770d163575Sopenharmony_ci
6780d163575Sopenharmony_ci
6790d163575Sopenharmony_cichar *realpath(const char *path, char *resolved_path)
6800d163575Sopenharmony_ci{
6810d163575Sopenharmony_ci    int ret, result;
6820d163575Sopenharmony_ci    char *new_path = NULL;
6830d163575Sopenharmony_ci    struct stat buf;
6840d163575Sopenharmony_ci
6850d163575Sopenharmony_ci    ret = vfs_normalize_path(NULL, path, &new_path);
6860d163575Sopenharmony_ci    if (ret < 0) {
6870d163575Sopenharmony_ci        ret = -ret;
6880d163575Sopenharmony_ci        set_errno(ret);
6890d163575Sopenharmony_ci        return NULL;
6900d163575Sopenharmony_ci    }
6910d163575Sopenharmony_ci
6920d163575Sopenharmony_ci    result = stat(new_path, &buf);
6930d163575Sopenharmony_ci
6940d163575Sopenharmony_ci    if (resolved_path == NULL) {
6950d163575Sopenharmony_ci        if (result != ENOERR) {
6960d163575Sopenharmony_ci            free(new_path);
6970d163575Sopenharmony_ci            return NULL;
6980d163575Sopenharmony_ci        }
6990d163575Sopenharmony_ci        return new_path;
7000d163575Sopenharmony_ci    }
7010d163575Sopenharmony_ci
7020d163575Sopenharmony_ci    ret = strcpy_s(resolved_path, PATH_MAX, new_path);
7030d163575Sopenharmony_ci    if (ret != EOK) {
7040d163575Sopenharmony_ci        ret = -ret;
7050d163575Sopenharmony_ci        set_errno(ret);
7060d163575Sopenharmony_ci        free(new_path);
7070d163575Sopenharmony_ci        return NULL;
7080d163575Sopenharmony_ci    }
7090d163575Sopenharmony_ci
7100d163575Sopenharmony_ci    free(new_path);
7110d163575Sopenharmony_ci    if (result != ENOERR) {
7120d163575Sopenharmony_ci        return NULL;
7130d163575Sopenharmony_ci    }
7140d163575Sopenharmony_ci    return resolved_path;
7150d163575Sopenharmony_ci}
7160d163575Sopenharmony_ci
7170d163575Sopenharmony_civoid lsfd(void)
7180d163575Sopenharmony_ci{
7190d163575Sopenharmony_ci    struct filelist *f_list = NULL;
7200d163575Sopenharmony_ci    unsigned int i = 3; /* file start fd */
7210d163575Sopenharmony_ci    int ret;
7220d163575Sopenharmony_ci    struct Vnode *node = NULL;
7230d163575Sopenharmony_ci
7240d163575Sopenharmony_ci    f_list = &tg_filelist;
7250d163575Sopenharmony_ci
7260d163575Sopenharmony_ci    PRINTK("   fd    filename\n");
7270d163575Sopenharmony_ci    ret = sem_wait(&f_list->fl_sem);
7280d163575Sopenharmony_ci    if (ret < 0) {
7290d163575Sopenharmony_ci        PRINTK("sem_wait error, ret=%d\n", ret);
7300d163575Sopenharmony_ci        return;
7310d163575Sopenharmony_ci    }
7320d163575Sopenharmony_ci
7330d163575Sopenharmony_ci    while (i < CONFIG_NFILE_DESCRIPTORS) {
7340d163575Sopenharmony_ci        node = files_get_openfile(i);
7350d163575Sopenharmony_ci        if (node) {
7360d163575Sopenharmony_ci            PRINTK("%5d   %s\n", i, f_list->fl_files[i].f_path);
7370d163575Sopenharmony_ci        }
7380d163575Sopenharmony_ci        i++;
7390d163575Sopenharmony_ci    }
7400d163575Sopenharmony_ci    (void)sem_post(&f_list->fl_sem);
7410d163575Sopenharmony_ci}
7420d163575Sopenharmony_ci
7430d163575Sopenharmony_cimode_t GetUmask(void)
7440d163575Sopenharmony_ci{
7450d163575Sopenharmony_ci    return OsCurrProcessGet()->umask;
7460d163575Sopenharmony_ci}
7470d163575Sopenharmony_ci
7480d163575Sopenharmony_cimode_t SysUmask(mode_t mask)
7490d163575Sopenharmony_ci{
7500d163575Sopenharmony_ci    UINT32 intSave;
7510d163575Sopenharmony_ci    mode_t umask;
7520d163575Sopenharmony_ci    mode_t oldUmask;
7530d163575Sopenharmony_ci    umask = mask & UMASK_FULL;
7540d163575Sopenharmony_ci    SCHEDULER_LOCK(intSave);
7550d163575Sopenharmony_ci    oldUmask = OsCurrProcessGet()->umask;
7560d163575Sopenharmony_ci    OsCurrProcessGet()->umask = umask;
7570d163575Sopenharmony_ci    SCHEDULER_UNLOCK(intSave);
7580d163575Sopenharmony_ci    return oldUmask;
7590d163575Sopenharmony_ci}
7600d163575Sopenharmony_ci
7610d163575Sopenharmony_ci#ifdef LOSCFG_CHROOT
7620d163575Sopenharmony_ciint chroot(const char *path)
7630d163575Sopenharmony_ci{
7640d163575Sopenharmony_ci    int ret;
7650d163575Sopenharmony_ci    struct Vnode *vnode = NULL;
7660d163575Sopenharmony_ci
7670d163575Sopenharmony_ci    if (!path) {
7680d163575Sopenharmony_ci        set_errno(EFAULT);
7690d163575Sopenharmony_ci        return VFS_ERROR;
7700d163575Sopenharmony_ci    }
7710d163575Sopenharmony_ci
7720d163575Sopenharmony_ci    if (!strlen(path)) {
7730d163575Sopenharmony_ci        set_errno(ENOENT);
7740d163575Sopenharmony_ci        return VFS_ERROR;
7750d163575Sopenharmony_ci    }
7760d163575Sopenharmony_ci
7770d163575Sopenharmony_ci    if (strlen(path) > PATH_MAX) {
7780d163575Sopenharmony_ci        set_errno(ENAMETOOLONG);
7790d163575Sopenharmony_ci        return VFS_ERROR;
7800d163575Sopenharmony_ci    }
7810d163575Sopenharmony_ci    VnodeHold();
7820d163575Sopenharmony_ci    ret = VnodeLookup(path, &vnode, 0);
7830d163575Sopenharmony_ci    if (ret != LOS_OK) {
7840d163575Sopenharmony_ci        VnodeDrop();
7850d163575Sopenharmony_ci        return ret;
7860d163575Sopenharmony_ci    }
7870d163575Sopenharmony_ci
7880d163575Sopenharmony_ci    LosProcessCB *curr = OsCurrProcessGet();
7890d163575Sopenharmony_ci    if ((curr->files == NULL) || (curr->files->rootVnode == NULL)) {
7900d163575Sopenharmony_ci        VnodeDrop();
7910d163575Sopenharmony_ci        return VFS_ERROR;
7920d163575Sopenharmony_ci    }
7930d163575Sopenharmony_ci    if (curr->files->rootVnode->useCount > 0) {
7940d163575Sopenharmony_ci        curr->files->rootVnode->useCount--;
7950d163575Sopenharmony_ci    }
7960d163575Sopenharmony_ci    vnode->useCount++;
7970d163575Sopenharmony_ci    curr->files->rootVnode = vnode;
7980d163575Sopenharmony_ci
7990d163575Sopenharmony_ci    VnodeDrop();
8000d163575Sopenharmony_ci    return LOS_OK;
8010d163575Sopenharmony_ci}
8020d163575Sopenharmony_ci#endif
803