• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "errno.h"
33 #include "stdlib.h"
34 #include "string.h"
35 #include "dirent.h"
36 #include "unistd.h"
37 #include "sys/select.h"
38 #include "sys/mount.h"
39 #include "sys/stat.h"
40 #include "sys/statfs.h"
41 #include "sys/prctl.h"
42 #include "fs/fd_table.h"
43 #include "fs/file.h"
44 #include "linux/spinlock.h"
45 #include "los_process_pri.h"
46 #include "los_task_pri.h"
47 #include "capability_api.h"
48 #include "vnode.h"
49 
50 #define MAX_DIR_ENT 1024
fstat(int fd,struct stat * buf)51 int fstat(int fd, struct stat *buf)
52 {
53     struct file *filep = NULL;
54 
55     int ret = fs_getfilep(fd, &filep);
56     if (ret < 0) {
57         return VFS_ERROR;
58     }
59 
60     return stat(filep->f_path, buf);
61 }
62 
fstat64(int fd,struct stat64 * buf)63 int fstat64(int fd, struct stat64 *buf)
64 {
65     struct file *filep = NULL;
66 
67     int ret = fs_getfilep(fd, &filep);
68     if (ret < 0) {
69         return VFS_ERROR;
70     }
71 
72     return stat64(filep->f_path, buf);
73 }
74 
lstat(const char * path,struct stat * buffer)75 int lstat(const char *path, struct stat *buffer)
76 {
77     return stat(path, buffer);
78 }
79 
VfsVnodePermissionCheck(const struct Vnode * node,int accMode)80 int VfsVnodePermissionCheck(const struct Vnode *node, int accMode)
81 {
82     uint fuid = node->uid;
83     uint fgid = node->gid;
84     uint fileMode = node->mode;
85     return VfsPermissionCheck(fuid, fgid, fileMode, accMode);
86 }
87 
VfsPermissionCheck(uint fuid,uint fgid,uint fileMode,int accMode)88 int VfsPermissionCheck(uint fuid, uint fgid, uint fileMode, int accMode)
89 {
90     uint uid = OsCurrUserGet()->effUserID;
91     mode_t tmpMode = fileMode;
92 
93     if (uid == fuid) {
94         tmpMode >>= USER_MODE_SHIFT;
95     } else if (LOS_CheckInGroups(fgid)) {
96         tmpMode >>= GROUP_MODE_SHIFT;
97     }
98 
99     tmpMode &= (READ_OP | WRITE_OP | EXEC_OP);
100 
101     if (((uint)accMode & tmpMode) == accMode) {
102         return 0;
103     }
104 
105     tmpMode = 0;
106     if (S_ISDIR(fileMode)) {
107         if (IsCapPermit(CAP_DAC_EXECUTE)
108             || (!((uint)accMode & WRITE_OP) && IsCapPermit(CAP_DAC_READ_SEARCH))) {
109             tmpMode |= EXEC_OP;
110         }
111     } else {
112         if (IsCapPermit(CAP_DAC_EXECUTE) && (fileMode & MODE_IXUGO)) {
113             tmpMode |= EXEC_OP;
114         }
115     }
116 
117     if (IsCapPermit(CAP_DAC_WRITE)) {
118         tmpMode |= WRITE_OP;
119     }
120 
121     if (IsCapPermit(CAP_DAC_READ_SEARCH)) {
122         tmpMode |= READ_OP;
123     }
124 
125     if (((uint)accMode & tmpMode) == accMode) {
126         return 0;
127     }
128 
129     return 1;
130 }
131 
132 #ifdef VFS_USING_WORKDIR
SetWorkDir(const char * dir,size_t len)133 static int SetWorkDir(const char *dir, size_t len)
134 {
135     errno_t ret;
136     uint lock_flags;
137     LosProcessCB *curr = OsCurrProcessGet();
138 
139     spin_lock_irqsave(&curr->files->workdir_lock, lock_flags);
140     ret = strncpy_s(curr->files->workdir, PATH_MAX, dir, len);
141     curr->files->workdir[PATH_MAX - 1] = '\0';
142     spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
143     if (ret != EOK) {
144         return -1;
145     }
146 
147         return 0;
148 }
149 #endif
150 
chdir(const char * path)151 int chdir(const char *path)
152 {
153     int ret;
154     char *fullpath = NULL;
155     char *fullpath_bak = NULL;
156     struct stat statBuff;
157 
158     if (!path) {
159         set_errno(EFAULT);
160         return -1;
161     }
162 
163     if (!strlen(path)) {
164         set_errno(ENOENT);
165         return -1;
166     }
167 
168     if (strlen(path) > PATH_MAX) {
169         set_errno(ENAMETOOLONG);
170         return -1;
171     }
172 
173     ret = vfs_normalize_path((const char *)NULL, path, &fullpath);
174     if (ret < 0) {
175         set_errno(-ret);
176         return -1; /* build path failed */
177     }
178     fullpath_bak = fullpath;
179     ret = stat(fullpath, &statBuff);
180     if (ret < 0) {
181         free(fullpath_bak);
182         return -1;
183     }
184 
185     if (!S_ISDIR(statBuff.st_mode)) {
186         set_errno(ENOTDIR);
187         free(fullpath_bak);
188         return -1;
189     }
190 
191     if (VfsPermissionCheck(statBuff.st_uid, statBuff.st_gid, statBuff.st_mode, EXEC_OP)) {
192         set_errno(EACCES);
193         free(fullpath_bak);
194         return -1;
195     }
196 
197 #ifdef VFS_USING_WORKDIR
198     ret = SetWorkDir(fullpath, strlen(fullpath));
199     if (ret != 0) {
200         PRINT_ERR("chdir path error!\n");
201         ret = -1;
202     }
203 #endif
204 
205     /* release normalize directory path name */
206 
207     free(fullpath_bak);
208 
209     return ret;
210 }
211 
212 /**
213  * this function is a POSIX compliant version, which will return current
214  * working directory.
215  *
216  * @param buf the returned current directory.
217  * @param size the buffer size.
218  *
219  * @return the returned current directory.
220  */
221 
getcwd(char * buf,size_t n)222 char *getcwd(char *buf, size_t n)
223 {
224 #ifdef VFS_USING_WORKDIR
225     int ret;
226     unsigned int len;
227     UINTPTR lock_flags;
228     LosProcessCB *curr = OsCurrProcessGet();
229 #endif
230     if (buf == NULL) {
231         set_errno(EINVAL);
232         return buf;
233     }
234 #ifdef VFS_USING_WORKDIR
235     spin_lock_irqsave(&curr->files->workdir_lock, lock_flags);
236     len = strlen(curr->files->workdir);
237     if (n <= len) {
238         set_errno(ERANGE);
239         spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
240         return NULL;
241     }
242     ret = memcpy_s(buf, n, curr->files->workdir, len + 1);
243     if (ret != EOK) {
244         set_errno(ENAMETOOLONG);
245         spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
246         return NULL;
247     }
248     spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
249 #else
250     PRINT_ERR("NO_WORKING_DIR\n");
251 #endif
252 
253     return buf;
254 }
255 
chmod(const char * path,mode_t mode)256 int chmod(const char *path, mode_t mode)
257 {
258     struct IATTR attr = {0};
259     attr.attr_chg_mode = mode;
260     attr.attr_chg_valid = CHG_MODE; /* change mode */
261     int ret;
262 
263     ret = chattr(path, &attr);
264     if (ret < 0) {
265         return VFS_ERROR;
266     }
267 
268     return OK;
269 }
270 
chown(const char * pathname,uid_t owner,gid_t group)271 int chown(const char *pathname, uid_t owner, gid_t group)
272 {
273     struct IATTR attr = {0};
274     attr.attr_chg_valid = 0;
275     int ret;
276 
277     if (owner != (uid_t)-1) {
278         attr.attr_chg_uid = owner;
279         attr.attr_chg_valid |= CHG_UID;
280     }
281     if (group != (gid_t)-1) {
282         attr.attr_chg_gid = group;
283         attr.attr_chg_valid |= CHG_GID;
284     }
285     ret = chattr(pathname, &attr);
286     if (ret < 0) {
287         return VFS_ERROR;
288     }
289 
290     return OK;
291 }
292 
access(const char * path,int amode)293 int access(const char *path, int amode)
294 {
295     int ret;
296     struct stat buf;
297     struct statfs fsBuf;
298 
299     ret = statfs(path, &fsBuf);
300     if (ret != 0) {
301         if (get_errno() != ENOSYS) {
302             return VFS_ERROR;
303         }
304         /* dev has no statfs ops, need devfs to handle this in feature */
305     }
306 
307     if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) {
308         set_errno(EROFS);
309         return VFS_ERROR;
310     }
311 
312     ret = stat(path, &buf);
313     if (ret != 0) {
314         return VFS_ERROR;
315     }
316 
317     if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) {
318         set_errno(EACCES);
319         return VFS_ERROR;
320     }
321 
322     return OK;
323 }
324 
scandir_get_file_list(const char * dir,int * num,int (* filter)(const struct dirent *))325 static struct dirent **scandir_get_file_list(const char *dir, int *num, int(*filter)(const struct dirent *))
326 {
327     DIR *od = NULL;
328     int listSize = MAX_DIR_ENT;
329     int n = 0;
330     struct dirent **list = NULL;
331     struct dirent **newList = NULL;
332     struct dirent *ent = NULL;
333     struct dirent *p = NULL;
334     int err;
335 
336     od = opendir(dir);
337     if (od == NULL) {
338         return NULL;
339     }
340 
341     list = (struct dirent **)malloc(listSize * sizeof(struct dirent *));
342     if (list == NULL) {
343         (void)closedir(od);
344         return NULL;
345     }
346 
347     for (ent = readdir(od); ent != NULL; ent = readdir(od)) {
348         if (filter && !filter(ent)) {
349             continue;
350         }
351 
352         if (n == listSize) {
353             listSize += MAX_DIR_ENT;
354             newList = (struct dirent **)malloc(listSize * sizeof(struct dirent *));
355             if (newList == NULL) {
356                 break;
357             }
358 
359             err = memcpy_s(newList, listSize * sizeof(struct dirent *), list, n * sizeof(struct dirent *));
360             if (err != EOK) {
361                 free(newList);
362                 break;
363             }
364             free(list);
365             list = newList;
366         }
367 
368         p = (struct dirent *)malloc(sizeof(struct dirent));
369         if (p == NULL) {
370             break;
371         }
372 
373         (void)memcpy_s((void *)p, sizeof(struct dirent), (void *)ent, sizeof(struct dirent));
374         list[n] = p;
375 
376         n++;
377     }
378 
379     if (closedir(od) < 0) {
380         while (n--) {
381             free(list[n]);
382         }
383         free(list);
384         return NULL;
385     }
386 
387     *num = n;
388     return list;
389 }
390 
scandir(const char * dir,struct dirent *** namelist,int (* filter)(const struct dirent *),int (* compar)(const struct dirent **,const struct dirent **))391 int scandir(const char *dir, struct dirent ***namelist,
392             int(*filter)(const struct dirent *),
393             int(*compar)(const struct dirent **, const struct dirent **))
394 {
395     int n = 0;
396     struct dirent **list = NULL;
397 
398     if ((dir == NULL) || (namelist == NULL)) {
399         return -1;
400     }
401 
402     list = scandir_get_file_list(dir, &n, filter);
403     if (list == NULL) {
404         return -1;
405     }
406 
407     /* Change to return to the array size */
408     *namelist = (struct dirent **)malloc(n * sizeof(struct dirent *));
409     if (*namelist == NULL && n > 0) {
410         *namelist = list;
411     } else if (*namelist != NULL) {
412         (void)memcpy_s(*namelist, n * sizeof(struct dirent *), list, n * sizeof(struct dirent *));
413         free(list);
414     } else {
415         free(list);
416     }
417 
418     /* Sort array */
419 
420     if (compar && *namelist) {
421         qsort((void *)*namelist, (size_t)n, sizeof(struct dirent *), (int (*)(const void *, const void *))*compar);
422     }
423 
424     return n;
425 }
426 
alphasort(const struct dirent ** a,const struct dirent ** b)427 int alphasort(const struct dirent **a, const struct dirent **b)
428 {
429     return strcoll((*a)->d_name, (*b)->d_name);
430 }
431 
rindex(const char * s,int c)432 char *rindex(const char *s, int c)
433 {
434     if (s == NULL) {
435         return NULL;
436     }
437 
438     /* Don't bother tracing - strrchr can do that */
439     return (char *)strrchr(s, c);
440 }
441 
ls_get_fullpath(const char * path,struct dirent * pdirent)442 static char *ls_get_fullpath(const char *path, struct dirent *pdirent)
443 {
444     char *fullpath = NULL;
445     int ret;
446 
447     if (path[1] != '\0') {
448         /* 2, The position of the path character: / and the end character '/0' */
449         fullpath = (char *)malloc(strlen(path) + strlen(pdirent->d_name) + 2);
450         if (fullpath == NULL) {
451             goto exit_with_nomem;
452         }
453 
454         /* 2, The position of the path character: / and the end character '/0' */
455         ret = snprintf_s(fullpath, strlen(path) + strlen(pdirent->d_name) + 2,
456                          strlen(path) + strlen(pdirent->d_name) + 1, "%s/%s", path, pdirent->d_name);
457         if (ret < 0) {
458             free(fullpath);
459             set_errno(ENAMETOOLONG);
460             return NULL;
461         }
462     } else {
463         /* 2, The position of the path character: / and the end character '/0' */
464         fullpath = (char *)malloc(strlen(pdirent->d_name) + 2);
465         if (fullpath == NULL) {
466             goto exit_with_nomem;
467         }
468 
469         /* 2, The position of the path character: / and the end character '/0' */
470         ret = snprintf_s(fullpath, strlen(pdirent->d_name) + 2, strlen(pdirent->d_name) + 1,
471                          "/%s", pdirent->d_name);
472         if (ret < 0) {
473             free(fullpath);
474             set_errno(ENAMETOOLONG);
475             return NULL;
476         }
477     }
478     return fullpath;
479 
480 exit_with_nomem:
481     set_errno(ENOSPC);
482     return (char *)NULL;
483 }
484 
PrintFileInfo64(const struct stat64 * stat64Info,const char * name,const char * linkName)485 static void PrintFileInfo64(const struct stat64 *stat64Info, const char *name, const char *linkName)
486 {
487     mode_t mode;
488     char str[UGO_NUMS][UGO_NUMS + 1] = {0};
489     char dirFlag;
490     int i;
491 
492     for (i = 0; i < UGO_NUMS; i++) {
493         mode = stat64Info->st_mode >> (uint)(USER_MODE_SHIFT - i * UGO_NUMS);
494         str[i][0] = (mode & READ_OP) ? 'r' : '-';
495         str[i][1] = (mode & WRITE_OP) ? 'w' : '-';
496         str[i][UGO_NUMS - 1] = (mode & EXEC_OP) ? 'x' : '-';
497     }
498 
499     if (S_ISDIR(stat64Info->st_mode)) {
500         dirFlag = 'd';
501     } else if (S_ISLNK(stat64Info->st_mode)) {
502         dirFlag = 'l';
503     } else {
504         dirFlag = '-';
505     }
506 
507     if (S_ISLNK(stat64Info->st_mode)) {
508         PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s -> %s\n", dirFlag,
509                str[0], str[1], str[UGO_NUMS - 1], stat64Info->st_size,
510                stat64Info->st_uid, stat64Info->st_gid, name, linkName);
511     } else {
512         PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s\n", dirFlag,
513                str[0], str[1], str[UGO_NUMS - 1], stat64Info->st_size,
514                stat64Info->st_uid, stat64Info->st_gid, name);
515     }
516 }
517 
PrintFileInfo(const struct stat * statInfo,const char * name,const char * linkName)518 static void PrintFileInfo(const struct stat *statInfo, const char *name, const char *linkName)
519 {
520     mode_t mode;
521     char str[UGO_NUMS][UGO_NUMS + 1] = {0};
522     char dirFlag;
523     int i;
524 
525     for (i = 0; i < UGO_NUMS; i++) {
526         mode = statInfo->st_mode >> (uint)(USER_MODE_SHIFT - i * UGO_NUMS);
527         str[i][0] = (mode & READ_OP) ? 'r' : '-';
528         str[i][1] = (mode & WRITE_OP) ? 'w' : '-';
529         str[i][UGO_NUMS - 1] = (mode & EXEC_OP) ? 'x' : '-';
530     }
531 
532     if (S_ISDIR(statInfo->st_mode)) {
533         dirFlag = 'd';
534     } else if (S_ISLNK(statInfo->st_mode)) {
535         dirFlag = 'l';
536     } else {
537         dirFlag = '-';
538     }
539 
540     if (S_ISLNK(statInfo->st_mode)) {
541         PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s -> %s\n", dirFlag,
542                str[0], str[1], str[UGO_NUMS - 1], statInfo->st_size,
543                statInfo->st_uid, statInfo->st_gid, name, linkName);
544     } else {
545         PRINTK("%c%s%s%s %-8lld u:%-5d g:%-5d %-10s\n", dirFlag,
546                str[0], str[1], str[UGO_NUMS - 1], statInfo->st_size,
547                statInfo->st_uid, statInfo->st_gid, name);
548     }
549 }
550 
LsFile(const char * path)551 int LsFile(const char *path)
552 {
553     struct stat64 stat64Info;
554     struct stat statInfo;
555     char linkName[NAME_MAX] = { 0 };
556 
557     if (stat64(path, &stat64Info) == 0) {
558         if (S_ISLNK(stat64Info.st_mode)) {
559             readlink(path, linkName, NAME_MAX);
560         }
561         PrintFileInfo64(&stat64Info, path, (const char *)linkName);
562     } else if (stat(path, &statInfo) == 0) {
563         if (S_ISLNK(statInfo.st_mode)) {
564             readlink(path, linkName, NAME_MAX);
565         }
566         PrintFileInfo(&statInfo, path, (const char *)linkName);
567     } else {
568         return -1;
569     }
570 
571     return 0;
572 }
573 
LsDir(const char * path)574 int LsDir(const char *path)
575 {
576     struct stat statInfo = { 0 };
577     struct stat64 stat64Info = { 0 };
578     char linkName[NAME_MAX] = { 0 };
579     DIR *d = NULL;
580     char *fullpath = NULL;
581     char *fullpath_bak = NULL;
582     struct dirent *pdirent = NULL;
583 
584     d = opendir(path);
585     if (d == NULL) {
586         return -1;
587     }
588 
589     PRINTK("Directory %s:\n", path);
590     do {
591         pdirent = readdir(d);
592         if (pdirent == NULL) {
593             break;
594         }
595         if (!strcmp(pdirent->d_name, ".") || !strcmp(pdirent->d_name, "..")) {
596             continue;
597         }
598         (void)memset_s(&statInfo, sizeof(struct stat), 0, sizeof(struct stat));
599         (void)memset_s(&stat64Info, sizeof(struct stat), 0, sizeof(struct stat));
600         (void)memset_s(&linkName, sizeof(linkName), 0, sizeof(linkName));
601         fullpath = ls_get_fullpath(path, pdirent);
602         if (fullpath == NULL) {
603             (void)closedir(d);
604             return -1;
605         }
606 
607         fullpath_bak = fullpath;
608         if (stat64(fullpath, &stat64Info) == 0) {
609             if (S_ISLNK(stat64Info.st_mode)) {
610                 readlink(fullpath, linkName, NAME_MAX);
611             }
612             PrintFileInfo64(&stat64Info, pdirent->d_name, linkName);
613         } else if (stat(fullpath, &statInfo) == 0) {
614             if (S_ISLNK(statInfo.st_mode)) {
615                 readlink(fullpath, linkName, NAME_MAX);
616             }
617             PrintFileInfo(&statInfo, pdirent->d_name, linkName);
618         } else {
619             PRINTK("BAD file: %s\n", pdirent->d_name);
620         }
621         free(fullpath_bak);
622     } while (1);
623     (void)closedir(d);
624 
625     return 0;
626 }
627 
ls(const char * pathname)628 void ls(const char *pathname)
629 {
630     struct stat statInfo = { 0 };
631     char *path = NULL;
632     int ret;
633 
634     if (pathname == NULL) {
635 #ifdef VFS_USING_WORKDIR
636         UINTPTR lock_flags;
637         LosProcessCB *curr = OsCurrProcessGet();
638 
639         /* open current working directory */
640 
641         spin_lock_irqsave(&curr->files->workdir_lock, lock_flags);
642         path = strdup(curr->files->workdir);
643         spin_unlock_irqrestore(&curr->files->workdir_lock, lock_flags);
644 #else
645         path = strdup("/");
646 #endif
647         if (path == NULL) {
648             return;
649         }
650     } else {
651         ret = vfs_normalize_path(NULL, pathname, &path);
652         if (ret < 0) {
653             set_errno(-ret);
654             return;
655         }
656     }
657 
658     ret = stat(path, &statInfo);
659     if (ret < 0) {
660         perror("ls error");
661         free(path);
662         return;
663     }
664 
665     if (statInfo.st_mode & S_IFDIR) { /* list all directory and file */
666         ret = LsDir((pathname == NULL) ? path : pathname);
667     } else { /* show the file information */
668         ret = LsFile(path);
669     }
670     if (ret < 0) {
671         perror("ls error");
672     }
673 
674     free(path);
675     return;
676 }
677 
678 
realpath(const char * path,char * resolved_path)679 char *realpath(const char *path, char *resolved_path)
680 {
681     int ret, result;
682     char *new_path = NULL;
683     struct stat buf;
684 
685     ret = vfs_normalize_path(NULL, path, &new_path);
686     if (ret < 0) {
687         ret = -ret;
688         set_errno(ret);
689         return NULL;
690     }
691 
692     result = stat(new_path, &buf);
693 
694     if (resolved_path == NULL) {
695         if (result != ENOERR) {
696             free(new_path);
697             return NULL;
698         }
699         return new_path;
700     }
701 
702     ret = strcpy_s(resolved_path, PATH_MAX, new_path);
703     if (ret != EOK) {
704         ret = -ret;
705         set_errno(ret);
706         free(new_path);
707         return NULL;
708     }
709 
710     free(new_path);
711     if (result != ENOERR) {
712         return NULL;
713     }
714     return resolved_path;
715 }
716 
lsfd(void)717 void lsfd(void)
718 {
719     struct filelist *f_list = NULL;
720     unsigned int i = 3; /* file start fd */
721     int ret;
722     struct Vnode *node = NULL;
723 
724     f_list = &tg_filelist;
725 
726     PRINTK("   fd    filename\n");
727     ret = sem_wait(&f_list->fl_sem);
728     if (ret < 0) {
729         PRINTK("sem_wait error, ret=%d\n", ret);
730         return;
731     }
732 
733     while (i < CONFIG_NFILE_DESCRIPTORS) {
734         node = files_get_openfile(i);
735         if (node) {
736             PRINTK("%5d   %s\n", i, f_list->fl_files[i].f_path);
737         }
738         i++;
739     }
740     (void)sem_post(&f_list->fl_sem);
741 }
742 
GetUmask(void)743 mode_t GetUmask(void)
744 {
745     return OsCurrProcessGet()->umask;
746 }
747 
SysUmask(mode_t mask)748 mode_t SysUmask(mode_t mask)
749 {
750     UINT32 intSave;
751     mode_t umask;
752     mode_t oldUmask;
753     umask = mask & UMASK_FULL;
754     SCHEDULER_LOCK(intSave);
755     oldUmask = OsCurrProcessGet()->umask;
756     OsCurrProcessGet()->umask = umask;
757     SCHEDULER_UNLOCK(intSave);
758     return oldUmask;
759 }
760 
761 #ifdef LOSCFG_CHROOT
chroot(const char * path)762 int chroot(const char *path)
763 {
764     int ret;
765     struct Vnode *vnode = NULL;
766 
767     if (!path) {
768         set_errno(EFAULT);
769         return VFS_ERROR;
770     }
771 
772     if (!strlen(path)) {
773         set_errno(ENOENT);
774         return VFS_ERROR;
775     }
776 
777     if (strlen(path) > PATH_MAX) {
778         set_errno(ENAMETOOLONG);
779         return VFS_ERROR;
780     }
781     VnodeHold();
782     ret = VnodeLookup(path, &vnode, 0);
783     if (ret != LOS_OK) {
784         VnodeDrop();
785         return ret;
786     }
787 
788     LosProcessCB *curr = OsCurrProcessGet();
789     if ((curr->files == NULL) || (curr->files->rootVnode == NULL)) {
790         VnodeDrop();
791         return VFS_ERROR;
792     }
793     if (curr->files->rootVnode->useCount > 0) {
794         curr->files->rootVnode->useCount--;
795     }
796     vnode->useCount++;
797     curr->files->rootVnode = vnode;
798 
799     VnodeDrop();
800     return LOS_OK;
801 }
802 #endif
803