RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
dfs.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2005-02-22 Bernard The first version.
9 * 2017-12-11 Bernard Use rt_free to instead of free in fd_is_open().
10 * 2018-03-20 Heyuanjie dynamic allocation FD
11 */
12
13#include <dfs.h>
14#include <dfs_fs.h>
15#include <dfs_dentry.h>
16#include <dfs_file.h>
17#include <dfs_mnt.h>
18
19#include <rtservice.h>
20
21#include "dfs_private.h"
22
23#define DBG_TAG "DFS"
24#define DBG_LVL DBG_INFO
25#include <rtdbg.h>
26
27#ifdef RT_USING_SMART
28#include <lwp.h>
29#endif
30
31#ifdef DFS_USING_WORKDIR
33#endif
34
35static rt_bool_t _dfs_init_ok = RT_FALSE;
36
37/* device filesystem lock */
38static struct rt_mutex fslock;
39static struct rt_mutex fdlock;
40static struct dfs_fdtable _fdtab = {0};
41
42static int _fdt_slot_expand(struct dfs_fdtable *fdt, int fd)
43{
44 int nr;
45 int index;
46 struct dfs_file **fds = NULL;
47
48 if (fd < fdt->maxfd)
49 {
50 return fd;
51 }
52 if (fd >= DFS_FD_MAX)
53 {
54 return -1;
55 }
56
57 nr = ((fd + 4) & ~3);
58 if (nr > DFS_FD_MAX)
59 {
60 nr = DFS_FD_MAX;
61 }
62 fds = (struct dfs_file **)rt_realloc(fdt->fds, nr * sizeof(struct dfs_file *));
63 if (!fds)
64 {
65 return -1;
66 }
67
68 /* clean the new allocated fds */
69 for (index = fdt->maxfd; index < nr; index++)
70 {
71 fds[index] = NULL;
72 }
73 fdt->fds = fds;
74 fdt->maxfd = nr;
75
76 return fd;
77}
78
79static int _fdt_slot_alloc(struct dfs_fdtable *fdt, int startfd)
80{
81 int idx;
82
83 /* find an empty fd slot */
84 for (idx = startfd; idx < (int)fdt->maxfd; idx++)
85 {
86 if (fdt->fds[idx] == RT_NULL)
87 {
88 return idx;
89 }
90 }
91
92 idx = fdt->maxfd;
93 if (idx < startfd)
94 {
95 idx = startfd;
96 }
97
98 if (_fdt_slot_expand(fdt, idx) < 0)
99 {
100 return -1;
101 }
102
103 return idx;
104}
105
106static int _fdt_fd_alloc(struct dfs_fdtable *fdt, int startfd)
107{
108 int idx;
109
110 idx = _fdt_slot_alloc(fdt, startfd);
111
112 return idx;
113}
114
121{
122 rt_err_t result = -RT_EBUSY;
123
124 while (result == -RT_EBUSY)
125 {
126 result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
127 }
128
129 return result;
130}
131
137void dfs_unlock(void)
138{
139 rt_mutex_release(&fslock);
140}
141
148{
149 rt_err_t result = -RT_EBUSY;
150
151 if (!_dfs_init_ok)
152 {
153 return -RT_ENOSYS;
154 }
155
156 while (result == -RT_EBUSY)
157 {
158 result = rt_mutex_take(&fdlock, RT_WAITING_FOREVER);
159 }
160
161 return result;
162}
163
165{
166 rt_mutex_release(&fdlock);
167}
168
172int dfs_init(void)
173{
174 if (_dfs_init_ok)
175 {
176 LOG_E("DFS was already initialized.\n");
177 return 0;
178 }
179
180 /* create device filesystem lock */
181 rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO);
182 rt_mutex_init(&fdlock, "fdlock", RT_IPC_FLAG_FIFO);
183
184 /* clean fd table */
186
187 _dfs_init_ok = RT_TRUE;
188
189 return 0;
190}
192
199int fdt_fd_new(struct dfs_fdtable *fdt)
200{
201 int idx = -1;
202
203 /* lock filesystem */
204 if (dfs_file_lock() != RT_EOK)
205 {
206 return -RT_ENOSYS;
207 }
208
209 /* find an empty fd entry */
210 idx = _fdt_fd_alloc(fdt, (fdt == &_fdtab) ? DFS_STDIO_OFFSET : 0);
211 /* can't find an empty fd entry */
212 if (idx < 0)
213 {
214 LOG_E("DFS fd new is failed! Could not found an empty fd entry.");
215 }
216 else if (!fdt->fds[idx])
217 {
218 struct dfs_file *file;
219
220 file = (struct dfs_file *)rt_calloc(1, sizeof(struct dfs_file));
221
222 if (file)
223 {
224 file->magic = DFS_FD_MAGIC;
225 file->ref_count = 1;
226 rt_mutex_init(&file->pos_lock, "fpos", RT_IPC_FLAG_PRIO);
227 fdt->fds[idx] = file;
228
229 LOG_D("allocate a new fd @ %d", idx);
230 }
231 else
232 {
233 fdt->fds[idx] = RT_NULL;
234 idx = -1;
235 }
236 }
237 else
238 {
239 LOG_E("DFS not found an empty fds entry.");
240 idx = -1;
241 }
242
244
245 return idx;
246}
247
248void fdt_fd_release(struct dfs_fdtable *fdt, int fd)
249{
250 if (fd < fdt->maxfd)
251 {
252 struct dfs_file *file;
253
254 file = fdt_get_file(fdt, fd);
255
256 if (file && file->ref_count == 1)
257 {
259
260 if (file->mmap_context)
261 {
262 rt_free(file->mmap_context);
263 }
264
265 rt_free(file);
266 }
267 else
268 {
269 rt_atomic_sub(&(file->ref_count), 1);
270 }
271
272 fdt->fds[fd] = RT_NULL;
273 }
274}
275
285
286struct dfs_file *fdt_get_file(struct dfs_fdtable *fdt, int fd)
287{
288 struct dfs_file *f;
289
290 if (fd < 0 || fd >= (int)fdt->maxfd)
291 {
292 return NULL;
293 }
294
295 f = fdt->fds[fd];
296
297 /* check file valid or not */
298 if ((f == NULL) || (f->magic != DFS_FD_MAGIC))
299 {
300 return NULL;
301 }
302
303 return f;
304}
305
306int fdt_fd_associate_file(struct dfs_fdtable *fdt, int fd, struct dfs_file *file)
307{
308 int retfd = -1;
309
310 if (!file)
311 {
312 return retfd;
313 }
314 if (!fdt)
315 {
316 return retfd;
317 }
318
319 if (dfs_file_lock() != RT_EOK)
320 {
321 return -RT_ENOSYS;
322 }
323
324 /* check old fd */
325 if ((fd < 0) || (fd >= fdt->maxfd))
326 {
327 goto exit;
328 }
329
330 if (fdt->fds[fd])
331 {
332 goto exit;
333 }
334
335 /* inc ref_count */
336 rt_atomic_add(&(file->ref_count), 1);
337 fdt->fds[fd] = file;
338 retfd = fd;
339
340exit:
342 return retfd;
343}
344
345int fd_new(void)
346{
347 struct dfs_fdtable *fdt;
348
349 fdt = dfs_fdtable_get();
350
351 return fdt_fd_new(fdt);
352}
353
359void fd_release(int fd)
360{
361 struct dfs_fdtable *fdt;
362
363 fdt = dfs_fdtable_get();
364 fdt_fd_release(fdt, fd);
365}
366
367struct dfs_file *fd_get(int fd)
368{
369 struct dfs_fdtable *fdt;
370
371 fdt = dfs_fdtable_get();
372
373 return fdt_get_file(fdt, fd);
374}
375
380{
381 struct dfs_fdtable *fdt;
382#ifdef RT_USING_SMART
383 struct rt_lwp *lwp = NULL;
384 rt_thread_t thread = rt_thread_self();
385
386 if (thread)
387 {
388 lwp = (struct rt_lwp *)thread->lwp;
389 }
390
391 if (lwp)
392 fdt = &lwp->fdt;
393 else
394 fdt = &_fdtab;
395#else
396 fdt = &_fdtab;
397#endif
398
399 return fdt;
400}
401
402#ifdef RT_USING_SMART
403struct dfs_fdtable *dfs_fdtable_get_from_pid(int pid)
404{
405 struct rt_lwp *lwp = RT_NULL;
406 struct dfs_fdtable *fdt = RT_NULL;
407
408 lwp_pid_lock_take();
409 lwp = lwp_from_pid_locked(pid);
410 if (lwp)
411 {
412 fdt = &lwp->fdt;
413 }
414 lwp_pid_lock_release();
415
416 return fdt;
417}
418#endif
419
421{
422 return &_fdtab;
423}
424
436int dfs_fdtable_dup(struct dfs_fdtable *fdt_dst, struct dfs_fdtable *fdt_src, int fd_src)
437{
438 int newfd = -1;
439
440 if (dfs_file_lock() != RT_EOK)
441 {
442 return -RT_ENOSYS;
443 }
444
445 if (fdt_src == NULL)
446 {
447 fdt_src = &_fdtab;
448 }
449
450 if (fdt_dst == NULL)
451 {
452 fdt_dst = &_fdtab;
453 }
454
455 /* check fd */
456 if ((fd_src < 0) || (fd_src >= fdt_src->maxfd))
457 {
458 goto _EXIT;
459 }
460 if (!fdt_src->fds[fd_src])
461 {
462 goto _EXIT;
463 }
464
465 /* get a new fd*/
466 newfd = fdt_fd_new(fdt_dst);
467 if (newfd >= 0)
468 {
469 fdt_dst->fds[newfd]->mode = fdt_src->fds[fd_src]->mode;
470 fdt_dst->fds[newfd]->flags = fdt_src->fds[fd_src]->flags;
471 fdt_dst->fds[newfd]->fops = fdt_src->fds[fd_src]->fops;
472 fdt_dst->fds[newfd]->dentry = dfs_dentry_ref(fdt_src->fds[fd_src]->dentry);
473 fdt_dst->fds[newfd]->vnode = fdt_src->fds[fd_src]->vnode;
474 fdt_dst->fds[newfd]->mmap_context = RT_NULL;
475 fdt_dst->fds[newfd]->data = fdt_src->fds[fd_src]->data;
476
477 /*
478 * dma-buf/socket fd is without dentry, so should used the vnode reference.
479 */
480 if (!fdt_dst->fds[newfd]->dentry)
481 {
482 rt_atomic_add(&(fdt_dst->fds[newfd]->vnode->ref_count), 1);
483 }
484 }
485
486_EXIT:
488
489 return newfd;
490}
491
501int dfs_fdtable_drop_fd(struct dfs_fdtable *fdt, int fd)
502{
503 int err = 0;
504
505 if (fdt == NULL)
506 {
507 fdt = &_fdtab;
508 }
509
510 if (dfs_file_lock() != RT_EOK)
511 {
512 return -RT_ENOSYS;
513 }
514
515 err = dfs_file_close(fdt->fds[fd]);
516 if (!err)
517 {
518 fdt_fd_release(fdt, fd);
519 }
520
522
523 return err;
524}
525
526int dfs_dup(int oldfd, int startfd)
527{
528 int newfd = -1;
529 struct dfs_fdtable *fdt = NULL;
530
531 if (dfs_file_lock() != RT_EOK)
532 {
533 return -RT_ENOSYS;
534 }
535
536 /* check old fd */
537 fdt = dfs_fdtable_get();
538 if ((oldfd < 0) || (oldfd >= fdt->maxfd))
539 {
540 rt_set_errno(-EBADF);
541 goto exit;
542 }
543 if (!fdt->fds[oldfd])
544 {
545 goto exit;
546 }
547 /* get a new fd */
548 newfd = _fdt_slot_alloc(fdt, startfd);
549 if (newfd >= 0)
550 {
551 fdt->fds[newfd] = fdt->fds[oldfd];
552
553 /* inc ref_count */
554 rt_atomic_add(&(fdt->fds[newfd]->ref_count), 1);
555 }
556exit:
558 return newfd;
559}
560
570int dfs_dup_to(int oldfd, struct dfs_fdtable *fdtab)
571{
572 int newfd = -1;
573 struct dfs_fdtable *fdt = NULL;
574
575 if (dfs_file_lock() != RT_EOK)
576 {
577 return -RT_ENOSYS;
578 }
579
580 if (fdtab == NULL)
581 {
582 fdtab = &_fdtab;
583 }
584
585 /* check old fd */
586 fdt = dfs_fdtable_get();
587 if ((oldfd < 0) || (oldfd >= fdt->maxfd))
588 {
589 goto exit;
590 }
591 if (!fdt->fds[oldfd])
592 {
593 goto exit;
594 }
595 /* get a new fd*/
596 newfd = _fdt_slot_alloc(fdtab, DFS_STDIO_OFFSET);
597 if (newfd >= 0)
598 {
599 fdtab->fds[newfd] = fdt->fds[oldfd];
600
601 /* inc ref_count */
602 rt_atomic_add(&(fdtab->fds[newfd]->ref_count), 1);
603 }
604exit:
606
607 return newfd;
608}
609
619int dfs_dup_from(int oldfd, struct dfs_fdtable *fdtab)
620{
621 int newfd = -1;
622 struct dfs_file *file;
623
624 if (dfs_file_lock() != RT_EOK)
625 {
626 return -RT_ENOSYS;
627 }
628
629 if (fdtab == NULL)
630 {
631 fdtab = &_fdtab;
632 }
633
634 /* check old fd */
635 if ((oldfd < 0) || (oldfd >= fdtab->maxfd))
636 {
637 goto exit;
638 }
639 if (!fdtab->fds[oldfd])
640 {
641 goto exit;
642 }
643 /* get a new fd*/
644 newfd = fd_new();
645 file = fd_get(newfd);
646 if (newfd >= 0 && file)
647 {
648 file->mode = fdtab->fds[oldfd]->mode;
649 file->flags = fdtab->fds[oldfd]->flags;
650 file->fops = fdtab->fds[oldfd]->fops;
651 file->dentry = dfs_dentry_ref(fdtab->fds[oldfd]->dentry);
652 file->vnode = fdtab->fds[oldfd]->vnode;
653 file->mmap_context = RT_NULL;
654 file->data = fdtab->fds[oldfd]->data;
655 }
656
657 dfs_file_close(fdtab->fds[oldfd]);
658
659exit:
660 fdt_fd_release(fdtab, oldfd);
662
663 return newfd;
664}
665
666#ifdef RT_USING_SMART
667sysret_t sys_dup(int oldfd)
668#else
669int sys_dup(int oldfd)
670#endif
671{
672 int err = 0;
673 int newfd = dfs_dup(oldfd, (dfs_fdtable_get() == &_fdtab) ? DFS_STDIO_OFFSET : 0);
674 if(newfd < 0)
675 {
676 err = rt_get_errno();
677 }
678
679#ifdef RT_USING_SMART
680 return err < 0 ? err : newfd;
681#else
682 return err < 0 ? err : newfd;
683#endif
684}
685
686rt_err_t sys_dup2(int oldfd, int newfd)
687{
688 struct dfs_fdtable *fdt = NULL;
689 int ret = 0;
690 int retfd = -1;
691
692 if (dfs_file_lock() != RT_EOK)
693 {
694 return -RT_ENOSYS;
695 }
696
697 /* check old fd */
698 fdt = dfs_fdtable_get();
699 if ((oldfd < 0) || (oldfd >= fdt->maxfd))
700 {
701 goto exit;
702 }
703 if (!fdt->fds[oldfd])
704 {
705 goto exit;
706 }
707 if (newfd < 0)
708 {
709 goto exit;
710 }
711 if (newfd >= fdt->maxfd)
712 {
713 newfd = _fdt_slot_expand(fdt, newfd);
714 if (newfd < 0)
715 {
716 goto exit;
717 }
718 }
719 if (fdt->fds[newfd] == fdt->fds[oldfd])
720 {
721 /* ok, return newfd */
722 retfd = newfd;
723 goto exit;
724 }
725
726 if (fdt->fds[newfd])
727 {
728 ret = dfs_file_close(fdt->fds[newfd]);
729 if (ret < 0)
730 {
731 goto exit;
732 }
733 fd_release(newfd);
734 }
735
736 fdt->fds[newfd] = fdt->fds[oldfd];
737 /* inc ref_count */
738 rt_atomic_add(&(fdt->fds[newfd]->ref_count), 1);
739 retfd = newfd;
740exit:
742 return retfd;
743}
744
753const char *dfs_subdir(const char *directory, const char *filename)
754{
755 const char *dir;
756
757 if (strlen(directory) == strlen(filename)) /* it's a same path */
758 return NULL;
759
760 dir = filename + strlen(directory);
761 if ((*dir != '/') && (dir != filename))
762 {
763 dir--;
764 }
765
766 return dir;
767}
769
779char *dfs_normalize_path(const char *directory, const char *filename)
780{
781 char *fullpath;
782 char *dst0, *dst, *src;
783
784 /* check parameters */
785 RT_ASSERT(filename != NULL);
786
787#ifdef DFS_USING_WORKDIR
788 if (directory == NULL) /* shall use working directory */
789 {
790#ifdef RT_USING_SMART
791 directory = lwp_getcwd();
792#else
793 directory = &working_directory[0];
794#endif
795 }
796#else
797 if ((directory == NULL) && (filename[0] != '/'))
798 {
800
801 return NULL;
802 }
803#endif
804
805 if (filename[0] != '/') /* it's a absolute path, use it directly */
806 {
807 int path_len;
808
809 path_len = strlen(directory) + strlen(filename) + 2;
810 if (path_len > DFS_PATH_MAX)
811 {
812 return NULL;
813 }
814
815 fullpath = (char *)rt_malloc(path_len);
816 if (fullpath == NULL)
817 {
818 return NULL;
819 }
820
821 /* join path and file name */
822 rt_snprintf(fullpath, strlen(directory) + strlen(filename) + 2,
823 "%s/%s", directory, filename);
824 }
825 else
826 {
827 fullpath = rt_strdup(filename); /* copy string */
828
829 if (fullpath == NULL)
830 return NULL;
831 }
832
833 src = fullpath;
834 dst = fullpath;
835
836 dst0 = dst;
837 while (1)
838 {
839 char c = *src;
840
841 if (c == '.')
842 {
843 if (!src[1])
844 src++; /* '.' and ends */
845 else if (src[1] == '/')
846 {
847 /* './' case */
848 src += 2;
849
850 while ((*src == '/') && (*src != '\0'))
851 src++;
852 continue;
853 }
854 else if (src[1] == '.')
855 {
856 if (!src[2])
857 {
858 /* '..' and ends case */
859 src += 2;
860 goto up_one;
861 }
862 else if (src[2] == '/')
863 {
864 /* '../' case */
865 src += 3;
866
867 while ((*src == '/') && (*src != '\0'))
868 src++;
869 goto up_one;
870 }
871 }
872 }
873
874 /* copy up the next '/' and erase all '/' */
875 while ((c = *src++) != '\0' && c != '/')
876 *dst++ = c;
877
878 if (c == '/')
879 {
880 *dst++ = '/';
881 while (c == '/')
882 c = *src++;
883
884 src--;
885 }
886 else if (!c)
887 break;
888
889 continue;
890
891 up_one:
892 dst--;
893 if (dst < dst0)
894 {
895 rt_free(fullpath);
896 return NULL;
897 }
898 while (dst0 < dst && dst[-1] != '/')
899 dst--;
900 }
901
902 *dst = '\0';
903
904 /* remove '/' in the end of path if exist */
905 dst--;
906 if (dst > fullpath && (*dst == '/'))
907 *dst = '\0';
908
909 /* final check fullpath is not empty, for the special path of lwext "/.." */
910 if ('\0' == fullpath[0])
911 {
912 fullpath[0] = '/';
913 fullpath[1] = '\0';
914 }
915
916 return fullpath;
917}
919
920#ifdef RT_USING_FINSH
921#include <finsh.h>
922int list_fd(void)
923{
924 int index;
925 struct dfs_fdtable *fd_table;
926
927 fd_table = dfs_fdtable_get();
928 if (!fd_table) return -1;
929
931
932 rt_kprintf("fd type ref magic path\n");
933 rt_kprintf("-- ------ --- ----- ------\n");
934 for (index = 0; index < (int)fd_table->maxfd; index++)
935 {
936 struct dfs_file *file = fd_table->fds[index];
937
938 if (file && file->vnode)
939 {
940 rt_kprintf("%2d ", index);
941 if (file->vnode->type == FT_DIRECTORY) rt_kprintf("%-7.7s ", "dir");
942 else if (file->vnode->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file");
943 else if (file->vnode->type == FT_SOCKET) rt_kprintf("%-7.7s ", "socket");
944 else if (file->vnode->type == FT_USER) rt_kprintf("%-7.7s ", "user");
945 else if (file->vnode->type == FT_DEVICE) rt_kprintf("%-7.7s ", "device");
946 else rt_kprintf("%-8.8s ", "unknown");
947 rt_kprintf("%3d ", file->ref_count);
948 rt_kprintf("%04x ", file->magic);
949
950 if (file->dentry)
951 {
952 rt_kprintf("%s%s\n", file->dentry->mnt->fullpath, file->dentry->pathname);
953 }
954 else
955 {
956 rt_kprintf("\n");
957 }
958 }
959 }
961
962 return 0;
963}
964MSH_CMD_EXPORT(list_fd, list file descriptor);
965
966int dfs_fd_dump(int argc, char** argv)
967{
968 int index;
969
970 if (dfs_file_lock() != RT_EOK)
971 {
972 return -RT_ENOSYS;
973 }
974
975 for (index = 0; index < _fdtab.maxfd; index++)
976 {
977 struct dfs_file *file = _fdtab.fds[index];
978 if (file)
979 {
980 char* fullpath = dfs_dentry_full_path(file->dentry);
981 if (fullpath)
982 {
983 printf("[%d] - %s, ref_count %zd\n", index,
984 fullpath, (size_t)rt_atomic_load(&(file->ref_count)));
985 rt_free(fullpath);
986 }
987 else
988 {
989 printf("[%d] - %s, ref_count %zd\n", index,
990 file->dentry->pathname, (size_t)rt_atomic_load(&(file->ref_count)));
991 }
992 }
993 }
995
996 return 0;
997}
999
1000#ifdef PKG_USING_DLOG
1001
1002int dfs_dlog(int argc, char** argv)
1003{
1004 if (argc == 2)
1005 {
1006 if (strcmp(argv[1], "on") == 0)
1007 {
1008 dlog_session_start();
1009 dlog_participant("dfs");
1010 dlog_participant("dfs_file");
1011 dlog_participant("dentry");
1012 dlog_participant("vnode");
1013 dlog_participant("mnt");
1014 dlog_participant("rom");
1015 dlog_participant("devfs");
1016 }
1017 else if (strcmp(argv[1], "off") == 0)
1018 {
1019 dlog_session_stop();
1020 }
1021 }
1022
1023 return 0;
1024}
1025MSH_CMD_EXPORT(dfs_dlog, dfs dlog on|off);
1026
1027#endif
1028
1029#endif
rt_err_t dfs_lock(void)
定义 dfs.c:120
void dfs_unlock(void)
定义 dfs.c:137
#define DFS_STDIO_OFFSET
定义 dfs.h:68
#define DFS_FD_MAX
定义 dfs.h:61
#define DFS_PATH_MAX
定义 dfs.h:72
int dfs_dentry_init(void)
char * dfs_dentry_full_path(struct dfs_dentry *dentry)
struct dfs_dentry * dfs_dentry_ref(struct dfs_dentry *dentry)
int dfs_file_close(struct dfs_file *file)
#define DFS_FD_MAGIC
char working_directory[]
#define NO_WORKING_DIR
struct dfs_fdtable * dfs_fdtable_get_global(void)
定义 dfs.c:420
int dfs_dup(int oldfd, int startfd)
定义 dfs.c:526
int dfs_init(void)
定义 dfs.c:172
int fd_new(void)
定义 dfs.c:345
char * dfs_normalize_path(const char *directory, const char *filename)
定义 dfs.c:779
int dfs_dup_to(int oldfd, struct dfs_fdtable *fdtab)
The fd in the current process dup to designate fd table.
定义 dfs.c:570
int dfs_fd_dump(int argc, char **argv)
定义 dfs.c:966
void dfs_file_unlock(void)
定义 dfs.c:164
int fdt_fd_associate_file(struct dfs_fdtable *fdt, int fd, struct dfs_file *file)
定义 dfs.c:306
int sys_dup(int oldfd)
定义 dfs.c:669
int dfs_fdtable_dup(struct dfs_fdtable *fdt_dst, struct dfs_fdtable *fdt_src, int fd_src)
Dup the specified fd_src from fdt_src to fdt_dst.
定义 dfs.c:436
int list_fd(void)
定义 dfs.c:922
void fdt_fd_release(struct dfs_fdtable *fdt, int fd)
定义 dfs.c:248
const char * dfs_subdir(const char *directory, const char *filename)
定义 dfs.c:753
rt_err_t dfs_file_lock(void)
定义 dfs.c:147
struct dfs_file * fd_get(int fd)
定义 dfs.c:367
struct dfs_fdtable * dfs_fdtable_get(void)
定义 dfs.c:379
rt_err_t sys_dup2(int oldfd, int newfd)
定义 dfs.c:686
int dfs_dup_from(int oldfd, struct dfs_fdtable *fdtab)
The fd in the designate fd table dup to current process.
定义 dfs.c:619
int dfs_fdtable_drop_fd(struct dfs_fdtable *fdt, int fd)
drop fd from the fd table.
定义 dfs.c:501
struct dfs_file * fdt_get_file(struct dfs_fdtable *fdt, int fd)
定义 dfs.c:286
void fd_release(int fd)
定义 dfs.c:359
int fdt_fd_new(struct dfs_fdtable *fdt)
定义 dfs.c:199
#define RT_IPC_FLAG_FIFO
#define RT_IPC_FLAG_PRIO
#define RT_WAITING_FOREVER
rt_weak void * rt_calloc(rt_size_t count, rt_size_t size)
This function will contiguously allocate enough space for count objects that are size bytes of memory...
#define rt_kprintf(...)
#define RT_ASSERT(EX)
rt_weak void * rt_realloc(void *ptr, rt_size_t newsize)
This function will change the size of previously allocated memory block.
rt_weak void rt_free(void *ptr)
This function will release the previously allocated memory block by rt_malloc. The released memory bl...
rt_weak void * rt_malloc(rt_size_t size)
Allocate a block of memory with a minimum of 'size' bytes.
void rt_exit_critical(void)
This function will unlock the thread scheduler.
rt_thread_t rt_thread_self(void)
This function will return self thread object.
rt_base_t rt_enter_critical(void)
This function will lock the thread scheduler.
struct rt_thread * rt_thread_t
#define MSH_CMD_EXPORT_ALIAS(...)
#define MSH_CMD_EXPORT(...)
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
定义 ipc.c:1537
rt_err_t rt_mutex_detach(rt_mutex_t mutex)
This function will detach a static mutex object.
定义 ipc.c:1054
rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag)
Initialize a static mutex object.
定义 ipc.c:1007
rt_err_t rt_mutex_release(rt_mutex_t mutex)
This function will release a mutex. If there is thread suspended on the mutex, the thread will be res...
定义 ipc.c:1589
#define rt_atomic_sub(ptr, v)
#define rt_atomic_add(ptr, v)
#define rt_atomic_load(ptr)
#define LOG_D(...)
#define LOG_E(fmt,...)
#define INIT_PREV_EXPORT(fn)
#define RTM_EXPORT(symbol)
定义 rtm.h:33
int rt_bool_t
rt_base_t rt_err_t
#define RT_TRUE
#define RT_FALSE
#define RT_NULL
struct dfs_mnt * mnt
uint32_t maxfd
定义 dfs.h:108
struct dfs_file ** fds
定义 dfs.h:109
struct dfs_vnode * vnode
struct dfs_dentry * dentry
const struct dfs_file_ops * fops
uint16_t magic
struct rt_mutex pos_lock
rt_atomic_t ref_count
void * mmap_context
uint32_t flags
uint16_t mode
char * fullpath
rt_atomic_t ref_count