diff --git a/kernel/tasks.c b/kernel/tasks.c index 9c1e103f..83aec680 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -198,7 +198,7 @@ static void wakeup_blocked_tasks(int result) static void NORETURN do_exit(int arg) { vma_t* tmp; task_t* curr_task = per_core(current_task); - uint32_t flags, core_id; + uint32_t flags, core_id, fd, status; kprintf("Terminate task: %u, return value %d\n", curr_task->id, arg); @@ -214,7 +214,31 @@ static void NORETURN do_exit(int arg) { kfree((void*) tmp, sizeof(vma_t)); } - //remove fildes_table + + + + + for (fd = 0; fd < NR_OPEN; fd++) { + if ((curr_task->fildes_table[fd] != NULL) && (curr_task->fildes_table[fd]->count == 1)) { + /* + * delete a descriptor from the per-process object + * reference table. If this is not the last reference to the underlying + * object, the object will be ignored. + */ + if (curr_task->fildes_table[fd]->count == 1) { + /* try to close the file */ + status = close_fs(curr_task->fildes_table[fd]); + /* close command failed -> return check = errno */ + if (BUILTIN_EXPECT(status < 0, 0)) + kprintf("Task %u was not able to close file descriptor %i. close_fs returned %d", curr_task->id, fd, -status); + kfree(curr_task->fildes_table[fd], sizeof(fildes_t)); + } else { + curr_task->fildes_table[fd]->count--; + } + } + } + + // after closing all file decriptors and cleaning up, the table has to be cleared. if(!curr_task->fildes_table) kfree(curr_task->fildes_table, sizeof(filp_t)*NR_OPEN);