root/kernel/signal.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_sgetmask
  2. sys_ssetmask
  3. save_old
  4. get_new
  5. sys_signal
  6. sys_sigaction
  7. do_signal

   1 /*
   2  *  linux/kernel/signal.c
   3  *
   4  *  (C) 1991  Linus Torvalds
   5  */
   6 
   7 #include <linux/sched.h>
   8 #include <linux/kernel.h>
   9 #include <asm/segment.h>
  10 
  11 #include <signal.h>
  12 
  13 volatile void do_exit(int error_code);
  14 
  15 int sys_sgetmask()
     /* [previous][next][first][last][top][bottom][index][help] */
  16 {
  17         return current->blocked;
  18 }
  19 
  20 int sys_ssetmask(int newmask)
     /* [previous][next][first][last][top][bottom][index][help] */
  21 {
  22         int old=current->blocked;
  23 
  24         current->blocked = newmask & ~(1<<(SIGKILL-1));
  25         return old;
  26 }
  27 
  28 static inline void save_old(char * from,char * to)
     /* [previous][next][first][last][top][bottom][index][help] */
  29 {
  30         int i;
  31 
  32         verify_area(to, sizeof(struct sigaction));
  33         for (i=0 ; i< sizeof(struct sigaction) ; i++) {
  34                 put_fs_byte(*from,to);
  35                 from++;
  36                 to++;
  37         }
  38 }
  39 
  40 static inline void get_new(char * from,char * to)
     /* [previous][next][first][last][top][bottom][index][help] */
  41 {
  42         int i;
  43 
  44         for (i=0 ; i< sizeof(struct sigaction) ; i++)
  45                 *(to++) = get_fs_byte(from++);
  46 }
  47 
  48 int sys_signal(int signum, long handler, long restorer)
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50         struct sigaction tmp;
  51 
  52         if (signum<1 || signum>32 || signum==SIGKILL)
  53                 return -1;
  54         tmp.sa_handler = (void (*)(int)) handler;
  55         tmp.sa_mask = 0;
  56         tmp.sa_flags = SA_ONESHOT | SA_NOMASK;
  57         tmp.sa_restorer = (void (*)(void)) restorer;
  58         handler = (long) current->sigaction[signum-1].sa_handler;
  59         current->sigaction[signum-1] = tmp;
  60         return handler;
  61 }
  62 
  63 int sys_sigaction(int signum, const struct sigaction * action,
     /* [previous][next][first][last][top][bottom][index][help] */
  64         struct sigaction * oldaction)
  65 {
  66         struct sigaction tmp;
  67 
  68         if (signum<1 || signum>32 || signum==SIGKILL)
  69                 return -1;
  70         tmp = current->sigaction[signum-1];
  71         get_new((char *) action,
  72                 (char *) (signum-1+current->sigaction));
  73         if (oldaction)
  74                 save_old((char *) &tmp,(char *) oldaction);
  75         if (current->sigaction[signum-1].sa_flags & SA_NOMASK)
  76                 current->sigaction[signum-1].sa_mask = 0;
  77         else
  78                 current->sigaction[signum-1].sa_mask |= (1<<(signum-1));
  79         return 0;
  80 }
  81 
  82 void do_signal(long signr,long eax, long ebx, long ecx, long edx,
     /* [previous][next][first][last][top][bottom][index][help] */
  83         long fs, long es, long ds,
  84         long eip, long cs, long eflags,
  85         unsigned long * esp, long ss)
  86 {
  87         long sa_handler;
  88         long old_eip=eip;
  89         struct sigaction * sa = current->sigaction + signr - 1;
  90         int longs;
  91         unsigned long * tmp_esp;
  92 
  93         sa_handler = (long) sa->sa_handler;
  94         if (sa_handler==1)
  95                 return;
  96         if (!sa_handler) {
  97                 if (signr==SIGCHLD)
  98                         return;
  99                 else
 100                         do_exit(1<<(signr-1));
 101         }
 102         if (sa->sa_flags & SA_ONESHOT)
 103                 sa->sa_handler = NULL;
 104         *(&eip) = sa_handler;
 105         longs = (sa->sa_flags & SA_NOMASK)?7:8;
 106         *(&esp) -= longs;
 107         verify_area(esp,longs*4);
 108         tmp_esp=esp;
 109         put_fs_long((long) sa->sa_restorer,tmp_esp++);
 110         put_fs_long(signr,tmp_esp++);
 111         if (!(sa->sa_flags & SA_NOMASK))
 112                 put_fs_long(current->blocked,tmp_esp++);
 113         put_fs_long(eax,tmp_esp++);
 114         put_fs_long(ecx,tmp_esp++);
 115         put_fs_long(edx,tmp_esp++);
 116         put_fs_long(eflags,tmp_esp++);
 117         put_fs_long(old_eip,tmp_esp++);
 118         current->blocked |= sa->sa_mask;
 119 }

/* [previous][next][first][last][top][bottom][index][help] */