File:  [Early Linux] / linux / kernel / signal.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:02:25 2018 UTC (2 years, 7 months ago) by root
Branches: linus, MAIN
CVS tags: linux011, HEAD
linux 0.11

    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()
   16: {
   17: 	return current->blocked;
   18: }
   19: 
   20: int sys_ssetmask(int newmask)
   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)
   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)
   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)
   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,
   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,
   83: 	long fs, long es, long ds,
   84: 	long eip, long cs, long eflags,
   85: 	unsigned long * esp, long ss)
   86: {
   87: 	unsigned 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 = (unsigned 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: }

unix.superglobalmegacorp.com