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 * 28d66a5066SPeter Wemm * $Id: linux_signal.c,v 1.3 1995/12/15 03:06:56 peter Exp $ 29c21dee17SSøren Schmidt */ 30c21dee17SSøren Schmidt 31c21dee17SSøren Schmidt #include <sys/param.h> 32c21dee17SSøren Schmidt #include <sys/systm.h> 331f3dad5aSBruce Evans #include <sys/sysproto.h> 34c21dee17SSøren Schmidt #include <sys/proc.h> 35c21dee17SSøren Schmidt #include <sys/exec.h> 36c21dee17SSøren Schmidt #include <sys/signal.h> 37c21dee17SSøren Schmidt #include <sys/signalvar.h> 38c21dee17SSøren Schmidt 39c21dee17SSøren Schmidt #include <i386/linux/linux.h> 40d66a5066SPeter Wemm #include <i386/linux/linux_proto.h> 41d66a5066SPeter Wemm #include <i386/linux/linux_util.h> 42c21dee17SSøren Schmidt 43c21dee17SSøren Schmidt static sigset_t 44d66a5066SPeter Wemm linux_to_bsd_sigset(linux_sigset_t mask) { 45d66a5066SPeter Wemm int b, l; 46c21dee17SSøren Schmidt sigset_t new = 0; 47c21dee17SSøren Schmidt 48d66a5066SPeter Wemm for (l = 1; l <= LINUX_NSIG; l++) { 49d66a5066SPeter Wemm if (mask & (1 << (l - 1))) { 50d66a5066SPeter Wemm if ((b = linux_to_bsd_signal[l])) 51d66a5066SPeter Wemm new |= (1 << (b - 1)); 52d66a5066SPeter Wemm } 53d66a5066SPeter Wemm } 54c21dee17SSøren Schmidt return new; 55c21dee17SSøren Schmidt } 56c21dee17SSøren Schmidt 57c21dee17SSøren Schmidt static linux_sigset_t 58d66a5066SPeter Wemm bsd_to_linux_sigset(sigset_t mask) { 59d66a5066SPeter Wemm int b, l; 60c21dee17SSøren Schmidt sigset_t new = 0; 61c21dee17SSøren Schmidt 62d66a5066SPeter Wemm for (b = 1; b <= NSIG; b++) { 63d66a5066SPeter Wemm if (mask & (1 << (b - 1))) { 64d66a5066SPeter Wemm if ((l = bsd_to_linux_signal[b])) 65d66a5066SPeter Wemm new |= (1 << (l - 1)); 66d66a5066SPeter Wemm } 67d66a5066SPeter Wemm } 68c21dee17SSøren Schmidt return new; 69c21dee17SSøren Schmidt } 70c21dee17SSøren Schmidt 71d66a5066SPeter Wemm void 72d66a5066SPeter Wemm linux_to_bsd_sigaction(linux_sigaction_t *lsa, struct sigaction *bsa) 73d66a5066SPeter Wemm { 74d66a5066SPeter Wemm bsa->sa_mask = linux_to_bsd_sigset(lsa->sa_mask); 75d66a5066SPeter Wemm bsa->sa_handler = lsa->sa_handler; 76d66a5066SPeter Wemm bsa->sa_flags = 0; 77d66a5066SPeter Wemm if (lsa->sa_flags & LINUX_SA_NOCLDSTOP) 78d66a5066SPeter Wemm bsa->sa_flags |= SA_NOCLDSTOP; 79d66a5066SPeter Wemm if (lsa->sa_flags & LINUX_SA_ONSTACK) 80d66a5066SPeter Wemm bsa->sa_flags |= SA_ONSTACK; 81d66a5066SPeter Wemm if (lsa->sa_flags & LINUX_SA_RESTART) 82d66a5066SPeter Wemm bsa->sa_flags |= SA_RESTART; 83d66a5066SPeter Wemm if (lsa->sa_flags & LINUX_SA_ONESHOT) 84d66a5066SPeter Wemm bsa->sa_flags |= SA_RESETHAND; 85d66a5066SPeter Wemm if (lsa->sa_flags & LINUX_SA_NOMASK) 86d66a5066SPeter Wemm bsa->sa_flags |= SA_NODEFER; 87d66a5066SPeter Wemm } 88d66a5066SPeter Wemm 89d66a5066SPeter Wemm void 90d66a5066SPeter Wemm bsd_to_linux_sigaction(struct sigaction *bsa, linux_sigaction_t *lsa) 91d66a5066SPeter Wemm { 92d66a5066SPeter Wemm lsa->sa_handler = bsa->sa_handler; 93d66a5066SPeter Wemm lsa->sa_restorer = NULL; /* unsupported */ 94d66a5066SPeter Wemm lsa->sa_mask = bsd_to_linux_sigset(bsa->sa_mask); 95d66a5066SPeter Wemm lsa->sa_flags = 0; 96d66a5066SPeter Wemm if (bsa->sa_flags & SA_NOCLDSTOP) 97d66a5066SPeter Wemm lsa->sa_flags |= LINUX_SA_NOCLDSTOP; 98d66a5066SPeter Wemm if (bsa->sa_flags & SA_ONSTACK) 99d66a5066SPeter Wemm lsa->sa_flags |= LINUX_SA_ONSTACK; 100d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESTART) 101d66a5066SPeter Wemm lsa->sa_flags |= LINUX_SA_RESTART; 102d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESETHAND) 103d66a5066SPeter Wemm lsa->sa_flags |= LINUX_SA_ONESHOT; 104d66a5066SPeter Wemm if (bsa->sa_flags & SA_NODEFER) 105d66a5066SPeter Wemm lsa->sa_flags |= LINUX_SA_NOMASK; 106d66a5066SPeter Wemm } 107c21dee17SSøren Schmidt 108c21dee17SSøren Schmidt int 109c21dee17SSøren Schmidt linux_sigaction(struct proc *p, struct linux_sigaction_args *args, int *retval) 110c21dee17SSøren Schmidt { 111c21dee17SSøren Schmidt linux_sigaction_t linux_sa; 112c21dee17SSøren Schmidt struct sigaction *nsa = NULL, *osa = NULL, bsd_sa; 113d66a5066SPeter Wemm struct sigaction_args sa; 114c21dee17SSøren Schmidt int error; 115d66a5066SPeter Wemm caddr_t sg = stackgap_init(); 116c21dee17SSøren Schmidt 117c21dee17SSøren Schmidt #ifdef DEBUG 118d66a5066SPeter Wemm printf("Linux-emul(%d): sigaction(%d, %08x, %08x)\n", p->p_pid, args->sig, 119d66a5066SPeter Wemm args->nsa, args->osa); 120c21dee17SSøren Schmidt #endif 121d66a5066SPeter Wemm 122c21dee17SSøren Schmidt if (args->osa) 123d66a5066SPeter Wemm osa = (struct sigaction *)stackgap_alloc(&sg, sizeof(struct sigaction)); 124c21dee17SSøren Schmidt 125c21dee17SSøren Schmidt if (args->nsa) { 126d66a5066SPeter Wemm nsa = (struct sigaction *)stackgap_alloc(&sg, sizeof(struct sigaction)); 127c21dee17SSøren Schmidt if (error = copyin(args->nsa, &linux_sa, sizeof(linux_sigaction_t))) 128c21dee17SSøren Schmidt return error; 129d66a5066SPeter Wemm linux_to_bsd_sigaction(&linux_sa, &bsd_sa); 130c21dee17SSøren Schmidt if (error = copyout(&bsd_sa, nsa, sizeof(struct sigaction))) 131c21dee17SSøren Schmidt return error; 132c21dee17SSøren Schmidt } 133ef04503dSPeter Wemm sa.signum = linux_to_bsd_signal[args->sig]; 134c21dee17SSøren Schmidt sa.nsa = nsa; 135c21dee17SSøren Schmidt sa.osa = osa; 136c21dee17SSøren Schmidt if ((error = sigaction(p, &sa, retval))) 137c21dee17SSøren Schmidt return error; 138c21dee17SSøren Schmidt 139c21dee17SSøren Schmidt if (args->osa) { 140c21dee17SSøren Schmidt if (error = copyin(osa, &bsd_sa, sizeof(struct sigaction))) 141c21dee17SSøren Schmidt return error; 142d66a5066SPeter Wemm bsd_to_linux_sigaction(&bsd_sa, &linux_sa); 143c21dee17SSøren Schmidt if (error = copyout(&linux_sa, args->osa, sizeof(linux_sigaction_t))) 144c21dee17SSøren Schmidt return error; 145c21dee17SSøren Schmidt } 146c21dee17SSøren Schmidt return 0; 147c21dee17SSøren Schmidt } 148c21dee17SSøren Schmidt 149d66a5066SPeter Wemm int 150d66a5066SPeter Wemm linux_signal(struct proc *p, struct linux_signal_args *args, int *retval) 151d66a5066SPeter Wemm { 152d66a5066SPeter Wemm caddr_t sg; 153d66a5066SPeter Wemm struct sigaction_args sa_args; 154d66a5066SPeter Wemm struct sigaction *osa, *nsa, tmpsa; 155d66a5066SPeter Wemm int error; 156d66a5066SPeter Wemm 157d66a5066SPeter Wemm #ifdef DEBUG 158d66a5066SPeter Wemm printf("Linux-emul(%d): signal(%d, %08x)\n", p->p_pid, 159d66a5066SPeter Wemm args->sig, args->handler); 160d66a5066SPeter Wemm #endif 161d66a5066SPeter Wemm sg = stackgap_init(); 162d66a5066SPeter Wemm nsa = stackgap_alloc(&sg, sizeof *nsa); 163d66a5066SPeter Wemm osa = stackgap_alloc(&sg, sizeof *osa); 164d66a5066SPeter Wemm 165d66a5066SPeter Wemm tmpsa.sa_handler = args->handler; 166d66a5066SPeter Wemm tmpsa.sa_mask = (sigset_t) 0; 167d66a5066SPeter Wemm tmpsa.sa_flags = SA_RESETHAND | SA_NODEFER; 168d66a5066SPeter Wemm if ((error = copyout(&tmpsa, nsa, sizeof tmpsa))) 169d66a5066SPeter Wemm return error; 170d66a5066SPeter Wemm 171d66a5066SPeter Wemm sa_args.signum = linux_to_bsd_signal[args->sig]; 172d66a5066SPeter Wemm sa_args.osa = osa; 173d66a5066SPeter Wemm sa_args.nsa = nsa; 174d66a5066SPeter Wemm if ((error = sigaction(p, &sa_args, retval))) 175d66a5066SPeter Wemm return error; 176d66a5066SPeter Wemm 177d66a5066SPeter Wemm if ((error = copyin(osa, &tmpsa, sizeof *osa))) 178d66a5066SPeter Wemm return error; 179d66a5066SPeter Wemm 180d66a5066SPeter Wemm *retval = (int)tmpsa.sa_handler; 181d66a5066SPeter Wemm 182d66a5066SPeter Wemm return 0; 183d66a5066SPeter Wemm } 184d66a5066SPeter Wemm 185c21dee17SSøren Schmidt 186c21dee17SSøren Schmidt int 187c21dee17SSøren Schmidt linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args, 188c21dee17SSøren Schmidt int *retval) 189c21dee17SSøren Schmidt { 190c21dee17SSøren Schmidt int error, s; 191c21dee17SSøren Schmidt sigset_t mask; 192c21dee17SSøren Schmidt sigset_t omask; 193c21dee17SSøren Schmidt 194c21dee17SSøren Schmidt #ifdef DEBUG 195c21dee17SSøren Schmidt printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how); 196c21dee17SSøren Schmidt #endif 197d66a5066SPeter Wemm 198d66a5066SPeter Wemm *retval = 0; 199d66a5066SPeter Wemm 200c21dee17SSøren Schmidt if (args->omask != NULL) { 201d66a5066SPeter Wemm omask = bsd_to_linux_sigset(p->p_sigmask); 202c21dee17SSøren Schmidt if (error = copyout(&omask, args->omask, sizeof(sigset_t))) 203c21dee17SSøren Schmidt return error; 204c21dee17SSøren Schmidt } 205c21dee17SSøren Schmidt if (!(args->mask)) 206c21dee17SSøren Schmidt return 0; 207c21dee17SSøren Schmidt if (error = copyin(args->mask, &mask, sizeof(linux_sigset_t))) 208c21dee17SSøren Schmidt return error; 209c21dee17SSøren Schmidt 210d66a5066SPeter Wemm mask = linux_to_bsd_sigset(mask); 211c21dee17SSøren Schmidt s = splhigh(); 212c21dee17SSøren Schmidt switch (args->how) { 213c21dee17SSøren Schmidt case LINUX_SIG_BLOCK: 214d66a5066SPeter Wemm p->p_sigmask |= (mask & ~sigcantmask); 215c21dee17SSøren Schmidt break; 216c21dee17SSøren Schmidt case LINUX_SIG_UNBLOCK: 217c21dee17SSøren Schmidt p->p_sigmask &= ~mask; 218c21dee17SSøren Schmidt break; 219c21dee17SSøren Schmidt case LINUX_SIG_SETMASK: 220d66a5066SPeter Wemm p->p_sigmask = (mask & ~sigcantmask); 221c21dee17SSøren Schmidt break; 222c21dee17SSøren Schmidt default: 223c21dee17SSøren Schmidt error = EINVAL; 224c21dee17SSøren Schmidt break; 225c21dee17SSøren Schmidt } 226c21dee17SSøren Schmidt splx(s); 227c21dee17SSøren Schmidt return error; 228c21dee17SSøren Schmidt } 229c21dee17SSøren Schmidt 230c21dee17SSøren Schmidt int 231d66a5066SPeter Wemm linux_siggetmask(struct proc *p, struct linux_siggetmask_args *args, int *retval) 232c21dee17SSøren Schmidt { 233c21dee17SSøren Schmidt #ifdef DEBUG 234c21dee17SSøren Schmidt printf("Linux-emul(%d): siggetmask()\n", p->p_pid); 235c21dee17SSøren Schmidt #endif 236d66a5066SPeter Wemm *retval = bsd_to_linux_sigset(p->p_sigmask); 237c21dee17SSøren Schmidt return 0; 238c21dee17SSøren Schmidt } 239c21dee17SSøren Schmidt 240c21dee17SSøren Schmidt int 241c21dee17SSøren Schmidt linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args,int *retval) 242c21dee17SSøren Schmidt { 243c21dee17SSøren Schmidt int s; 244d66a5066SPeter Wemm sigset_t mask; 245c21dee17SSøren Schmidt 246c21dee17SSøren Schmidt #ifdef DEBUG 247c21dee17SSøren Schmidt printf("Linux-emul(%d): sigsetmask(%08x)\n", p->p_pid, args->mask); 248c21dee17SSøren Schmidt #endif 249d66a5066SPeter Wemm *retval = bsd_to_linux_sigset(p->p_sigmask); 250d66a5066SPeter Wemm 251d66a5066SPeter Wemm mask = linux_to_bsd_sigset(args->mask); 252c21dee17SSøren Schmidt s = splhigh(); 253d66a5066SPeter Wemm p->p_sigmask = mask & ~sigcantmask; 254c21dee17SSøren Schmidt splx(s); 255c21dee17SSøren Schmidt return 0; 256c21dee17SSøren Schmidt } 257c21dee17SSøren Schmidt 258c21dee17SSøren Schmidt int 259c21dee17SSøren Schmidt linux_sigpending(struct proc *p, struct linux_sigpending_args *args,int *retval) 260c21dee17SSøren Schmidt { 261c21dee17SSøren Schmidt linux_sigset_t linux_sig; 262c21dee17SSøren Schmidt 263c21dee17SSøren Schmidt #ifdef DEBUG 264c21dee17SSøren Schmidt printf("Linux-emul(%d): sigpending(*)\n", p->p_pid); 265c21dee17SSøren Schmidt #endif 266d66a5066SPeter Wemm linux_sig = bsd_to_linux_sigset(p->p_siglist & p->p_sigmask); 267c21dee17SSøren Schmidt return copyout(&linux_sig, args->mask, sizeof(linux_sig)); 268c21dee17SSøren Schmidt } 269c21dee17SSøren Schmidt 270c21dee17SSøren Schmidt int 271c21dee17SSøren Schmidt linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args,int *retval) 272c21dee17SSøren Schmidt { 273d66a5066SPeter Wemm struct sigsuspend_args tmp; 274d66a5066SPeter Wemm int error; 275c21dee17SSøren Schmidt 276c21dee17SSøren Schmidt #ifdef DEBUG 277c21dee17SSøren Schmidt printf("Linux-emul(%d): sigsuspend(%08x)\n", p->p_pid, args->mask); 278c21dee17SSøren Schmidt #endif 279d66a5066SPeter Wemm tmp.mask = linux_to_bsd_sigset(args->mask); 280c21dee17SSøren Schmidt return sigsuspend(p, &tmp , retval); 281c21dee17SSøren Schmidt } 282c21dee17SSøren Schmidt 283d66a5066SPeter Wemm int 284d66a5066SPeter Wemm linux_pause(struct proc *p, struct linux_pause_args *args,int *retval) 285d66a5066SPeter Wemm { 286d66a5066SPeter Wemm struct sigsuspend_args tmp; 287d66a5066SPeter Wemm int error; 288d66a5066SPeter Wemm 289d66a5066SPeter Wemm #ifdef DEBUG 290d66a5066SPeter Wemm printf("Linux-emul(%d): pause()\n", p->p_pid); 291d66a5066SPeter Wemm #endif 292d66a5066SPeter Wemm tmp.mask = p->p_sigmask; 293d66a5066SPeter Wemm return sigsuspend(p, &tmp , retval); 294d66a5066SPeter Wemm } 295c21dee17SSøren Schmidt 296c21dee17SSøren Schmidt int 297c21dee17SSøren Schmidt linux_kill(struct proc *p, struct linux_kill_args *args, int *retval) 298c21dee17SSøren Schmidt { 299ef04503dSPeter Wemm struct kill_args /* { 300c21dee17SSøren Schmidt int pid; 301c21dee17SSøren Schmidt int signum; 302ef04503dSPeter Wemm } */ tmp; 303c21dee17SSøren Schmidt 304c21dee17SSøren Schmidt #ifdef DEBUG 305c21dee17SSøren Schmidt printf("Linux-emul(%d): kill(%d, %d)\n", 306c21dee17SSøren Schmidt p->p_pid, args->pid, args->signum); 307c21dee17SSøren Schmidt #endif 308c21dee17SSøren Schmidt tmp.pid = args->pid; 309c21dee17SSøren Schmidt tmp.signum = linux_to_bsd_signal[args->signum]; 310c21dee17SSøren Schmidt return kill(p, &tmp, retval); 311c21dee17SSøren Schmidt } 312