RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
Device Virtual File System
+ Device Virtual File System 的协作图:

专题

 File Descriptor
 
 File System API
 
 File API
 
 File POSIX API
 

函数

rt_err_t dfs_file_lock (void)
 
void dfs_file_unlock (void)
 
int dfs_init (void)
 
 INIT_PREV_EXPORT (dfs_init)
 
void fdt_fd_release (struct dfs_fdtable *fdt, int fd)
 
int fdt_fd_associate_file (struct dfs_fdtable *fdt, int fd, struct dfs_file *file)
 
int fd_new (void)
 
struct dfs_filefd_get (int fd)
 
struct dfs_fdtabledfs_fdtable_get (void)
 
struct dfs_fdtabledfs_fdtable_get_global (void)
 
int dfs_fdtable_dup (struct dfs_fdtable *fdt_dst, struct dfs_fdtable *fdt_src, int fd_src)
 
int dfs_fdtable_drop_fd (struct dfs_fdtable *fdt, int fd)
 
int dfs_dup (int oldfd, int startfd)
 
int dfs_dup_to (int oldfd, struct dfs_fdtable *fdtab)
 
int dfs_dup_from (int oldfd, struct dfs_fdtable *fdtab)
 
int sys_dup (int oldfd)
 
rt_err_t sys_dup2 (int oldfd, int newfd)
 
const char * dfs_subdir (const char *directory, const char *filename)
 
 RTM_EXPORT (dfs_subdir)
 
char * dfs_normalize_path (const char *directory, const char *filename)
 
 RTM_EXPORT (dfs_normalize_path)
 
int list_fd (void)
 
 MSH_CMD_EXPORT (list_fd, list file descriptor)
 
int dfs_fd_dump (int argc, char **argv)
 
 MSH_CMD_EXPORT_ALIAS (dfs_fd_dump, fd_dump, fd dump)
 

详细描述

DFS is a virtual file system in RT-Thread RTOS.

The DFS (Device Virtual File System) is a vfs file system of RT-Thread RTOS, which is focused on embedded device. VFS is an abstraction layer on top of a more concrete file system. The purpose of a VFS is to allow client applications to access different types of concrete file systems in a uniform way.

Figure 4: Device Virtual File System Architecture

The DFS specifies an interface between the kernel and a concrete file system. Therefore, it is easy to add support for new file system types to the kernel simply by fulfilling the interface.

函数说明

◆ dfs_file_lock()

rt_err_t dfs_file_lock ( void )

在文件 dfs.c147 行定义.

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}
#define RT_WAITING_FOREVER
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
定义 ipc.c:1537
rt_base_t rt_err_t

引用了 rt_mutex_take() , 以及 RT_WAITING_FOREVER.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_file_unlock()

void dfs_file_unlock ( void )

在文件 dfs.c164 行定义.

165{
166 rt_mutex_release(&fdlock);
167}
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

引用了 rt_mutex_release().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_init()

int dfs_init ( void )

this function will initialize device file system.

在文件 dfs.c172 行定义.

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}
int dfs_dentry_init(void)
#define RT_IPC_FLAG_FIFO
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
#define LOG_E(fmt,...)
#define RT_TRUE

引用了 dfs_dentry_init(), LOG_E, RT_IPC_FLAG_FIFO, rt_mutex_init() , 以及 RT_TRUE.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ INIT_PREV_EXPORT()

INIT_PREV_EXPORT ( dfs_init )

引用了 dfs_init().

+ 函数调用图:

◆ fdt_fd_release()

void fdt_fd_release ( struct dfs_fdtable * fdt,
int fd )

在文件 dfs.c248 行定义.

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}
struct dfs_file * fdt_get_file(struct dfs_fdtable *fdt, int fd)
定义 dfs.c:286
rt_weak void rt_free(void *ptr)
This function will release the previously allocated memory block by rt_malloc. The released memory bl...
rt_err_t rt_mutex_detach(rt_mutex_t mutex)
This function will detach a static mutex object.
定义 ipc.c:1054
#define rt_atomic_sub(ptr, v)
#define RT_NULL
struct dfs_file ** fds
定义 dfs.h:109
struct rt_mutex pos_lock
rt_atomic_t ref_count
void * mmap_context

引用了 dfs_fdtable::fds, fdt_get_file(), dfs_file::mmap_context, dfs_file::pos_lock, dfs_file::ref_count, rt_atomic_sub, rt_free(), rt_mutex_detach() , 以及 RT_NULL.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ fdt_fd_associate_file()

int fdt_fd_associate_file ( struct dfs_fdtable * fdt,
int fd,
struct dfs_file * file )

