feature (proc): implemented file descriptors

This commit is contained in:
antifallobst 2023-04-18 19:06:25 +02:00
parent af95bd2ba1
commit c14013efaa
2 changed files with 151 additions and 0 deletions

View File

@ -0,0 +1,41 @@
// This file is part of noxos and licensed under the MIT open source license
#ifndef NOX_FILE_DESCRIPTOR_H
#define NOX_FILE_DESCRIPTOR_H
#include "utils/stdtypes.h"
#include "utils/bitmap.h"
#include "drivers/fs/vfs.h"
#define FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE 2
typedef int32_t file_descriptor_t;
typedef enum {
FILE_DESCRIPTOR_INVALID = -1
} std_file_descriptors_E;
typedef struct file_descriptor_array_chunk_T file_descriptor_array_chunk_T;
struct file_descriptor_array_chunk_T {
file_descriptor_array_chunk_T* prev;
file_descriptor_array_chunk_T* next;
vfs_node_T* lookup [FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE];
bitmap_T bitmap;
uint32_t amount;
};
typedef struct {
file_descriptor_array_chunk_T* base_chunk;
} file_descriptor_array_T;
file_descriptor_t file_descriptor_request (file_descriptor_array_T* fd_array, vfs_node_T* node);
vfs_node_T* file_descriptor_resolve (file_descriptor_array_T* fd_array, file_descriptor_t fd);
void file_descriptor_free (file_descriptor_array_T* fd_array, file_descriptor_t fd);
file_descriptor_array_T* file_descriptor_array_alloc ();
void file_descriptor_array_destruct (file_descriptor_array_T* fd_array);
file_descriptor_array_chunk_T* file_descriptor_array_chunk_alloc (file_descriptor_array_chunk_T* prev);
void file_descriptor_array_chunk_destruct (file_descriptor_array_chunk_T* chunk);
#endif //NOX_FILE_DESCRIPTOR_H

View File

@ -0,0 +1,110 @@
// This file is part of noxos and licensed under the MIT open source license
#include "proc/file_descriptor.h"
#include "utils/memory.h"
file_descriptor_t file_descriptor_request(file_descriptor_array_T* fd_array, vfs_node_T* node) {
file_descriptor_t fd = 0;
file_descriptor_array_chunk_T* chunk = fd_array->base_chunk;
while (chunk->amount == FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE) {
if (chunk->next == NULL) file_descriptor_array_chunk_alloc(chunk);
chunk = chunk->next;
fd +=FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE;
}
for (int i = 0; i < FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE; i++) {
if (bitmap_get(&chunk->bitmap, i)) continue;
bitmap_set(&chunk->bitmap, i, true);
chunk->lookup[i] = node;
chunk->amount++;
fd += i;
return fd;
}
// this should never happen
return FILE_DESCRIPTOR_INVALID;
}
vfs_node_T* file_descriptor_resolve(file_descriptor_array_T* fd_array, file_descriptor_t fd) {
if (fd == FILE_DESCRIPTOR_INVALID) return NULL;
uint32_t chunk_selector = fd / FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE;
file_descriptor_array_chunk_T* chunk = fd_array->base_chunk;
for (int i = 0; i < chunk_selector; i++) {
chunk = chunk->next;
if (chunk == NULL) return NULL;
}
uint32_t fd_selector = fd % FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE;
// Check if the file descriptor exists
if (!bitmap_get(&chunk->bitmap, fd_selector)) return NULL;
return chunk->lookup[fd_selector];
}
void file_descriptor_free(file_descriptor_array_T* fd_array, file_descriptor_t fd) {
if (fd == FILE_DESCRIPTOR_INVALID) return;
uint32_t chunk_selector = fd / FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE;
file_descriptor_array_chunk_T* chunk = fd_array->base_chunk;
for (int i = 0; i < chunk_selector; i++) {
chunk = chunk->next;
if (chunk == NULL) return;
}
bitmap_set(&chunk->bitmap, fd % FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE, false);
chunk->amount--;
}
file_descriptor_array_T* file_descriptor_array_alloc() {
file_descriptor_array_T* fd_array = memory_allocate(sizeof(file_descriptor_array_T));
fd_array->base_chunk = file_descriptor_array_chunk_alloc(NULL);
return fd_array;
}
void file_descriptor_array_destruct(file_descriptor_array_T* fd_array) {
file_descriptor_array_chunk_T* chunk = fd_array->base_chunk;
file_descriptor_array_chunk_T* next_chunk;
while (chunk != NULL) {
next_chunk = chunk->next;
file_descriptor_array_chunk_destruct(chunk);
chunk = next_chunk;
}
memory_free(fd_array);
}
file_descriptor_array_chunk_T* file_descriptor_array_chunk_alloc(file_descriptor_array_chunk_T* prev) {
file_descriptor_array_chunk_T* chunk = memory_allocate(sizeof(file_descriptor_array_chunk_T));
chunk->bitmap = bitmap_init(FILE_DESCRIPTOR_ARRAY_CHUNK_SIZE);
chunk->amount = 0;
chunk->prev = prev;
if (chunk->prev != NULL) {
chunk->prev->next = chunk;
}
return chunk;
}
void file_descriptor_array_chunk_destruct(file_descriptor_array_chunk_T* chunk) {
if (chunk->prev != NULL) {
chunk->prev->next = NULL;
}
bitmap_destruct(&chunk->bitmap);
memory_free(chunk);
}