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