Fork me on GitHub

root/kernel/syscalls/exit.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_exit
  2. sys_exit

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

/* [previous][next][first][last][top][bottom][index][help] */