Home | History | Annotate | Line # | Download | only in common
linux_signal.c revision 1.4
      1 /*	$NetBSD: linux_signal.c,v 1.4 1995/06/22 21:34:39 fvdl Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1995 Frank van der Linden
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *      This product includes software developed for the NetBSD Project
     18  *      by Frank van der Linden
     19  * 4. The name of the author may not be used to endorse or promote products
     20  *    derived from this software without specific prior written permission
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  *
     33  * heavily from: svr4_signal.c,v 1.7 1995/01/09 01:04:21 christos Exp
     34  */
     35 
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 #include <sys/namei.h>
     39 #include <sys/proc.h>
     40 #include <sys/filedesc.h>
     41 #include <sys/ioctl.h>
     42 #include <sys/mount.h>
     43 #include <sys/kernel.h>
     44 #include <sys/signal.h>
     45 #include <sys/signalvar.h>
     46 #include <sys/malloc.h>
     47 #include <sys/exec.h>
     48 
     49 #include <sys/syscallargs.h>
     50 
     51 #include <compat/linux/linux_types.h>
     52 #include <compat/linux/linux_syscallargs.h>
     53 #include <compat/linux/linux_util.h>
     54 #include <compat/linux/linux_signal.h>
     55 
     56 /*
     57  * Most of ths stuff in this file is taken from Christos' SVR4 emul
     58  * code. The things that need to be done are largely the same, so
     59  * re-inventing the wheel doesn't make much sense.
     60  */
     61 
     62 /*
     63  * Some boring signal conversion functions. Just a switch() for all signals;
     64  * return the converted signal number, 0 if not supported.
     65  */
     66 
     67 int
     68 bsd_to_linux_sig(sig)
     69 	int sig;
     70 {
     71 	switch(sig) {
     72 	case SIGHUP:
     73 		return LINUX_SIGHUP;
     74 	case SIGINT:
     75 		return LINUX_SIGINT;
     76 	case SIGQUIT:
     77 		return LINUX_SIGQUIT;
     78 	case SIGILL:
     79 		return LINUX_SIGILL;
     80 	case SIGTRAP:
     81 		return LINUX_SIGTRAP;
     82 	case SIGABRT:
     83 		return LINUX_SIGABRT;
     84 	case SIGFPE:
     85 		return LINUX_SIGFPE;
     86 	case SIGKILL:
     87 		return LINUX_SIGKILL;
     88 	case SIGBUS:
     89 		return LINUX_SIGBUS;
     90 	case SIGSEGV:
     91 		return LINUX_SIGSEGV;
     92 	case SIGPIPE:
     93 		return LINUX_SIGPIPE;
     94 	case SIGALRM:
     95 		return LINUX_SIGALRM;
     96 	case SIGTERM:
     97 		return LINUX_SIGTERM;
     98 	case SIGURG:
     99 		return LINUX_SIGURG;
    100 	case SIGSTOP:
    101 		return LINUX_SIGSTOP;
    102 	case SIGTSTP:
    103 		return LINUX_SIGTSTP;
    104 	case SIGCONT:
    105 		return LINUX_SIGCONT;
    106 	case SIGCHLD:
    107 		return LINUX_SIGCHLD;
    108 	case SIGTTIN:
    109 		return LINUX_SIGTTIN;
    110 	case SIGTTOU:
    111 		return LINUX_SIGTTOU;
    112 	case SIGIO:
    113 		return LINUX_SIGIO;
    114 	case SIGXCPU:
    115 		return LINUX_SIGXCPU;
    116 	case SIGXFSZ:
    117 		return LINUX_SIGXFSZ;
    118 	case SIGVTALRM:
    119 		return LINUX_SIGVTALRM;
    120 	case SIGPROF:
    121 		return LINUX_SIGPROF;
    122 	case SIGWINCH:
    123 		return LINUX_SIGWINCH;
    124 	case SIGUSR1:
    125 		return LINUX_SIGUSR1;
    126 	case SIGUSR2:
    127 		return LINUX_SIGUSR2;
    128 	/* Not supported: EMT, SYS, INFO */
    129 	}
    130 	return 0;
    131 }
    132 
    133 int
    134 linux_to_bsd_sig(sig)
    135 	int sig;
    136 {
    137 	switch(sig) {
    138 	case LINUX_SIGHUP:
    139 		return SIGHUP;
    140 	case LINUX_SIGINT:
    141 		return SIGINT;
    142 	case LINUX_SIGQUIT:
    143 		return SIGQUIT;
    144 	case LINUX_SIGILL:
    145 		return SIGILL;
    146 	case LINUX_SIGTRAP:
    147 		return SIGTRAP;
    148 	case LINUX_SIGABRT:
    149 		return SIGABRT;
    150 	case LINUX_SIGBUS:
    151 		return SIGBUS;
    152 	case LINUX_SIGFPE:
    153 		return SIGFPE;
    154 	case LINUX_SIGKILL:
    155 		return SIGKILL;
    156 	case LINUX_SIGUSR1:
    157 		return SIGUSR1;
    158 	case LINUX_SIGSEGV:
    159 		return SIGSEGV;
    160 	case LINUX_SIGUSR2:
    161 		return SIGUSR2;
    162 	case LINUX_SIGPIPE:
    163 		return SIGPIPE;
    164 	case LINUX_SIGALRM:
    165 		return SIGALRM;
    166 	case LINUX_SIGTERM:
    167 		return SIGTERM;
    168 	case LINUX_SIGCHLD:
    169 		return SIGCHLD;
    170 	case LINUX_SIGCONT:
    171 		return SIGCONT;
    172 	case LINUX_SIGSTOP:
    173 		return SIGSTOP;
    174 	case LINUX_SIGTSTP:
    175 		return SIGTSTP;
    176 	case LINUX_SIGTTIN:
    177 		return SIGTTIN;
    178 	case LINUX_SIGTTOU:
    179 		return SIGTTOU;
    180 	case LINUX_SIGURG:
    181 		return SIGURG;
    182 	case LINUX_SIGXCPU:
    183 		return SIGXCPU;
    184 	case LINUX_SIGXFSZ:
    185 		return SIGXFSZ;
    186 	case LINUX_SIGVTALRM:
    187 		return SIGVTALRM;
    188 	case LINUX_SIGPROF:
    189 		return SIGPROF;
    190 	case LINUX_SIGWINCH:
    191 		return SIGWINCH;
    192 	case LINUX_SIGIO:
    193 		return SIGIO;
    194 	/* Not supported: STKFLT, PWR */
    195 	}
    196 	return 0;
    197 }
    198 
    199 /*
    200  * Ok, we know that Linux and BSD signals both are just an unsigned int.
    201  * Don't bother to use the sigismember() stuff for now.
    202  */
    203 static void
    204 linux_to_bsd_sigset(lss, bss)
    205 	const linux_sigset_t *lss;
    206 	sigset_t *bss;
    207 {
    208 	int i, newsig;
    209 
    210 	*bss = (sigset_t) 0;
    211 	for (i = 1; i <= LINUX_NSIG; i++) {
    212 		if (*lss & sigmask(i)) {
    213 			newsig = linux_to_bsd_sig(i);
    214 			if (newsig)
    215 				*bss |= sigmask(newsig);
    216 		}
    217 	}
    218 }
    219 
    220 void
    221 bsd_to_linux_sigset(bss, lss)
    222 	const sigset_t *bss;
    223 	linux_sigset_t *lss;
    224 {
    225 	int i, newsig;
    226 
    227 	*lss = (linux_sigset_t) 0;
    228 	for (i = 1; i <= NSIG; i++) {
    229 		if (*bss & sigmask(i)) {
    230 			newsig = bsd_to_linux_sig(i);
    231 			if (newsig)
    232 				*lss |= sigmask(newsig);
    233 		}
    234 	}
    235 }
    236 
    237 /*
    238  * Convert between Linux and BSD sigaction structures. Linux has
    239  * one extra field (sa_restorer) which we don't support. The Linux
    240  * SA_ONESHOT and SA_NOMASK flags (which together form the old
    241  * SysV signal behavior) are silently ignored. XXX
    242  */
    243 void
    244 linux_to_bsd_sigaction(lsa, bsa)
    245 	struct linux_sigaction *lsa;
    246 	struct sigaction *bsa;
    247 {
    248 	bsa->sa_handler = lsa->sa_handler;
    249 	linux_to_bsd_sigset(&bsa->sa_mask, &lsa->sa_mask);
    250 	bsa->sa_flags = 0;
    251 	bsa->sa_flags |= cvtto_bsd_mask(lsa->sa_flags, LINUX_SA_NOCLDSTOP,
    252 	    SA_NOCLDSTOP);
    253 	bsa->sa_flags |= cvtto_bsd_mask(lsa->sa_flags, LINUX_SA_ONSTACK,
    254 	    SA_ONSTACK);
    255 	bsa->sa_flags |= cvtto_bsd_mask(lsa->sa_flags, LINUX_SA_RESTART,
    256 	    SA_RESTART);
    257 }
    258 
    259 void
    260 bsd_to_linux_sigaction(bsa, lsa)
    261 	struct sigaction *bsa;
    262 	struct linux_sigaction *lsa;
    263 {
    264 	lsa->sa_handler = bsa->sa_handler;
    265 	bsd_to_linux_sigset(&lsa->sa_mask, &bsa->sa_mask);
    266 	lsa->sa_flags = 0;
    267 	lsa->sa_flags |= cvtto_linux_mask(bsa->sa_flags, SA_NOCLDSTOP,
    268 	    LINUX_SA_NOCLDSTOP);
    269 	lsa->sa_flags |= cvtto_linux_mask(bsa->sa_flags, SA_ONSTACK,
    270 	    LINUX_SA_ONSTACK);
    271 	lsa->sa_flags |= cvtto_linux_mask(bsa->sa_flags, SA_RESTART,
    272 	    LINUX_SA_RESTART);
    273 	lsa->sa_restorer = NULL;
    274 }
    275 
    276 
    277 /*
    278  * The Linux sigaction() system call. Do the usual conversions,
    279  * and just call sigaction(). Some flags and values are silently
    280  * ignored (see above).
    281  */
    282 int
    283 linux_sigaction(p, uap, retval)
    284 	register struct proc *p;
    285 	struct linux_sigaction_args /* {
    286 		syscallarg(int) signum;
    287 		syscallarg(struct linux_sigaction *) nsa;
    288 		syscallarg(struct linux_sigaction *) osa;
    289 	} */ *uap;
    290 	register_t *retval;
    291 {
    292 	struct sigaction *nbsda = NULL, *obsda = NULL, tmpbsda;
    293 	struct linux_sigaction *nlsa, *olsa, tmplsa;
    294 	struct sigaction_args sa;
    295 	caddr_t sg;
    296 	int error;
    297 
    298 	sg = stackgap_init();
    299 	olsa = SCARG(uap, osa);
    300 	nlsa = SCARG(uap, nsa);
    301 
    302 	if (olsa != NULL)
    303 		obsda = stackgap_alloc(&sg, sizeof (struct sigaction));
    304 
    305 	if (nlsa != NULL) {
    306 		nbsda = stackgap_alloc(&sg, sizeof (struct sigaction));
    307 		if ((error = copyin(nlsa, &tmplsa, sizeof tmplsa)))
    308 			return error;
    309 		linux_to_bsd_sigaction(&tmplsa, &tmpbsda);
    310 		if ((error = copyout(&tmpbsda, nbsda, sizeof tmpbsda)))
    311 			return error;
    312 	}
    313 
    314 	SCARG(&sa, signum) = linux_to_bsd_sig(SCARG(uap, signum));
    315 	SCARG(&sa, nsa) = nbsda;
    316 	SCARG(&sa, osa) = obsda;
    317 
    318 	if ((error = sigaction(p, &sa, retval)))
    319 		return error;
    320 
    321 	if (olsa != NULL) {
    322 		if ((error = copyin(obsda, &tmpbsda, sizeof tmpbsda)))
    323 			return error;
    324 		bsd_to_linux_sigaction(&tmpbsda, &tmplsa);
    325 		if ((error = copyout(&tmplsa, olsa, sizeof tmplsa)))
    326 			return error;
    327 	}
    328 	return 0;
    329 }
    330 
    331 /*
    332  * The Linux signal() system call. I think that the signal() in the C
    333  * library actually calls sigaction, so I doubt this one is ever used.
    334  * But hey, it can't hurt having it here. The same restrictions as for
    335  * sigaction() apply.
    336  */
    337 int
    338 linux_signal(p, uap, retval)
    339 	register struct proc *p;
    340 	struct linux_signal_args /* {
    341 		syscallarg(int) sig;
    342 		syscallarg(linux_handler_t) handler;
    343 	} */ *uap;
    344 	register_t *retval;
    345 {
    346 	caddr_t sg;
    347 	struct sigaction_args sa_args;
    348 	struct sigaction *osa, *nsa, tmpsa;
    349 	int error;
    350 
    351 	sg = stackgap_init();
    352 	nsa = stackgap_alloc(&sg, sizeof *nsa);
    353 	osa = stackgap_alloc(&sg, sizeof *osa);
    354 
    355 	tmpsa.sa_handler = SCARG(uap, handler);
    356 	tmpsa.sa_mask = (sigset_t) 0;
    357 	tmpsa.sa_flags = 0;
    358 	if ((error = copyout(&tmpsa, nsa, sizeof tmpsa)))
    359 		return error;
    360 
    361 	SCARG(&sa_args, signum) = linux_to_bsd_sig(SCARG(uap, sig));
    362 	SCARG(&sa_args, osa) = osa;
    363 	SCARG(&sa_args, nsa) = nsa;
    364 	if ((error = sigaction(p, &sa_args, retval)))
    365 		return error;
    366 
    367 	if ((error = copyin(osa, &tmpsa, sizeof *osa)))
    368 		return error;
    369 	retval[0] = (register_t) tmpsa.sa_handler;
    370 
    371 	return 0;
    372 }
    373 
    374 /*
    375  * This is just a copy of the svr4 compat one. I feel so creative now.
    376  */
    377 int
    378 linux_sigprocmask(p, uap, retval)
    379 	register struct proc *p;
    380 	register struct linux_sigprocmask_args /* {
    381 		syscallarg(int) how;
    382 		syscallarg(linux_sigset_t *) set;
    383 		syscallarg(linux_sigset_t * oset;
    384 	} */ *uap;
    385 	register_t *retval;
    386 {
    387 	linux_sigset_t ss;
    388 	sigset_t bs;
    389 	int error = 0;
    390 
    391 	*retval = 0;
    392 
    393 	if (SCARG(uap, oset) != NULL) {
    394 		/* Fix the return value first if needed */
    395 		bsd_to_linux_sigset(&p->p_sigmask, &ss);
    396 		if ((error = copyout(&ss, SCARG(uap, oset), sizeof(ss))) != 0)
    397 			return error;
    398 	}
    399 
    400 	if (SCARG(uap, set) == NULL)
    401 		/* Just examine */
    402 		return 0;
    403 
    404 	if ((error = copyin(SCARG(uap, set), &ss, sizeof(ss))) != 0)
    405 		return error;
    406 
    407 	linux_to_bsd_sigset(&ss, &bs);
    408 
    409 	(void) splhigh();
    410 
    411 	switch (SCARG(uap, how)) {
    412 	case LINUX_SIG_BLOCK:
    413 		p->p_sigmask |= bs & ~sigcantmask;
    414 		break;
    415 
    416 	case LINUX_SIG_UNBLOCK:
    417 		p->p_sigmask &= ~bs;
    418 		break;
    419 
    420 	case LINUX_SIG_SETMASK:
    421 		p->p_sigmask = bs & ~sigcantmask;
    422 		break;
    423 
    424 	default:
    425 		error = EINVAL;
    426 		break;
    427 	}
    428 
    429 	(void) spl0();
    430 
    431 	return error;
    432 }
    433 
    434 /*
    435  * The functions below really make no distinction between an int
    436  * and [linux_]sigset_t. This is ok for now, but it might break
    437  * sometime. Then again, sigset_t is trusted to be an int everywhere
    438  * else in the kernel too.
    439  */
    440 /* ARGSUSED */
    441 int
    442 linux_siggetmask(p, uap, retval)
    443 	struct proc *p;
    444 	void *uap;
    445 	register_t *retval;
    446 {
    447 	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *) retval);
    448 	return 0;
    449 }
    450 
    451 /*
    452  * The following three functions fiddle with a process' signal mask.
    453  * Convert the signal masks because of the different signal
    454  * values for Linux. The need for this is the reason why
    455  * they are here, and have not been mapped directly.
    456  */
    457 int
    458 linux_sigsetmask(p, uap, retval)
    459 	struct proc *p;
    460 	struct linux_sigsetmask_args /* {
    461 		syscallarg(linux_sigset_t) mask;
    462 	} */ *uap;
    463 	register_t *retval;
    464 {
    465 	linux_sigset_t mask;
    466 	sigset_t bsdsig;
    467 
    468 	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *) retval);
    469 
    470 	mask = SCARG(uap, mask);
    471 	bsd_to_linux_sigset(&mask, &bsdsig);
    472 
    473 	splhigh();
    474 	p->p_sigmask = bsdsig & ~sigcantmask;
    475 	spl0();
    476 
    477 	return 0;
    478 }
    479 
    480 int
    481 linux_sigpending(p, uap, retval)
    482 	struct proc *p;
    483 	struct linux_sigpending_args /* {
    484 		syscallarg(linux_sigset_t *) mask;
    485 	} */ *uap;
    486 	register_t *retval;
    487 {
    488 	sigset_t bsdsig;
    489 	linux_sigset_t linuxsig;
    490 
    491 	bsdsig = p->p_siglist & p->p_sigmask;
    492 
    493 	bsd_to_linux_sigset(&bsdsig, &linuxsig);
    494 	return copyout(&linuxsig, SCARG(uap, mask), sizeof linuxsig);
    495 }
    496 
    497 int
    498 linux_sigsuspend(p, uap, retval)
    499 	struct proc *p;
    500 	struct linux_sigsuspend_args /* {
    501 		syscallarg(caddr_t) restart;
    502 		syscallarg(int) oldmask;
    503 		syscallarg(int) mask;
    504 	} */ *uap;
    505 	register_t *retval;
    506 {
    507 	struct sigsuspend_args ssa;
    508 
    509 	linux_to_bsd_sigset(&SCARG(uap, mask), &SCARG(&ssa, mask));
    510 	return sigsuspend(p, &ssa, retval);
    511 }
    512 
    513 /*
    514  * The deprecated pause(2), which is really just an instance
    515  * of sigsuspend(2).
    516  */
    517 int
    518 linux_pause(p, uap, retval)
    519 	struct proc *p;
    520 	void *uap;
    521 	register_t *retval;
    522 {
    523 	struct sigsuspend_args bsa;
    524 
    525 	SCARG(&bsa, mask) = p->p_sigmask;
    526 	return sigsuspend(p, &bsa, retval);
    527 }
    528 
    529 /*
    530  * Once more: only a signal conversion is needed.
    531  */
    532 int
    533 linux_kill(p, uap, retval)
    534 	struct proc *p;
    535 	struct linux_kill_args /* {
    536 		syscallarg(int) pid;
    537 		syscallarg(int) signum;
    538 	} */ *uap;
    539 	register_t *retval;
    540 {
    541 	SCARG(uap, signum) = linux_to_bsd_sig(SCARG(uap, signum));
    542 	return kill(p, (struct kill_args *) uap, retval);
    543 }
    544