|
|
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: {
1.1.1.2 ! root 87: unsigned long sa_handler;
1.1 root 88: long old_eip=eip;
89: struct sigaction * sa = current->sigaction + signr - 1;
90: int longs;
91: unsigned long * tmp_esp;
92:
1.1.1.2 ! root 93: sa_handler = (unsigned long) sa->sa_handler;
1.1 root 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.