summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/drivers/mouse.c2
-rw-r--r--kernel/fs/ext2.c6
-rw-r--r--kernel/fs/fifo.c8
-rw-r--r--kernel/fs/tmpfs.c17
-rw-r--r--kernel/fs/vfs.c43
-rw-r--r--kernel/lib/list.c21
-rw-r--r--kernel/lib/list.h2
-rw-r--r--kernel/sched/scheduler.c45
-rw-r--r--kernel/sched/scheduler.h4
-rw-r--r--kernel/socket.c16
10 files changed, 84 insertions, 80 deletions
diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c
index 7096ae9..87a4955 100644
--- a/kernel/drivers/mouse.c
+++ b/kernel/drivers/mouse.c
@@ -43,7 +43,7 @@ void add_mouse(void) {
// Don't look at this
int fd = vfs_open("/dev/mouse", O_RDWR, 0);
mouse_fd = get_vfs_fd(fd, NULL);
- current_task->file_descriptors[fd] = NULL;
+ list_set(&current_task->file_descriptors, fd, NULL);
}
void what(registers_t *r) {
diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c
index 167c2aa..e815e79 100644
--- a/kernel/fs/ext2.c
+++ b/kernel/fs/ext2.c
@@ -806,8 +806,10 @@ vfs_inode_t *ext2_mount(void) {
cache = kcalloc(3000, sizeof(struct BLOCK_CACHE));
// TODO: Can this be done better? Maybe create a seperate function in
// the VFS?
- mount_fd = current_task->file_descriptors[fd];
- current_task->file_descriptors[fd] = NULL;
+ mount_fd = get_vfs_fd(fd, NULL);
+ // Remove the FD from the current task
+ // FIXME: This is a hacky solution
+ list_set(&current_task->file_descriptors, fd, NULL);
parse_superblock();
return vfs_create_inode(
0 /*inode_num*/, 0 /*type*/, 0 /*has_data*/, 0 /*can_write*/,
diff --git a/kernel/fs/fifo.c b/kernel/fs/fifo.c
index f2ad933..a0a9248 100644
--- a/kernel/fs/fifo.c
+++ b/kernel/fs/fifo.c
@@ -1,4 +1,5 @@
#include "fifo.h"
+#include <assert.h>
#include <errno.h>
#define STARTING_SIZE 4096
@@ -63,13 +64,12 @@ FIFO_FILE *create_fifo_object(void) {
}
int create_fifo(void) {
- int fd_n = 0;
- for (; current_task->file_descriptors[fd_n]; fd_n++)
- ;
vfs_fd_t *fd = kmalloc(sizeof(vfs_fd_t));
+ int fd_n;
+ assert(list_add(&current_task->file_descriptors, fd, &fd_n));
+
fd->flags = O_RDWR | O_NONBLOCK;
- current_task->file_descriptors[fd_n] = fd;
fd->inode = kmalloc(sizeof(vfs_inode_t));
fd->inode->internal_object = (void *)create_fifo_object();
diff --git a/kernel/fs/tmpfs.c b/kernel/fs/tmpfs.c
index f8e6712..e31a08e 100644
--- a/kernel/fs/tmpfs.c
+++ b/kernel/fs/tmpfs.c
@@ -37,6 +37,7 @@ int tmp_read(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
}
void dual_pipe(int fd[2]) {
+ vfs_fd_t *fd_ptrs[2];
for (int i = 0; i < 2; i++) {
tmp_inode *pipe = kmalloc(sizeof(tmp_inode));
pipe->fifo = create_fifo_object();
@@ -53,12 +54,12 @@ void dual_pipe(int fd[2]) {
NULL /*send_signal*/);
assert(inode);
- vfs_fd_t *fd_ptr;
- fd[i] = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, 0 /*is_tty*/, inode, &fd_ptr);
+ fd[i] =
+ vfs_create_fd(O_RDWR | O_NONBLOCK, 0, 0 /*is_tty*/, inode, &fd_ptrs[i]);
assert(-1 != fd[i]);
}
- vfs_inode_t *f_inode = current_task->file_descriptors[fd[0]]->inode;
- vfs_inode_t *s_inode = current_task->file_descriptors[fd[1]]->inode;
+ vfs_inode_t *f_inode = fd_ptrs[0]->inode;
+ vfs_inode_t *s_inode = fd_ptrs[1]->inode;
tmp_inode *f_pipe = f_inode->internal_object;
tmp_inode *s_pipe = s_inode->internal_object;
f_pipe->read_inode = s_inode;
@@ -68,6 +69,7 @@ void dual_pipe(int fd[2]) {
}
void pipe(int fd[2]) {
+ vfs_fd_t *fd_ptrs[2];
for (int i = 0; i < 2; i++) {
tmp_inode *pipe = kmalloc(sizeof(tmp_inode));
pipe->fifo = create_fifo_object();
@@ -84,12 +86,11 @@ void pipe(int fd[2]) {
NULL /*send_signal*/);
assert(inode);
- vfs_fd_t *fd_ptr;
- fd[i] = vfs_create_fd(O_RDWR, 0, 0 /*is_tty*/, inode, &fd_ptr);
+ fd[i] = vfs_create_fd(O_RDWR, 0, 0 /*is_tty*/, inode, &fd_ptrs[i]);
assert(-1 != fd[i]);
}
- vfs_inode_t *f_inode = current_task->file_descriptors[fd[0]]->inode;
- vfs_inode_t *s_inode = current_task->file_descriptors[fd[1]]->inode;
+ vfs_inode_t *f_inode = fd_ptrs[0]->inode;
+ vfs_inode_t *s_inode = fd_ptrs[1]->inode;
tmp_inode *f_pipe = f_inode->internal_object;
tmp_inode *s_pipe = s_inode->internal_object;
f_pipe->read_inode = s_inode;
diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c
index c167e8f..bff0cb6 100644
--- a/kernel/fs/vfs.c
+++ b/kernel/fs/vfs.c
@@ -12,17 +12,12 @@ vfs_fd_t *get_vfs_fd(int fd, process_t *p) {
if (!p) {
p = current_task;
}
- if (fd >= 100) {
- klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN);
- dump_backtrace(12);
- return NULL;
- }
- if (fd < 0) {
- klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN);
- dump_backtrace(12);
+
+ vfs_fd_t *r;
+ if (!list_get(&p->file_descriptors, fd, (void **)&r)) {
return NULL;
}
- return p->file_descriptors[fd];
+ return r;
}
vfs_inode_t *vfs_create_inode(
@@ -62,16 +57,6 @@ vfs_inode_t *vfs_create_inode(
int vfs_create_fd(int flags, int mode, int is_tty, vfs_inode_t *inode,
vfs_fd_t **fd) {
- process_t *p = (process_t *)current_task;
- int i;
- for (i = 0; i < 100; i++) {
- if (!p->file_descriptors[i]) {
- break;
- }
- }
- if (p->file_descriptors[i]) {
- return -1;
- }
inode->ref++;
vfs_fd_t *r = kmalloc(sizeof(vfs_fd_t));
r->flags = flags;
@@ -80,11 +65,12 @@ int vfs_create_fd(int flags, int mode, int is_tty, vfs_inode_t *inode,
r->reference_count = 1;
r->is_tty = is_tty;
r->offset = 0;
- p->file_descriptors[i] = r;
if (fd) {
*fd = r;
}
- return i;
+ int index;
+ list_add(&current_task->file_descriptors, r, &index);
+ return index;
}
int vfs_create_file(const char *file) {
@@ -304,7 +290,7 @@ int vfs_close_process(process_t *p, int fd) {
assert(0 < fd_ptr->reference_count);
// Remove process reference
fd_ptr->reference_count--;
- p->file_descriptors[fd] = 0;
+ list_set(&p->file_descriptors, fd, NULL);
// If no references left then free the contents
if (0 == fd_ptr->reference_count) {
if (fd_ptr->inode->close) {
@@ -417,9 +403,16 @@ vfs_vm_object_t *vfs_get_vm_object(int fd, u64 length, u64 offset) {
}
int vfs_dup2(int org_fd, int new_fd) {
- current_task->file_descriptors[new_fd] =
- current_task->file_descriptors[org_fd];
- current_task->file_descriptors[new_fd]->reference_count++;
+ vfs_fd_t *orig;
+ if (!list_get(&current_task->file_descriptors, org_fd, (void **)&orig)) {
+ assert(0);
+ return -1;
+ }
+ if (!list_set(&current_task->file_descriptors, new_fd, orig)) {
+ assert(0);
+ return -1;
+ }
+ orig->reference_count++;
return 1;
}
diff --git a/kernel/lib/list.c b/kernel/lib/list.c
index d189c86..c663230 100644
--- a/kernel/lib/list.c
+++ b/kernel/lib/list.c
@@ -17,6 +17,18 @@ void list_reset(struct list *list) {
list->tail_index = -1;
}
+int list_clone(struct list *in, struct list *out) {
+ list_init(out);
+ for (int i = 0;; i++) {
+ void *output;
+ if (!list_get(in, i, &output)) {
+ break;
+ }
+ list_add(out, output, NULL);
+ }
+ return 1;
+}
+
int list_add(struct list *list, void *entry, int *index) {
if (list->tail_index + 1 >= list->capacity) {
list->capacity += 25;
@@ -30,6 +42,15 @@ int list_add(struct list *list, void *entry, int *index) {
return 1;
}
+int list_set(struct list *list, int index, void *entry) {
+ if (index > list->tail_index) {
+ assert(0);
+ return 0;
+ }
+ list->entries[index] = entry;
+ return 1;
+}
+
int list_get(const struct list *list, int index, void **out) {
if (index > list->tail_index) {
return 0;
diff --git a/kernel/lib/list.h b/kernel/lib/list.h
index b7085cd..b1f0127 100644
--- a/kernel/lib/list.h
+++ b/kernel/lib/list.h
@@ -9,6 +9,8 @@ struct list {
int list_init(struct list *list);
void list_reset(struct list *list);
void list_free(struct list *list);
+int list_clone(struct list *in, struct list *out);
int list_add(struct list *list, void *entry, int *index);
+int list_set(struct list *list, int index, void *entry);
int list_get(const struct list *list, int index, void **out);
#endif
diff --git a/kernel/sched/scheduler.c b/kernel/sched/scheduler.c
index 2fa9ad3..52e4848 100644
--- a/kernel/sched/scheduler.c
+++ b/kernel/sched/scheduler.c
@@ -118,6 +118,20 @@ process_t *create_process(process_t *p, u32 esp, u32 eip) {
r->tcb = kcalloc(1, sizeof(struct TCB));
r->tcb->CR3 = r->cr3->physical_address;
+ if (p) {
+ list_clone(&p->file_descriptors, &r->file_descriptors);
+ for (int i = 0;; i++) {
+ vfs_fd_t *out;
+ if (!list_get(&p->file_descriptors, i, (void **)&out)) {
+ break;
+ }
+ if (out) {
+ out->reference_count++;
+ }
+ }
+ } else {
+ list_init(&r->file_descriptors);
+ }
list_init(&r->read_list);
list_init(&r->write_list);
list_init(&r->disconnect_list);
@@ -149,39 +163,9 @@ process_t *create_process(process_t *p, u32 esp, u32 eip) {
strcpy(r->current_working_directory, "/");
}
r->data_segment_end = (p) ? p->data_segment_end : NULL;
- for (int i = 0; i < 100; i++) {
- if (p) {
- r->file_descriptors[i] = p->file_descriptors[i];
- if (r->file_descriptors[i]) {
- r->file_descriptors[i]->reference_count++;
- }
- } else {
- r->file_descriptors[i] = NULL;
- }
- }
return r;
}
-int get_free_fd(process_t *p, int allocate) {
- if (!p) {
- p = (process_t *)current_task;
- }
- int i;
- for (i = 0; i < 100; i++) {
- if (!p->file_descriptors[i]) {
- break;
- }
- }
- if (p->file_descriptors[i]) {
- return -1;
- }
- if (allocate) {
- vfs_fd_t *fd = p->file_descriptors[i] = kmalloc(sizeof(vfs_fd_t));
- fd->inode = kmalloc(sizeof(vfs_inode_t));
- }
- return i;
-}
-
void tasking_init(void) {
current_task = ready_queue = create_process(NULL, 0, 0);
current_task_TCB = current_task->tcb;
@@ -216,6 +200,7 @@ void free_process(process_t *p) {
list_free(&p->tcp_sockets);
list_free(&p->tcp_listen);
list_free(&p->event_queue);
+ list_free(&p->file_descriptors);
kfree(p->tcb);
}
diff --git a/kernel/sched/scheduler.h b/kernel/sched/scheduler.h
index b408f59..bdf32d4 100644
--- a/kernel/sched/scheduler.h
+++ b/kernel/sched/scheduler.h
@@ -62,7 +62,8 @@ struct Process {
void *interrupt_handler;
PageDirectory *cr3;
struct IpcMailbox ipc_mailbox;
- vfs_fd_t *file_descriptors[100];
+
+ struct list file_descriptors;
struct list read_list;
struct list write_list;
@@ -97,7 +98,6 @@ struct Process {
};
bool get_task_from_pid(u32 pid, process_t **out);
-int get_free_fd(process_t *p, int allocate);
void free_process(process_t *p);
void *get_free_virtual_memory(size_t length);
#endif
diff --git a/kernel/socket.c b/kernel/socket.c
index 4017ca1..589d99a 100644
--- a/kernel/socket.c
+++ b/kernel/socket.c
@@ -239,7 +239,7 @@ int uds_open(const char *path) {
fifo_object_write((u8 *)&c, 1, 0, s->fifo_file);
s->ptr_socket_fd->inode->has_data = 1;
- s->incoming_fd = current_task->file_descriptors[fd[1]];
+ s->incoming_fd = get_vfs_fd(fd[1], NULL);
// vfs_close(fd[1]);
return fd[0];
}
@@ -247,7 +247,9 @@ int uds_open(const char *path) {
int accept(int socket, struct sockaddr *address, socklen_t *address_len) {
(void)address;
(void)address_len;
- vfs_inode_t *inode = current_task->file_descriptors[socket]->inode;
+ vfs_fd_t *fd_ptr = get_vfs_fd(socket, NULL);
+ assert(fd_ptr);
+ vfs_inode_t *inode = fd_ptr->inode;
SOCKET *s = (SOCKET *)inode->internal_object;
if (NULL == s->incoming_fd) {
@@ -259,18 +261,16 @@ int accept(int socket, struct sockaddr *address, socklen_t *address_len) {
poll(fds, 1, 0);
}
- int n = 0;
- for (; current_task->file_descriptors[n]; n++)
- ;
- current_task->file_descriptors[n] = s->incoming_fd;
- current_task->file_descriptors[n]->reference_count++;
+ int index;
+ assert(list_add(&current_task->file_descriptors, s->incoming_fd, &index));
+ s->incoming_fd->reference_count++;
s->incoming_fd = NULL;
// for (char c; 0 < vfs_pread(s->fifo_fd, &c, 1, 0);)
// ;
inode->has_data = 0;
// s->ptr_fifo_fd->inode->has_data = 0;
- return n;
+ return index;
}
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {