📄 exit.c,v
字号:
head 1.3;branch ;access ;symbols ;locks ; strict;comment @ * @;1.3date 91.12.01.09.21.46; author tytso; state Exp;branches ;next 1.2;1.2date 91.11.20.00.10.00; author tytso; state Exp;branches ;next 1.1;1.1date 91.11.16.21.02.17; author tytso; state Exp;branches ;next ;desc@@1.3log@Patches sent to Linus@text@/* * linux/kernel/exit.c * * (C) 1991 Linus Torvalds */#include <errno.h>#include <signal.h>#include <sys/wait.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/tty.h>#include <asm/segment.h>int sys_pause(void);int sys_close(int fd);void release(struct task_struct * p){ int i; if (!p) return; for (i=1 ; i<NR_TASKS ; i++) if (task[i]==p) { task[i]=NULL; free_page((long)p); schedule(); return; } panic("trying to release non-existent task");}static inline int send_sig(long sig,struct task_struct * p,int priv){ if (!p || sig<1 || sig>32) return -EINVAL; if (priv || (current->euid==p->euid) || suser()) p->signal |= (1<<(sig-1)); else return -EPERM; return 0;}static void kill_session(void){ struct task_struct **p = NR_TASKS + task; while (--p > &FIRST_TASK) { if (*p && (*p)->session == current->session) (*p)->signal |= 1<<(SIGHUP-1); }}/* * XXX need to check permissions needed to send signals to process * groups, etc. etc. kill() permissions semantics are tricky! */int sys_kill(int pid,int sig){ struct task_struct **p = NR_TASKS + task; int err, retval = 0; if (!pid) while (--p > &FIRST_TASK) { if (*p && (*p)->pgrp == current->pid) if (err=send_sig(sig,*p,1)) retval = err; } else if (pid>0) while (--p > &FIRST_TASK) { if (*p && (*p)->pid == pid) if (err=send_sig(sig,*p,0)) retval = err; } else if (pid == -1) while (--p > &FIRST_TASK) if (err = send_sig(sig,*p,0)) retval = err; else while (--p > &FIRST_TASK) if (*p && (*p)->pgrp == -pid) if (err = send_sig(sig,*p,0)) retval = err; return retval;}static void tell_father(int pid){ int i; if (pid) for (i=0;i<NR_TASKS;i++) { if (!task[i]) continue; if (task[i]->pid != pid) continue; task[i]->signal |= (1<<(SIGCHLD-1)); return; }/* if we don't find any fathers, we just release ourselves */ release(current);}int do_exit(long code){ int i; free_page_tables(get_base(current->ldt[1]),get_limit(0x0f)); free_page_tables(get_base(current->ldt[2]),get_limit(0x17)); for (i=0 ; i<NR_TASKS ; i++) if (task[i] && task[i]->father == current->pid) task[i]->father = 0; for (i=0 ; i<NR_OPEN ; i++) if (current->filp[i]) sys_close(i); iput(current->pwd); current->pwd=NULL; iput(current->root); current->root=NULL; if (current->leader && current->tty >= 0) tty_table[current->tty].pgrp = 0; if (last_task_used_math == current) last_task_used_math = NULL; if (current->leader) kill_session(); current->state = TASK_ZOMBIE; current->exit_code = code; tell_father(current->father); schedule(); return (-1); /* just to suppress warnings */}int sys_exit(int error_code){ return do_exit((error_code&0xff)<<8);}int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options){ int flag; struct task_struct ** p; verify_area(stat_addr,4);repeat: flag=0; for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) { if (!*p || *p == current) continue; if ((*p)->father != current->pid) continue; if (pid>0) { if ((*p)->pid != pid) continue; } else if (!pid) { if ((*p)->pgrp != current->pgrp) continue; } else if (pid != -1) { if ((*p)->pgrp != -pid) continue; } switch ((*p)->state) { case TASK_STOPPED: if (!(options & WUNTRACED)) continue; put_fs_long(0x7f,stat_addr); return (*p)->pid; case TASK_ZOMBIE: current->cutime += (*p)->utime; current->cstime += (*p)->stime; flag = (*p)->pid; put_fs_long((*p)->exit_code,stat_addr); release(*p); return flag; default: flag=1; continue; } } if (flag) { if (options & WNOHANG) return 0; current->state=TASK_INTERRUPTIBLE; schedule(); if (!(current->signal &= ~(1<<(SIGCHLD-1)))) goto repeat; else return -EINTR; } return -ECHILD;}@1.2log@Fixed bug in waitpid() so that the proper exit code would be returned.@text@d35 1a35 1static inline void send_sig(long sig,struct task_struct * p,int priv)d38 2a39 6 return; if (priv || current->uid==p->uid || current->euid==p->uid || current->uid==p->euid || current->euid==p->euid)d41 3d49 1a49 1d56 5a60 1void do_kill(long pid,long sig,int priv)d63 1d66 3a68 2 if (*p && (*p)->pgrp == current->pid) send_sig(sig,*p,priv);d70 3a72 2 if (*p && (*p)->pid == pid) send_sig(sig,*p,priv);d74 2a75 1 send_sig(sig,*p,priv);d78 3a80 7 send_sig(sig,*p,priv);}int sys_kill(int pid,int sig){ do_kill(pid,sig,!(current->uid || current->euid)); return 0;@1.1log@Initial revision@text@d164 1a165 1 put_fs_long((*p)->exit_code,stat_addr);@
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -