diff --git a/kernel/include/process.h b/kernel/include/process.h index 8fc6ee08..5799d92b 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -112,7 +112,7 @@ typedef struct { } sleeper_t; extern void initialize_process_tree(void); -extern process_t * spawn_process(volatile process_t * parent); +extern process_t * spawn_process(volatile process_t * parent, int reuse_fds); extern void debug_print_process_tree(void); extern process_t * spawn_init(void); extern process_t * spawn_kidle(void); diff --git a/kernel/sys/process.c b/kernel/sys/process.c index ce9d5bed..bd6a269e 100644 --- a/kernel/sys/process.c +++ b/kernel/sys/process.c @@ -337,7 +337,7 @@ void process_disown(process_t * proc) { * @param parent The parent process to spawn the new one off of. * @return A pointer to the new process. */ -process_t * spawn_process(volatile process_t * parent) { +process_t * spawn_process(volatile process_t * parent, int reuse_fds) { assert(process_tree->root && "Attempted to spawn a process without init."); /* Allocate a new process */ @@ -379,18 +379,23 @@ process_t * spawn_process(volatile process_t * parent) { assert(proc->image.stack && "Failed to allocate kernel stack for new process."); /* Clone the file descriptors from the original process */ - proc->fds = malloc(sizeof(fd_table_t)); - proc->fds->refs = 1; - proc->fds->length = parent->fds->length; - proc->fds->capacity = parent->fds->capacity; - debug_print(INFO," fds / files {"); - proc->fds->entries = malloc(sizeof(fs_node_t *) * proc->fds->capacity); - assert(proc->fds->entries && "Failed to allocate file descriptor table for new process."); - debug_print(INFO," ---"); - for (uint32_t i = 0; i < parent->fds->length; ++i) { - proc->fds->entries[i] = clone_fs(parent->fds->entries[i]); + if (reuse_fds) { + proc->fds = parent->fds; + proc->fds->refs++; + } else { + proc->fds = malloc(sizeof(fd_table_t)); + proc->fds->refs = 1; + proc->fds->length = parent->fds->length; + proc->fds->capacity = parent->fds->capacity; + debug_print(INFO," fds / files {"); + proc->fds->entries = malloc(sizeof(fs_node_t *) * proc->fds->capacity); + assert(proc->fds->entries && "Failed to allocate file descriptor table for new process."); + debug_print(INFO," ---"); + for (uint32_t i = 0; i < parent->fds->length; ++i) { + proc->fds->entries[i] = clone_fs(parent->fds->entries[i]); + } + debug_print(INFO," }"); } - debug_print(INFO," }"); /* As well as the working directory */ proc->wd_node = clone_fs(parent->wd_node); diff --git a/kernel/sys/task.c b/kernel/sys/task.c index 7686a31a..e8ea11f8 100644 --- a/kernel/sys/task.c +++ b/kernel/sys/task.c @@ -199,7 +199,7 @@ uint32_t fork(void) { assert(directory && "Could not allocate a new page directory!"); /* Spawn a new process from this one */ debug_print(INFO,"\033[1;32mALLOC {\033[0m"); - process_t * new_proc = spawn_process(current_process); + process_t * new_proc = spawn_process(current_process, 0); debug_print(INFO,"\033[1;32m}\033[0m"); assert(new_proc && "Could not allocate a new process!"); /* Set the new process' page directory to clone */ @@ -243,7 +243,7 @@ int create_kernel_tasklet(tasklet_t tasklet, char * name, void * argp) { page_directory_t * directory = kernel_directory; /* Spawn a new process from this one */ - process_t * new_proc = spawn_process(current_process); + process_t * new_proc = spawn_process(current_process, 0); assert(new_proc && "Could not allocate a new process!"); /* Set the new process' page directory to the original process' */ set_process_environment(new_proc, directory); @@ -302,7 +302,7 @@ clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg) { assert(parent && "Cloned from nothing??"); page_directory_t * directory = current_directory; /* Spawn a new process from this one */ - process_t * new_proc = spawn_process(current_process); + process_t * new_proc = spawn_process(current_process, 1); assert(new_proc && "Could not allocate a new process!"); /* Set the new process' page directory to the original process' */ set_process_environment(new_proc, directory); @@ -342,10 +342,6 @@ clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg) { new_proc->is_tasklet = parent->is_tasklet; - free(new_proc->fds); - new_proc->fds = current_process->fds; - new_proc->fds->refs++; - new_proc->thread.eip = (uintptr_t)&return_to_userspace; /* Add the new process to the ready queue */