在文件 dfs.c306 行定义.

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}
void dfs_file_unlock(void)
定义 dfs.c:164
rt_err_t dfs_file_lock(void)
定义 dfs.c:147
#define rt_atomic_add(ptr, v)
uint32_t maxfd
定义 dfs.h:108

引用了 dfs_file_lock(), dfs_file_unlock(), dfs_fdtable::fds, dfs_fdtable::maxfd, dfs_file::ref_count , 以及 rt_atomic_add.

+ 函数调用图:

◆ fd_new()

int fd_new ( void )

在文件 dfs.c345 行定义.

346{
347 struct dfs_fdtable *fdt;
348
349 fdt = dfs_fdtable_get();
350
351 return fdt_fd_new(fdt);
352}
struct dfs_fdtable * dfs_fdtable_get(void)
定义 dfs.c:379
int fdt_fd_new(struct dfs_fdtable *fdt)
定义 dfs.c:199

引用了 dfs_fdtable_get() , 以及 fdt_fd_new().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ fd_get()

struct dfs_file * fd_get ( int fd)

在文件 dfs.c367 行定义.

368{
369 struct dfs_fdtable *fdt;
370
371 fdt = dfs_fdtable_get();
372
373 return fdt_get_file(fdt, fd);
374}

引用了 dfs_fdtable_get() , 以及 fdt_get_file().

+ 函数调用图:

◆ dfs_fdtable_get()

struct dfs_fdtable * dfs_fdtable_get ( void )

This function will get the file descriptor table of current process.

在文件 dfs.c379 行定义.

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}
rt_thread_t rt_thread_self(void)
This function will return self thread object.
struct rt_thread * rt_thread_t

引用了 rt_thread_self().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_fdtable_get_global()

struct dfs_fdtable * dfs_fdtable_get_global ( void )

在文件 dfs.c420 行定义.

421{
422 return &_fdtab;
423}

◆ dfs_fdtable_dup()

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.

参数
fdt_dstis the fd table for destination, if empty, use global (_fdtab).
fdt_srcis the fd table for source, if empty, use global (_fdtab).
fd_srcis the fd in the designate fdt_src table.
返回
-1 on failed or the allocated file descriptor.

在文件 dfs.c436 行定义.

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}
struct dfs_dentry * dfs_dentry_ref(struct dfs_dentry *dentry)
struct dfs_vnode * vnode
struct dfs_dentry * dentry
const struct dfs_file_ops * fops
uint32_t flags
uint16_t mode
rt_atomic_t ref_count

引用了 dfs_file::data, dfs_file::dentry, dfs_dentry_ref(), dfs_file_lock(), dfs_file_unlock(), dfs_fdtable::fds, fdt_fd_new(), dfs_file::flags, dfs_file::fops, dfs_fdtable::maxfd, dfs_file::mmap_context, dfs_file::mode, dfs_vnode::ref_count, rt_atomic_add, RT_NULL , 以及 dfs_file::vnode.

+ 函数调用图:

◆ dfs_fdtable_drop_fd()

int dfs_fdtable_drop_fd ( struct dfs_fdtable * fdt,
int fd )

drop fd from the fd table.

参数
fdtis the fd table, if empty, use global (_fdtab).
fdis the fd in the designate fd table.
返回
-1 on failed the drop file descriptor.

在文件 dfs.c501 行定义.

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}
int dfs_file_close(struct dfs_file *file)
void fdt_fd_release(struct dfs_fdtable *fdt, int fd)
定义 dfs.c:248

引用了 dfs_file_close(), dfs_file_lock(), dfs_file_unlock(), dfs_fdtable::fds , 以及 fdt_fd_release().

+ 函数调用图:

◆ dfs_dup()

int dfs_dup ( int oldfd,
int startfd )

在文件 dfs.c526 行定义.

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}

引用了 dfs_fdtable_get(), dfs_file_lock(), dfs_file_unlock(), dfs_fdtable::fds, dfs_fdtable::maxfd, dfs_file::ref_count , 以及 rt_atomic_add.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ dfs_dup_to()

int dfs_dup_to ( int oldfd,
struct dfs_fdtable * fdtab )

The fd in the current process dup to designate fd table.

参数
oldfdis the fd in current process.
fdtabis the fd table to dup, if empty, use global (_fdtab).
返回
-1 on failed or the allocated file descriptor.

在文件 dfs.c570 行定义.

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}
#define DFS_STDIO_OFFSET
定义 dfs.h:68

引用了 dfs_fdtable_get(), dfs_file_lock(), dfs_file_unlock(), DFS_STDIO_OFFSET, dfs_fdtable::fds, dfs_fdtable::maxfd, dfs_file::ref_count , 以及 rt_atomic_add.

+ 函数调用图:

◆ dfs_dup_from()

