File:  [Early Linux] / linux / kernel / exit.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:00:41 2018 UTC (2 years, 2 months ago) by root
Branches: linus, MAIN
CVS tags: linux001, HEAD
linux 0.01

    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