Diff for /linux/kernel/exit.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2018/04/24 18:00:41 version 1.1.1.2, 2018/04/24 18:01:35
Line 1 Line 1
   /*
    *  linux/kernel/exit.c
    *
    *  (C) 1991  Linus Torvalds
    */
   
 #include <errno.h>  #include <errno.h>
 #include <signal.h>  #include <signal.h>
 #include <sys/wait.h>  #include <sys/wait.h>
Line 26  void release(struct task_struct * p) Line 32  void release(struct task_struct * p)
         panic("trying to release non-existent task");          panic("trying to release non-existent task");
 }  }
   
 static inline void send_sig(long sig,struct task_struct * p,int priv)  static inline int send_sig(long sig,struct task_struct * p,int priv)
 {  {
         if (!p || sig<1 || sig>32)          if (!p || sig<1 || sig>32)
                 return;                  return -EINVAL;
         if (priv ||          if (priv || (current->euid==p->euid) || suser())
                 current->uid==p->uid ||  
                 current->euid==p->uid ||  
                 current->uid==p->euid ||  
                 current->euid==p->euid)  
                 p->signal |= (1<<(sig-1));                  p->signal |= (1<<(sig-1));
           else
                   return -EPERM;
           return 0;
 }  }
   
 void do_kill(long pid,long sig,int priv)  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;          struct task_struct **p = NR_TASKS + task;
           int err, retval = 0;
   
         if (!pid) while (--p > &FIRST_TASK) {          if (!pid) while (--p > &FIRST_TASK) {
                 if (*p && (*p)->pgrp == current->pid)                  if (*p && (*p)->pgrp == current->pid) 
                         send_sig(sig,*p,priv);                          if (err=send_sig(sig,*p,1))
                                   retval = err;
         } else if (pid>0) while (--p > &FIRST_TASK) {          } else if (pid>0) while (--p > &FIRST_TASK) {
                 if (*p && (*p)->pid == pid)                  if (*p && (*p)->pid == pid) 
                         send_sig(sig,*p,priv);                          if (err=send_sig(sig,*p,0))
                                   retval = err;
         } else if (pid == -1) while (--p > &FIRST_TASK)          } else if (pid == -1) while (--p > &FIRST_TASK)
                 send_sig(sig,*p,priv);                  if (err = send_sig(sig,*p,0))
                           retval = err;
         else while (--p > &FIRST_TASK)          else while (--p > &FIRST_TASK)
                 if (*p && (*p)->pgrp == -pid)                  if (*p && (*p)->pgrp == -pid)
                         send_sig(sig,*p,priv);                          if (err = send_sig(sig,*p,0))
                                   retval = err;
           return retval;
 }  }
   
 int sys_kill(int pid,int sig)  static void tell_father(int pid)
 {  {
         do_kill(pid,sig,!(current->uid || current->euid));          int i;
         return 0;  
           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 do_exit(long code)
Line 81  int do_exit(long code) Line 117  int do_exit(long code)
                 tty_table[current->tty].pgrp = 0;                  tty_table[current->tty].pgrp = 0;
         if (last_task_used_math == current)          if (last_task_used_math == current)
                 last_task_used_math = NULL;                  last_task_used_math = NULL;
         if (current->father) {          if (current->leader)
                 current->state = TASK_ZOMBIE;                  kill_session();
                 do_kill(current->father,SIGCHLD,1);          current->state = TASK_ZOMBIE;
                 current->exit_code = code;          current->exit_code = code;
         } else          tell_father(current->father);
                 release(current);  
         schedule();          schedule();
         return (-1);    /* just to suppress warnings */          return (-1);    /* just to suppress warnings */
 }  }
Line 96  int sys_exit(int error_code) Line 131  int sys_exit(int error_code)
         return do_exit((error_code&0xff)<<8);          return do_exit((error_code&0xff)<<8);
 }  }
   
 int sys_waitpid(pid_t pid,int * stat_addr, int options)  int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
 {  {
         int flag=0;          int flag;
         struct task_struct ** p;          struct task_struct ** p;
   
         verify_area(stat_addr,4);          verify_area(stat_addr,4);
 repeat:  repeat:
         for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)          flag=0;
                 if (*p && *p != current &&          for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
                    (pid==-1 || (*p)->pid==pid ||                  if (!*p || *p == current)
                    (pid==0 && (*p)->pgrp==current->pgrp) ||                          continue;
                    (pid<0 && (*p)->pgrp==-pid)))                  if ((*p)->father != current->pid)
                         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;                                  flag=1;
                                 if ((*p)->state==TASK_ZOMBIE) {                                  continue;
                                         put_fs_long((*p)->exit_code,                  }
                                                 (unsigned long *) stat_addr);          }
                                         current->cutime += (*p)->utime;  
                                         current->cstime += (*p)->stime;  
                                         flag = (*p)->pid;  
                                         release(*p);  
                                         return flag;  
                                 }  
                         }  
         if (flag) {          if (flag) {
                 if (options & WNOHANG)                  if (options & WNOHANG)
                         return 0;                          return 0;
                 sys_pause();                  current->state=TASK_INTERRUPTIBLE;
                   schedule();
                 if (!(current->signal &= ~(1<<(SIGCHLD-1))))                  if (!(current->signal &= ~(1<<(SIGCHLD-1))))
                         goto repeat;                          goto repeat;
                 else                  else

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


unix.superglobalmegacorp.com