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