Annotation of linux/kernel/exit.c, revision 1.1.1.2

1.1.1.2 ! root        1: /*
        !             2:  *  linux/kernel/exit.c
        !             3:  *
        !             4:  *  (C) 1991  Linus Torvalds
        !             5:  */
        !             6: 
1.1       root        7: #include <errno.h>
                      8: #include <signal.h>
                      9: #include <sys/wait.h>
                     10: 
                     11: #include <linux/sched.h>
                     12: #include <linux/kernel.h>
                     13: #include <linux/tty.h>
                     14: #include <asm/segment.h>
                     15: 
                     16: int sys_pause(void);
                     17: int sys_close(int fd);
                     18: 
                     19: void release(struct task_struct * p)
                     20: {
                     21:        int i;
                     22: 
                     23:        if (!p)
                     24:                return;
                     25:        for (i=1 ; i<NR_TASKS ; i++)
                     26:                if (task[i]==p) {
                     27:                        task[i]=NULL;
                     28:                        free_page((long)p);
                     29:                        schedule();
                     30:                        return;
                     31:                }
                     32:        panic("trying to release non-existent task");
                     33: }
                     34: 
1.1.1.2 ! root       35: static inline int send_sig(long sig,struct task_struct * p,int priv)
1.1       root       36: {
                     37:        if (!p || sig<1 || sig>32)
1.1.1.2 ! root       38:                return -EINVAL;
        !            39:        if (priv || (current->euid==p->euid) || suser())
1.1       root       40:                p->signal |= (1<<(sig-1));
1.1.1.2 ! root       41:        else
        !            42:                return -EPERM;
        !            43:        return 0;
1.1       root       44: }
                     45: 
1.1.1.2 ! root       46: static void kill_session(void)
        !            47: {
        !            48:        struct task_struct **p = NR_TASKS + task;
        !            49:        
        !            50:        while (--p > &FIRST_TASK) {
        !            51:                if (*p && (*p)->session == current->session)
        !            52:                        (*p)->signal |= 1<<(SIGHUP-1);
        !            53:        }
        !            54: }
        !            55: 
        !            56: /*
        !            57:  * XXX need to check permissions needed to send signals to process
        !            58:  * groups, etc. etc.  kill() permissions semantics are tricky!
        !            59:  */
        !            60: int sys_kill(int pid,int sig)
1.1       root       61: {
                     62:        struct task_struct **p = NR_TASKS + task;
1.1.1.2 ! root       63:        int err, retval = 0;
1.1       root       64: 
                     65:        if (!pid) while (--p > &FIRST_TASK) {
1.1.1.2 ! root       66:                if (*p && (*p)->pgrp == current->pid) 
        !            67:                        if (err=send_sig(sig,*p,1))
        !            68:                                retval = err;
1.1       root       69:        } else if (pid>0) while (--p > &FIRST_TASK) {
1.1.1.2 ! root       70:                if (*p && (*p)->pid == pid) 
        !            71:                        if (err=send_sig(sig,*p,0))
        !            72:                                retval = err;
1.1       root       73:        } else if (pid == -1) while (--p > &FIRST_TASK)
1.1.1.2 ! root       74:                if (err = send_sig(sig,*p,0))
        !            75:                        retval = err;
1.1       root       76:        else while (--p > &FIRST_TASK)
                     77:                if (*p && (*p)->pgrp == -pid)
1.1.1.2 ! root       78:                        if (err = send_sig(sig,*p,0))
        !            79:                                retval = err;
        !            80:        return retval;
1.1       root       81: }
                     82: 
