xref: /freebsd/sys/compat/linux/linux_signal.c (revision c21dee177fdd039bd54a169d52bad2c66942d766)
1c21dee17SSøren Schmidt /*-
2c21dee17SSøren Schmidt  * Copyright (c) 1994-1995 S�ren Schmidt
3c21dee17SSøren Schmidt  * All rights reserved.
4c21dee17SSøren Schmidt  *
5c21dee17SSøren Schmidt  * Redistribution and use in source and binary forms, with or without
6c21dee17SSøren Schmidt  * modification, are permitted provided that the following conditions
7c21dee17SSøren Schmidt  * are met:
8c21dee17SSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
9c21dee17SSøren Schmidt  *    notice, this list of conditions and the following disclaimer
10c21dee17SSøren Schmidt  *    in this position and unchanged.
11c21dee17SSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
12c21dee17SSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
13c21dee17SSøren Schmidt  *    documentation and/or other materials provided with the distribution.
14c21dee17SSøren Schmidt  * 3. The name of the author may not be used to endorse or promote products
15c21dee17SSøren Schmidt  *    derived from this software withough specific prior written permission
16c21dee17SSøren Schmidt  *
17c21dee17SSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18c21dee17SSøren Schmidt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19c21dee17SSøren Schmidt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20c21dee17SSøren Schmidt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21c21dee17SSøren Schmidt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22c21dee17SSøren Schmidt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23c21dee17SSøren Schmidt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24c21dee17SSøren Schmidt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25c21dee17SSøren Schmidt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26c21dee17SSøren Schmidt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27c21dee17SSøren Schmidt  *
28c21dee17SSøren Schmidt  *  $Id: linux_signal.c,v 1.2 1995/06/07 21:27:57 sos Exp $
29c21dee17SSøren Schmidt  */
30c21dee17SSøren Schmidt 
31c21dee17SSøren Schmidt #include <sys/param.h>
32c21dee17SSøren Schmidt #include <sys/systm.h>
33c21dee17SSøren Schmidt #include <sys/proc.h>
34c21dee17SSøren Schmidt #include <sys/exec.h>
35c21dee17SSøren Schmidt #include <sys/signal.h>
36c21dee17SSøren Schmidt #include <sys/signalvar.h>
37c21dee17SSøren Schmidt 
38c21dee17SSøren Schmidt #include <vm/vm.h>
39c21dee17SSøren Schmidt 
40c21dee17SSøren Schmidt #include <i386/linux/linux.h>
41c21dee17SSøren Schmidt 
42c21dee17SSøren Schmidt #define DONTMASK    (sigmask(SIGKILL)|sigmask(SIGSTOP)|sigmask(SIGCHLD))
43c21dee17SSøren Schmidt 
44c21dee17SSøren Schmidt static sigset_t
45c21dee17SSøren Schmidt linux_to_bsd_sigmask(linux_sigset_t mask) {
46c21dee17SSøren Schmidt     int i;
47c21dee17SSøren Schmidt     sigset_t new = 0;
48c21dee17SSøren Schmidt 
49c21dee17SSøren Schmidt     for (i = 1; i <= LINUX_NSIG; i++)
50c21dee17SSøren Schmidt 	if (mask & (1 << i-1))
51c21dee17SSøren Schmidt 	    new |= (1 << (linux_to_bsd_signal[i]-1));
52c21dee17SSøren Schmidt     return new;
53c21dee17SSøren Schmidt }
54c21dee17SSøren Schmidt 
55c21dee17SSøren Schmidt static linux_sigset_t
56c21dee17SSøren Schmidt bsd_to_linux_sigmask(sigset_t mask) {
57c21dee17SSøren Schmidt     int i;
58c21dee17SSøren Schmidt     sigset_t new = 0;
59c21dee17SSøren Schmidt 
60c21dee17SSøren Schmidt     for (i = 1; i <= NSIG; i++)
61c21dee17SSøren Schmidt 	if (mask & (1 << i-1))
62c21dee17SSøren Schmidt 	    new |= (1 << (bsd_to_linux_signal[i]-1));
63c21dee17SSøren Schmidt     return new;
64c21dee17SSøren Schmidt }
65c21dee17SSøren Schmidt 
66c21dee17SSøren Schmidt struct linux_sigaction_args {
67c21dee17SSøren Schmidt     int sig;
68c21dee17SSøren Schmidt     linux_sigaction_t *nsa;
69c21dee17SSøren Schmidt     linux_sigaction_t *osa;
70c21dee17SSøren Schmidt };
71c21dee17SSøren Schmidt 
72c21dee17SSøren Schmidt int
73c21dee17SSøren Schmidt linux_sigaction(struct proc *p, struct linux_sigaction_args *args, int *retval)
74c21dee17SSøren Schmidt {
75c21dee17SSøren Schmidt     linux_sigaction_t linux_sa;
76c21dee17SSøren Schmidt     struct sigaction *nsa = NULL, *osa = NULL, bsd_sa;
77c21dee17SSøren Schmidt     struct sigaction_args {
78c21dee17SSøren Schmidt 	int sig;
79c21dee17SSøren Schmidt 	struct sigaction *nsa;
80c21dee17SSøren Schmidt 	struct sigaction *osa;
81c21dee17SSøren Schmidt     } sa;
82c21dee17SSøren Schmidt     int error;
83c21dee17SSøren Schmidt 
84c21dee17SSøren Schmidt #ifdef DEBUG
85c21dee17SSøren Schmidt     printf("Linux-emul(%d): sigaction(%d, *, *)\n", p->p_pid, args->sig);
86c21dee17SSøren Schmidt #endif
87c21dee17SSøren Schmidt     if (args->osa)
88c21dee17SSøren Schmidt 	osa = (struct sigaction *)ua_alloc_init(sizeof(struct sigaction));
89c21dee17SSøren Schmidt 
90c21dee17SSøren Schmidt     if (args->nsa) {
91c21dee17SSøren Schmidt 	nsa = (struct sigaction *)ua_alloc(sizeof(struct sigaction));
92c21dee17SSøren Schmidt 	if (error = copyin(args->nsa, &linux_sa, sizeof(linux_sigaction_t)))
93c21dee17SSøren Schmidt 	    return error;
94c21dee17SSøren Schmidt 	bsd_sa.sa_mask = linux_to_bsd_sigmask(linux_sa.sa_mask);
95c21dee17SSøren Schmidt 	bsd_sa.sa_handler = linux_sa.sa_handler;
96c21dee17SSøren Schmidt 	bsd_sa.sa_flags = 0;
97c21dee17SSøren Schmidt 	if (linux_sa.sa_flags & LINUX_SA_NOCLDSTOP)
98c21dee17SSøren Schmidt 	    bsd_sa.sa_flags |= SA_NOCLDSTOP;
99c21dee17SSøren Schmidt 	if (linux_sa.sa_flags & LINUX_SA_ONSTACK)
100c21dee17SSøren Schmidt 	    bsd_sa.sa_flags |= SA_ONSTACK;
101c21dee17SSøren Schmidt 	if (linux_sa.sa_flags & LINUX_SA_RESTART)
102c21dee17SSøren Schmidt 	    bsd_sa.sa_flags |= SA_RESTART;
103c21dee17SSøren Schmidt 	if (error = copyout(&bsd_sa, nsa, sizeof(struct sigaction)))
104c21dee17SSøren Schmidt 	    return error;
105c21dee17SSøren Schmidt     }
106c21dee17SSøren Schmidt     sa.sig = linux_to_bsd_signal[args->sig];
107c21dee17SSøren Schmidt     sa.nsa = nsa;
108c21dee17SSøren Schmidt     sa.osa = osa;
109c21dee17SSøren Schmidt     if ((error = sigaction(p, &sa, retval)))
110c21dee17SSøren Schmidt 	return error;
111c21dee17SSøren Schmidt 
112c21dee17SSøren Schmidt     if (args->osa) {
113c21dee17SSøren Schmidt 	if (error = copyin(osa, &bsd_sa, sizeof(struct sigaction)))
114c21dee17SSøren Schmidt 	    return error;
115c21dee17SSøren Schmidt 	linux_sa.sa_handler = bsd_sa.sa_handler;
116c21dee17SSøren Schmidt 	linux_sa.sa_restorer = NULL;
117c21dee17SSøren Schmidt 	linux_sa.sa_mask = bsd_to_linux_sigmask(bsd_sa.sa_mask);
118c21dee17SSøren Schmidt 	linux_sa.sa_flags = 0;
119c21dee17SSøren Schmidt 	if (bsd_sa.sa_flags & SA_NOCLDSTOP)
120c21dee17SSøren Schmidt 	    linux_sa.sa_flags |= LINUX_SA_NOCLDSTOP;
121c21dee17SSøren Schmidt 	if (bsd_sa.sa_flags & SA_ONSTACK)
122c21dee17SSøren Schmidt 	    linux_sa.sa_flags |= LINUX_SA_ONSTACK;
123c21dee17SSøren Schmidt 	if (bsd_sa.sa_flags & SA_RESTART)
124c21dee17SSøren Schmidt 	    linux_sa.sa_flags |= LINUX_SA_RESTART;
125c21dee17SSøren Schmidt 	if (error = copyout(&linux_sa, args->osa, sizeof(linux_sigaction_t)))
126c21dee17SSøren Schmidt 	    return error;
127c21dee17SSøren Schmidt     }
128c21dee17SSøren Schmidt     return 0;
129c21dee17SSøren Schmidt }
130c21dee17SSøren Schmidt 
131c21dee17SSøren Schmidt struct linux_sigprocmask_args {
132c21dee17SSøren Schmidt     int how;
133c21dee17SSøren Schmidt     linux_sigset_t *mask;
134c21dee17SSøren Schmidt     linux_sigset_t *omask;
135c21dee17SSøren Schmidt };
136c21dee17SSøren Schmidt 
137c21dee17SSøren Schmidt int
138c21dee17SSøren Schmidt linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args,
139c21dee17SSøren Schmidt 		  int *retval)
140c21dee17SSøren Schmidt {
141c21dee17SSøren Schmidt     int error, s;
142c21dee17SSøren Schmidt     sigset_t mask;
143c21dee17SSøren Schmidt     sigset_t omask;
144c21dee17SSøren Schmidt 
145c21dee17SSøren Schmidt #ifdef DEBUG
146c21dee17SSøren Schmidt     printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how);
147c21dee17SSøren Schmidt #endif
148c21dee17SSøren Schmidt     if (args->omask != NULL) {
149c21dee17SSøren Schmidt 	omask = bsd_to_linux_sigmask(p->p_sigmask);
150c21dee17SSøren Schmidt 	if (error = copyout(&omask, args->omask, sizeof(sigset_t)))
151c21dee17SSøren Schmidt 	    return error;
152c21dee17SSøren Schmidt     }
153c21dee17SSøren Schmidt     if (!(args->mask))
154c21dee17SSøren Schmidt 	return 0;
155c21dee17SSøren Schmidt     if (error = copyin(args->mask, &mask, sizeof(linux_sigset_t)))
156c21dee17SSøren Schmidt 	return error;
157c21dee17SSøren Schmidt 
158c21dee17SSøren Schmidt     mask = linux_to_bsd_sigmask(mask);
159c21dee17SSøren Schmidt     s = splhigh();
160c21dee17SSøren Schmidt     switch (args->how) {
161c21dee17SSøren Schmidt     case LINUX_SIG_BLOCK:
162c21dee17SSøren Schmidt 	p->p_sigmask |= (mask & ~DONTMASK);
163c21dee17SSøren Schmidt 	break;
164c21dee17SSøren Schmidt     case LINUX_SIG_UNBLOCK:
165c21dee17SSøren Schmidt 	p->p_sigmask &= ~mask;
166c21dee17SSøren Schmidt 	break;
167c21dee17SSøren Schmidt     case LINUX_SIG_SETMASK:
168c21dee17SSøren Schmidt 	p->p_sigmask = (mask & ~DONTMASK);
169c21dee17SSøren Schmidt 	break;
170c21dee17SSøren Schmidt     default:
171c21dee17SSøren Schmidt 	error = EINVAL;
172c21dee17SSøren Schmidt 	break;
173c21dee17SSøren Schmidt     }
174c21dee17SSøren Schmidt     splx(s);
175c21dee17SSøren Schmidt     return error;
176c21dee17SSøren Schmidt }
177c21dee17SSøren Schmidt 
178c21dee17SSøren Schmidt int
179c21dee17SSøren Schmidt linux_siggetmask(struct proc *p, void *args, int *retval)
180c21dee17SSøren Schmidt {
181c21dee17SSøren Schmidt #ifdef DEBUG
182c21dee17SSøren Schmidt     printf("Linux-emul(%d): siggetmask()\n", p->p_pid);
183c21dee17SSøren Schmidt #endif
184c21dee17SSøren Schmidt     *retval = bsd_to_linux_sigmask(p->p_sigmask);
185c21dee17SSøren Schmidt     return 0;
186c21dee17SSøren Schmidt }
187c21dee17SSøren Schmidt 
188c21dee17SSøren Schmidt struct linux_sigsetmask_args {
189c21dee17SSøren Schmidt     linux_sigset_t mask;
190c21dee17SSøren Schmidt };
191c21dee17SSøren Schmidt 
192c21dee17SSøren Schmidt int
193c21dee17SSøren Schmidt linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args,int *retval)
194c21dee17SSøren Schmidt {
195c21dee17SSøren Schmidt     int s;
196c21dee17SSøren Schmidt 
197c21dee17SSøren Schmidt #ifdef DEBUG
198c21dee17SSøren Schmidt     printf("Linux-emul(%d): sigsetmask(%08x)\n", p->p_pid, args->mask);
199c21dee17SSøren Schmidt #endif
200c21dee17SSøren Schmidt     s = splhigh();
201c21dee17SSøren Schmidt     p->p_sigmask = (linux_to_bsd_sigmask(args->mask) & ~DONTMASK);
202c21dee17SSøren Schmidt     splx(s);
203c21dee17SSøren Schmidt     *retval = bsd_to_linux_sigmask(p->p_sigmask);
204c21dee17SSøren Schmidt     return 0;
205c21dee17SSøren Schmidt }
206c21dee17SSøren Schmidt 
207c21dee17SSøren Schmidt struct linux_sigpending_args {
208c21dee17SSøren Schmidt     linux_sigset_t *mask;
209c21dee17SSøren Schmidt };
210c21dee17SSøren Schmidt 
211c21dee17SSøren Schmidt int
212c21dee17SSøren Schmidt linux_sigpending(struct proc *p, struct linux_sigpending_args *args,int *retval)
213c21dee17SSøren Schmidt {
214c21dee17SSøren Schmidt     linux_sigset_t linux_sig;
215c21dee17SSøren Schmidt 
216c21dee17SSøren Schmidt #ifdef DEBUG
217c21dee17SSøren Schmidt     printf("Linux-emul(%d): sigpending(*)\n", p->p_pid);
218c21dee17SSøren Schmidt #endif
219c21dee17SSøren Schmidt     linux_sig = bsd_to_linux_sigmask(p->p_siglist & p->p_sigmask);
220c21dee17SSøren Schmidt     return copyout(&linux_sig, args->mask, sizeof(linux_sig));
221c21dee17SSøren Schmidt }
222c21dee17SSøren Schmidt 
223c21dee17SSøren Schmidt struct linux_sigsuspend_args {
224c21dee17SSøren Schmidt     linux_sigset_t mask;
225c21dee17SSøren Schmidt };
226c21dee17SSøren Schmidt 
227c21dee17SSøren Schmidt int
228c21dee17SSøren Schmidt linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args,int *retval)
229c21dee17SSøren Schmidt {
230c21dee17SSøren Schmidt     sigset_t tmp;
231c21dee17SSøren Schmidt 
232c21dee17SSøren Schmidt #ifdef DEBUG
233c21dee17SSøren Schmidt     printf("Linux-emul(%d): sigsuspend(%08x)\n", p->p_pid, args->mask);
234c21dee17SSøren Schmidt #endif
235c21dee17SSøren Schmidt     tmp = linux_to_bsd_sigmask(args->mask);
236c21dee17SSøren Schmidt     return sigsuspend(p, &tmp , retval);
237c21dee17SSøren Schmidt }
238c21dee17SSøren Schmidt 
239c21dee17SSøren Schmidt struct linux_kill_args {
240c21dee17SSøren Schmidt     int pid;
241c21dee17SSøren Schmidt     int signum;
242c21dee17SSøren Schmidt };
243c21dee17SSøren Schmidt 
244c21dee17SSøren Schmidt int
245c21dee17SSøren Schmidt linux_kill(struct proc *p, struct linux_kill_args *args, int *retval)
246c21dee17SSøren Schmidt {
247c21dee17SSøren Schmidt     struct {
248c21dee17SSøren Schmidt 	int pid;
249c21dee17SSøren Schmidt 	int signum;
250c21dee17SSøren Schmidt     } tmp;
251c21dee17SSøren Schmidt 
252c21dee17SSøren Schmidt #ifdef DEBUG
253c21dee17SSøren Schmidt     printf("Linux-emul(%d): kill(%d, %d)\n",
254c21dee17SSøren Schmidt 	   p->p_pid, args->pid, args->signum);
255c21dee17SSøren Schmidt #endif
256c21dee17SSøren Schmidt     tmp.pid = args->pid;
257c21dee17SSøren Schmidt     tmp.signum = linux_to_bsd_signal[args->signum];
258c21dee17SSøren Schmidt     return kill(p, &tmp, retval);
259c21dee17SSøren Schmidt }
260