93 lines
2.0 KiB
C
93 lines
2.0 KiB
C
#include "vfs.h"
|
|
|
|
#include "lib/memory.h"
|
|
|
|
#define MAX_PROCESS_FDS 32
|
|
file_t fd_table[MAX_PROCESS_FDS];
|
|
|
|
vfs_node_t* root = NULL;
|
|
|
|
vfs_node_t* vfs_create_root() {
|
|
root = kalloc(sizeof(vfs_node_t));
|
|
memset((uint8_t*)root, 0, sizeof(vfs_node_t));
|
|
|
|
strcpy(root->name, "root");
|
|
|
|
root->flags |= VFS_DIRECTORY;
|
|
root->size = 0;
|
|
root->finddir = NULL;
|
|
|
|
return root;
|
|
}
|
|
|
|
void mount(vfs_node_t* _mnt, vfs_node_t* _fs) {
|
|
if (!_fs || !_mnt || !(_mnt->flags & VFS_DIRECTORY)) return;
|
|
_mnt->mnt = _fs;
|
|
}
|
|
|
|
static vfs_node_t* lookup(const char* path) {
|
|
if (path[0] != '/') return NULL;
|
|
vfs_node_t* current = root;
|
|
|
|
if (current->mnt) {
|
|
current = current->mnt;
|
|
}
|
|
|
|
const char* cmp = path + 1;
|
|
if (*cmp == '\0') return current;
|
|
|
|
if (current->finddir) {
|
|
return current->finddir(current, cmp);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int open(const char* _path, int flags) {
|
|
vfs_node_t* file = lookup(_path);
|
|
if (!file) return -1;
|
|
for (int i = 0; i < MAX_PROCESS_FDS; i++) {
|
|
if (fd_table[i].node == NULL) {
|
|
fd_table[i].node = file;
|
|
fd_table[i].offset = 0;
|
|
fd_table[i].flags = flags;
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int read(int fd, void* buf, size_t sz) {
|
|
if (fd < 0 || fd >= MAX_PROCESS_FDS || !fd_table[fd].node) {
|
|
return -1;
|
|
}
|
|
|
|
file_t* file = &fd_table[fd];
|
|
|
|
if (!file->node->read) return -1;
|
|
|
|
uint32_t bytes_read = file->node->read(file->node, file->offset, sz, buf);
|
|
file->offset += bytes_read;
|
|
|
|
return bytes_read;
|
|
}
|
|
|
|
int fstat(int fd, file_t* dst) {
|
|
if (fd < 0 || fd >= MAX_PROCESS_FDS || !fd_table[fd].node) {
|
|
return 0;
|
|
}
|
|
|
|
file_t* src = &fd_table[fd];
|
|
memcpy(src, dst, sizeof(file_t));
|
|
return 1;
|
|
}
|
|
|
|
int fseek(int fd, size_t offset) {
|
|
if (fd < 0 || fd >= MAX_PROCESS_FDS || !fd_table[fd].node) {
|
|
return 0;
|
|
}
|
|
|
|
file_t* file = &fd_table[fd];
|
|
file->offset = offset;
|
|
return 1;
|
|
}
|