int dfs_dup_from ( int oldfd,
struct dfs_fdtable * fdtab )

The fd in the designate fd table dup to current process.

参数
oldfdis the fd in the designate fd table.
fdtabis the fd table for oldfd, if empty, use global (_fdtab).
返回
-1 on failed or the allocated file descriptor.

在文件 dfs.c619 行定义.

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}
int fd_new(void)
定义 dfs.c:345
struct dfs_file * fd_get(int fd)
定义 dfs.c:367

引用了 dfs_file::data, dfs_file::dentry, dfs_dentry_ref(), dfs_file_close(), dfs_file_lock(), dfs_file_unlock(), fd_get(), fd_new(), dfs_fdtable::fds, fdt_fd_release(), dfs_file::flags, dfs_file::fops, dfs_fdtable::maxfd, dfs_file::mmap_context, dfs_file::mode, RT_NULL , 以及 dfs_file::vnode.

+ 函数调用图:

◆ sys_dup()

int sys_dup ( int oldfd)

在文件 dfs.c669 行定义.

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}
int dfs_dup(int oldfd, int startfd)
定义 dfs.c:526

引用了 dfs_dup(), dfs_fdtable_get() , 以及 DFS_STDIO_OFFSET.

+ 函数调用图:

◆ sys_dup2()

rt_err_t sys_dup2 ( int oldfd,
int newfd )

在文件 dfs.c686 行定义.

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}
void fd_release(int fd)
定义 dfs.c:359

引用了 dfs_fdtable_get(), dfs_file_close(), dfs_file_lock(), dfs_file_unlock(), fd_release(), dfs_fdtable::fds, dfs_fdtable::maxfd, dfs_file::ref_count , 以及 rt_atomic_add.

+ 函数调用图:

◆ dfs_subdir()

const char * dfs_subdir ( const char * directory,
const char * filename )

this function will return a sub-path name under directory.

参数
directorythe parent directory.
filenamethe filename.
返回
the subdir pointer in filename

在文件 dfs.c753 行定义.

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}
+ 这是这个函数的调用关系图:

◆ RTM_EXPORT() [1/2]

RTM_EXPORT ( dfs_subdir )

引用了 dfs_subdir().

+ 函数调用图:

◆ dfs_normalize_path()

char * dfs_normalize_path ( const char * directory,
const char * filename )

this function will normalize a path according to specified parent directory and file name.

参数
directorythe parent path
filenamethe file name
返回
the built full file path (absolute path)

在文件 dfs.c779 行定义.

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}
#define DFS_PATH_MAX
定义 dfs.h:72
char working_directory[]
#define NO_WORKING_DIR
#define rt_kprintf(...)
#define RT_ASSERT(EX)
rt_weak void * rt_malloc(rt_size_t size)
Allocate a block of memory with a minimum of 'size' bytes.

引用了 DFS_PATH_MAX, NO_WORKING_DIR, RT_ASSERT, rt_free(), rt_kprintf, rt_malloc() , 以及 working_directory.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ RTM_EXPORT() [2/2]

RTM_EXPORT ( dfs_normalize_path )

引用了 dfs_normalize_path().

+ 函数调用图:

◆ list_fd()

int list_fd ( void )

在文件 dfs.c922 行定义.

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}
void rt_exit_critical(void)
This function will unlock the thread scheduler.
rt_base_t rt_enter_critical(void)
This function will lock the thread scheduler.
struct dfs_mnt * mnt
uint16_t magic
char * fullpath

引用了 dfs_file::dentry, dfs_fdtable_get(), dfs_fdtable::fds, dfs_mnt::fullpath, dfs_file::magic, dfs_fdtable::maxfd, dfs_dentry::mnt, dfs_dentry::pathname, dfs_file::ref_count, rt_enter_critical(), rt_exit_critical(), rt_kprintf, dfs_vnode::type , 以及 dfs_file::vnode.

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ MSH_CMD_EXPORT()

MSH_CMD_EXPORT ( list_fd ,
list file descriptor )

引用了 list_fd().

+ 函数调用图:

◆ dfs_fd_dump()

int dfs_fd_dump ( int argc,
char ** argv )

在文件 dfs.c966 行定义.

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}
char * dfs_dentry_full_path(struct dfs_dentry *dentry)
#define rt_atomic_load(ptr)

引用了 dfs_file::dentry, dfs_dentry_full_path(), dfs_file_lock(), dfs_file_unlock(), dfs_dentry::pathname, dfs_file::ref_count, rt_atomic_load , 以及 rt_free().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ MSH_CMD_EXPORT_ALIAS()

MSH_CMD_EXPORT_ALIAS ( dfs_fd_dump ,
fd_dump ,
fd dump )

引用了 dfs_fd_dump().

+ 函数调用图: