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

1.1       root        1: #include <errno.h>
                      2: #include <signal.h>
                      3: #include <sys/wait.h>
                      4: 
                      5: #include <linux/sched.h>
                      6: #include <linux/kernel.h>
                      7: #include <linux/tty.h>
                      8: #include <asm/segment.h>
                      9: 
                     10: int sys_pause(void);
                     11: int sys_close(int fd);
                     12: 
                     13: void release(struct task_struct * p)
                     14: {
                     15:        int i;
                     16: 
                     17:        if (!p)
                     18:                return;
                     19:        for (i=1 ; i<NR_TASKS ; i++)
                     20:                if (task[i]==p) {
                     21:                        task[i]=NULL;
                     22:                        free_page((long)p);
                     23:                        schedule();
                     24:                        return;
                     25:                }
                     26:        panic("trying to release non-existent task");
                     27: }
                     28: 
                     29: static inline void send_sig(long sig,struct task_struct * p,int priv)
                     30: {
                     31:        if (!p || sig<1 || sig>32)
                     32:                return;
                     33:        if (priv ||
                     34:                current->uid==p->uid ||
                     35:                current->euid==p->uid ||
                     36:                current->uid==p->euid ||
                     37:                current->euid==p->euid)
                     38:                p->signal |= (1<<(sig-1));
                     39: }
                     40: 
                     41: void do_kill(long pid,long sig,int priv)
                     42: {
                     43:        struct task_struct **p = NR_TASKS + task;
                     44: 
                     45:        if (!pid) while (--p > &FIRST_TASK) {
                     46:                if (*p && (*p)->pgrp == current->pid)
                     47:                        send_sig(sig,*p,priv);
                     48:        } else if (pid>0) while (--p > &FIRST_TASK) {
                     49:                if (*p && (*p)->pid == pid)
                     50:                        send_sig(sig,*p,priv);
                     51:        } else if (pid == -1) while (--p > &FIRST_TASK)
                     52:                send_sig(sig,*p,priv);
                     53:        else while (--p > &FIRST_TASK)
                     54:                if (*p && (*p)->pgrp == -pid)
                     55:                        send_sig(sig,*p,priv);
                     56: }
                     57: 
                     58: int sys_kill(int pid,int sig)
                     59: {
                     60:        do_kill(pid,sig,!(current->uid || current->euid));
                     61:        return 0;
                     62: }
                     63: 
                     64: int do_exit(long code)
                     65: {
                     66:        int i;
                     67: 
                     68:        free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
                     69:        free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
                     70:        for (i=0 ; i<NR_TASKS ; i++)
                     71:                if (task[i] && task[i]->father == current->pid)
                     72:                        task[i]->father = 0;
                     73:        for (i=0 ; i<NR_OPEN ; i++)
                     74:                if (current->filp[i])
                     75:                        sys_close(i);
                     76:        iput(current->pwd);
                     77:        current->pwd=NULL;
                     78:        iput(current->root);
                     79:        current->root=NULL;
                     80:        if (current->leader && current->tty >= 0)
                     81:                tty_table[current->tty].pgrp = 0;
                     82:        if (last_task_used_math == current)
                     83:                last_task_used_math = NULL;
                     84:        if (current->father) {
                     85:                current->state = TASK_ZOMBIE;
                     86:                do_kill(current->father,SIGCHLD,1);
                     87:                current->exit_code = code;
                     88:        } else
                     89:                release(current);
                     90:        schedule();
                     91:        return (-1);    /* just to suppress warnings */
                     92: }
                     93: 
                     94: int sys_exit(int error_code)
                     95: {
                     96:        return do_exit((error_code&0xff)<<8);
                     97: }
                     98: 
                     99: int sys_waitpid(pid_t pid,int * stat_addr, int options)
                    100: {
                    101:        int flag=0;
                    102:        struct task_struct ** p;
                    103: 
                    104:        verify_area(stat_addr,4);
                    105: repeat:
                    106:        for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
                    107:                if (*p && *p != current &&
                    108:                   (pid==-1 || (*p)->pid==pid ||
                    109:                   (pid==0 && (*p)->pgrp==current->pgrp) ||
                    110:                   (pid<0 && (*p)->pgrp==-pid)))
                    111:                        if ((*p)->father == current->pid) {
                    112:                                flag=1;
                    113:                                if ((*p)->state==TASK_ZOMBIE) {
                    114:                                        put_fs_long((*p)->exit_code,
                    115:                                                (unsigned long *) stat_addr);
                    116:                                        current->cutime += (*p)->utime;
                    117:                                        current->cstime += (*p)->stime;
                    118:                                        flag = (*p)->pid;
                    119:                                        release(*p);
                    120:                                        return flag;
                    121:                                }
                    122:                        }
                    123:        if (flag) {
                    124:                if (options & WNOHANG)
                    125:                        return 0;
                    126:                sys_pause();
                    127:                if (!(current->signal &= ~(1<<(SIGCHLD-1))))
                    128:                        goto repeat;
                    129:                else
                    130:                        return -EINTR;
                    131:        }
                    132:        return -ECHILD;
                    133: }
                    134: 
                    135: 

unix.superglobalmegacorp.com