/* +------------------------------------------------------------------------------ | Function : dfile_raw_rename +------------------------------------------------------------------------------ | Description : | | Parameters : | Returns : | +------------------------------------------------------------------------------ */ int dfile_raw_rename(const char* oldpath, const char* newpath) { struct dfs_filesystem *oldfs, *newfs; char *oldfullpath, *newfullpath; #ifdef DFS_USING_WORKDIR /* Change DFS_PATH_MAX to DFS_PATH_MAX + 1, [email protected]*/ char old_realpath[DFS_PATH_MAX + 1], new_realpath[DFS_PATH_MAX + 1]; #endif oldfullpath = (char*)oldpath; newfullpath = (char*)newpath; if ( oldfullpath[0] != '/' ) { #ifdef DFS_USING_WORKDIR /* build full path */ oldfullpath = old_realpath; dfs_lock(); build_fullpath(working_directory, oldpath, oldfullpath); dfs_unlock(); #else rt_kprintf("bad filename\n"); return -1; #endif } if ( newfullpath[0] != '/' ) { #ifdef DFS_USING_WORKDIR /* build full path */ newfullpath = new_realpath; dfs_lock(); build_fullpath(working_directory, newpath, newfullpath); dfs_unlock(); #else rt_kprintf("bad filename"); return -1; #endif } if ( (oldfs = dfs_filesystem_lookup(oldfullpath)) == RT_NULL ) { return -DFS_STATUS_ENOENT; } if ( (newfs = dfs_filesystem_lookup(newfullpath)) == RT_NULL ) { return -DFS_STATUS_ENOENT; } if ( oldfs == newfs ) { if ( oldfs->ops->rename == RT_NULL ) return -DFS_STATUS_ENOSYS; return oldfs->ops->rename(oldfs, oldfullpath, newfullpath); } /* not at same file system, return EXDEV */ return -DFS_STATUS_EXDEV; }
/** * @ingroup Fd * * This function will return a file descriptor structure according to file * descriptor. * * @return NULL on on this file descriptor or the file descriptor structure * pointer. */ struct dfs_fd *fd_get(int fd) { struct dfs_fd *d; #ifdef DFS_USING_STDIO if (fd < 3 || fd >= DFS_FD_MAX + 3) return RT_NULL; #else if (fd < 0 || fd >= DFS_FD_MAX) return RT_NULL; #endif dfs_lock(); d = &fd_table[fd]; /* check dfs_fd valid or not */ if (d->magic != DFS_FD_MAGIC) { dfs_unlock(); return RT_NULL; } /* increase the reference count */ d->ref_count ++; dfs_unlock(); return d; }
/* +------------------------------------------------------------------------------ | Function : dfile_raw_unlink +------------------------------------------------------------------------------ | Description : | | Parameters : | Returns : | +------------------------------------------------------------------------------ */ int dfile_raw_unlink(const char *path) { struct dfs_filesystem* fs; char *fullpath, *real_path, search_path[DFS_PATH_MAX + 1]; #ifdef DFS_USING_WORKDIR char full_path[DFS_PATH_MAX+1]; #endif struct dfs_fd* fd; int index, fspathlen; /* Make sure we have an absolute path */ fullpath = (char*)path; if ( fullpath[0] != '/') { #ifdef DFS_USING_WORKDIR /* build full path */ fullpath = full_path; dfs_lock(); build_fullpath(working_directory, path, fullpath); dfs_unlock(); #else #ifdef RT_USING_FINSH rt_kprintf("bad filename"); #endif return -1; #endif } if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL) return -DFS_STATUS_ENOENT; /* Check whether file is already open */ dfs_lock(); for (index = 0; index < DFS_FD_MAX; index++) { fd = &(fd_table[index]); if (fd->fs == RT_NULL) continue; build_fullpath(fd->fs->path, fd->path, search_path); if (strcmp(fullpath, search_path) == 0) { dfs_unlock(); return -DFS_STATUS_EEXIST; } } dfs_unlock(); fspathlen = strlen(fs->path); real_path = search_path; rt_memset( real_path, 0, sizeof( real_path ) ); if (*(fullpath + fspathlen) != '/') strcpy(real_path, "/"); strcat(real_path, fullpath + fspathlen); if (fs->ops->unlink != RT_NULL) return fs->ops->unlink(fs, real_path); return -DFS_STATUS_ENOSYS; }
/** * @ingroup Fd * * 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 fd_is_open(const char *pathname) { char *fullpath; unsigned int index; struct dfs_filesystem *fs; struct dfs_fd *fd; fullpath = dfs_normalize_path(RT_NULL, pathname); if (fullpath != RT_NULL) { char *mountpath; fs = dfs_filesystem_lookup(fullpath); if (fs == RT_NULL) { /* can't find mounted file system */ rt_free(fullpath); return -1; } /* get file path name under mounted file system */ if (fs->path[0] == '/' && fs->path[1] == '\0') mountpath = fullpath; else mountpath = fullpath + strlen(fs->path); dfs_lock(); for (index = 0; index < DFS_FD_MAX; index++) { fd = &(fd_table[index]); if (fd->fs == RT_NULL) continue; if (fd->fs == fs && strcmp(fd->path, mountpath) == 0) { /* found file in file descriptor table */ rt_free(fullpath); dfs_unlock(); return 0; } } dfs_unlock(); rt_free(fullpath); } return -1; }
/** * @ingroup Fd * This function will allocate a file descriptor. * * @return -1 on failed or the allocated file descriptor. */ int fd_new(void) { struct dfs_fd *d; int idx; /* lock filesystem */ dfs_lock(); /* find an empty fd entry */ #ifdef DFS_USING_STDIO for (idx = 3; idx < DFS_FD_MAX + 3 && fd_table[idx].ref_count > 0; idx++); #else for (idx = 0; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++); #endif /* can't find an empty fd entry */ #ifdef DFS_USING_STDIO if (idx == DFS_FD_MAX + 3) #else if (idx == DFS_FD_MAX) #endif { idx = -1; goto __result; } d = &(fd_table[idx]); d->ref_count = 1; __result: dfs_unlock(); return idx; }
/* +------------------------------------------------------------------------------ | Function : fd_put +------------------------------------------------------------------------------ | Description : | | Parameters : | Returns : | +------------------------------------------------------------------------------ */ void fd_put(struct dfs_fd* fd) { dfs_lock(); fd->ref_count --; /* clear this fd entry */ if ( fd->ref_count == 0 ) { rt_memset(fd, 0, sizeof(struct dfs_fd)); } dfs_unlock(); };
/* +------------------------------------------------------------------------------ | Function : dfile_raw_stat +------------------------------------------------------------------------------ | Description : get the file or directory stat description | | Parameters : path, the file or directory path | buf, the stat description will be saved in it | Returns : | +------------------------------------------------------------------------------ */ int dfile_raw_stat(const char *path, struct dfs_stat *buf) { struct dfs_filesystem* fs; char* fullpath, real_path[DFS_PATH_MAX + 1]; #ifdef DFS_USING_WORKDIR char full_path[DFS_PATH_MAX + 1]; #endif int fspathlen; fullpath = (char*)path; if ( fullpath[0] != '/' ) { #ifdef DFS_USING_WORKDIR /* build full path */ fullpath = full_path; dfs_lock(); build_fullpath(working_directory, path, fullpath); dfs_unlock(); #else #ifdef RT_USING_FINSH rt_kprintf("not support working directory, bad filename\n"); #endif return -1; #endif } if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL ) { dfs_log(DFS_DEBUG_ERROR, ("can't find mounted filesystem on this path:%s", fullpath)); return -DFS_STATUS_ENOENT; } fspathlen = strlen(fs->path); rt_memset(real_path, 0, sizeof(real_path)); if (*(fullpath + fspathlen) != '/') strcpy(real_path, "/"); strcat(real_path, fullpath + fspathlen); if (fs->ops->stat == RT_NULL) { dfs_log(DFS_DEBUG_ERROR, ("the filesystem didn't implement this function")); return -DFS_STATUS_ENOSYS; } return fs->ops->stat(fs, real_path, buf); }
/* +------------------------------------------------------------------------------ | Function : fd_get +------------------------------------------------------------------------------ | Description : | | Parameters : | Returns : | +------------------------------------------------------------------------------ */ struct dfs_fd* fd_get(int fd) { struct dfs_fd* d; #ifdef DFS_USING_STDIO if ( fd < 3 || fd > DFS_FD_MAX + 3) return RT_NULL; #else if ( fd < 0 || fd > DFS_FD_MAX ) return RT_NULL; #endif d = &fd_table[fd]; dfs_lock(); d->ref_count ++; dfs_unlock(); return d; }
/* +------------------------------------------------------------------------------ | Function : dfile_raw_open +------------------------------------------------------------------------------ | Description : | | Parameters : | Returns : | +------------------------------------------------------------------------------ */ int dfile_raw_open(struct dfs_fd* fd, const char *path, int flags) { struct dfs_filesystem* fs; char *fullpath; #ifdef DFS_USING_WORKDIR char full_path[DFS_PATH_MAX + 1]; #endif int fspathlen, result; /* parameter check */ if ( fd == RT_NULL ) return -DFS_STATUS_EINVAL; /* make sure we have an absolute path */ fullpath = (char*)path; if ( fullpath[0] != '/') { #ifdef DFS_USING_WORKDIR /* build full path */ fullpath = &full_path[0]; dfs_lock(); build_fullpath(working_directory, path, fullpath); dfs_unlock(); #else #ifdef RT_USING_FINSH rt_kprintf("bad filename"); #endif return -1; #endif } dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath)); /* find filesystem */ fs = dfs_filesystem_lookup(fullpath); if ( fs == RT_NULL ) return -DFS_STATUS_ENOENT; dfs_log(DFS_DEBUG_INFO, ("open in filesystem:%s", fs->ops->name)); fd->fs = fs; /* initilize the fd item */ fd->type = FT_REGULAR; //fd->ref_count = 1; fd->flags = flags; fd->size = 0; fd->pos = 0; fspathlen = strlen(fs->path); rt_memset(fd->path, 0, DFS_PATH_MAX + 1); if (*(fullpath + fspathlen) != '/') strcpy(fd->path, "/"); strcat(fd->path, fullpath + fspathlen); /* specific file system open routine */ if (fs->ops->open == RT_NULL) { /* clear fd */ rt_memset(fd->path, 0, DFS_PATH_MAX + 1); fd->type = FT_REGULAR; fd->ref_count = 0; fd->fs = RT_NULL; fd->flags = 0; fd->size = 0; fd->pos = 0; fd->data = RT_NULL; return -DFS_STATUS_ENOSYS; } if ((result = fs->ops->open(fd)) < 0) { /* clear fd */ fd->fs = RT_NULL; fd->flags = 0; fd->data = RT_NULL; dfs_log(DFS_DEBUG_INFO, ("open failed")); return result; } fd->flags |= DFS_F_OPEN; if ( flags & DFS_O_DIRECTORY ) { fd->type = FT_DIRECTORY; fd->flags |= DFS_F_DIRECTORY; } dfs_log(DFS_DEBUG_INFO, ("open successful")); return 0; }