#include #include #include #include #include #include #include #include "dir.h" #include "path.h" #include "tree.h" struct mufs_file { struct mufs *fs; struct mufs_tree *tree; int mode; uint32_t va; }; int mufs_create(struct mufs *fs, const char *path) { return mufs_mkpath(fs, path, MUFS_FILE); } struct mufs_file *mufs_open(struct mufs *fs, const char *path, int mode) { struct mufs_file *file; if (!(file = malloc(sizeof(*file)))) return NULL; file->fs = fs; if (!(file->tree = resolve_path(fs, path))) goto err_free_file; file->mode = mode; file->va = 0; return file; err_free_file: free(file); return NULL; } void mufs_close(struct mufs_file *file) { if (!file) return; free(file); } long mufs_seek(struct mufs_file *file, long offset, int whence) { if (!file) return -1; switch (whence) { case SEEK_SET: break; case SEEK_CUR: offset = file->va + offset; break; case SEEK_END: offset = file->tree->file_size; break; default: return -1; } if (offset > file->tree->file_size || offset >= UINT32_MAX) return -1; file->va = offset; return offset; } size_t mufs_read(struct mufs_file *file, void *data, size_t len) { size_t ret; if (!file || !data || !len) return 0; if (!(file->mode & MUFS_READ)) return 0; if (!(ret = mufs_tree_read(file->tree, data, file->va, len))) return 0; file->va += ret; return ret; } size_t mufs_write(struct mufs_file *file, const void *data, size_t len) { size_t ret; if (!file || !data || !len) return 0; if (!(file->mode & MUFS_WRITE)) return 0; if (file->mode & MUFS_APPEND) file->va = file->tree->file_size; if (!(ret = mufs_tree_write(file->tree, (void *)data, file->va, len))) return 0; file->va += ret; if (file->tree->file_size <= file->va && mufs_sync_tree(file->tree) < 0) return 0; return ret; }