void my_close(int fd) { lock_acquire(&filesys_lock); struct thread *t = thread_current(); struct list_elem *e = list_begin(&t->file_list); struct process_file *pf; int count = 0; while(e != list_end(&t->file_list)){ pf = list_entry (e, struct process_file, elem); // khg : order is important e = list_next(e); if(fd == pf->fd || fd == CLOSE_ALL){ file_allow_write(pf->file); file_close(pf->file); list_remove(&pf->elem); free(pf); count++; // khg : fd reset.... //(t->fd)--; if(fd != CLOSE_ALL) break; } } lock_release(&filesys_lock); if(count == 0 && fd != CLOSE_ALL) my_exit(-1); return; }
/*! Closes FILE. */ void file_close(struct file *file) { if (file != NULL) { file_allow_write(file); inode_close(file->inode); free(file); } }
void sys_exit (int status) { struct thread *t = thread_current(); int fd; t->exit_code = status; t->end = true; for (fd=0; fd < t->fd_num; fd++){ // close all open fd if (t->fd_list[fd] != NULL){ file_close(t->fd_list[fd]); t->fd_list[fd] = 0; } } printf("%s: exit(%d)\n", t->process_name, status); sema_up (&t->wait_this); //unblock parent sema_down (&t->kill_this); //kill_this will up when parent get exit_code succefully file_allow_write (t->open_file); file_close (t->open_file); thread_exit(); }
void thread_cleanup_and_exit (int status) { printf ("%s: exit(%d)\n", thread_name (), status); /* close all open file descriptors */ struct thread *t = thread_current (); struct list_elem *e; /* close all the files opened and free spaces allocated for the file list */ while (!list_empty (&t->file_list)) { e = list_pop_back (&t->file_list); struct file_elem *f_elem = list_entry (e, struct file_elem, elem); file_close (f_elem->file); free (f_elem); } /* free waited_children_list and children_list */ while (!list_empty (&t->children_list)) { e = list_pop_back (&t->children_list); struct child_elem *c_elem = list_entry (e, struct child_elem, elem); // free children from the global exit_list free_thread_from_exit_list (c_elem->pid); free (c_elem); } while (!list_empty (&t->waited_children_list)) { e = list_pop_back (&t->waited_children_list); struct wait_child_elem *w_elem = list_entry (e, struct wait_child_elem, elem); free (w_elem); } add_thread_to_exited_list (t->tid, status); /* allow file write to executable */ if (t->exec_file) { file_allow_write (t->exec_file); file_close (t->exec_file); } /* release all the locks that have not already been released */ while (!list_empty (&t->acquired_locks)) { struct list_elem *e = list_front (&t->acquired_locks); struct lock *l = list_entry (e, struct lock, elem); lock_release (l); } /* wake parent up if its waiting on it */ struct thread *parent = get_thread (thread_current ()->parent_id); if (parent) { sema_up (&parent->waiting_on_child_exit_sema); } thread_exit (); }
void exit_handler (int status) { printf("%s: exit(%d)\n", &thread_current ()->name, status); lock_acquire(&ref_count_lock); struct p_data* parent = thread_current()->parent_data; if (parent != NULL) { parent->exit_status = status; parent->child_thread = NULL; sema_up(&parent->sema); parent->ref_count--; if (parent->cwd != NULL) { dir_close(parent->cwd); } if (parent->ref_count == 0) { thread_current()->parent_data = NULL; free(parent); } } if (thread_current()->cwd != NULL) { dir_close(thread_current()->cwd); } /* iterate through children and remove this as their parent*/ struct list_elem* e; struct list *childs = &thread_current()->child_processes; for (e = list_begin(childs); e != list_end(childs); e = list_next(e)) { struct p_data* child = list_entry(e, struct p_data, elem); child->ref_count --; list_remove(e); if (child->ref_count == 0) { struct thread *t = child->child_thread; if (t != NULL) { t->parent_data = NULL; } free(child); } } struct list *files = &thread_current()->files; for (e = list_begin(files); e != list_end(files); e = list_begin(files)) { close_handler(list_entry(e, struct file_struct, elem)->fd); } struct file_struct *executable = thread_current()->executable; if (executable != NULL) { file_allow_write(executable->sys_file); file_close(executable->sys_file); thread_current()->executable = NULL; free(executable); } lock_release(&ref_count_lock); thread_exit(); }
/* Closes FILE. */ void file_close (struct file *file) { if (file != NULL) { /* Close the directory if possible. */ if (file->inode->data.is_dir) { dir_close (file->opened_dir); } file_allow_write (file); inode_close (file->inode); free (file); } }