Welcome to The Fiwix Project
A UNIX-like kernel for the i386 architecture
1 /* 2 * fiwix/kernel/syscalls/exit.c 3 * 4 * Copyright 2018-2021, Jordi Sanfeliu. All rights reserved. 5 * Distributed under the terms of the Fiwix License. 6 */ 7 8 #include <fiwix/asm.h> 9 #include <fiwix/kernel.h> 10 #include <fiwix/syscalls.h> 11 #include <fiwix/process.h> 12 #include <fiwix/sched.h> 13 #include <fiwix/mman.h> 14 #include <fiwix/sleep.h> 15 #include <fiwix/stdio.h> 16 #include <fiwix/string.h> 17 18 void do_exit(int exit_code) 19 { 20 int n; 21 struct proc *p, *init; 22 23 #ifdef __DEBUG__ 24 printk("\n"); 25 printk("sys_exit(pid %d, ppid %d)\n", current->pid, current->ppid); 26 printk("------------------------------\n"); 27 #endif /*__DEBUG__ */ 28 29 release_binary(); 30 current->argv = NULL; 31 current->envp = NULL; 32 33 init = get_proc_by_pid(INIT); 34 FOR_EACH_PROCESS(p) { 35 if(SESS_LEADER(current)) { 36 if(p->sid == current->sid && p->state != PROC_ZOMBIE) { 37 p->pgid = 0; 38 p->sid = 0; 39 p->ctty = NULL; 40 send_sig(p, SIGHUP); 41 send_sig(p, SIGCONT); 42 } 43 } 44 45 /* make INIT inherit the children of this exiting process */ 46 if(p->ppid == current->pid) { 47 p->ppid = INIT; 48 init->children++; 49 current->children--; 50 if(p->state == PROC_ZOMBIE) { 51 send_sig(init, SIGCHLD); 52 if(init->sleep_address == &sys_wait4) { 53 wakeup_proc(init); 54 } 55 } 56 } 57 p = p->next; 58 } 59 60 if(SESS_LEADER(current)) { 61 disassociate_ctty(current->ctty); 62 } 63 64 for(n = 0; n < OPEN_MAX; n++) { 65 if(current->fd[n]) { 66 sys_close(n); 67 } 68 } 69 70 iput(current->root); 71 current->root = NULL; 72 iput(current->pwd); 73 current->pwd = NULL; 74 current->exit_code = exit_code; 75 if(!--nr_processes) { 76 printk("\n"); 77 printk("WARNING: the last user process has exited. The kernel will stop itself.\n"); 78 stop_kernel(); 79 } 80 81 /* notify the parent about the child's death */ 82 if((p = get_proc_by_pid(current->ppid))) { 83 send_sig(p, SIGCHLD); 84 if(p->sleep_address == &sys_wait4) { 85 wakeup_proc(p); 86 } 87 } 88 89 current->sigpending = 0; 90 current->sigblocked = 0; 91 current->sigexecuting = 0; 92 for(n = 0; n < NSIG; n++) { 93 current->sigaction[n].sa_mask = 0; 94 current->sigaction[n].sa_flags = 0; 95 current->sigaction[n].sa_handler = SIG_IGN; 96 } 97 98 not_runnable(current, PROC_ZOMBIE); 99 need_resched = 1; 100 do_sched(); 101 } 102 103 int sys_exit(int exit_code) 104 { 105 #ifdef __DEBUG__ 106 printk("(pid %d) sys_exit()\n", current->pid); 107 #endif /*__DEBUG__ */ 108 109 /* exit code in the second byte. 110 * 15 8 7 0 111 * +-------------------+-------------------+ 112 * | exit code (0-255) | 0 | 113 * +-------------------+-------------------+ 114 */ 115 do_exit((exit_code & 0xFF) << 8); 116 return 0; 117 }