diff options
| author | guo <[email protected]> | 2022-12-03 12:07:44 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-12-03 12:07:44 +0800 |
| commit | ecf2d8215961ca7c539132b62a72df6072cc3e14 (patch) | |
| tree | 59005f0f74f2593c0435059264f624c862a89f55 /components/dfs/src | |
| parent | aaf5462c6d4ae9466a0a8cd2a4bb00cfe1fef2f2 (diff) | |
sync branch rt-smart. (#6641)
* Synchronize the code of the rt mart branch to the master branch.
* TTY device
* Add lwP code from rt-smart
* Add vnode in DFS, but DFS will be re-write for rt-smart
* There are three libcpu for rt-smart:
* arm/cortex-a, arm/aarch64
* riscv64
Co-authored-by: Rbb666 <[email protected]>
Co-authored-by: zhkag <[email protected]>
Diffstat (limited to 'components/dfs/src')
| -rw-r--r-- | components/dfs/src/dfs.c | 605 | ||||
| -rw-r--r-- | components/dfs/src/dfs_file.c | 412 | ||||
| -rw-r--r-- | components/dfs/src/dfs_fs.c | 17 | ||||
| -rw-r--r-- | components/dfs/src/dfs_posix.c | 131 |
4 files changed, 917 insertions, 248 deletions
diff --git a/components/dfs/src/dfs.c b/components/dfs/src/dfs.c index f1d7571c0c..f3f9c2354b 100644 --- a/components/dfs/src/dfs.c +++ b/components/dfs/src/dfs.c @@ -28,12 +28,14 @@ struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX]; /* device filesystem lock */ static struct rt_mutex fslock; +static struct rt_mutex fdlock; #ifdef DFS_USING_WORKDIR char working_directory[DFS_PATH_MAX] = {"/"}; #endif static struct dfs_fdtable _fdtab; +static int fd_alloc(struct dfs_fdtable *fdt, int startfd); /** * @addtogroup DFS @@ -54,6 +56,9 @@ int dfs_init(void) return 0; } + /* init vnode hash table */ + dfs_fnode_mgr_init(); + /* clear filesystem operations table */ rt_memset((void *)filesystem_operation_table, 0, sizeof(filesystem_operation_table)); /* clear filesystem table */ @@ -63,6 +68,7 @@ int dfs_init(void) /* create device filesystem lock */ rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_PRIO); + rt_mutex_init(&fdlock, "fdlock", RT_IPC_FLAG_PRIO); #ifdef DFS_USING_WORKDIR /* set current working directory */ @@ -70,6 +76,13 @@ int dfs_init(void) working_directory[0] = '/'; #endif +#ifdef RT_USING_DFS_TMPFS + { + extern int dfs_tmpfs_init(void); + dfs_tmpfs_init(); + } +#endif + #ifdef RT_USING_DFS_DEVFS { extern int devfs_init(void); @@ -79,6 +92,13 @@ int dfs_init(void) dfs_mount(NULL, "/dev", "devfs", 0, 0); } +#if defined(RT_USING_DEV_BUS) && defined(RT_USING_DFS_TMPFS) + mkdir("/dev/shm", 0x777); + if (dfs_mount(RT_NULL, "/dev/shm", "tmp", 0, 0) != 0) + { + rt_kprintf("Dir /dev/shm mount failed!\n"); + } +#endif #endif init_ok = RT_TRUE; @@ -107,6 +127,21 @@ void dfs_lock(void) } } +void dfs_fd_lock(void) +{ + rt_err_t result = -RT_EBUSY; + + while (result == -RT_EBUSY) + { + result = rt_mutex_take(&fdlock, RT_WAITING_FOREVER); + } + + if (result != RT_EOK) + { + RT_ASSERT(0); + } +} + /** * this function will lock device file system. * @@ -118,51 +153,95 @@ void dfs_unlock(void) } #ifdef DFS_USING_POSIX -static int fd_alloc(struct dfs_fdtable *fdt, int startfd) + +void dfs_fd_unlock(void) { - int idx; + rt_mutex_release(&fdlock); +} - /* find an empty fd entry */ - for (idx = startfd; idx < (int)fdt->maxfd; idx++) +static int fd_slot_expand(struct dfs_fdtable *fdt, int fd) +{ + int nr; + int index; + struct dfs_fd **fds = NULL; + + if (fd < fdt->maxfd) { - if (fdt->fds[idx] == RT_NULL) - break; - if (fdt->fds[idx]->ref_count == 0) - break; + return fd; + } + if (fd >= DFS_FD_MAX) + { + return -1; } - /* allocate a larger FD container */ - if (idx == (int)fdt->maxfd && fdt->maxfd < DFS_FD_MAX) + nr = ((fd + 4) & ~3); + if (nr > DFS_FD_MAX) { - int cnt, index; - struct dfs_fd **fds; + nr = DFS_FD_MAX; + } + fds = (struct dfs_fd **)rt_realloc(fdt->fds, nr * sizeof(struct dfs_fd *)); + if (!fds) + { + return -1; + } - /* increase the number of FD with 4 step length */ - cnt = fdt->maxfd + 4; - cnt = cnt > DFS_FD_MAX ? DFS_FD_MAX : cnt; + /* clean the new allocated fds */ + for (index = fdt->maxfd; index < nr; index++) + { + fds[index] = NULL; + } + fdt->fds = fds; + fdt->maxfd = nr; - fds = (struct dfs_fd **)rt_realloc(fdt->fds, cnt * sizeof(struct dfs_fd *)); - if (fds == NULL) goto __exit; /* return fdt->maxfd */ + return fd; +} + +static int fd_slot_alloc(struct dfs_fdtable *fdt, int startfd) +{ + int idx; - /* clean the new allocated fds */ - for (index = (int)fdt->maxfd; index < cnt; index ++) + /* find an empty fd slot */ + for (idx = startfd; idx < (int)fdt->maxfd; idx++) + { + if (fdt->fds[idx] == RT_NULL) { - fds[index] = NULL; + return idx; } + } - fdt->fds = fds; - fdt->maxfd = cnt; + idx = fdt->maxfd; + if (idx < startfd) + { + idx = startfd; } + if (fd_slot_expand(fdt, idx) < 0) + { + return -1; + } + return idx; +} +static int fd_alloc(struct dfs_fdtable *fdt, int startfd) +{ + int idx; + struct dfs_fd *fd = NULL; + + idx = fd_slot_alloc(fdt, startfd); /* allocate 'struct dfs_fd' */ - if (idx < (int)fdt->maxfd && fdt->fds[idx] == RT_NULL) + if (idx < 0) { - fdt->fds[idx] = (struct dfs_fd *)rt_calloc(1, sizeof(struct dfs_fd)); - if (fdt->fds[idx] == RT_NULL) - idx = fdt->maxfd; + return -1; } + fd = (struct dfs_fd *)rt_calloc(1, sizeof(struct dfs_fd)); + if (!fd) + { + return -1; + } + fd->ref_count = 1; + fd->magic = DFS_FD_MAGIC; + fd->vnode = NULL; + fdt->fds[idx] = fd; -__exit: return idx; } @@ -172,34 +251,32 @@ __exit: * * @return -1 on failed or the allocated file descriptor. */ -int fd_new(void) +int fdt_fd_new(struct dfs_fdtable *fdt) { - struct dfs_fd *d; int idx; - struct dfs_fdtable *fdt; - fdt = dfs_fdtable_get(); /* lock filesystem */ - dfs_lock(); + dfs_fd_lock(); /* find an empty fd entry */ - idx = fd_alloc(fdt, 0); + idx = fd_alloc(fdt, DFS_STDIO_OFFSET); /* can't find an empty fd entry */ - if (idx == (int)fdt->maxfd) + if (idx < 0) { - idx = -(1 + DFS_FD_OFFSET); LOG_E("DFS fd new is failed! Could not found an empty fd entry."); - goto __result; } - d = fdt->fds[idx]; - d->ref_count = 1; - d->magic = DFS_FD_MAGIC; + dfs_fd_unlock(); + return idx; +} -__result: - dfs_unlock(); - return idx + DFS_FD_OFFSET; +int fd_new(void) +{ + struct dfs_fdtable *fdt = NULL; + + fdt = dfs_fdtable_get(); + return fdt_fd_new(fdt); } /** @@ -211,69 +288,119 @@ __result: * @return NULL on on this file descriptor or the file descriptor structure * pointer. */ -struct dfs_fd *fd_get(int fd) + +struct dfs_fd *fdt_fd_get(struct dfs_fdtable* fdt, int fd) { struct dfs_fd *d; - struct dfs_fdtable *fdt; -#ifdef RT_USING_POSIX_STDIO - if ((0 <= fd) && (fd <= 2)) - fd = libc_stdio_get_console(); -#endif /* RT_USING_POSIX_STDIO */ - - fdt = dfs_fdtable_get(); - fd = fd - DFS_FD_OFFSET; if (fd < 0 || fd >= (int)fdt->maxfd) + { return NULL; + } - dfs_lock(); + dfs_fd_lock(); d = fdt->fds[fd]; /* check dfs_fd valid or not */ if ((d == NULL) || (d->magic != DFS_FD_MAGIC)) { - dfs_unlock(); + dfs_fd_unlock(); return NULL; } - /* increase the reference count */ - d->ref_count ++; - dfs_unlock(); + dfs_fd_unlock(); return d; } +struct dfs_fd *fd_get(int fd) +{ + struct dfs_fdtable *fdt; + + fdt = dfs_fdtable_get(); + return fdt_fd_get(fdt, fd); +} + /** * @ingroup Fd * * This function will put the file descriptor. */ -void fd_put(struct dfs_fd *fd) +void fdt_fd_release(struct dfs_fdtable* fdt, int fd) { - RT_ASSERT(fd != NULL); + struct dfs_fd *fd_slot = NULL; - dfs_lock(); + RT_ASSERT(fdt != NULL); - fd->ref_count --; + dfs_fd_lock(); - /* clear this fd entry */ - if (fd->ref_count == 0) + if ((fd < 0) || (fd >= fdt->maxfd)) { - int index; - struct dfs_fdtable *fdt; + dfs_fd_unlock(); + return; + } + + fd_slot = fdt->fds[fd]; + if (fd_slot == NULL) + { + dfs_fd_unlock(); + return; + } + fdt->fds[fd] = NULL; - fdt = dfs_fdtable_get(); - for (index = 0; index < (int)fdt->maxfd; index ++) + /* check fd */ + RT_ASSERT(fd_slot->magic == DFS_FD_MAGIC); + + fd_slot->ref_count--; + + /* clear this fd entry */ + if (fd_slot->ref_count == 0) + { + struct dfs_fnode *vnode = fd_slot->vnode; + if (vnode) { - if (fdt->fds[index] == fd) - { - rt_free(fd); - fdt->fds[index] = 0; - break; - } + vnode->ref_count--; } + rt_free(fd_slot); } - dfs_unlock(); + dfs_fd_unlock(); +} + +void fd_release(int fd) +{ + struct dfs_fdtable *fdt; + + fdt = dfs_fdtable_get(); + fdt_fd_release(fdt, fd); +} + +int sys_dup(int oldfd) +{ + int newfd = -1; + struct dfs_fdtable *fdt = NULL; + + dfs_fd_lock(); + /* check old fd */ + fdt = dfs_fdtable_get(); + if ((oldfd < 0) || (oldfd >= fdt->maxfd)) + { + goto exit; + } + if (!fdt->fds[oldfd]) + { + goto exit; + } + /* get a new fd */ + newfd = fd_slot_alloc(fdt, DFS_STDIO_OFFSET); + if (newfd >= 0) + { + fdt->fds[newfd] = fdt->fds[oldfd]; + /* inc ref_count */ + fdt->fds[newfd]->ref_count++; + } +exit: + dfs_fd_unlock(); + return newfd; } #endif /* DFS_USING_POSIX */ @@ -320,9 +447,9 @@ int fd_is_open(const char *pathname) for (index = 0; index < fdt->maxfd; index++) { fd = fdt->fds[index]; - if (fd == NULL || fd->fops == NULL || fd->path == NULL) continue; + if (fd == NULL || fd->vnode->fops == NULL || fd->vnode->path == NULL) continue; - if (fd->fs == fs && strcmp(fd->path, mountpath) == 0) + if (fd->vnode->fs == fs && strcmp(fd->vnode->path, mountpath) == 0) { /* found file in file descriptor table */ rt_free(fullpath); @@ -339,6 +466,139 @@ int fd_is_open(const char *pathname) return -1; } +int sys_dup2(int oldfd, int newfd) +{ + struct dfs_fdtable *fdt = NULL; + int ret = 0; + int retfd = -1; + + dfs_fd_lock(); + /* check old fd */ + fdt = dfs_fdtable_get(); + if ((oldfd < 0) || (oldfd >= fdt->maxfd)) + { + goto exit; + } + if (!fdt->fds[oldfd]) + { + goto exit; + } + if (newfd < 0) + { + goto exit; + } + if (newfd >= fdt->maxfd) + { + newfd = fd_slot_expand(fdt, newfd); + if (newfd < 0) + { + goto exit; + } + } + if (fdt->fds[newfd] == fdt->fds[oldfd]) + { + /* ok, return newfd */ + retfd = newfd; + goto exit; + } + + if (fdt->fds[newfd]) + { + ret = dfs_file_close(fdt->fds[newfd]); + if (ret < 0) + { + goto exit; + } + fd_release(newfd); + } + + fdt->fds[newfd] = fdt->fds[oldfd]; + /* inc ref_count */ + fdt->fds[newfd]->ref_count++; + retfd = newfd; +exit: + dfs_fd_unlock(); + return retfd; +} + +static int fd_get_fd_index_form_fdt(struct dfs_fdtable *fdt, struct dfs_fd *file) +{ + int fd = -1; + + if (file == RT_NULL) + { + return -1; + } + + dfs_fd_lock(); + + for(int index = 0; index < (int)fdt->maxfd; index++) + { + if(fdt->fds[index] == file) + { + fd = index; + break; + } + } + + dfs_fd_unlock(); + + return fd; +} + +int fd_get_fd_index(struct dfs_fd *file) +{ + struct dfs_fdtable *fdt; + + fdt = dfs_fdtable_get(); + return fd_get_fd_index_form_fdt(fdt, file); +} + +int fd_associate(struct dfs_fdtable *fdt, int fd, struct dfs_fd *file) +{ + int retfd = -1; + + if (!file) + { + return retfd; + } + if (!fdt) + { + return retfd; + } + + dfs_fd_lock(); + /* check old fd */ + if ((fd < 0) || (fd >= fdt->maxfd)) + { + goto exit; + } + + if (fdt->fds[fd]) + { + goto exit; + } + /* inc ref_count */ + file->ref_count++; + fdt->fds[fd] = file; + retfd = fd; +exit: + dfs_fd_unlock(); + return retfd; +} + +void fd_init(struct dfs_fd *fd) +{ + if (fd) + { + fd->magic = DFS_FD_MAGIC; + fd->ref_count = 1; + fd->pos = 0; + fd->vnode = NULL; + fd->data = NULL; + } +} + /** * this function will return a sub-path name under directory. * @@ -383,7 +643,13 @@ char *dfs_normalize_path(const char *directory, const char *filename) #ifdef DFS_USING_WORKDIR if (directory == NULL) /* shall use working directory */ + { +#ifdef RT_USING_LWP + directory = lwp_getcwd(); +#else directory = &working_directory[0]; +#endif + } #else if ((directory == NULL) && (filename[0] != '/')) { @@ -422,14 +688,14 @@ char *dfs_normalize_path(const char *directory, const char *filename) if (c == '.') { - if (!src[1]) src ++; /* '.' and ends */ + if (!src[1]) src++; /* '.' and ends */ else if (src[1] == '/') { /* './' case */ src += 2; while ((*src == '/') && (*src != '\0')) - src ++; + src++; continue; } else if (src[1] == '.') @@ -446,7 +712,7 @@ char *dfs_normalize_path(const char *directory, const char *filename) src += 3; while ((*src == '/') && (*src != '\0')) - src ++; + src++; goto up_one; } } @@ -454,15 +720,15 @@ char *dfs_normalize_path(const char *directory, const char *filename) /* copy up the next '/' and erase all '/' */ while ((c = *src++) != '\0' && c != '/') - *dst ++ = c; + *dst++ = c; if (c == '/') { - *dst ++ = '/'; + *dst++ = '/'; while (c == '/') c = *src++; - src --; + src--; } else if (!c) break; @@ -470,20 +736,25 @@ char *dfs_normalize_path(const char *directory, const char *filename) continue; up_one: - dst --; - if (dst < dst0) + /* keep the topmost root directory */ + if (dst - dst0 != 1 || dst[-1] != '/') { - rt_free(fullpath); - return NULL; + dst--; + + if (dst < dst0) + { + rt_free(fullpath); + return NULL; + } } while (dst0 < dst && dst[-1] != '/') - dst --; + dst--; } *dst = '\0'; /* remove '/' in the end of path if exist */ - dst --; + dst--; if ((dst != fullpath) && (*dst == '/')) *dst = '\0'; @@ -519,6 +790,27 @@ struct dfs_fdtable *dfs_fdtable_get(void) return fdt; } +#ifdef RT_USING_LWP +struct dfs_fdtable *dfs_fdtable_get_pid(int pid) +{ + struct rt_lwp *lwp = RT_NULL; + struct dfs_fdtable *fdt = RT_NULL; + + lwp = lwp_from_pid(pid); + if (lwp) + { + fdt = &lwp->fdt; + } + + return fdt; +} +#endif + +struct dfs_fdtable *dfs_fdtable_get_global(void) +{ + return &_fdtab; +} + #ifdef RT_USING_FINSH int list_fd(void) { @@ -532,28 +824,97 @@ int list_fd(void) rt_kprintf("fd type ref magic path\n"); rt_kprintf("-- ------ --- ----- ------\n"); - for (index = 0; index < (int)fd_table->maxfd; index ++) + for (index = 0; index < (int)fd_table->maxfd; index++) { struct dfs_fd *fd = fd_table->fds[index]; - if (fd && fd->fops) + if (fd && fd->vnode->fops) { - rt_kprintf("%2d ", index + DFS_FD_OFFSET); - if (fd->type == FT_DIRECTORY) rt_kprintf("%-7.7s ", "dir"); - else if (fd->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file"); - else if (fd->type == FT_SOCKET) rt_kprintf("%-7.7s ", "socket"); - else if (fd->type == FT_USER) rt_kprintf("%-7.7s ", "user"); - else if (fd->type == FT_DEVICE) rt_kprintf("%-7.7s ", "device"); + rt_kprintf("%2d ", index); + if (fd->vnode->type == FT_DIRECTORY) rt_kprintf("%-7.7s ", "dir"); + else if (fd->vnode->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file"); + else if (fd->vnode->type == FT_SOCKET) rt_kprintf("%-7.7s ", "socket"); + else if (fd->vnode->type == FT_USER) rt_kprintf("%-7.7s ", "user"); + else if (fd->vnode->type == FT_DEVICE) rt_kprintf("%-7.7s ", "device"); else rt_kprintf("%-8.8s ", "unknown"); - rt_kprintf("%3d ", fd->ref_count); + rt_kprintf("%3d ", fd->vnode->ref_count); rt_kprintf("%04x ", fd->magic); - if (fd->fs && fd->fs->path && rt_strlen(fd->fs->path) > 1) + if (fd->vnode->path) { - rt_kprintf("%s", fd->fs->path); + rt_kprintf("%s\n", fd->vnode->path); } - if (fd->path) + else { - rt_kprintf("%s\n", fd->path); + rt_kprintf("\n"); + } + } + } + dfs_unlock(); + + return 0; +} + +#ifdef RT_USING_LWP +static int lsofp(int pid) +{ + int index; + struct dfs_fdtable *fd_table = RT_NULL; + + if (pid == (-1)) + { + fd_table = dfs_fdtable_get(); + if (!fd_table) return -1; + } + else + { + fd_table = dfs_fdtable_get_pid(pid); + if (!fd_table) + { + rt_kprintf("PID %s is not a applet(lwp)\n", pid); + return -1; + } + } + + rt_kprintf("--- -- ------ ------ ----- ---------- ---------- ---------- ------\n"); + + rt_enter_critical(); + for (index = 0; index < (int)fd_table->maxfd; index++) + { + struct dfs_fd *fd = fd_table->fds[index]; + + if (fd && fd->vnode->fops) + { + if(pid == (-1)) + { + rt_kprintf(" K "); + } + else + { + rt_kprintf("%3d ", pid); + } + + rt_kprintf("%2d ", index); + if (fd->vnode->type == FT_DIRECTORY) rt_kprintf("%-7.7s ", "dir"); + else if (fd->vnode->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file"); + else if (fd->vnode->type == FT_SOCKET) rt_kprintf("%-7.7s ", "socket"); + else if (fd->vnode->type == FT_USER) rt_kprintf("%-7.7s ", "user"); + else if (fd->vnode->type == FT_DEVICE) rt_kprintf("%-7.7s ", "device"); + else rt_kprintf("%-8.8s ", "unknown"); + rt_kprintf("%6d ", fd->vnode->ref_count); + rt_kprintf("%04x 0x%.8x ", fd->magic, (int)(size_t)fd->vnode); + + if(fd->vnode == RT_NULL) + { + rt_kprintf("0x%.8x 0x%.8x ", (int)0x00000000, (int)(size_t)fd); + } + else + { + rt_kprintf("0x%.8x 0x%.8x ", (int)(size_t)(fd->vnode->data), (int)(size_t)fd); + } + + if (fd->vnode->path) + { + rt_kprintf("%s \n", fd->vnode->path); } else { @@ -561,10 +922,50 @@ int list_fd(void) } } } - dfs_unlock(); + rt_exit_critical(); + + return 0; +} + +int lsof(int argc, char *argv[]) +{ + rt_kprintf("PID fd type fd-ref magic vnode vnode/data addr path \n"); + + if (argc == 1) + { + struct rt_list_node *node, *list; + struct lwp_avl_struct *pids = lwp_get_pid_ary(); + + lsofp(-1); + + for (int index = 0; index < RT_LWP_MAX_NR; index++) + { + struct rt_lwp *lwp = (struct rt_lwp *)pids[index].data; + + if (lwp) + { + list = &lwp->t_grp; + for (node = list->next; node != list; node = node->next) + { + lsofp(lwp_to_pid(lwp)); + } + } + } + } + else if (argc == 3) + { + if (argv[1][0] == '-' && argv[1][1] == 'p') + { + int pid = atoi(argv[2]); + lsofp(pid); + } + } return 0; } -#endif /* RT_USING_FINSH */ +MSH_CMD_EXPORT(lsof, list open files); +#endif /* RT_USING_LWP */ +#endif /*@}*/ + diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c index a798bd3c59..1f6f0d1e29 100644 --- a/components/dfs/src/dfs_file.c +++ b/components/dfs/src/dfs_file.c @@ -14,6 +14,78 @@ #include <dfs.h> #include <dfs_file.h> #include <dfs_private.h> +#include <unistd.h> + +#define DFS_FNODE_HASH_NR 128 + +struct dfs_fnode_mgr +{ + struct rt_mutex lock; + rt_list_t head[DFS_FNODE_HASH_NR]; +}; + +static struct dfs_fnode_mgr dfs_fm; + +void dfs_fm_lock(void) +{ + rt_mutex_take(&dfs_fm.lock, RT_WAITING_FOREVER); +} + +void dfs_fm_unlock(void) +{ + rt_mutex_release(&dfs_fm.lock); +} + +void dfs_fnode_mgr_init(void) +{ + int i = 0; + + rt_mutex_init(&dfs_fm.lock, "dfs_mgr", RT_IPC_FLAG_PRIO); + for (i = 0; i < DFS_FNODE_HASH_NR; i++) + { + rt_list_init(&dfs_fm.head[i]); + } +} + +/* BKDR Hash Function */ +static unsigned int bkdr_hash(const char *str) +{ + unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. + unsigned int hash = 0; + + while (*str) + { + hash = hash * seed + (*str++); + } + + return (hash % DFS_FNODE_HASH_NR); +} + +static struct dfs_fnode *dfs_fnode_find(const char *path, rt_list_t **hash_head) +{ + struct dfs_fnode *vnode = NULL; + int hash = bkdr_hash(path); + rt_list_t *hh; + + hh = dfs_fm.head[hash].next; + + if (hash_head) + { + *hash_head = &dfs_fm.head[hash]; + } + + while (hh != &dfs_fm.head[hash]) + { + vnode = rt_container_of(hh, struct dfs_fnode, list); + if (rt_strcmp(path, vnode->fullpath) == 0) + { + /* found */ + return vnode; + } + hh = hh->next; + } + return NULL; +} /** * @addtogroup FileApi @@ -22,6 +94,34 @@ /*@{*/ /** + * This function will return whether this file has been opend. + * + * @param pathname the file path name. + * + * @return 0 on file has been open successfully, -1 on open failed. + */ +int dfs_file_is_open(const char *pathname) +{ + char *fullpath = NULL; + struct dfs_fnode *vnode = NULL; + int ret = 0; + + fullpath = dfs_normalize_path(NULL, pathname); + + dfs_fm_lock(); + vnode = dfs_fnode_find(fullpath, NULL); + if (vnode) + { + ret = 1; + } + dfs_fm_unlock(); + + rt_free(fullpath); + return ret; +} + + +/** * this function will open a file which specified by path with specified flags. * * @param fd the file descriptor pointer to return the corresponding result. @@ -35,6 +135,8 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags) struct dfs_filesystem *fs; char *fullpath; int result; + struct dfs_fnode *vnode = NULL; + rt_list_t *hash_head; /* parameter check */ if (fd == NULL) @@ -49,56 +151,101 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags) LOG_D("open file:%s", fullpath); - /* find filesystem */ - fs = dfs_filesystem_lookup(fullpath); - if (fs == NULL) + dfs_fm_lock(); + /* vnode find */ + vnode = dfs_fnode_find(fullpath, &hash_head); + if (vnode) { + vnode->ref_count++; + fd->pos = 0; + fd->vnode = vnode; + dfs_fm_unlock(); rt_free(fullpath); /* release path */ - - return -ENOENT; } + else + { + /* find filesystem */ + fs = dfs_filesystem_lookup(fullpath); + if (fs == NULL) + { + dfs_fm_unlock(); + rt_free(fullpath); /* release path */ + return -ENOENT; + } + + vnode = rt_calloc(1, sizeof(struct dfs_fnode)); + if (!vnode) + { + dfs_fm_unlock(); + rt_free(fullpath); /* release path */ + return -ENOMEM; + } + vnode->ref_count = 1; - LOG_D("open in filesystem:%s", fs->ops->name); - fd->fs = fs; /* set file system */ - fd->fops = fs->ops->fops; /* set file ops */ + LOG_D("open in filesystem:%s", fs->ops->name); + vnode->fs = fs; /* set file system */ + vnode->fops = fs->ops->fops; /* set file ops */ - /* initialize the fd item */ - fd->type = FT_REGULAR; - fd->flags = flags; - fd->size = 0; - fd->pos = 0; - fd->data = fs; + /* initialize the fd item */ + vnode->type = FT_REGULAR; + vnode->flags = 0; - if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH)) - { - if (dfs_subdir(fs->path, fullpath) == NULL) - fd->path = rt_strdup("/"); + if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH)) + { + if (dfs_subdir(fs->path, fullpath) == NULL) + vnode->path = rt_strdup("/"); + else + vnode->path = rt_strdup(dfs_subdir(fs->path, fullpath)); + LOG_D("Actual file path: %s", vnode->path); + } else - fd->path = rt_strdup(dfs_subdir(fs->path, fullpath)); - rt_free(fullpath); - LOG_D("Actual file path: %s", fd->path); - } - else - { - fd->path = fullpath; - } + { + vnode->path = fullpath; + } + vnode->fullpath = fullpath; - /* specific file system open routine */ - if (fd->fops->open == NULL) - { - /* clear fd */ - rt_free(fd->path); - fd->path = NULL; + /* specific file system open routine */ + if (vnode->fops->open == NULL) + { + dfs_fm_unlock(); + /* clear fd */ + if (vnode->path != vnode->fullpath) + { + rt_free(vnode->fullpath); + } + rt_free(vnode->path); + rt_free(vnode); - return -ENOSYS; + return -ENOSYS; + } + + fd->pos = 0; + fd->vnode = vnode; + + /* insert vnode to hash */ + rt_list_insert_after(hash_head, &vnode->list); } - if ((result = fd->fops->open(fd)) < 0) + fd->flags = flags; + + if ((result = vnode->fops->open(fd)) < 0) { - /* clear fd */ - rt_free(fd->path); - fd->path = NULL; + vnode->ref_count--; + if (vnode->ref_count == 0) + { + /* remove from hash */ + rt_list_remove(&vnode->list); + /* clear fd */ + if (vnode->path != vnode->fullpath) + { + rt_free(vnode->fullpath); + } + rt_free(vnode->path); + fd->vnode = NULL; + rt_free(vnode); + } + dfs_fm_unlock(); LOG_D("%s open failed", fullpath); return result; @@ -107,9 +254,10 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags) fd->flags |= DFS_F_OPEN; if (flags & O_DIRECTORY) { - fd->type = FT_DIRECTORY; + fd->vnode->type = FT_DIRECTORY; fd->flags |= DFS_F_DIRECTORY; } + dfs_fm_unlock(); LOG_D("open successful"); return 0; @@ -124,20 +272,52 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags) */ int dfs_file_close(struct dfs_fd *fd) { + struct dfs_fnode *vnode = NULL; int result = 0; if (fd == NULL) + { return -ENXIO; + } - if (fd->fops->close != NULL) - result = fd->fops->close(fd); + if (fd->ref_count == 1) + { + dfs_fm_lock(); + vnode = fd->vnode; - /* close fd error, return */ - if (result < 0) - return result; + if (vnode->ref_count <= 0) + { + dfs_fm_unlock(); + return -ENXIO; + } - rt_free(fd->path); - fd->path = NULL; + if (vnode->fops->close != NULL) + { + result = vnode->fops->close(fd); + } + + /* close fd error, return */ + if (result < 0) + { + dfs_fm_unlock(); + return result; + } + + if (vnode->ref_count == 1) + { + /* remove from hash */ + rt_list_remove(&vnode->list); + fd->vnode = NULL; + + if (vnode->path != vnode->fullpath) + { + rt_free(vnode->fullpath); + } + rt_free(vnode->path); + rt_free(vnode); + } + dfs_fm_unlock(); + } return result; } @@ -154,10 +334,12 @@ int dfs_file_close(struct dfs_fd *fd) int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args) { if (fd == NULL) + { return -EINVAL; + } /* regular file system fd */ - if (fd->type == FT_REGULAR) + if (fd->vnode->type == FT_REGULAR || fd->vnode->type == FT_DEVICE) { switch (cmd) { @@ -176,8 +358,10 @@ int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args) } } - if (fd->fops->ioctl != NULL) - return fd->fops->ioctl(fd, cmd, args); + if (fd->vnode->fops->ioctl != NULL) + { + return fd->vnode->fops->ioctl(fd, cmd, args); + } return -ENOSYS; } @@ -197,13 +381,19 @@ int dfs_file_read(struct dfs_fd *fd, void *buf, size_t len) int result = 0; if (fd == NULL) + { return -EINVAL; + } - if (fd->fops->read == NULL) + if (fd->vnode->fops->read == NULL) + { return -ENOSYS; + } - if ((result = fd->fops->read(fd, buf, len)) < 0) + if ((result = fd->vnode->fops->read(fd, buf, len)) < 0) + { fd->flags |= DFS_F_EOF; + } return result; } @@ -220,11 +410,20 @@ int dfs_file_read(struct dfs_fd *fd, void *buf, size_t len) int dfs_file_getdents(struct dfs_fd *fd, struct dirent *dirp, size_t nbytes) { /* parameter check */ - if (fd == NULL || fd->type != FT_DIRECTORY) + if (fd == NULL) + { + return -EINVAL; + } + + if (fd->vnode->type != FT_DIRECTORY) + { return -EINVAL; + } - if (fd->fops->getdents != NULL) - return fd->fops->getdents(fd, dirp, nbytes); + if (fd->vnode->fops->getdents != NULL) + { + return fd->vnode->fops->getdents(fd, dirp, nbytes); + } return -ENOSYS; } @@ -249,17 +448,17 @@ int dfs_file_unlink(const char *path) return -EINVAL; } - /* get filesystem */ - if ((fs = dfs_filesystem_lookup(fullpath)) == NULL) + /* Check whether file is already open */ + if (dfs_file_is_open(fullpath)) { - result = -ENOENT; + result = -EBUSY; goto __exit; } - /* Check whether file is already open */ - if (fd_is_open(fullpath) == 0) + /* get filesystem */ + if ((fs = dfs_filesystem_lookup(fullpath)) == NULL) { - result = -EBUSY; + result = -ENOENT; goto __exit; } @@ -294,12 +493,16 @@ __exit: int dfs_file_write(struct dfs_fd *fd, const void *buf, size_t len) { if (fd == NULL) + { return -EINVAL; + } - if (fd->fops->write == NULL) + if (fd->vnode->fops->write == NULL) + { return -ENOSYS; + } - return fd->fops->write(fd, buf, len); + return fd->vnode->fops->write(fd, buf, len); } /** @@ -314,10 +517,10 @@ int dfs_file_flush(struct dfs_fd *fd) if (fd == NULL) return -EINVAL; - if (fd->fops->flush == NULL) + if (fd->vnode->fops->flush == NULL) return -ENOSYS; - return fd->fops->flush(fd); + return fd->vnode->fops->flush(fd); } /** @@ -335,10 +538,10 @@ int dfs_file_lseek(struct dfs_fd *fd, off_t offset) if (fd == NULL) return -EINVAL; - if (fd->fops->lseek == NULL) + if (fd->vnode->fops->lseek == NULL) return -ENOSYS; - result = fd->fops->lseek(fd, offset); + result = fd->vnode->fops->lseek(fd, offset); /* update current position */ if (result >= 0) @@ -425,11 +628,10 @@ int dfs_file_stat(const char *path, struct stat *buf) */ int dfs_file_rename(const char *oldpath, const char *newpath) { - int result; - struct dfs_filesystem *oldfs, *newfs; - char *oldfullpath, *newfullpath; + int result = RT_EOK; + struct dfs_filesystem *oldfs = NULL, *newfs = NULL; + char *oldfullpath = NULL, *newfullpath = NULL; - result = RT_EOK; newfullpath = NULL; oldfullpath = NULL; @@ -440,6 +642,12 @@ int dfs_file_rename(const char *oldpath, const char *newpath) goto __exit; } + if (dfs_file_is_open((const char *)oldfullpath)) + { + result = -EBUSY; + goto __exit; + } + newfullpath = dfs_normalize_path(NULL, newpath); if (newfullpath == NULL) { @@ -473,8 +681,14 @@ int dfs_file_rename(const char *oldpath, const char *newpath) } __exit: - rt_free(oldfullpath); - rt_free(newfullpath); + if (oldfullpath) + { + rt_free(oldfullpath); + } + if (newfullpath) + { + rt_free(newfullpath); + } /* not at same file system, return EXDEV */ return result; @@ -494,28 +708,52 @@ int dfs_file_ftruncate(struct dfs_fd *fd, off_t length) int result; /* fd is null or not a regular file system fd, or length is invalid */ - if (fd == NULL || fd->type != FT_REGULAR || length < 0) + if (fd == NULL || fd->vnode->type != FT_REGULAR || length < 0) return -EINVAL; - if (fd->fops->ioctl == NULL) + if (fd->vnode->fops->ioctl == NULL) return -ENOSYS; - result = fd->fops->ioctl(fd, RT_FIOFTRUNCATE, (void*)&length); + result = fd->vnode->fops->ioctl(fd, RT_FIOFTRUNCATE, (void*)&length); /* update current size */ if (result == 0) - fd->size = length; + fd->vnode->size = length; return result; } +int dfs_file_mmap2(struct dfs_fd *fd, struct dfs_mmap2_args *mmap2) +{ + int ret = 0; + + if (fd && mmap2) + { + if (fd->vnode->type != FT_DEVICE || !fd->vnode->fops->ioctl) + { + rt_set_errno(EINVAL); + } + else if (fd->vnode->type == FT_DEVICE && fd->vnode->fops->ioctl) + { + ret = fd->vnode->fops->ioctl(fd, RT_FIOMMAP2, mmap2); + if (ret != 0) + { + ret = ret > 0? ret : -ret; + rt_set_errno(ret); + } + } + } + + return ret; +} + #ifdef RT_USING_FINSH #include <finsh.h> -static struct dfs_fd fd; -static struct dirent dirent; void ls(const char *pathname) { + struct dfs_fd fd; + struct dirent dirent; struct stat stat; int length; char *fullpath, *path; @@ -537,6 +775,7 @@ void ls(const char *pathname) path = (char *)pathname; } + fd_init(&fd); /* list directory */ if (dfs_file_open(&fd, path, O_DIRECTORY) == 0) { @@ -595,9 +834,11 @@ FINSH_FUNCTION_EXPORT(rm, remove files or directories); void cat(const char *filename) { - uint32_t length; + struct dfs_fd fd; + int length = 0; char buffer[81]; + fd_init(&fd); if (dfs_file_open(&fd, filename, O_RDONLY) < 0) { rt_kprintf("Open %s failed\n", filename); @@ -607,15 +848,15 @@ void cat(const char *filename) do { - rt_memset(buffer, 0, sizeof(buffer)); - length = dfs_file_read(&fd, buffer, sizeof(buffer) - 1); + rt_memset(buffer, 0x0, sizeof(buffer)); + length = dfs_file_read(&fd, (void *)buffer, sizeof(buffer) - 1); if (length > 0) { - rt_kprintf("%s", buffer); + buffer[length] = '\0'; + rt_device_t out_device = rt_console_get_device(); + rt_device_write(out_device, 0, (void *)buffer, sizeof(buffer)); } - } - while (length > 0); - rt_kprintf("\n"); + } while (length > 0); dfs_file_close(&fd); } @@ -625,6 +866,7 @@ FINSH_FUNCTION_EXPORT(cat, print file); #define BUF_SZ 4096 static void copyfile(const char *src, const char *dst) { + struct dfs_fd fd; struct dfs_fd src_fd; rt_uint8_t *block_ptr; rt_int32_t read_bytes; @@ -637,6 +879,7 @@ static void copyfile(const char *src, const char *dst) return; } + fd_init(&src_fd); if (dfs_file_open(&src_fd, src, O_RDONLY) < 0) { rt_free(block_ptr); @@ -644,6 +887,7 @@ static void copyfile(const char *src, const char *dst) return; } + fd_init(&fd); if (dfs_file_open(&fd, dst, O_WRONLY | O_CREAT) < 0) { rt_free(block_ptr); diff --git a/components/dfs/src/dfs_fs.c b/components/dfs/src/dfs_fs.c index 2abad9dfeb..7724afc7bc 100644 --- a/components/dfs/src/dfs_fs.c +++ b/components/dfs/src/dfs_fs.c @@ -241,7 +241,7 @@ int dfs_mount(const char *device_name, for (ops = &filesystem_operation_table[0]; ops < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; ops++) - if ((*ops != NULL) && (strcmp((*ops)->name, filesystemtype) == 0)) + if ((*ops != NULL) && (strncmp((*ops)->name, filesystemtype, strlen((*ops)->name)) == 0)) break; dfs_unlock(); @@ -273,6 +273,7 @@ int dfs_mount(const char *device_name, { struct dfs_fd fd; + fd_init(&fd); if (dfs_file_open(&fd, fullpath, O_RDONLY | O_DIRECTORY) < 0) { rt_free(fullpath); @@ -312,6 +313,9 @@ int dfs_mount(const char *device_name, fs->path = fullpath; fs->ops = *ops; fs->dev_id = dev_id; + /* For UFS, record the real filesystem name */ + fs->data = (void *) filesystemtype; + /* release filesystem_table lock */ dfs_unlock(); @@ -447,7 +451,8 @@ int dfs_mkfs(const char *fs_name, const char *device_name) for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index ++) { if (filesystem_operation_table[index] != NULL && - strcmp(filesystem_operation_table[index]->name, fs_name) == 0) + strncmp(filesystem_operation_table[index]->name, fs_name, + strlen(filesystem_operation_table[index]->name)) == 0) break; } dfs_unlock(); @@ -463,7 +468,7 @@ int dfs_mkfs(const char *fs_name, const char *device_name) return -1; } - return ops->mkfs(dev_id); + return ops->mkfs(dev_id, fs_name); } LOG_E("File system (%s) was not found.", fs_name); @@ -490,6 +495,7 @@ int dfs_statfs(const char *path, struct statfs *buffer) return fs->ops->statfs(fs, buffer); } + rt_set_errno(-ENOSYS); return -1; } @@ -625,7 +631,10 @@ int df(const char *path) result = dfs_statfs(path ? path : NULL, &buffer); if (result != 0) { - rt_kprintf("dfs_statfs failed.\n"); + if (rt_get_errno() == -ENOSYS) + rt_kprintf("The function is not implemented.\n"); + else + rt_kprintf("statfs failed: errno=%d.\n", rt_get_errno()); return -1; } diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c index ed0647121d..e3efa5bed6 100644 --- a/components/dfs/src/dfs_posix.c +++ b/components/dfs/src/dfs_posix.c @@ -14,6 +14,16 @@ #include <dfs_private.h> #include <sys/errno.h> +#ifdef RT_USING_LWP +#include <lwp.h> +#endif + +/** + * @addtogroup FsPosixApi + */ + +/*@{*/ + /** * this function is a POSIX compliant version, which will open a file and * return a file descriptor according specified flags. @@ -42,17 +52,13 @@ int open(const char *file, int flags, ...) if (result < 0) { /* release the ref-count of fd */ - fd_put(d); - fd_put(d); + fd_release(fd); rt_set_errno(result); return -1; } - /* release the ref-count of fd */ - fd_put(d); - return fd; } RTM_EXPORT(open); @@ -94,7 +100,6 @@ int close(int fd) } result = dfs_file_close(d); - fd_put(d); if (result < 0) { @@ -103,7 +108,7 @@ int close(int fd) return -1; } - fd_put(d); + fd_release(fd); return 0; } @@ -141,15 +146,11 @@ ssize_t read(int fd, void *buf, size_t len) result = dfs_file_read(d, buf, len); if (result < 0) { - fd_put(d); rt_set_errno(result); return -1; } - /* release the ref-count of fd */ - fd_put(d); - return result; } RTM_EXPORT(read); @@ -185,15 +186,11 @@ ssize_t write(int fd, const void *buf, size_t len) result = dfs_file_write(d, buf, len); if (result < 0) { - fd_put(d); rt_set_errno(result); return -1; } - /* release the ref-count of fd */ - fd_put(d); - return result; } RTM_EXPORT(write); @@ -231,11 +228,10 @@ off_t lseek(int fd, off_t offset, int whence) break; case SEEK_END: - offset += d->size; + offset += d->vnode->size; break; default: - fd_put(d); rt_set_errno(-EINVAL); return -1; @@ -243,24 +239,17 @@ off_t lseek(int fd, off_t offset, int whence) if (offset < 0) { - fd_put(d); rt_set_errno(-EINVAL); return -1; } - if(offset != d->pos) + result = dfs_file_lseek(d, offset); + if (result < 0) { - result = dfs_file_lseek(d, offset); - if (result < 0) - { - fd_put(d); - rt_set_errno(result); + rt_set_errno(result); - return -1; - } + return -1; } - /* release the ref-count of fd */ - fd_put(d); return offset; } @@ -369,17 +358,15 @@ int fstat(int fildes, struct stat *buf) buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH; - if (d->type == FT_DIRECTORY) + if (d->vnode->type == FT_DIRECTORY) { buf->st_mode &= ~S_IFREG; buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; } - buf->st_size = d->size; + buf->st_size = d->vnode->size; buf->st_mtime = 0; - fd_put(d); - return RT_EOK; } RTM_EXPORT(fstat); @@ -409,7 +396,6 @@ int fsync(int fildes) ret = dfs_file_flush(d); - fd_put(d); return ret; } RTM_EXPORT(fsync); @@ -443,7 +429,6 @@ int fcntl(int fildes, int cmd, ...) va_end(ap); ret = dfs_file_ioctl(d, cmd, arg); - fd_put(d); } else ret = -EBADF; @@ -508,7 +493,6 @@ int ftruncate(int fd, off_t length) if (length < 0) { - fd_put(d); rt_set_errno(-EINVAL); return -1; @@ -516,15 +500,11 @@ int ftruncate(int fd, off_t length) result = dfs_file_ftruncate(d, length); if (result < 0) { - fd_put(d); rt_set_errno(result); return -1; } - /* release the ref-count of fd */ - fd_put(d); - return 0; } RTM_EXPORT(ftruncate); @@ -582,16 +562,14 @@ int mkdir(const char *path, mode_t mode) if (result < 0) { - fd_put(d); - fd_put(d); + fd_release(fd); rt_set_errno(result); return -1; } dfs_file_close(d); - fd_put(d); - fd_put(d); + fd_release(fd); return 0; } @@ -653,7 +631,7 @@ DIR *opendir(const char *name) if (t == NULL) { dfs_file_close(d); - fd_put(d); + fd_release(fd); } else { @@ -661,14 +639,12 @@ DIR *opendir(const char *name) t->fd = fd; } - fd_put(d); return t; } /* open failed */ - fd_put(d); - fd_put(d); + fd_release(fd); rt_set_errno(result); return NULL; @@ -711,7 +687,6 @@ struct dirent *readdir(DIR *d) sizeof(d->buf) - 1); if (result <= 0) { - fd_put(fd); rt_set_errno(result); return NULL; @@ -721,8 +696,6 @@ struct dirent *readdir(DIR *d) d->cur = 0; /* current entry index */ } - fd_put(fd); - return (struct dirent *)(d->buf + d->cur); } RTM_EXPORT(readdir); @@ -749,7 +722,6 @@ long telldir(DIR *d) } result = fd->pos - d->num + d->cur; - fd_put(fd); return result; } @@ -777,7 +749,6 @@ void seekdir(DIR *d, long offset) /* seek to the offset position of directory */ if (dfs_file_lseek(fd, offset) >= 0) d->num = d->cur = 0; - fd_put(fd); } RTM_EXPORT(seekdir); @@ -802,7 +773,6 @@ void rewinddir(DIR *d) /* seek to the beginning of directory */ if (dfs_file_lseek(fd, 0) >= 0) d->num = d->cur = 0; - fd_put(fd); } RTM_EXPORT(rewinddir); @@ -828,9 +798,8 @@ int closedir(DIR *d) } result = dfs_file_close(fd); - fd_put(fd); + fd_release(d->fd); - fd_put(fd); rt_free(d); if (result < 0) @@ -861,7 +830,9 @@ int chdir(const char *path) if (path == NULL) { dfs_lock(); +#ifdef DFS_USING_WORKDIR rt_kprintf("%s\n", working_directory); +#endif dfs_unlock(); return 0; @@ -895,9 +866,12 @@ int chdir(const char *path) /* close directory stream */ closedir(d); - +#ifdef RT_USING_LWP /* copy full path to working directory */ - strncpy(working_directory, fullpath, DFS_PATH_MAX); + lwp_setcwd(fullpath); +#else + rt_strncpy(working_directory, fullpath, DFS_PATH_MAX); +#endif /* release normalize directory path name */ rt_free(fullpath); @@ -930,6 +904,31 @@ int access(const char *path, int amode) /* ignore R_OK,W_OK,X_OK condition */ return 0; } +/** + * this function is a POSIX compliant version, which will set current + * working directory. + * + * @param buf the current directory. + * + * @return null. + */ +void setcwd(char *buf) +{ +#ifdef DFS_USING_WORKDIR + dfs_lock(); +#ifdef RT_USING_LWP + lwp_setcwd(buf); +#else + rt_strncpy(working_directory, buf, DFS_PATH_MAX); +#endif + dfs_unlock(); +#else + rt_kprintf(NO_WORKING_DIR); +#endif + + return ; +} +RTM_EXPORT(setcwd); /** * this function is a POSIX compliant version, which will return current @@ -943,8 +942,22 @@ int access(const char *path, int amode) char *getcwd(char *buf, size_t size) { #ifdef DFS_USING_WORKDIR + char *dir_buf = RT_NULL; + dfs_lock(); - strncpy(buf, working_directory, size); + +#ifdef RT_USING_LWP + dir_buf = lwp_getcwd(); +#else + dir_buf = &working_directory[0]; +#endif + + /* copy to buf parameter */ + if (buf) + { + rt_strncpy(buf, dir_buf, size); + } + dfs_unlock(); #else rt_kprintf(NO_WORKING_DIR); @@ -953,3 +966,5 @@ char *getcwd(char *buf, size_t size) return buf; } RTM_EXPORT(getcwd); + +/* @} */ |
