📄 fatfs.c
字号:
// -------------------------------------------------------------------------// fatfs_open()// Open a file for reading or writing.static int fatfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name, int mode, cyg_file *file){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_node_t *node = NULL; fatfs_dirsearch_t ds; int err; printf( "Open mte=%p dir=%p name='%s' mode=%d file=%p", mte, dir, name, mode, file); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err == ENOENT) { if (ds.last && (mode & O_CREAT)) { fatfs_node_t node_data; // No node there, if the O_CREAT bit is set then we must // create a new one. The dir and name fields of the dirsearch // object will have been updated so we know where to put it. printf( "Creating new file '%s'", name); err = fatfs_create_file(disk, ds.dir, ds.name, ds.namelen, &node_data); if (err != ENOERR) return err; node = fatfs_node_alloc(disk, &node_data); if (NULL == node) return ENOMEM; // Update directory times ds.dir->atime = ds.dir->mtime = timeGetTime(); err = ENOERR; } } else if (err == ENOERR) { // The node exists. If the O_CREAT and O_EXCL bits are set, we // must fail the open. if ((mode & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) err = EEXIST; else node = ds.node; } if (err == ENOERR && (mode & O_TRUNC)) { // If the O_TRUNC bit is set we must clean out the file data. printf( "Truncating file"); fatfs_trunc_file(disk, node); } if (err != ENOERR) return err; // Check that we actually have a file here if (S_ISDIR(node->mode)) return EISDIR; // Make a reference to this file node fatfs_node_ref(disk, node); // Initialize the file object file->f_flag |= mode & CYG_FILE_MODE_MASK; file->f_type = CYG_FILE_TYPE_FILE; file->f_offset = (mode & O_APPEND) ? node->size : 0; file->f_data = (CYG_ADDRWORD)node; file->f_xops = 0; return ENOERR;}// -------------------------------------------------------------------------// fatfs_unlink()// Remove a file link from its directory.static int fatfs_unlink(cyg_mtab_entry *mte, cyg_dir dir, const char *name){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds; int err; printf( "Unlink mte=%p dir=%p name='%s'", mte, dir, name); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err != ENOERR) return err; if (ds.node->refcnt > 0) return EBUSY; // Delete node err = fatfs_delete_file(disk, ds.node); if (err == ENOERR) fatfs_node_free(disk, ds.node); return err;}// -------------------------------------------------------------------------// fatfs_mkdir()// Create a new directory.static intfatfs_mkdir(cyg_mtab_entry *mte, cyg_dir dir, const char *name){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds; int err; printf( "Mkdir mte=%p dir=%p name='%s'", mte, dir, name); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err == ENOENT) { if (ds.last) { fatfs_node_t node_data; // The entry does not exist, and it is the last element in // the pathname, so we can create it here. err = fatfs_create_dir(disk, ds.dir, ds.name, ds.namelen, &node_data); if (err != ENOERR) return err; fatfs_node_alloc(disk, &node_data); return ENOERR; } } else if (err == ENOERR) { return EEXIST; } return err;}// -------------------------------------------------------------------------// fatfs_rmdir()// Remove a directory.static int fatfs_rmdir(cyg_mtab_entry *mte, cyg_dir dir, const char *name){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds; int err; printf( "Rmdir mte=%p dir=%p name='%s'", mte, dir, name); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err != ENOERR) return err; // Check that this is actually a directory. if (!S_ISDIR(ds.node->mode)) return EPERM; if (ds.node->refcnt > 0) return EBUSY; err = fatfs_delete_file(disk, ds.node); if (err == ENOERR) fatfs_node_free(disk, ds.node); return err;}// -------------------------------------------------------------------------// fatfs_rename()// Rename a file/dir.static int fatfs_rename(cyg_mtab_entry *mte, cyg_dir dir1, const char *name1, cyg_dir dir2, const char *name2){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds1, ds2; int err; printf( "Rename mte=%p dir1=%p name1='%s' dir2=%p name2='%s'", mte, dir1, name1, dir2, name2); init_dirsearch(&ds1, disk, (fatfs_node_t *)dir1, name1); err = fatfs_find(&ds1); if (err != ENOERR) return err; // Protect the found nodes from being reused by the // following search fatfs_node_ref(disk, ds1.dir); fatfs_node_ref(disk, ds1.node); init_dirsearch(&ds2, disk, (fatfs_node_t *)dir2, name2); err = fatfs_find(&ds2); if (err == ENOERR && ds2.last) { err = EEXIST; goto out; } if (err == ENOENT && !ds2.last) goto out; if (ds1.node == ds2.node) { err = ENOERR; goto out; } err = fatfs_rename_file(disk, ds1.dir, ds1.node, ds2.dir, ds2.name, ds2.namelen); fatfs_node_rehash(disk, ds1.node);out: fatfs_node_unref(disk, ds1.dir); fatfs_node_unref(disk, ds1.node); if (err == ENOERR) { ds1.dir->atime = ds1.dir->mtime = ds2.dir->atime = ds2.dir->mtime = timeGetTime(); } return err;}// -------------------------------------------------------------------------// fatfs_link()// Make a new directory entry for a file.static int fatfs_link(cyg_mtab_entry *mte, cyg_dir dir1, const char *name1, cyg_dir dir2, const char *name2, int type){ printf( "Link mte=%p dir1=%p name1='%s' dir2=%p name2='%s' type=%d", mte, dir1, name1, dir2, name2, type); // Linking not supported return EINVAL;}// -------------------------------------------------------------------------// fatfs_opendir()// Open a directory for reading.static intfatfs_opendir(cyg_mtab_entry *mte, cyg_dir dir, const char *name, cyg_file *file){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds; int err; printf( "Opendir mte=%p dir=%p name='%s' file=%p", mte, dir, name, file); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err != ENOERR) return err; // Check it is really a directory. if (!S_ISDIR(ds.node->mode)) return ENOTDIR; // Make a reference to this dir node fatfs_node_ref(disk, ds.node); // Initialize the file object file->f_type = CYG_FILE_TYPE_FILE; file->f_data = (CYG_ADDRWORD)ds.node; file->f_xops = 0; file->f_offset = 0; return ENOERR;}// -------------------------------------------------------------------------// fatfs_chdir()// Change directory support.static intfatfs_chdir(cyg_mtab_entry *mte, cyg_dir dir, const char *name, cyg_dir *dir_out){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; printf( "Chdir mte=%p dir=%p dir_out=%p name=%d", mte, dir, dir_out, name); if (dir_out != NULL) { // This is a request to get a new directory pointer in // *dir_out. fatfs_dirsearch_t ds; int err; init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds); if (err != ENOERR) return err; // Check it is a directory if (!S_ISDIR(ds.node->mode)) return ENOTDIR; if (ds.node != disk->root) fatfs_node_ref(disk, ds.node); *dir_out = (cyg_dir)ds.node; } else { // If no output dir is required, this means that the mte and // dir arguments are the current cdir setting and we should // forget this fact. fatfs_node_t *node = (fatfs_node_t *)dir; if (node != disk->root) fatfs_node_unref(disk, node); } return ENOERR;}// -------------------------------------------------------------------------// fatfs_stat()// Get struct stat info for named object.static intfatfs_stat(cyg_mtab_entry *mte, cyg_dir dir, const char *name, struct stat *buf){ fatfs_disk_t *disk = (fatfs_disk_t *)mte->data; fatfs_dirsearch_t ds; int err; printf( "Stat mte=%p dir=%p name='%s' buf=%p", mte, dir, name, buf); init_dirsearch(&ds, disk, (fatfs_node_t *)dir, name); err = fatfs_find(&ds);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -