This source file includes following definitions.
- sys_sgetmask
- sys_ssetmask
- sys_sigpending
- sys_sigsuspend
- save_old
- get_new
- sys_signal
- sys_sigaction
- core_dump
- do_signal
1
2
3
4
5
6
7 #include <linux/sched.h>
8 #include <linux/kernel.h>
9 #include <asm/segment.h>
10
11 #include <signal.h>
12 #include <sys/wait.h>
13 #include <errno.h>
14
15 int send_sig (int, struct task_struct *, int);
16
17 int sys_sgetmask()
18 {
19 return current->blocked;
20 }
21
22 int sys_ssetmask(int newmask)
23 {
24 int old=current->blocked;
25
26 current->blocked = newmask & ~(1<<(SIGKILL-1)) & ~(1<<(SIGSTOP-1));
27 return old;
28 }
29
30 int sys_sigpending(sigset_t *set)
31 {
32
33 verify_area(set,4);
34 put_fs_long(current->blocked & current->signal, (unsigned long *)set);
35 return 0;
36 }
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 int sys_sigsuspend(int restart, unsigned long old_mask, unsigned long set)
52 {
53 extern int sys_pause(void);
54
55 if (restart) {
56
57 current->blocked = old_mask;
58 return -EINTR;
59 }
60
61 *(&restart) = 1;
62 *(&old_mask) = current->blocked;
63 current->blocked = set;
64 (void) sys_pause();
65 return -ERESTARTNOINTR;
66 }
67
68 static inline void save_old(char * from,char * to)
69 {
70 int i;
71
72 verify_area(to, sizeof(struct sigaction));
73 for (i=0 ; i< sizeof(struct sigaction) ; i++) {
74 put_fs_byte(*from,to);
75 from++;
76 to++;
77 }
78 }
79
80 static inline void get_new(char * from,char * to)
81 {
82 int i;
83
84 for (i=0 ; i< sizeof(struct sigaction) ; i++)
85 *(to++) = get_fs_byte(from++);
86 }
87
88 int sys_signal(int signum, long handler, long restorer)
89 {
90 struct sigaction tmp;
91
92 if (signum<1 || signum>32 || signum==SIGKILL || signum==SIGSTOP)
93 return -EINVAL;
94 tmp.sa_handler = (void (*)(int)) handler;
95 tmp.sa_mask = 0;
96 tmp.sa_flags = SA_ONESHOT | SA_NOMASK;
97 tmp.sa_restorer = (void (*)(void)) restorer;
98 handler = (long) current->sigaction[signum-1].sa_handler;
99 current->sigaction[signum-1] = tmp;
100 return handler;
101 }
102
103 int sys_sigaction(int signum, const struct sigaction * action,
104 struct sigaction * oldaction)
105 {
106 struct sigaction tmp;
107
108 if (signum<1 || signum>32 || signum==SIGKILL || signum==SIGSTOP)
109 return -EINVAL;
110 tmp = current->sigaction[signum-1];
111 get_new((char *) action,
112 (char *) (signum-1+current->sigaction));
113 if (oldaction)
114 save_old((char *) &tmp,(char *) oldaction);
115 if (current->sigaction[signum-1].sa_flags & SA_NOMASK)
116 current->sigaction[signum-1].sa_mask = 0;
117 else
118 current->sigaction[signum-1].sa_mask |= (1<<(signum-1));
119 return 0;
120 }
121
122
123
124
125
126 int core_dump(long signr)
127 {
128 return(0);
129 }
130
131 extern int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
132
133 int do_signal(long signr,long ebx, long ecx, long edx,
134 long esi, long edi, long ebp, long eax,
135 long ds, long es, long fs, long gs,
136 long orig_eax,
137 long eip, long cs, long eflags,
138 unsigned long * esp, long ss)
139 {
140 unsigned long sa_handler;
141 long old_eip=eip;
142 struct sigaction * sa = current->sigaction + signr - 1;
143 int longs;
144
145 unsigned long * tmp_esp;
146
147 #ifdef notdef
148 printk("pid: %d, signr: %x, eax=%d, oeax = %d, int=%d\n",
149 current->pid, signr, eax, orig_eax,
150 sa->sa_flags & SA_INTERRUPT);
151 #endif
152 if ((orig_eax != -1) &&
153 ((eax == -ERESTARTSYS) || (eax == -ERESTARTNOINTR))) {
154 if ((eax == -ERESTARTSYS) && ((sa->sa_flags & SA_INTERRUPT) ||
155 signr < SIGCONT || signr > SIGTTOU))
156 *(&eax) = -EINTR;
157 else {
158 *(&eax) = orig_eax;
159 *(&eip) = old_eip -= 2;
160 }
161 }
162 sa_handler = (unsigned long) sa->sa_handler;
163 if (sa_handler==1) {
164
165 if (signr == SIGCHLD)
166 while (sys_waitpid(-1,NULL,WNOHANG) > 0)
167 ;
168 return(1);
169 }
170 if (!sa_handler) {
171 switch (signr) {
172 case SIGCONT:
173 case SIGCHLD:
174 case SIGWINCH:
175 return(1);
176
177 case SIGSTOP:
178 case SIGTSTP:
179 case SIGTTIN:
180 case SIGTTOU:
181 current->state = TASK_STOPPED;
182 current->exit_code = signr;
183 if (!(current->p_pptr->sigaction[SIGCHLD-1].sa_flags &
184 SA_NOCLDSTOP))
185 send_sig(SIGCHLD, current->p_pptr, 1);
186
187
188 return(1);
189
190 case SIGQUIT:
191 case SIGILL:
192 case SIGTRAP:
193 case SIGIOT:
194 case SIGFPE:
195 case SIGSEGV:
196 if (core_dump(signr))
197 do_exit(signr|0x80);
198
199 default:
200 do_exit(signr);
201 }
202 }
203
204
205
206 if (sa->sa_flags & SA_ONESHOT)
207 sa->sa_handler = NULL;
208 *(&eip) = sa_handler;
209 longs = (sa->sa_flags & SA_NOMASK)?7:8;
210 *(&esp) -= longs;
211 verify_area(esp,longs*4);
212 tmp_esp=esp;
213 put_fs_long((long) sa->sa_restorer,tmp_esp++);
214 put_fs_long(signr,tmp_esp++);
215 if (!(sa->sa_flags & SA_NOMASK))
216 put_fs_long(current->blocked,tmp_esp++);
217 put_fs_long(eax,tmp_esp++);
218 put_fs_long(ecx,tmp_esp++);
219 put_fs_long(edx,tmp_esp++);
220 put_fs_long(eflags,tmp_esp++);
221 put_fs_long(old_eip,tmp_esp++);
222 current->blocked |= sa->sa_mask;
223
224 __asm__("testb $0,%%fs:%0"::"m" (*(char *) sa_handler));
225 return(0);
226 }