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