|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.