|
|
1.1 ! root 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: 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.