/** * exit will perform the following tasks: * 1. close all open files (through file_close_all()) * 2. set the given exit code inside the proc structure. * 3. mark each child process as orphan. * 4. if orphan, will destroy the proc associated with the current thread. * 4.1 if not orphan, will signal the parent regarding our death. * 5. call thread_exit() so we become a zombie. */ void sys__exit( int code ) { struct proc *p = NULL; int err; KASSERT( curthread != NULL ); KASSERT( curthread->td_proc != NULL ); p = curthread->td_proc; //close all open files. err = file_close_all( p ); if( err ) panic( "problem closing a file." ); //lock so we can adjust the return value. PROC_LOCK( p ); p->p_retval = code; p->p_is_dead = true; //if we are orphans ourselves, no one is interested //in our return code, so we simply destroy ourselves. if( p->p_proc == NULL ) { PROC_UNLOCK( p ); proc_destroy( p ); } else { //signal that we are done. V( p->p_sem ); PROC_UNLOCK( p ); } //all that is left now is to kill our thread. thread_exit(); }
__attribute__((noinline)) static void tm_process_exit(int code) { spinlock_acquire(¤t_thread->status_lock); if(code != -9) current_process->exit_reason.cause = __EXIT; current_process->exit_reason.ret = code; current_process->exit_reason.pid = current_process->pid; spinlock_release(¤t_thread->status_lock); /* update times */ if(current_process->parent) { time_t total_utime = current_process->utime + current_process->cutime; time_t total_stime = current_process->stime + current_process->cstime; atomic_fetch_add_explicit(¤t_process->parent->cutime, total_utime, memory_order_relaxed); atomic_fetch_add_explicit(¤t_process->parent->cstime, total_stime, memory_order_relaxed); } file_close_all(); if(current_process->root) vfs_icache_put(current_process->root); if(current_process->cwd) vfs_icache_put(current_process->cwd); mutex_destroy(¤t_process->fdlock); mm_destroy_all_mappings(current_process); linkedlist_destroy(&(current_process->mappings)); valloc_destroy(¤t_process->mmf_valloc); /* this is done before SIGCHILD is sent out */ atomic_fetch_or(¤t_process->flags, PROCESS_EXITED); if(current_process->parent) { struct process *init = tm_process_get(0); assert(init); __linkedlist_lock(process_list); struct process *child; struct linkedentry *node; for(node = linkedlist_iter_start(process_list); node != linkedlist_iter_end(process_list); node = linkedlist_iter_next(node)) { child = linkedentry_obj(node); if(child->parent == current_process) { tm_process_inc_reference(init); child->parent = init; tm_process_put(current_process); } } __linkedlist_unlock(process_list); tm_signal_send_process(current_process->parent, SIGCHILD); tm_blocklist_wakeall(¤t_process->waitlist); tm_process_put(init); } tm_process_put(current_process); /* fork starts us out at refs = 1 */ }
static void file_delete(struct file_info *file) { struct dir_entry_info *entry = file->links; file_close_all(file); while (entry) { struct dir_entry_info *next = entry->next_link; file_unlink(entry); entry = next; } }
void _cedit_cmd_file_quit (GtkAction *action, CeditWindow *window) { cedit_debug (DEBUG_COMMANDS); g_return_if_fail (!(cedit_window_get_state (window) & (CEDIT_WINDOW_STATE_SAVING | CEDIT_WINDOW_STATE_PRINTING | CEDIT_WINDOW_STATE_SAVING_SESSION))); file_close_all (window, TRUE); }
/*! *@brief jvmti的Agent_OnUnload接口的实现,用于清理gcmon资源 *@author zhaohm3 *@param[in] vm *@retval *@note * *@since 2014-9-15 18:08 *@attention * */ JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm) { GCMON_PRINT_FUNC(); JVMClearJvmtiEnv(); gcmon_thread_exit(); rbtree_free(gpPerfTree); gcmon_souter_free(); file_close_all(); if (!gbOOMEvent) { file_remove(file_get_fsname()); file_remove(file_get_frname()); } args_free_agentargs(); }
int rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context) { struct rtems_bsd_program_control *prog_ctrl; int error; int exit_code; prog_ctrl = calloc(1, sizeof(*prog_ctrl)); if (prog_ctrl == NULL) { errno = ENOMEM; return (EXIT_FAILURE); } error = rtems_bsd_program_set_control(prog_ctrl); if (error != 0) { free(prog_ctrl); errno = error; return (EXIT_FAILURE); } prog_ctrl->context = context; prog_ctrl->name = name; prog_ctrl->exit_code = EXIT_FAILURE; LIST_INIT(&prog_ctrl->open_fd); LIST_INIT(&prog_ctrl->open_file); LIST_INIT(&prog_ctrl->allocated_mem); if (setjmp(prog_ctrl->return_context) == 0) { exit_code = (*prog)(context); } else { exit_code = prog_ctrl->exit_code; } rtems_bsd_program_set_control(NULL); fd_close_all(prog_ctrl); file_close_all(prog_ctrl); allocmem_free_all(prog_ctrl); free(prog_ctrl); return (exit_code); }
/** * Daemonize the process. */ void start_daemon(void) { umask(0); int pid = fork(); if (pid < 0) { exit(1); } else if (pid != 0) { exit(0); } if (setsid() == -1) exit(1); if ((pid = fork()) < 0) { exit(1); } else if (pid != 0) { exit(0); } file_close_all(); for (int n = 1; n <= NSIG; n++) fb_signal(n, SIG_IGN); }