1.1.1.2 ! root       83: static void tell_father(int pid)
1.1       root       84: {
1.1.1.2 ! root       85:        int i;
        !            86: 
        !            87:        if (pid)
        !            88:                for (i=0;i<NR_TASKS;i++) {
        !            89:                        if (!task[i])
        !            90:                                continue;
        !            91:                        if (task[i]->pid != pid)
        !            92:                                continue;
        !            93:                        task[i]->signal |= (1<<(SIGCHLD-1));
        !            94:                        return;
        !            95:                }
        !            96: /* if we don't find any fathers, we just release ourselves */
        !            97:        release(current);
1.1       root       98: }
                     99: 
                    100: int do_exit(long code)
                    101: {
                    102:        int i;
                    103: 
                    104:        free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
                    105:        free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
                    106:        for (i=0 ; i<NR_TASKS ; i++)
                    107:                if (task[i] && task[i]->father == current->pid)
                    108:                        task[i]->father = 0;
                    109:        for (i=0 ; i<NR_OPEN ; i++)
                    110:                if (current->filp[i])
                    111:                        sys_close(i);
                    112:        iput(current->pwd);
                    113:        current->pwd=NULL;
                    114:        iput(current->root);
                    115:        current->root=NULL;
                    116:        if (current->leader && current->tty >= 0)
                    117:                tty_table[current->tty].pgrp = 0;
                    118:        if (last_task_used_math == current)
                    119:                last_task_used_math = NULL;
1.1.1.2 ! root      120:        if (current->leader)
        !           121:                kill_session();
        !           122:        current->state = TASK_ZOMBIE;
        !           123:        current->exit_code = code;
        !           124:        tell_father(current->father);
1.1       root      125:        schedule();
                    126:        return (-1);    /* just to suppress warnings */
                    127: }
                    128: 
                    129: int sys_exit(int error_code)
                    130: {
                    131:        return do_exit((error_code&0xff)<<8);
                    132: }
                    133: 
1.1.1.2 ! root      134: int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
1.1       root      135: {
1.1.1.2 ! root      136:        int flag;
1.1       root      137:        struct task_struct ** p;
                    138: 
                    139:        verify_area(stat_addr,4);
                    140: repeat:
1.1.1.2 ! root      141:        flag=0;
        !           142:        for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
        !           143:                if (!*p || *p == current)
        !           144:                        continue;
        !           145:                if ((*p)->father != current->pid)
        !           146:                        continue;
        !           147:                if (pid>0) {
        !           148:                        if ((*p)->pid != pid)
        !           149:                                continue;
        !           150:                } else if (!pid) {
        !           151:                        if ((*p)->pgrp != current->pgrp)
        !           152:                                continue;
        !           153:                } else if (pid != -1) {
        !           154:                        if ((*p)->pgrp != -pid)
        !           155:                                continue;
        !           156:                }
        !           157:                switch ((*p)->state) {
        !           158:                        case TASK_STOPPED:
        !           159:                                if (!(options & WUNTRACED))
        !           160:                                        continue;
        !           161:                                put_fs_long(0x7f,stat_addr);
        !           162:                                return (*p)->pid;
        !           163:                        case TASK_ZOMBIE:
        !           164:                                current->cutime += (*p)->utime;
        !           165:                                current->cstime += (*p)->stime;
        !           166:                                flag = (*p)->pid;
        !           167:                                put_fs_long((*p)->exit_code,stat_addr);
        !           168:                                release(*p);
        !           169:                                return flag;
        !           170:                        default:
1.1       root      171:                                flag=1;
1.1.1.2 ! root      172:                                continue;
        !           173:                }
        !           174:        }
1.1       root      175:        if (flag) {
                    176:                if (options & WNOHANG)
                    177:                        return 0;
1.1.1.2 ! root      178:                current->state=TASK_INTERRUPTIBLE;
        !           179:                schedule();
1.1       root      180:                if (!(current->signal &= ~(1<<(SIGCHLD-1))))
                    181:                        goto repeat;
                    182:                else
                    183:                        return -EINTR;
                    184:        }
                    185:        return -ECHILD;
                    186: }
                    187: 
                    188: 

unix.superglobalmegacorp.com