static int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path) { int result; struct uffs_stat s; /* judge file type, dir is to be delete by uffs_rmdir, others by uffs_remove */ if (uffs_lstat(path, &s) < 0) { return uffs_result_to_dfs(uffs_get_error()); } switch(s.st_mode & US_IFMT) { case US_IFREG: result = uffs_remove(path); break; case US_IFDIR: result = uffs_rmdir(path); break; default: /* unknown file type */ return -1; } if (result < 0) return uffs_result_to_dfs(uffs_get_error()); return 0; }
static int dfs_uffs_seek(struct dfs_fd* file, rt_off_t offset) { int result; /* set offset as current offset */ if (file->type == FT_DIRECTORY) { uffs_rewinddir((uffs_DIR *)(file->data)); result = uffs_seekdir((uffs_DIR *)(file->data), offset/sizeof(struct dirent)); if (result >= 0) { file->pos = offset; return offset; } } else if (file->type == FT_REGULAR) { result = uffs_seek((int)(file->data), offset, USEEK_SET); if (result >= 0) return offset; } return uffs_result_to_dfs(uffs_get_error()); }
static byte CdCmd(const unsigned char *cmd, const CLS1_ConstStdIOType *io) { /* precondition: cmd starts with "cd" */ // TODO: support relative pathnames char d_name[UFFS_PATHSIZE]; byte res = ERR_OK; if (*(cmd + sizeof("cd") - 1) == ' ') { /* space after "cd": read name */ if (UTIL1_ReadEscapedName(cmd + sizeof("cd"), (unsigned char*)d_name, sizeof(d_name), NULL, NULL, NULL) == ERR_OK) { cwd = uffs_opendir(d_name); res = uffs_get_error(); } else { CLS1_SendStr((unsigned char*) "reading directory name failed!\r\n", io->stdErr); res = ERR_FAILED; } } /* print current directory */ CLS1_SendStr((unsigned char*)cwd->obj->name, io->stdOut); CLS1_SendStr((unsigned char*) "\r\n", io->stdOut); return res; }
/* * 函数功能: 创建一个文件 * 输入参数: 文件名称 * 返回参数: */ int uffs_mkfile(const char *name) { uffs_Object *fp; int ret = 0; int err = 0; fp = uffs_GetObject(); if(fp != NULL) { if(uffs_CreateObject(fp, name, UO_CREATE) != U_SUCC) { err = fp->err; ret = -1; uffs_Perror(UFFS_ERR_NORMAL, "Create %s fail, err: %d", name, uffs_get_error()); } else { uffs_Perror(UFFS_ERR_NORMAL, "Create %s succ.", name); uffs_CloseObject(fp); ret = 0; } uffs_PutObject(fp); } else { err = UEMFILE; ret = -1; } uffs_set_error(-err); return ret; }
static URET DoTest2(void) { int fd = -1; URET ret = U_FAIL; char buf[100], buf_1[100]; fd = uffs_open("/abc/", UO_RDWR|UO_DIR); if (fd < 0) { MSGLN("Can't open dir abc, err: %d", uffs_get_error()); MSGLN("Try to create a new one..."); fd = uffs_open("/abc/", UO_RDWR|UO_CREATE|UO_DIR); if (fd < 0) { MSGLN("Can't create new dir /abc/"); goto exit_test; } else { uffs_close(fd); } } else { uffs_close(fd); } sprintf(buf, "123456789ABCDEF"); fd = uffs_open("/abc/test.txt", UO_RDONLY); if( fd < 0 ){ fd = uffs_open("/abc/test.txt", UO_RDWR|UO_CREATE); if (fd < 0) { MSGLN("Can't open /abc/test.txt"); goto exit_test; } ret = uffs_write(fd, buf, strlen(buf)); MSGLN("write %d bytes to file, content: %s", ret, buf); ret = uffs_seek(fd, 3, USEEK_SET); MSGLN("new file position: %d", ret); memset(buf_1, 0, sizeof(buf_1)); } else{ ret = uffs_seek(fd, 3, USEEK_SET); ret = uffs_read(fd, buf_1, 5); } MSGLN("read %d bytes, content: %s", ret, buf_1); if (memcmp(buf + 3, buf_1, 5) != 0) { ret = U_FAIL; } else { ret = U_SUCC; } uffs_close(fd); exit_test: return ret; }
static int dfs_uffs_flush(struct dfs_fd* file) { int fd; int result; fd = (int)(file->data); result = uffs_flush(fd); if (result < 0 ) return uffs_result_to_dfs(uffs_get_error()); return 0; }
static int dfs_uffs_rename( struct dfs_filesystem* fs, const char* oldpath, const char* newpath) { int result; result = uffs_rename(oldpath, newpath); if (result < 0) return uffs_result_to_dfs(uffs_get_error()); return 0; }
static int dfs_uffs_close(struct dfs_fd* file) { int oflag; int fd; oflag = file->flags; if (oflag & DFS_O_DIRECTORY) { /* operations about dir */ if (uffs_closedir((uffs_DIR *)(file->data)) < 0) return uffs_result_to_dfs(uffs_get_error()); return 0; } /* regular file operations */ fd = (int)(file->data); if (uffs_close(fd) == 0) return 0; return uffs_result_to_dfs(uffs_get_error()); }
static int dfs_uffs_read(struct dfs_fd * file, void* buf, rt_size_t len) { int fd; int char_read; fd = (int)(file->data); char_read = uffs_read(fd, buf, len); if (char_read < 0) return uffs_result_to_dfs(uffs_get_error()); /* update position */ file->pos = uffs_seek(fd, 0, USEEK_CUR); return char_read; }
static int dfs_uffs_write(struct dfs_fd* file, const void* buf, size_t len) { int fd; int char_write; fd = (int)(file->data); char_write = uffs_write(fd, buf, len); if (char_write < 0) return uffs_result_to_dfs(uffs_get_error()); /* update position */ file->pos = uffs_seek(fd, 0, USEEK_CUR); return char_write; }
/** mkdir <dir> */ static int cmd_mkdir(int argc, char *argv[]) { const char *name; CHK_ARGC(2, 0); name = argv[1]; if (uffs_mkdir(name) < 0) { MSGLN("Create %s fail, err: %d", name, uffs_get_error()); return -1; } else { MSGLN("Create %s succ.", name); } return 0; }
static int dfs_uffs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st) { int result; struct uffs_stat s; result = uffs_stat(path, &s); if (result < 0) return uffs_result_to_dfs(uffs_get_error()); /* convert uffs stat to dfs stat structure */ /* FIXME, these field may not be the same */ st->st_dev = 0; st->st_mode = s.st_mode; st->st_size = s.st_size; st->st_mtime = s.st_mtime; return 0; }
static int dfs_uffs_mkfs(const char* device_name) { rt_base_t index; rt_uint32_t block; struct rt_mtd_nand_device * mtd; /*1. find the device index */ for (index = 0; index < UFFS_DEVICE_MAX; index++) { if (rt_strncmp(nand_part[index].dev->parent.parent.name, device_name, RT_NAME_MAX) == 0) break; } if (index == UFFS_DEVICE_MAX) { /* can't find device driver */ rt_kprintf("can not find device driver: %s\n", device_name); return -DFS_STATUS_ENOENT; } /*2. then unmount the partition */ uffs_Mount(nand_part[index].mount_path); mtd = nand_part[index].dev; /*3. erase all blocks on the partition */ block = mtd->block_start; for (; block <= mtd->block_end; block++) { rt_mtd_nand_erase_block(mtd, block); if (rt_mtd_nand_check_block(mtd, block) != RT_EOK) { rt_kprintf("found bad block %d\n", block); rt_mtd_nand_mark_badblock(mtd, block); } } /*4. remount it */ if (init_uffs_fs(&nand_part[index]) < 0) { return uffs_result_to_dfs(uffs_get_error()); } return DFS_STATUS_OK; }
static int dfs_uffs_mount( struct dfs_filesystem* fs, unsigned long rwflag, const void* data) { rt_base_t index; uffs_MountTable * mount_part; struct rt_mtd_nand_device * dev; RT_ASSERT(rt_strlen(fs->path) < (UFFS_MOUNT_PATH_MAX-1)); dev = RT_MTD_NAND_DEVICE(fs->dev_id); /*1. find a empty entry in partition table */ for (index = 0; index < UFFS_DEVICE_MAX ; index ++) { if (nand_part[index].dev == RT_NULL) break; } if (index == UFFS_DEVICE_MAX) return -DFS_STATUS_ENOENT; /*2. fill partition structure */ nand_part[index].dev = dev; /* make a right mount path for uffs, end with '/' */ rt_snprintf(nand_part[index].mount_path, UFFS_MOUNT_PATH_MAX, "%s/", fs->path); if (nand_part[index].mount_path[1] == '/') nand_part[index].mount_path[1] = 0; mount_part = &(nand_part[index].mount_table); mount_part->mount = nand_part[index].mount_path; mount_part->dev = &(nand_part[index].uffs_dev); rt_memset(mount_part->dev, 0, sizeof(uffs_Device));//in order to make uffs happy. mount_part->dev->_private = dev; /* save dev_id into uffs */ mount_part->start_block = dev->block_start; mount_part->end_block = dev->block_end; /*3. mount uffs */ if (init_uffs_fs(&nand_part[index]) < 0) { return uffs_result_to_dfs(uffs_get_error()); } return 0; }
static int dfs_uffs_mkfs(rt_device_t dev_id) { rt_base_t index; rt_uint32_t block; struct rt_mtd_nand_device * mtd; /*1. find the device index */ for (index = 0; index < UFFS_DEVICE_MAX; index++) { if (nand_part[index].dev == (struct rt_mtd_nand_device *)dev_id) break; } if (index == UFFS_DEVICE_MAX) { /* can't find device driver */ return -ENOENT; } /*2. then unmount the partition */ uffs_Mount(nand_part[index].mount_path); mtd = nand_part[index].dev; /*3. erase all blocks on the partition */ block = mtd->block_start; for (; block <= mtd->block_end; block++) { rt_mtd_nand_erase_block(mtd, block); if (rt_mtd_nand_check_block(mtd, block) != RT_EOK) { rt_kprintf("found bad block %d\n", block); rt_mtd_nand_mark_badblock(mtd, block); } } /*4. remount it */ if (init_uffs_fs(&nand_part[index]) < 0) { return uffs_result_to_dfs(uffs_get_error()); } return RT_EOK; }
/// dir is the DOS equivalent of ls static byte DirCmd(const unsigned char *cmd, const CLS1_ConstStdIOType *io) { /* precondition: cmd starts with "dir" */ uffs_DIR *curdir = cwd; char d_name[UFFS_PATHSIZE]; byte res = ERR_OK; if (*(cmd + sizeof("dir") - 1) == ' ') { /* space after "dir": read name */ if (UTIL1_ReadEscapedName(cmd + sizeof("dir"), (unsigned char*)d_name, sizeof(d_name), NULL, NULL, NULL) == ERR_OK) { curdir = uffs_opendir(d_name); res = uffs_get_error(); } else { CLS1_SendStr((unsigned char*) "reading directory name failed!\r\n", io->stdErr); res = ERR_FAILED; } } // else use current directory struct uffs_dirent *entry; if (curdir == NULL) { CLS1_SendStr((unsigned char*) "can't open dir\r\n", io->stdErr); res = ERR_FAILED; } uffs_rewinddir(curdir); while ((entry = uffs_readdir(curdir))) { MSGLN( "%s", entry->d_name); } // unless it was cwd close it if (*(cmd + sizeof("dir") - 1) == ' ') uffs_closedir(curdir); return res; }
/** mkf <file> */ static int cmd_mkf(int argc, char *argv[]) { int fd; const char *name; int oflags = UO_RDWR | UO_CREATE; CHK_ARGC(2, 2); name = argv[1]; fd = uffs_open(name, oflags); if (fd < 0) { MSGLN("Create %s fail, err: %d", name, uffs_get_error()); return -1; } else { MSGLN("Create %s succ.", name); uffs_close(fd); } return 0; }
static int dfs_uffs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st) { int result; struct uffs_stat s; struct rt_mtd_nand_device * mtd; result = uffs_stat(path, &s); if (result < 0) return uffs_result_to_dfs(uffs_get_error()); /* convert uffs stat to dfs stat structure */ /* FIXME, these field may not be the same */ st->st_dev = 0; st->st_mode = s.st_mode; st->st_size = s.st_size; st->st_mtime = s.st_mtime; mtd = RT_MTD_NAND_DEVICE(fs->dev_id); st->st_blksize = mtd->page_size; return 0; }
static byte DeleteCmd(const unsigned char *cmd, const CLS1_ConstStdIOType *io) { /* precondition: cmd starts with "delete" */ char f_name[UFFS_PATHSIZE]; byte res = ERR_OK; if (UTIL1_ReadEscapedName(cmd + sizeof("delete"), (unsigned char*)f_name, sizeof(f_name), NULL, NULL, NULL) == ERR_OK) { res = uffs_remove( f_name ); if(uffs_get_error() == UEISDIR) { res = uffs_rmdir( f_name ); } } else { CmdUsageError(cmd, (unsigned char*) "delete fileName", io); res = ERR_FAILED; } return res; }
/* return the size of struct dirent*/ static int dfs_uffs_getdents( struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count) { rt_uint32_t index; char * file_path; struct dirent* d; uffs_DIR* dir; struct uffs_dirent * uffs_d; dir = (uffs_DIR*)(file->data); RT_ASSERT(dir != RT_NULL); /* round count, count is always 1 */ count = (count / sizeof(struct dirent)) * sizeof(struct dirent); if (count == 0) return -DFS_STATUS_EINVAL; /* allocate file name */ file_path = rt_malloc(FILE_PATH_MAX); if (file_path == RT_NULL) return -DFS_STATUS_ENOMEM; index = 0; /* usually, the while loop should only be looped only once! */ while (1) { struct uffs_stat s; d = dirp + index; uffs_d = uffs_readdir(dir); if (uffs_d == RT_NULL) { rt_free(file_path); return (uffs_result_to_dfs(uffs_get_error())); } if (file->path[0] == '/' && !(file->path[1] == 0)) rt_snprintf(file_path, FILE_PATH_MAX, "%s/%s", file->path, uffs_d->d_name); else rt_strncpy(file_path, uffs_d->d_name, FILE_PATH_MAX); uffs_stat(file_path, &s); switch(s.st_mode & US_IFMT) /* file type mark */ { case US_IFREG: /* directory */ d->d_type = DFS_DT_REG; break; case US_IFDIR: /* regular file */ d->d_type = DFS_DT_DIR; break; case US_IFLNK: /* symbolic link */ case US_IREAD: /* read permission */ case US_IWRITE:/* write permission */ default: d->d_type = DFS_DT_UNKNOWN; break; } /* write the rest args of struct dirent* dirp */ d->d_namlen = rt_strlen(uffs_d->d_name); d->d_reclen = (rt_uint16_t)sizeof(struct dirent); rt_strncpy(d->d_name, uffs_d->d_name, rt_strlen(uffs_d->d_name) + 1); index ++; if (index * sizeof(struct dirent) >= count) break; } /* free file name buf */ rt_free(file_path); if (index == 0) return uffs_result_to_dfs(uffs_get_error()); file->pos += index * sizeof(struct dirent); return index * sizeof(struct dirent); }
static int dfs_uffs_open(struct dfs_fd* file) { int fd; int oflag, mode; char * file_path; oflag = file->flags; if (oflag & DFS_O_DIRECTORY) /* operations about dir */ { uffs_DIR * dir; if (oflag & DFS_O_CREAT) /* create a dir*/ { if (uffs_mkdir(file->path) < 0) return uffs_result_to_dfs(uffs_get_error()); } /* open dir */ file_path = rt_malloc(FILE_PATH_MAX); if(file_path == RT_NULL) return -DFS_STATUS_ENOMEM; if (file->path[0] == '/' && !(file->path[1] == 0)) rt_snprintf(file_path, FILE_PATH_MAX, "%s/", file->path); else { file_path[0] = '/'; file_path[1] = 0; } dir = uffs_opendir(file_path); if (dir == RT_NULL) { rt_free(file_path); return uffs_result_to_dfs(uffs_get_error()); } /* save this pointer,will used by dfs_uffs_getdents*/ file->data = dir; rt_free(file_path); return DFS_STATUS_OK; } /* regular file operations */ /* int uffs_open(const char *name, int oflag, ...); what is this? * uffs_open can open dir!! **/ mode = 0; if (oflag & DFS_O_RDONLY) mode |= UO_RDONLY; if (oflag & DFS_O_WRONLY) mode |= UO_WRONLY; if (oflag & DFS_O_RDWR) mode |= UO_RDWR; /* Opens the file, if it is existing. If not, a new file is created. */ if (oflag & DFS_O_CREAT) mode |= UO_CREATE; /* Creates a new file. If the file is existing, it is truncated and overwritten. */ if (oflag & DFS_O_TRUNC) mode |= UO_TRUNC; /* Creates a new file. The function fails if the file is already existing. */ if (oflag & DFS_O_EXCL) mode |= UO_EXCL; fd = uffs_open(file->path, mode); if (fd < 0) { return uffs_result_to_dfs(uffs_get_error()); } /* save this pointer, it will be used when calling read()£¬write(), * flush(), seek(), and will be free when calling close()*/ file->data = (void *)fd; file->pos = uffs_seek(fd, 0, USEEK_CUR); file->size = uffs_seek(fd, 0, USEEK_END); uffs_seek(fd, file->pos, USEEK_SET); if (oflag & DFS_O_APPEND) { file->pos = uffs_seek(fd, 0, USEEK_END); } return 0; }