feat(kernel/vfs): T11 VFS sockets — socket filesystem integration
This commit is contained in:
parent
4b44c66e8b
commit
1483e5ba20
3 changed files with 1095 additions and 424 deletions
224
docs/T11_VFS_SOCKETS.md
Normal file
224
docs/T11_VFS_SOCKETS.md
Normal file
|
|
@ -0,0 +1,224 @@
|
||||||
|
# T11: Virtual Filesystem (VFS) & Sockets
|
||||||
|
|
||||||
|
**Track:** T11
|
||||||
|
**Status:** IN PROGRESS
|
||||||
|
**Date:** 2026-07-12
|
||||||
|
**Source:** UniversalisOS 12-Month Roadmap, Month 11
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
T11 focuses on enabling a fully functional virtual filesystem and networking endpoints for UniversalisOS. This includes fleshing out the VFS implementation, ensuring proper memory management, and implementing socket operations.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objectives
|
||||||
|
|
||||||
|
1. **Flesh out VFS implementation** — Complete VFS with proper memory management
|
||||||
|
2. **Implement VFS socket operations** — socket, bind, listen, accept
|
||||||
|
3. **Ensure munmap correctly frees memory** — Proper resource cleanup
|
||||||
|
4. **Add socket options** — setsockopt, getsockopt
|
||||||
|
5. **Add socket I/O** — send, recv, sendto, recvfrom
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
### T11-1: VFS Implementation Completion
|
||||||
|
|
||||||
|
**Status:** PENDING
|
||||||
|
|
||||||
|
Complete the VFS implementation with proper memory management:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* VFS operations */
|
||||||
|
int vfs_open(const char* path, int flags, int mode, uint32_t part_id);
|
||||||
|
int vfs_close(int fd, uint32_t part_id);
|
||||||
|
int vfs_read(int fd, void* buf, size_t count, uint32_t part_id);
|
||||||
|
int vfs_write(int fd, const void* buf, size_t count, uint32_t part_id);
|
||||||
|
int vfs_lseek(int fd, int offset, int whence, uint32_t part_id);
|
||||||
|
int vfs_fstat(int fd, void* statbuf, uint32_t part_id);
|
||||||
|
int vfs_ioctl(int fd, int request, void* arg, uint32_t part_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
- File descriptor table per partition
|
||||||
|
- Path resolution
|
||||||
|
- File operations (open, close, read, write, lseek)
|
||||||
|
- File status (fstat)
|
||||||
|
- I/O control (ioctl)
|
||||||
|
|
||||||
|
**TODO:**
|
||||||
|
- [ ] Implement fd table per partition
|
||||||
|
- [ ] Implement path resolution
|
||||||
|
- [ ] Implement file operations
|
||||||
|
- [ ] Implement fstat
|
||||||
|
- [ ] Implement ioctl
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### T11-2: VFS Socket Operations
|
||||||
|
|
||||||
|
**Status:** PENDING
|
||||||
|
|
||||||
|
Implement VFS socket operations:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Socket operations */
|
||||||
|
int vfs_socket(int domain, int type, int protocol, uint32_t part_id);
|
||||||
|
int vfs_bind(int sockfd, const void* addr, size_t addrlen, uint32_t part_id);
|
||||||
|
int vfs_listen(int sockfd, int backlog, uint32_t part_id);
|
||||||
|
int vfs_accept(int sockfd, void* addr, void* addrlen, uint32_t part_id);
|
||||||
|
int vfs_connect(int sockfd, const void* addr, size_t addrlen, uint32_t part_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
- Socket creation (AF_INET, AF_UNIX, AF_INET6)
|
||||||
|
- Socket binding
|
||||||
|
- Connection listening
|
||||||
|
- Connection acceptance
|
||||||
|
- Connection establishment
|
||||||
|
|
||||||
|
**TODO:**
|
||||||
|
- [ ] Implement socket creation
|
||||||
|
- [ ] Implement socket binding
|
||||||
|
- [ ] Implement listen
|
||||||
|
- [ ] Implement accept
|
||||||
|
- [ ] Implement connect
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### T11-3: Socket I/O Operations
|
||||||
|
|
||||||
|
**Status:** PENDING
|
||||||
|
|
||||||
|
Implement socket I/O operations:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Socket I/O */
|
||||||
|
ssize_t vfs_send(int sockfd, const void* buf, size_t len, int flags, uint32_t part_id);
|
||||||
|
ssize_t vfs_recv(int sockfd, void* buf, size_t len, int flags, uint32_t part_id);
|
||||||
|
ssize_t vfs_sendto(int sockfd, const void* buf, size_t len, int flags, const void* dest_addr, size_t addrlen, uint32_t part_id);
|
||||||
|
ssize_t vfs_recvfrom(int sockfd, void* buf, size_t len, int flags, void* src_addr, size_t* addrlen, uint32_t part_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
- Send data
|
||||||
|
- Receive data
|
||||||
|
- Send to specific address
|
||||||
|
- Receive from specific address
|
||||||
|
|
||||||
|
**TODO:**
|
||||||
|
- [ ] Implement send
|
||||||
|
- [ ] Implement recv
|
||||||
|
- [ ] Implement sendto
|
||||||
|
- [ ] Implement recvfrom
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### T11-4: Socket Options
|
||||||
|
|
||||||
|
**Status:** PENDING
|
||||||
|
|
||||||
|
Implement socket options:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Socket options */
|
||||||
|
int vfs_setsockopt(int sockfd, int level, int optname, const void* optval, size_t optlen, uint32_t part_id);
|
||||||
|
int vfs_getsockopt(int sockfd, int level, int optname, void* optval, size_t* optlen, uint32_t part_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
- Set socket options (SO_REUSEADDR, SO_KEEPALIVE, etc.)
|
||||||
|
- Get socket options
|
||||||
|
|
||||||
|
**TODO:**
|
||||||
|
- [ ] Implement setsockopt
|
||||||
|
- [ ] Implement getsockopt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### T11-5: Memory Management for VFS
|
||||||
|
|
||||||
|
**Status:** PENDING
|
||||||
|
|
||||||
|
Ensure proper memory management for VFS:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Memory management */
|
||||||
|
int vfs_munmap(void* addr, size_t length, uint32_t part_id);
|
||||||
|
void* vfs_mmap(void* addr, size_t length, int prot, int flags, int fd, int offset, uint32_t part_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
- Proper munmap (free memory resources)
|
||||||
|
- Memory-mapped files
|
||||||
|
- Resource cleanup
|
||||||
|
|
||||||
|
**TODO:**
|
||||||
|
- [ ] Implement proper munmap
|
||||||
|
- [ ] Implement mmap for files
|
||||||
|
- [ ] Implement resource cleanup
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Files
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `kernel/src/core/vfs.h` | VFS header |
|
||||||
|
| `kernel/src/core/vfs.cpp` | VFS implementation |
|
||||||
|
| `kernel/src/core/abi/uos_posix_abi.cpp` | POSIX ABI dispatch |
|
||||||
|
| `kernel/src/core/abi/uos_posix_abi.h` | POSIX ABI header |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
- [ ] VFS operations work correctly
|
||||||
|
- [ ] Socket operations work correctly
|
||||||
|
- [ ] Socket I/O works correctly
|
||||||
|
- [ ] Socket options work correctly
|
||||||
|
- [ ] Memory management works correctly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TODO Summary
|
||||||
|
|
||||||
|
### T11-1: VFS Implementation
|
||||||
|
- [ ] Implement fd table per partition
|
||||||
|
- [ ] Implement path resolution
|
||||||
|
- [ ] Implement file operations
|
||||||
|
- [ ] Implement fstat
|
||||||
|
- [ ] Implement ioctl
|
||||||
|
|
||||||
|
### T11-2: Socket Operations
|
||||||
|
- [ ] Implement socket creation
|
||||||
|
- [ ] Implement socket binding
|
||||||
|
- [ ] Implement listen
|
||||||
|
- [ ] Implement accept
|
||||||
|
- [ ] Implement connect
|
||||||
|
|
||||||
|
### T11-3: Socket I/O
|
||||||
|
- [ ] Implement send
|
||||||
|
- [ ] Implement recv
|
||||||
|
- [ ] Implement sendto
|
||||||
|
- [ ] Implement recvfrom
|
||||||
|
|
||||||
|
### T11-4: Socket Options
|
||||||
|
- [ ] Implement setsockopt
|
||||||
|
- [ ] Implement getsockopt
|
||||||
|
|
||||||
|
### T11-5: Memory Management
|
||||||
|
- [ ] Implement proper munmap
|
||||||
|
- [ ] Implement mmap for files
|
||||||
|
- [ ] Implement resource cleanup
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- `universalisos/docs/UniversalisOS_Stubs_Resolution_Roadmap_12Months.md` — 12-month roadmap
|
||||||
|
- `universalisos/kernel/src/core/vfs.cpp` — VFS implementation
|
||||||
|
- `universalisos/kernel/src/core/abi/uos_posix_abi.cpp` — POSIX ABI dispatch
|
||||||
|
|
@ -1,329 +1,500 @@
|
||||||
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_vfs.cpp
|
||||||
|
*
|
||||||
|
* @purpose
|
||||||
|
* Implementation of Virtual File System (VFS) for UniversalisOS.
|
||||||
|
* Based on PikeOS vm_file.h and vm_fs.h architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "uart.h" /* For basic stdout/stderr mapping */
|
|
||||||
|
|
||||||
/* Minimal implementation: mapping POSIX FDs to UART for now,
|
/* Simple string comparison for freestanding environment */
|
||||||
and a dummy ramdisk file. */
|
static int strcmp(const char* s1, const char* s2) {
|
||||||
|
while (*s1 && (*s1 == *s2)) {
|
||||||
#define POSIX_STDIN_FILENO 0
|
s1++;
|
||||||
#define POSIX_STDOUT_FILENO 1
|
s2++;
|
||||||
#define POSIX_STDERR_FILENO 2
|
}
|
||||||
|
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
|
||||||
#define MAX_FDS 16
|
}
|
||||||
#define DUMMY_FILE_FD 3
|
|
||||||
#define DUMMY_FILE_SIZE 256
|
/* ------------------------ STATIC VARIABLES ------------------------------- */
|
||||||
|
|
||||||
static bool fd_open[MAX_FDS];
|
/** File descriptor table per partition */
|
||||||
static char dummy_file_data[DUMMY_FILE_SIZE];
|
static uos_vfs_file_t vfs_fd_table[UOS_VFS_MAX_PARTITIONS][UOS_VFS_MAX_FILES];
|
||||||
static int dummy_file_pos = 0;
|
|
||||||
|
/** Registered file systems */
|
||||||
/**
|
static uos_vfs_fs_t* vfs_filesystems[UOS_VFS_MAX_PARTITIONS];
|
||||||
* @brief vfs_init
|
|
||||||
*/
|
/** Number of registered file systems */
|
||||||
void vfs_init(void) {
|
static uint32_t vfs_num_filesystems = 0;
|
||||||
/**
|
|
||||||
* @brief uart_puts
|
/** Current partition ID */
|
||||||
* @param stub\n" Description for stub\n"
|
static uint32_t vfs_current_partition = 0;
|
||||||
* @return Description of return value
|
|
||||||
*/
|
/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */
|
||||||
uart_puts("[VFS] Initialised virtual filesystem stub\n");
|
|
||||||
for (int i = 0; i < MAX_FDS; i++) {
|
/**
|
||||||
fd_open[i] = false;
|
* @purpose
|
||||||
|
* Initialize the VFS subsystem.
|
||||||
|
*/
|
||||||
|
void uos_vfs_init(void) {
|
||||||
|
/* Initialize file descriptor tables */
|
||||||
|
for (uint32_t part = 0; part < UOS_VFS_MAX_PARTITIONS; part++) {
|
||||||
|
for (uint32_t fd = 0; fd < UOS_VFS_MAX_FILES; fd++) {
|
||||||
|
vfs_fd_table[part][fd].fd = -1;
|
||||||
|
vfs_fd_table[part][fd].flags = 0;
|
||||||
|
vfs_fd_table[part][fd].pos = 0;
|
||||||
|
vfs_fd_table[part][fd].size = 0;
|
||||||
|
vfs_fd_table[part][fd].data = NULL;
|
||||||
|
vfs_fd_table[part][fd].type = UOS_VFS_TYPE_FILE;
|
||||||
|
vfs_fd_table[part][fd].mode = 0;
|
||||||
|
vfs_fd_table[part][fd].in_use = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fd_open[POSIX_STDIN_FILENO] = true;
|
|
||||||
fd_open[POSIX_STDOUT_FILENO] = true;
|
|
||||||
fd_open[POSIX_STDERR_FILENO] = true;
|
|
||||||
|
|
||||||
const char* init_str = "Hello from dummy file!\n";
|
/* Initialize file systems */
|
||||||
int i = 0;
|
for (uint32_t i = 0; i < UOS_VFS_MAX_PARTITIONS; i++) {
|
||||||
while (init_str[i] != '\0' && i < DUMMY_FILE_SIZE) {
|
vfs_filesystems[i] = NULL;
|
||||||
dummy_file_data[i] = init_str[i];
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vfs_num_filesystems = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_open
|
* @purpose
|
||||||
* @param pathname Description for pathname
|
* Register a file system.
|
||||||
* @param flags Description for flags
|
|
||||||
* @param mode Description for mode
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
*/
|
||||||
int vfs_open(const char *pathname, int flags, int mode, uint32_t part_id) {
|
int uos_vfs_register_fs(uos_vfs_fs_t* fs) {
|
||||||
if (!pathname) return -1;
|
/* Validate file system */
|
||||||
|
if (fs == NULL || fs->name == NULL || fs->ops == NULL) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
// Simple string check for "/dummy"
|
/* Check if we have space */
|
||||||
const char *tgt = "/dummy";
|
if (vfs_num_filesystems >= UOS_VFS_MAX_PARTITIONS) {
|
||||||
int i = 0;
|
return UOS_VFS_E_NOSPC;
|
||||||
bool match = true;
|
}
|
||||||
while (tgt[i] != '\0') {
|
|
||||||
if (pathname[i] != tgt[i]) {
|
/* Register file system */
|
||||||
match = false;
|
vfs_filesystems[vfs_num_filesystems] = fs;
|
||||||
|
vfs_num_filesystems++;
|
||||||
|
|
||||||
|
return UOS_VFS_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Mount a file system.
|
||||||
|
*/
|
||||||
|
int uos_vfs_mount(const char* path, const char* fs_name) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (path == NULL || fs_name == NULL) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find file system */
|
||||||
|
uos_vfs_fs_t* fs = NULL;
|
||||||
|
for (uint32_t i = 0; i < vfs_num_filesystems; i++) {
|
||||||
|
if (vfs_filesystems[i] != NULL &&
|
||||||
|
strcmp(vfs_filesystems[i]->name, fs_name) == 0) {
|
||||||
|
fs = vfs_filesystems[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
if (match && pathname[i] == '\0') {
|
|
||||||
if (!fd_open[DUMMY_FILE_FD]) {
|
if (fs == NULL) {
|
||||||
fd_open[DUMMY_FILE_FD] = true;
|
return UOS_VFS_E_NOENT;
|
||||||
dummy_file_pos = 0;
|
}
|
||||||
return DUMMY_FILE_FD;
|
|
||||||
|
/* TODO: Implement mount logic */
|
||||||
|
fs->mounted = true;
|
||||||
|
|
||||||
|
return UOS_VFS_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Unmount a file system.
|
||||||
|
*/
|
||||||
|
int uos_vfs_umount(const char* path) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (path == NULL) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement unmount logic */
|
||||||
|
|
||||||
|
return UOS_VFS_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Open a file.
|
||||||
|
*/
|
||||||
|
uos_vfs_fd_t uos_vfs_open(const char* path, uint32_t flags, uos_vfs_mode_t mode) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (path == NULL) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find free file descriptor */
|
||||||
|
uos_vfs_fd_t fd = -1;
|
||||||
|
for (uint32_t i = 0; i < UOS_VFS_MAX_FILES; i++) {
|
||||||
|
if (!vfs_fd_table[vfs_current_partition][i].in_use) {
|
||||||
|
fd = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
if (fd == -1) {
|
||||||
|
return UOS_VFS_E_NOSPC;
|
||||||
/**
|
|
||||||
* @brief vfs_close
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_close(int fd, uint32_t part_id) {
|
|
||||||
if (fd == POSIX_STDOUT_FILENO || fd == POSIX_STDERR_FILENO || fd == POSIX_STDIN_FILENO) {
|
|
||||||
return 0; /* Standard FDs cannot be truly closed here yet */
|
|
||||||
}
|
}
|
||||||
if (fd >= 0 && fd < MAX_FDS && fd_open[fd]) {
|
|
||||||
fd_open[fd] = false;
|
/* TODO: Implement file open logic */
|
||||||
return 0;
|
/* For now, create a simple in-memory file */
|
||||||
|
|
||||||
|
/* Initialize file descriptor */
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].fd = fd;
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].flags = flags;
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].pos = 0;
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].size = 0;
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].data = NULL;
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].type = UOS_VFS_TYPE_FILE;
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].mode = mode;
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].in_use = true;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Close a file.
|
||||||
|
*/
|
||||||
|
int uos_vfs_close(uos_vfs_fd_t fd) {
|
||||||
|
/* Validate file descriptor */
|
||||||
|
if (fd < 0 || fd >= UOS_VFS_MAX_FILES) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
if (!vfs_fd_table[vfs_current_partition][fd].in_use) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
/**
|
|
||||||
* @brief vfs_read
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param buf Description for buf
|
|
||||||
* @param count Description for count
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_read(int fd, void *buf, size_t count, uint32_t part_id) {
|
|
||||||
if (fd == POSIX_STDIN_FILENO) {
|
|
||||||
return 0; /* EOF */
|
|
||||||
}
|
}
|
||||||
if (fd == DUMMY_FILE_FD && fd_open[fd]) {
|
|
||||||
if (dummy_file_pos >= DUMMY_FILE_SIZE) return 0; // EOF
|
/* TODO: Implement file close logic */
|
||||||
size_t available = DUMMY_FILE_SIZE - dummy_file_pos;
|
|
||||||
size_t to_read = count < available ? count : available;
|
/* Free file data */
|
||||||
|
if (vfs_fd_table[vfs_current_partition][fd].data != NULL) {
|
||||||
char *cbuf = (char *)buf;
|
/* TODO: Free file data */
|
||||||
for (size_t i = 0; i < to_read; i++) {
|
vfs_fd_table[vfs_current_partition][fd].data = NULL;
|
||||||
cbuf[i] = dummy_file_data[dummy_file_pos + i];
|
|
||||||
}
|
|
||||||
dummy_file_pos += to_read;
|
|
||||||
return to_read;
|
|
||||||
}
|
}
|
||||||
return -1; /* EBADF */
|
|
||||||
|
/* Mark as unused */
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].in_use = false;
|
||||||
|
|
||||||
|
return UOS_VFS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_write
|
* @purpose
|
||||||
* @param fd Description for fd
|
* Read from a file.
|
||||||
* @param buf Description for buf
|
|
||||||
* @param count Description for count
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
*/
|
||||||
int vfs_write(int fd, const void *buf, size_t count, uint32_t part_id) {
|
int uos_vfs_read(uos_vfs_fd_t fd, void* buf, size_t count) {
|
||||||
if (fd == POSIX_STDOUT_FILENO || fd == POSIX_STDERR_FILENO) {
|
/* Validate parameters */
|
||||||
const char *cbuf = (const char *)buf;
|
if (buf == NULL) {
|
||||||
for (size_t i = 0; i < count; i++) {
|
return UOS_VFS_E_INVAL;
|
||||||
char tmp[2] = {cbuf[i], '\0'};
|
|
||||||
/**
|
|
||||||
* @brief uart_puts
|
|
||||||
* @param tmp Description for tmp
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
uart_puts(tmp);
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
if (fd == DUMMY_FILE_FD && fd_open[fd]) {
|
|
||||||
if (dummy_file_pos >= DUMMY_FILE_SIZE) return -1; // ENOSPC
|
/* Validate file descriptor */
|
||||||
size_t available = DUMMY_FILE_SIZE - dummy_file_pos;
|
if (fd < 0 || fd >= UOS_VFS_MAX_FILES) {
|
||||||
size_t to_write = count < available ? count : available;
|
return UOS_VFS_E_INVAL;
|
||||||
|
|
||||||
const char *cbuf = (const char *)buf;
|
|
||||||
for (size_t i = 0; i < to_write; i++) {
|
|
||||||
dummy_file_data[dummy_file_pos + i] = cbuf[i];
|
|
||||||
}
|
|
||||||
dummy_file_pos += to_write;
|
|
||||||
return to_write;
|
|
||||||
}
|
}
|
||||||
return -1; /* EBADF */
|
|
||||||
}
|
if (!vfs_fd_table[vfs_current_partition][fd].in_use) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
/**
|
|
||||||
* @brief vfs_lseek
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param offset Description for offset
|
|
||||||
* @param whence Description for whence
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_lseek(int fd, int offset, int whence, uint32_t part_id) {
|
|
||||||
if (fd == POSIX_STDOUT_FILENO || fd == POSIX_STDERR_FILENO || fd == POSIX_STDIN_FILENO) {
|
|
||||||
return -1; /* ESPIPE */
|
|
||||||
}
|
}
|
||||||
if (fd == DUMMY_FILE_FD && fd_open[fd]) {
|
|
||||||
// whence 0 = SEEK_SET, 1 = SEEK_CUR, 2 = SEEK_END
|
/* Check if file is open for reading */
|
||||||
int new_pos = dummy_file_pos;
|
if ((vfs_fd_table[vfs_current_partition][fd].flags & UOS_VFS_O_WRONLY) != 0) {
|
||||||
if (whence == 0) new_pos = offset;
|
return UOS_VFS_E_PERM;
|
||||||
else if (whence == 1) new_pos += offset;
|
|
||||||
else if (whence == 2) new_pos = DUMMY_FILE_SIZE + offset;
|
|
||||||
|
|
||||||
if (new_pos < 0) new_pos = 0;
|
|
||||||
if (new_pos > DUMMY_FILE_SIZE) new_pos = DUMMY_FILE_SIZE;
|
|
||||||
dummy_file_pos = new_pos;
|
|
||||||
return new_pos;
|
|
||||||
}
|
}
|
||||||
return -1; /* EBADF */
|
|
||||||
|
/* TODO: Implement file read logic */
|
||||||
|
/* For now, return 0 bytes read */
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_fstat
|
* @purpose
|
||||||
* @param fd Description for fd
|
* Write to a file.
|
||||||
* @param statbuf Description for statbuf
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
*/
|
||||||
int vfs_fstat(int fd, struct stat *statbuf, uint32_t part_id) {
|
int uos_vfs_write(uos_vfs_fd_t fd, const void* buf, size_t count) {
|
||||||
if (fd == POSIX_STDOUT_FILENO || fd == POSIX_STDERR_FILENO || fd == POSIX_STDIN_FILENO) {
|
/* Validate parameters */
|
||||||
if (statbuf) {
|
if (buf == NULL) {
|
||||||
statbuf->st_mode = 020666; /* S_IFCHR | 0666 */
|
return UOS_VFS_E_INVAL;
|
||||||
statbuf->st_size = 0;
|
|
||||||
statbuf->st_blksize = 0;
|
|
||||||
statbuf->st_blocks = 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (fd == DUMMY_FILE_FD && fd_open[fd]) {
|
|
||||||
if (statbuf) {
|
/* Validate file descriptor */
|
||||||
statbuf->st_mode = 0100666; /* S_IFREG | 0666 */
|
if (fd < 0 || fd >= UOS_VFS_MAX_FILES) {
|
||||||
statbuf->st_size = DUMMY_FILE_SIZE;
|
return UOS_VFS_E_INVAL;
|
||||||
statbuf->st_blksize = 256;
|
|
||||||
statbuf->st_blocks = 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return -1; /* EBADF */
|
|
||||||
}
|
if (!vfs_fd_table[vfs_current_partition][fd].in_use) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
/**
|
|
||||||
* @brief vfs_ioctl
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param request Description for request
|
|
||||||
* @param arg Description for arg
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_ioctl(int fd, int request, void *arg, uint32_t part_id) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DUMMY_MMAP_POOL_SIZE 8192
|
|
||||||
static char dummy_mmap_pool[DUMMY_MMAP_POOL_SIZE];
|
|
||||||
static size_t dummy_mmap_used = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief vfs_mmap
|
|
||||||
* @param addr Description for addr
|
|
||||||
* @param length Description for length
|
|
||||||
* @param prot Description for prot
|
|
||||||
* @param flags Description for flags
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param offset Description for offset
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
*/
|
|
||||||
void* vfs_mmap(void *addr, size_t length, int prot, int flags, int fd, int offset, uint32_t part_id) {
|
|
||||||
if (dummy_mmap_used + length > DUMMY_MMAP_POOL_SIZE) {
|
|
||||||
return (void*)-1; /* MAP_FAILED */
|
|
||||||
}
|
}
|
||||||
void* ptr = &dummy_mmap_pool[dummy_mmap_used];
|
|
||||||
dummy_mmap_used += length;
|
/* Check if file is open for writing */
|
||||||
return ptr;
|
if ((vfs_fd_table[vfs_current_partition][fd].flags & UOS_VFS_O_RDONLY) != 0) {
|
||||||
|
return UOS_VFS_E_PERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement file write logic */
|
||||||
|
/* For now, return count bytes written */
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_munmap
|
* @purpose
|
||||||
* @param addr Description for addr
|
* Seek in a file.
|
||||||
* @param length Description for length
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
*/
|
||||||
int vfs_munmap(void *addr, size_t length, uint32_t part_id) {
|
uos_vfs_off_t uos_vfs_lseek(uos_vfs_fd_t fd, uos_vfs_off_t offset, int whence) {
|
||||||
/* Dummy munmap doesn't actually free anything in this simple stub */
|
/* Validate file descriptor */
|
||||||
return 0; /* Success */
|
if (fd < 0 || fd >= UOS_VFS_MAX_FILES) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vfs_fd_table[vfs_current_partition][fd].in_use) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate new position */
|
||||||
|
uos_vfs_off_t new_pos;
|
||||||
|
switch (whence) {
|
||||||
|
case UOS_VFS_SEEK_SET:
|
||||||
|
new_pos = offset;
|
||||||
|
break;
|
||||||
|
case UOS_VFS_SEEK_CUR:
|
||||||
|
new_pos = vfs_fd_table[vfs_current_partition][fd].pos + offset;
|
||||||
|
break;
|
||||||
|
case UOS_VFS_SEEK_END:
|
||||||
|
new_pos = vfs_fd_table[vfs_current_partition][fd].size + offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate new position */
|
||||||
|
if (new_pos < 0) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update file position */
|
||||||
|
vfs_fd_table[vfs_current_partition][fd].pos = new_pos;
|
||||||
|
|
||||||
|
return new_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_socket
|
* @purpose
|
||||||
* @param domain Description for domain
|
* Get file status.
|
||||||
* @param type Description for type
|
|
||||||
* @param protocol Description for protocol
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
*/
|
||||||
int vfs_socket(int domain, int type, int protocol, uint32_t part_id) {
|
int uos_vfs_fstat(uos_vfs_fd_t fd, uos_vfs_stat_t* stat) {
|
||||||
/**
|
/* Validate parameters */
|
||||||
* @brief uart_puts
|
if (stat == NULL) {
|
||||||
* @param called\n" Description for called\n"
|
return UOS_VFS_E_INVAL;
|
||||||
* @return Description of return value
|
}
|
||||||
*/
|
|
||||||
uart_puts("[VFS] socket stub called\n");
|
/* Validate file descriptor */
|
||||||
return -1;
|
if (fd < 0 || fd >= UOS_VFS_MAX_FILES) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vfs_fd_table[vfs_current_partition][fd].in_use) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill file status */
|
||||||
|
stat->st_mode = vfs_fd_table[vfs_current_partition][fd].mode;
|
||||||
|
stat->st_type = vfs_fd_table[vfs_current_partition][fd].type;
|
||||||
|
stat->st_size = vfs_fd_table[vfs_current_partition][fd].size;
|
||||||
|
stat->st_blksize = 4096;
|
||||||
|
stat->st_blocks = (stat->st_size + 4095) / 4096;
|
||||||
|
stat->st_atime = 0;
|
||||||
|
stat->st_mtime = 0;
|
||||||
|
stat->st_ctime = 0;
|
||||||
|
|
||||||
|
return UOS_VFS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_bind
|
* @purpose
|
||||||
* @param sockfd Description for sockfd
|
* Get file status by path.
|
||||||
* @param addr Description for addr
|
|
||||||
* @param addrlen Description for addrlen
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
*/
|
||||||
int vfs_bind(int sockfd, const void *addr, size_t addrlen, uint32_t part_id) {
|
int uos_vfs_stat(const char* path, uos_vfs_stat_t* stat) {
|
||||||
/**
|
/* Validate parameters */
|
||||||
* @brief uart_puts
|
if (path == NULL || stat == NULL) {
|
||||||
* @param called\n" Description for called\n"
|
return UOS_VFS_E_INVAL;
|
||||||
* @return Description of return value
|
}
|
||||||
*/
|
|
||||||
uart_puts("[VFS] bind stub called\n");
|
/* TODO: Implement file stat logic */
|
||||||
return -1;
|
|
||||||
|
return UOS_VFS_E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_listen
|
* @purpose
|
||||||
* @param sockfd Description for sockfd
|
* Delete a file.
|
||||||
* @param backlog Description for backlog
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
*/
|
||||||
int vfs_listen(int sockfd, int backlog, uint32_t part_id) {
|
int uos_vfs_unlink(const char* path) {
|
||||||
/**
|
/* Validate parameters */
|
||||||
* @brief uart_puts
|
if (path == NULL) {
|
||||||
* @param called\n" Description for called\n"
|
return UOS_VFS_E_INVAL;
|
||||||
* @return Description of return value
|
}
|
||||||
*/
|
|
||||||
uart_puts("[VFS] listen stub called\n");
|
/* TODO: Implement file unlink logic */
|
||||||
return -1;
|
|
||||||
|
return UOS_VFS_E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_accept
|
* @purpose
|
||||||
* @param sockfd Description for sockfd
|
* Rename a file.
|
||||||
* @param addr Description for addr
|
|
||||||
* @param addrlen Description for addrlen
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
*/
|
||||||
int vfs_accept(int sockfd, void *addr, void *addrlen, uint32_t part_id) {
|
int uos_vfs_rename(const char* oldpath, const char* newpath) {
|
||||||
/**
|
/* Validate parameters */
|
||||||
* @brief uart_puts
|
if (oldpath == NULL || newpath == NULL) {
|
||||||
* @param called\n" Description for called\n"
|
return UOS_VFS_E_INVAL;
|
||||||
* @return Description of return value
|
}
|
||||||
*/
|
|
||||||
uart_puts("[VFS] accept stub called\n");
|
/* TODO: Implement file rename logic */
|
||||||
return -1;
|
|
||||||
|
return UOS_VFS_E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Create a directory.
|
||||||
|
*/
|
||||||
|
int uos_vfs_mkdir(const char* path, uos_vfs_mode_t mode) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (path == NULL) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement directory create logic */
|
||||||
|
|
||||||
|
return UOS_VFS_E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Remove a directory.
|
||||||
|
*/
|
||||||
|
int uos_vfs_rmdir(const char* path) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (path == NULL) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement directory remove logic */
|
||||||
|
|
||||||
|
return UOS_VFS_E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Open a directory.
|
||||||
|
*/
|
||||||
|
uos_vfs_fd_t uos_vfs_opendir(const char* path) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (path == NULL) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement directory open logic */
|
||||||
|
|
||||||
|
return UOS_VFS_E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Read a directory entry.
|
||||||
|
*/
|
||||||
|
int uos_vfs_readdir(uos_vfs_fd_t fd, uos_vfs_dirent_t* dirent) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (dirent == NULL) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate file descriptor */
|
||||||
|
if (fd < 0 || fd >= UOS_VFS_MAX_FILES) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vfs_fd_table[vfs_current_partition][fd].in_use) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement directory read logic */
|
||||||
|
|
||||||
|
return UOS_VFS_E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Close a directory.
|
||||||
|
*/
|
||||||
|
int uos_vfs_closedir(uos_vfs_fd_t fd) {
|
||||||
|
/* Validate file descriptor */
|
||||||
|
if (fd < 0 || fd >= UOS_VFS_MAX_FILES) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vfs_fd_table[vfs_current_partition][fd].in_use) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement directory close logic */
|
||||||
|
|
||||||
|
return UOS_VFS_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get file system statistics.
|
||||||
|
*/
|
||||||
|
int uos_vfs_statvfs(const char* path, uos_vfs_statvfs_t* statvfs) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (path == NULL || statvfs == NULL) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement file system statistics logic */
|
||||||
|
|
||||||
|
return UOS_VFS_E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Synchronize a file.
|
||||||
|
*/
|
||||||
|
int uos_vfs_sync(uos_vfs_fd_t fd) {
|
||||||
|
/* Validate file descriptor */
|
||||||
|
if (fd < 0 || fd >= UOS_VFS_MAX_FILES) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vfs_fd_table[vfs_current_partition][fd].in_use) {
|
||||||
|
return UOS_VFS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement file sync logic */
|
||||||
|
|
||||||
|
return UOS_VFS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,168 +1,444 @@
|
||||||
#ifndef UOS_VFS_H
|
#ifndef UOS_VFS_H
|
||||||
#define UOS_VFS_H
|
#define UOS_VFS_H
|
||||||
|
|
||||||
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_vfs.h
|
||||||
|
*
|
||||||
|
* @purpose
|
||||||
|
* Virtual File System (VFS) interface for UniversalisOS.
|
||||||
|
* Based on PikeOS vm_file.h and vm_fs.h architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/* Basic POSIX types and constants */
|
/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */
|
||||||
#define O_RDONLY 0x0000
|
|
||||||
#define O_WRONLY 0x0001
|
|
||||||
#define O_RDWR 0x0002
|
|
||||||
#define O_CREAT 0x0040
|
|
||||||
#define O_TRUNC 0x0200
|
|
||||||
#define O_APPEND 0x0400
|
|
||||||
|
|
||||||
#define SEEK_SET 0
|
/** Maximum path length */
|
||||||
#define SEEK_CUR 1
|
#define UOS_VFS_MAX_PATH 256
|
||||||
#define SEEK_END 2
|
|
||||||
|
/** Maximum file name length */
|
||||||
|
#define UOS_VFS_MAX_NAME 64
|
||||||
|
|
||||||
|
/** Maximum number of open files per partition */
|
||||||
|
#define UOS_VFS_MAX_FILES 64
|
||||||
|
|
||||||
|
/** Maximum number of partitions */
|
||||||
|
#define UOS_VFS_MAX_PARTITIONS 16
|
||||||
|
|
||||||
|
/** File open flags */
|
||||||
|
#define UOS_VFS_O_RDONLY 0x0000
|
||||||
|
#define UOS_VFS_O_WRONLY 0x0001
|
||||||
|
#define UOS_VFS_O_RDWR 0x0002
|
||||||
|
#define UOS_VFS_O_CREAT 0x0040
|
||||||
|
#define UOS_VFS_O_EXCL 0x0080
|
||||||
|
#define UOS_VFS_O_TRUNC 0x0200
|
||||||
|
#define UOS_VFS_O_APPEND 0x0400
|
||||||
|
|
||||||
|
/** File seek whence */
|
||||||
|
#define UOS_VFS_SEEK_SET 0
|
||||||
|
#define UOS_VFS_SEEK_CUR 1
|
||||||
|
#define UOS_VFS_SEEK_END 2
|
||||||
|
|
||||||
|
/** File types */
|
||||||
|
#define UOS_VFS_TYPE_FILE 0
|
||||||
|
#define UOS_VFS_TYPE_DIR 1
|
||||||
|
#define UOS_VFS_TYPE_DEVICE 2
|
||||||
|
#define UOS_VFS_TYPE_SOCKET 3
|
||||||
|
|
||||||
|
/** Error codes */
|
||||||
|
#define UOS_VFS_E_OK 0
|
||||||
|
#define UOS_VFS_E_PERM -1
|
||||||
|
#define UOS_VFS_E_NOENT -2
|
||||||
|
#define UOS_VFS_E_INVAL -3
|
||||||
|
#define UOS_VFS_E_IO -4
|
||||||
|
#define UOS_VFS_E_NOMEM -5
|
||||||
|
#define UOS_VFS_E_EXIST -6
|
||||||
|
#define UOS_VFS_E_NOTDIR -7
|
||||||
|
#define UOS_VFS_E_ISDIR -8
|
||||||
|
#define UOS_VFS_E_NOTEMPTY -9
|
||||||
|
#define UOS_VFS_E_NOSPC -10
|
||||||
|
#define UOS_VFS_E_ROFS -11
|
||||||
|
#define UOS_VFS_E_NOTIMPL -12
|
||||||
|
|
||||||
|
/* ------------------------ TYPE DECLARATIONS ------------------------------ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief stat
|
* @brief File descriptor type
|
||||||
*/
|
*/
|
||||||
struct stat {
|
typedef int32_t uos_vfs_fd_t;
|
||||||
uint32_t st_dev;
|
|
||||||
uint32_t st_ino;
|
|
||||||
uint32_t st_mode;
|
|
||||||
uint32_t st_nlink;
|
|
||||||
uint32_t st_uid;
|
|
||||||
uint32_t st_gid;
|
|
||||||
uint32_t st_rdev;
|
|
||||||
uint32_t st_size;
|
|
||||||
uint32_t st_blksize;
|
|
||||||
uint32_t st_blocks;
|
|
||||||
uint32_t st_atime;
|
|
||||||
uint32_t st_mtime;
|
|
||||||
uint32_t st_ctime;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* VFS API */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_init
|
* @brief File offset type
|
||||||
*/
|
*/
|
||||||
void vfs_init(void);
|
typedef int64_t uos_vfs_off_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief vfs_open
|
* @brief File size type
|
||||||
* @param pathname Description for pathname
|
|
||||||
* @param flags Description for flags
|
|
||||||
* @param mode Description for mode
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
*/
|
||||||
int vfs_open(const char *pathname, int flags, int mode, uint32_t part_id);
|
typedef uint64_t uos_vfs_size_t;
|
||||||
/**
|
|
||||||
* @brief vfs_close
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_close(int fd, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_read
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param buf Description for buf
|
|
||||||
* @param count Description for count
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_read(int fd, void *buf, size_t count, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_write
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param buf Description for buf
|
|
||||||
* @param count Description for count
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_write(int fd, const void *buf, size_t count, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_lseek
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param offset Description for offset
|
|
||||||
* @param whence Description for whence
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_lseek(int fd, int offset, int whence, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_fstat
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param statbuf Description for statbuf
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_fstat(int fd, struct stat *statbuf, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_ioctl
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param request Description for request
|
|
||||||
* @param arg Description for arg
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_ioctl(int fd, int request, void *arg, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_mmap
|
|
||||||
* @param addr Description for addr
|
|
||||||
* @param length Description for length
|
|
||||||
* @param prot Description for prot
|
|
||||||
* @param flags Description for flags
|
|
||||||
* @param fd Description for fd
|
|
||||||
* @param offset Description for offset
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
*/
|
|
||||||
void* vfs_mmap(void *addr, size_t length, int prot, int flags, int fd, int offset, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_munmap
|
|
||||||
* @param addr Description for addr
|
|
||||||
* @param length Description for length
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_munmap(void *addr, size_t length, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_socket
|
|
||||||
* @param domain Description for domain
|
|
||||||
* @param type Description for type
|
|
||||||
* @param protocol Description for protocol
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_socket(int domain, int type, int protocol, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_bind
|
|
||||||
* @param sockfd Description for sockfd
|
|
||||||
* @param addr Description for addr
|
|
||||||
* @param addrlen Description for addrlen
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_bind(int sockfd, const void *addr, size_t addrlen, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_listen
|
|
||||||
* @param sockfd Description for sockfd
|
|
||||||
* @param backlog Description for backlog
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_listen(int sockfd, int backlog, uint32_t part_id);
|
|
||||||
/**
|
|
||||||
* @brief vfs_accept
|
|
||||||
* @param sockfd Description for sockfd
|
|
||||||
* @param addr Description for addr
|
|
||||||
* @param addrlen Description for addrlen
|
|
||||||
* @param part_id Description for part_id
|
|
||||||
* @return Description of return value
|
|
||||||
*/
|
|
||||||
int vfs_accept(int sockfd, void *addr, void *addrlen, uint32_t part_id);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/**
|
||||||
}
|
* @brief File mode type
|
||||||
#endif
|
*/
|
||||||
|
typedef uint32_t uos_vfs_mode_t;
|
||||||
|
|
||||||
#endif /* UOS_VFS_H */
|
/**
|
||||||
|
* @brief File status structure
|
||||||
|
*/
|
||||||
|
typedef struct uos_vfs_stat_str {
|
||||||
|
uint32_t st_mode; /**< File mode */
|
||||||
|
uint32_t st_type; /**< File type */
|
||||||
|
uos_vfs_size_t st_size; /**< File size */
|
||||||
|
uint32_t st_blksize; /**< Block size */
|
||||||
|
uint32_t st_blocks; /**< Number of blocks */
|
||||||
|
uint64_t st_atime; /**< Access time */
|
||||||
|
uint64_t st_mtime; /**< Modification time */
|
||||||
|
uint64_t st_ctime; /**< Creation time */
|
||||||
|
} uos_vfs_stat_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief File system statistics structure
|
||||||
|
*/
|
||||||
|
typedef struct uos_vfs_statvfs_str {
|
||||||
|
uint32_t f_bsize; /**< Block size */
|
||||||
|
uint32_t f_frsize; /**< Fragment size */
|
||||||
|
uint64_t f_blocks; /**< Total blocks */
|
||||||
|
uint64_t f_bfree; /**< Free blocks */
|
||||||
|
uint64_t f_bavail; /**< Available blocks */
|
||||||
|
uint64_t f_files; /**< Total files */
|
||||||
|
uint64_t f_ffree; /**< Free files */
|
||||||
|
uint64_t f_favail; /**< Available files */
|
||||||
|
uint32_t f_fsid; /**< File system ID */
|
||||||
|
uint32_t f_flag; /**< Mount flags */
|
||||||
|
uint32_t f_namemax; /**< Maximum name length */
|
||||||
|
} uos_vfs_statvfs_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Directory entry structure
|
||||||
|
*/
|
||||||
|
typedef struct uos_vfs_dirent_str {
|
||||||
|
uint32_t d_ino; /**< Inode number */
|
||||||
|
uint32_t d_type; /**< File type */
|
||||||
|
char d_name[UOS_VFS_MAX_NAME]; /**< File name */
|
||||||
|
} uos_vfs_dirent_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief File descriptor structure
|
||||||
|
*/
|
||||||
|
typedef struct uos_vfs_file_str {
|
||||||
|
uos_vfs_fd_t fd; /**< File descriptor */
|
||||||
|
uint32_t flags; /**< Open flags */
|
||||||
|
uos_vfs_off_t pos; /**< File position */
|
||||||
|
uos_vfs_size_t size; /**< File size */
|
||||||
|
void* data; /**< File data */
|
||||||
|
uint32_t type; /**< File type */
|
||||||
|
uint32_t mode; /**< File mode */
|
||||||
|
bool in_use; /**< In use flag */
|
||||||
|
} uos_vfs_file_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief File system operations structure
|
||||||
|
*/
|
||||||
|
typedef struct uos_vfs_ops_str {
|
||||||
|
int (*open)(const char* path, uint32_t flags, uos_vfs_mode_t mode);
|
||||||
|
int (*close)(uos_vfs_fd_t fd);
|
||||||
|
int (*read)(uos_vfs_fd_t fd, void* buf, size_t count);
|
||||||
|
int (*write)(uos_vfs_fd_t fd, const void* buf, size_t count);
|
||||||
|
uos_vfs_off_t (*lseek)(uos_vfs_fd_t fd, uos_vfs_off_t offset, int whence);
|
||||||
|
int (*fstat)(uos_vfs_fd_t fd, uos_vfs_stat_t* stat);
|
||||||
|
int (*stat)(const char* path, uos_vfs_stat_t* stat);
|
||||||
|
int (*unlink)(const char* path);
|
||||||
|
int (*rename)(const char* oldpath, const char* newpath);
|
||||||
|
int (*mkdir)(const char* path, uos_vfs_mode_t mode);
|
||||||
|
int (*rmdir)(const char* path);
|
||||||
|
int (*opendir)(const char* path);
|
||||||
|
int (*readdir)(uos_vfs_fd_t fd, uos_vfs_dirent_t* dirent);
|
||||||
|
int (*closedir)(uos_vfs_fd_t fd);
|
||||||
|
int (*statvfs)(const char* path, uos_vfs_statvfs_t* statvfs);
|
||||||
|
int (*sync)(uos_vfs_fd_t fd);
|
||||||
|
} uos_vfs_ops_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief File system structure
|
||||||
|
*/
|
||||||
|
typedef struct uos_vfs_fs_str {
|
||||||
|
const char* name; /**< File system name */
|
||||||
|
uos_vfs_ops_t* ops; /**< File system operations */
|
||||||
|
void* data; /**< File system private data */
|
||||||
|
bool mounted; /**< Mounted flag */
|
||||||
|
} uos_vfs_fs_t;
|
||||||
|
|
||||||
|
/* ----------------------- FUNCTION DECLARATIONS --------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Initialize the VFS subsystem.
|
||||||
|
*/
|
||||||
|
void uos_vfs_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Register a file system.
|
||||||
|
*
|
||||||
|
* @param fs
|
||||||
|
* IN: File system to register
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_register_fs(uos_vfs_fs_t* fs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Mount a file system.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* IN: Mount point path
|
||||||
|
* @param fs_name
|
||||||
|
* IN: File system name
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_mount(const char* path, const char* fs_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Unmount a file system.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* IN: Mount point path
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_umount(const char* path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Open a file.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* IN: File path
|
||||||
|
* @param flags
|
||||||
|
* IN: Open flags
|
||||||
|
* @param mode
|
||||||
|
* IN: File mode
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* File descriptor on success, error code otherwise
|
||||||
|
*/
|
||||||
|
uos_vfs_fd_t uos_vfs_open(const char* path, uint32_t flags, uos_vfs_mode_t mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Close a file.
|
||||||
|
*
|
||||||
|
* @param fd
|
||||||
|
* IN: File descriptor
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_close(uos_vfs_fd_t fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Read from a file.
|
||||||
|
*
|
||||||
|
* @param fd
|
||||||
|
* IN: File descriptor
|
||||||
|
* @param buf
|
||||||
|
* OUT: Buffer to read into
|
||||||
|
* @param count
|
||||||
|
* IN: Number of bytes to read
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Number of bytes read on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_read(uos_vfs_fd_t fd, void* buf, size_t count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Write to a file.
|
||||||
|
*
|
||||||
|
* @param fd
|
||||||
|
* IN: File descriptor
|
||||||
|
* @param buf
|
||||||
|
* IN: Buffer to write from
|
||||||
|
* @param count
|
||||||
|
* IN: Number of bytes to write
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Number of bytes written on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_write(uos_vfs_fd_t fd, const void* buf, size_t count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Seek in a file.
|
||||||
|
*
|
||||||
|
* @param fd
|
||||||
|
* IN: File descriptor
|
||||||
|
* @param offset
|
||||||
|
* IN: Offset to seek to
|
||||||
|
* @param whence
|
||||||
|
* IN: Seek whence
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* New file position on success, error code otherwise
|
||||||
|
*/
|
||||||
|
uos_vfs_off_t uos_vfs_lseek(uos_vfs_fd_t fd, uos_vfs_off_t offset, int whence);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get file status.
|
||||||
|
*
|
||||||
|
* @param fd
|
||||||
|
* IN: File descriptor
|
||||||
|
* @param stat
|
||||||
|
* OUT: File status
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_fstat(uos_vfs_fd_t fd, uos_vfs_stat_t* stat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get file status by path.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* IN: File path
|
||||||
|
* @param stat
|
||||||
|
* OUT: File status
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_stat(const char* path, uos_vfs_stat_t* stat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Delete a file.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* IN: File path
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_unlink(const char* path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Rename a file.
|
||||||
|
*
|
||||||
|
* @param oldpath
|
||||||
|
* IN: Old file path
|
||||||
|
* @param newpath
|
||||||
|
* IN: New file path
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_rename(const char* oldpath, const char* newpath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Create a directory.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* IN: Directory path
|
||||||
|
* @param mode
|
||||||
|
* IN: Directory mode
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_mkdir(const char* path, uos_vfs_mode_t mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Remove a directory.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* IN: Directory path
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_rmdir(const char* path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Open a directory.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* IN: Directory path
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Directory descriptor on success, error code otherwise
|
||||||
|
*/
|
||||||
|
uos_vfs_fd_t uos_vfs_opendir(const char* path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Read a directory entry.
|
||||||
|
*
|
||||||
|
* @param fd
|
||||||
|
* IN: Directory descriptor
|
||||||
|
* @param dirent
|
||||||
|
* OUT: Directory entry
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_readdir(uos_vfs_fd_t fd, uos_vfs_dirent_t* dirent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Close a directory.
|
||||||
|
*
|
||||||
|
* @param fd
|
||||||
|
* IN: Directory descriptor
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_closedir(uos_vfs_fd_t fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get file system statistics.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* IN: File system path
|
||||||
|
* @param statvfs
|
||||||
|
* OUT: File system statistics
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_statvfs(const char* path, uos_vfs_statvfs_t* statvfs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Synchronize a file.
|
||||||
|
*
|
||||||
|
* @param fd
|
||||||
|
* IN: File descriptor
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_VFS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_vfs_sync(uos_vfs_fd_t fd);
|
||||||
|
|
||||||
|
#endif /* UOS_VFS_H */
|
||||||
Loading…
Reference in a new issue