1139799Simp/*- 211397Sswallace * Copyright (c) 1995 Scott Bartram 311605Sswallace * Copyright (c) 1995 Steven Wallace 43584Ssos * All rights reserved. 53584Ssos * 63584Ssos * Redistribution and use in source and binary forms, with or without 73584Ssos * modification, are permitted provided that the following conditions 83584Ssos * are met: 93584Ssos * 1. Redistributions of source code must retain the above copyright 1011397Sswallace * notice, this list of conditions and the following disclaimer. 113584Ssos * 2. Redistributions in binary form must reproduce the above copyright 123584Ssos * notice, this list of conditions and the following disclaimer in the 133584Ssos * documentation and/or other materials provided with the distribution. 1411397Sswallace * 3. The name of the author may not be used to endorse or promote products 1511397Sswallace * derived from this software without specific prior written permission 163584Ssos * 1711397Sswallace * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1811397Sswallace * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1911397Sswallace * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2011397Sswallace * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2111397Sswallace * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2211397Sswallace * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311397Sswallace * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411397Sswallace * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511397Sswallace * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2611397Sswallace * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273584Ssos */ 283584Ssos 29115684Sobrien#include <sys/cdefs.h> 30115684Sobrien__FBSDID("$FreeBSD$"); 31115684Sobrien 323584Ssos#include <sys/param.h> 333584Ssos#include <sys/systm.h> 3476166Smarkm#include <sys/lock.h> 3576166Smarkm#include <sys/mutex.h> 363584Ssos#include <sys/signalvar.h> 37113859Sjhb#include <sys/syscallsubr.h> 3811397Sswallace#include <sys/sysproto.h> 393584Ssos 4011397Sswallace#include <i386/ibcs2/ibcs2_types.h> 4111397Sswallace#include <i386/ibcs2/ibcs2_signal.h> 4211397Sswallace#include <i386/ibcs2/ibcs2_proto.h> 4311397Sswallace#include <i386/ibcs2/ibcs2_xenix.h> 4411397Sswallace#include <i386/ibcs2/ibcs2_util.h> 453584Ssos 4651793Smarcel#define sigemptyset(s) SIGEMPTYSET(*(s)) 4751793Smarcel#define sigismember(s, n) SIGISMEMBER(*(s), n) 4851793Smarcel#define sigaddset(s, n) SIGADDSET(*(s), n) 493584Ssos 5011397Sswallace#define ibcs2_sigmask(n) (1 << ((n) - 1)) 5111397Sswallace#define ibcs2_sigemptyset(s) bzero((s), sizeof(*(s))) 5211397Sswallace#define ibcs2_sigismember(s, n) (*(s) & ibcs2_sigmask(n)) 5311397Sswallace#define ibcs2_sigaddset(s, n) (*(s) |= ibcs2_sigmask(n)) 543584Ssos 5592761Salfredstatic void ibcs2_to_bsd_sigset(const ibcs2_sigset_t *, sigset_t *); 5692761Salfredstatic void bsd_to_ibcs2_sigset(const sigset_t *, ibcs2_sigset_t *); 5792761Salfredstatic void ibcs2_to_bsd_sigaction(struct ibcs2_sigaction *, 5892761Salfred struct sigaction *); 5992761Salfredstatic void bsd_to_ibcs2_sigaction(struct sigaction *, 6092761Salfred struct ibcs2_sigaction *); 6111397Sswallace 6251793Smarcelint bsd_to_ibcs2_sig[IBCS2_SIGTBLSZ] = { 6311397Sswallace IBCS2_SIGHUP, /* 1 */ 6411397Sswallace IBCS2_SIGINT, /* 2 */ 6511397Sswallace IBCS2_SIGQUIT, /* 3 */ 6611397Sswallace IBCS2_SIGILL, /* 4 */ 6711397Sswallace IBCS2_SIGTRAP, /* 5 */ 6811397Sswallace IBCS2_SIGABRT, /* 6 */ 6911397Sswallace IBCS2_SIGEMT, /* 7 */ 7011397Sswallace IBCS2_SIGFPE, /* 8 */ 7111397Sswallace IBCS2_SIGKILL, /* 9 */ 7211397Sswallace IBCS2_SIGBUS, /* 10 */ 7311397Sswallace IBCS2_SIGSEGV, /* 11 */ 7411397Sswallace IBCS2_SIGSYS, /* 12 */ 7511397Sswallace IBCS2_SIGPIPE, /* 13 */ 7611397Sswallace IBCS2_SIGALRM, /* 14 */ 7711397Sswallace IBCS2_SIGTERM, /* 15 */ 7811397Sswallace 0, /* 16 - SIGURG */ 7911397Sswallace IBCS2_SIGSTOP, /* 17 */ 8011397Sswallace IBCS2_SIGTSTP, /* 18 */ 8111397Sswallace IBCS2_SIGCONT, /* 19 */ 8211397Sswallace IBCS2_SIGCLD, /* 20 */ 8311397Sswallace IBCS2_SIGTTIN, /* 21 */ 8411397Sswallace IBCS2_SIGTTOU, /* 22 */ 8511397Sswallace IBCS2_SIGPOLL, /* 23 */ 8611397Sswallace 0, /* 24 - SIGXCPU */ 8711397Sswallace 0, /* 25 - SIGXFSZ */ 8811397Sswallace IBCS2_SIGVTALRM, /* 26 */ 8911397Sswallace IBCS2_SIGPROF, /* 27 */ 9011397Sswallace IBCS2_SIGWINCH, /* 28 */ 9111397Sswallace 0, /* 29 */ 9211397Sswallace IBCS2_SIGUSR1, /* 30 */ 9311397Sswallace IBCS2_SIGUSR2, /* 31 */ 9451793Smarcel 0 /* 32 */ 953584Ssos}; 963584Ssos 9751793Smarcelstatic int ibcs2_to_bsd_sig[IBCS2_SIGTBLSZ] = { 9811397Sswallace SIGHUP, /* 1 */ 9911397Sswallace SIGINT, /* 2 */ 10011397Sswallace SIGQUIT, /* 3 */ 10111397Sswallace SIGILL, /* 4 */ 10211397Sswallace SIGTRAP, /* 5 */ 10311397Sswallace SIGABRT, /* 6 */ 10411397Sswallace SIGEMT, /* 7 */ 10511397Sswallace SIGFPE, /* 8 */ 10611397Sswallace SIGKILL, /* 9 */ 10711397Sswallace SIGBUS, /* 10 */ 10811397Sswallace SIGSEGV, /* 11 */ 10911397Sswallace SIGSYS, /* 12 */ 11011397Sswallace SIGPIPE, /* 13 */ 11111397Sswallace SIGALRM, /* 14 */ 11211397Sswallace SIGTERM, /* 15 */ 11311397Sswallace SIGUSR1, /* 16 */ 11411397Sswallace SIGUSR2, /* 17 */ 11511397Sswallace SIGCHLD, /* 18 */ 11611397Sswallace 0, /* 19 - SIGPWR */ 11711397Sswallace SIGWINCH, /* 20 */ 11811397Sswallace 0, /* 21 */ 11911397Sswallace SIGIO, /* 22 */ 12011397Sswallace SIGSTOP, /* 23 */ 12111397Sswallace SIGTSTP, /* 24 */ 12211397Sswallace SIGCONT, /* 25 */ 12311397Sswallace SIGTTIN, /* 26 */ 12411397Sswallace SIGTTOU, /* 27 */ 12511397Sswallace SIGVTALRM, /* 28 */ 12611397Sswallace SIGPROF, /* 29 */ 12711397Sswallace 0, /* 30 */ 12811397Sswallace 0, /* 31 */ 12951793Smarcel 0 /* 32 */ 1303584Ssos}; 1313584Ssos 13211397Sswallacevoid 13311397Sswallaceibcs2_to_bsd_sigset(iss, bss) 13411397Sswallace const ibcs2_sigset_t *iss; 13511397Sswallace sigset_t *bss; 1363584Ssos{ 13711397Sswallace int i, newsig; 13811397Sswallace 13911397Sswallace sigemptyset(bss); 14051793Smarcel for (i = 1; i <= IBCS2_SIGTBLSZ; i++) { 14111397Sswallace if (ibcs2_sigismember(iss, i)) { 14251793Smarcel newsig = ibcs2_to_bsd_sig[_SIG_IDX(i)]; 14311397Sswallace if (newsig) 14411397Sswallace sigaddset(bss, newsig); 14511397Sswallace } 1463584Ssos } 1473584Ssos} 1483584Ssos 14911397Sswallacestatic void 15011397Sswallacebsd_to_ibcs2_sigset(bss, iss) 15111397Sswallace const sigset_t *bss; 15211397Sswallace ibcs2_sigset_t *iss; 1533584Ssos{ 15411397Sswallace int i, newsig; 1553584Ssos 15611397Sswallace ibcs2_sigemptyset(iss); 15751793Smarcel for (i = 1; i <= IBCS2_SIGTBLSZ; i++) { 15811397Sswallace if (sigismember(bss, i)) { 15951793Smarcel newsig = bsd_to_ibcs2_sig[_SIG_IDX(i)]; 16011397Sswallace if (newsig) 16111397Sswallace ibcs2_sigaddset(iss, newsig); 16211397Sswallace } 1633584Ssos } 1643584Ssos} 1653584Ssos 16611397Sswallacestatic void 16711397Sswallaceibcs2_to_bsd_sigaction(isa, bsa) 16811397Sswallace struct ibcs2_sigaction *isa; 16911397Sswallace struct sigaction *bsa; 17011397Sswallace{ 17111397Sswallace 17248620Scracauer bsa->sa_handler = isa->isa_handler; 17348620Scracauer ibcs2_to_bsd_sigset(&isa->isa_mask, &bsa->sa_mask); 17411574Sswallace bsa->sa_flags = 0; /* ??? SA_NODEFER */ 17548620Scracauer if ((isa->isa_flags & IBCS2_SA_NOCLDSTOP) != 0) 17611397Sswallace bsa->sa_flags |= SA_NOCLDSTOP; 1773584Ssos} 1783584Ssos 17911397Sswallacestatic void 18011397Sswallacebsd_to_ibcs2_sigaction(bsa, isa) 18111397Sswallace struct sigaction *bsa; 18211397Sswallace struct ibcs2_sigaction *isa; 18311397Sswallace{ 1843584Ssos 18548620Scracauer isa->isa_handler = bsa->sa_handler; 18648620Scracauer bsd_to_ibcs2_sigset(&bsa->sa_mask, &isa->isa_mask); 18748620Scracauer isa->isa_flags = 0; 18811397Sswallace if ((bsa->sa_flags & SA_NOCLDSTOP) != 0) 18948620Scracauer isa->isa_flags |= IBCS2_SA_NOCLDSTOP; 1903584Ssos} 1913584Ssos 19211397Sswallaceint 19383366Sjulianibcs2_sigaction(td, uap) 19483366Sjulian register struct thread *td; 19511397Sswallace struct ibcs2_sigaction_args *uap; 19611397Sswallace{ 197113859Sjhb struct ibcs2_sigaction isa; 198113859Sjhb struct sigaction nbsa, obsa; 199113859Sjhb struct sigaction *nbsap; 200113859Sjhb int error; 2013584Ssos 202113859Sjhb if (uap->act != NULL) { 203113859Sjhb if ((error = copyin(uap->act, &isa, sizeof(isa))) != 0) 204113859Sjhb return (error); 205113859Sjhb ibcs2_to_bsd_sigaction(&isa, &nbsa); 206113859Sjhb nbsap = &nbsa; 20711397Sswallace } else 208113859Sjhb nbsap = NULL; 209121016Stjr if (uap->sig <= 0 || uap->sig > IBCS2_NSIG) 210121016Stjr return (EINVAL); 211113859Sjhb error = kern_sigaction(td, ibcs2_to_bsd_sig[_SIG_IDX(uap->sig)], &nbsa, 212113859Sjhb &obsa, 0); 213113859Sjhb if (error == 0 && uap->oact != NULL) { 214113859Sjhb bsd_to_ibcs2_sigaction(&obsa, &isa); 215113859Sjhb error = copyout(&isa, uap->oact, sizeof(isa)); 2163584Ssos } 217113859Sjhb return (error); 2188876Srgrimes} 2193584Ssos 22011397Sswallaceint 22183366Sjulianibcs2_sigsys(td, uap) 22283366Sjulian register struct thread *td; 22311397Sswallace struct ibcs2_sigsys_args *uap; 2243584Ssos{ 22583366Sjulian struct proc *p = td->td_proc; 22611605Sswallace struct sigaction sa; 227121016Stjr int signum = IBCS2_SIGNO(uap->sig); 22811397Sswallace int error; 2293584Ssos 230121016Stjr if (signum <= 0 || signum > IBCS2_NSIG) { 231107849Salfred if (IBCS2_SIGCALL(uap->sig) == IBCS2_SIGNAL_MASK || 232107849Salfred IBCS2_SIGCALL(uap->sig) == IBCS2_SIGSET_MASK) 23383366Sjulian td->td_retval[0] = (int)IBCS2_SIG_ERR; 23411397Sswallace return EINVAL; 23511397Sswallace } 236121016Stjr signum = ibcs2_to_bsd_sig[_SIG_IDX(signum)]; 23711397Sswallace 238107849Salfred switch (IBCS2_SIGCALL(uap->sig)) { 23911397Sswallace case IBCS2_SIGSET_MASK: 24011397Sswallace /* 24111605Sswallace * Check for SIG_HOLD action. 24211605Sswallace * Otherwise, perform signal() except with different sa_flags. 24311397Sswallace */ 244107849Salfred if (uap->fp != IBCS2_SIG_HOLD) { 24511605Sswallace /* add sig to mask before exececuting signal handler */ 24611605Sswallace sa.sa_flags = 0; 24711605Sswallace goto ibcs2_sigset; 24811605Sswallace } 249102412Scharnier /* else FALLTHROUGH to sighold */ 25011605Sswallace 25111605Sswallace case IBCS2_SIGHOLD_MASK: 25211605Sswallace { 25352084Smarcel sigset_t mask; 2543584Ssos 25552084Smarcel SIGEMPTYSET(mask); 25652084Smarcel SIGADDSET(mask, signum); 257113859Sjhb return (kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, 258113859Sjhb 0)); 25911397Sswallace } 26011605Sswallace 26111397Sswallace case IBCS2_SIGNAL_MASK: 26211397Sswallace { 263113859Sjhb struct sigaction osa; 2643584Ssos 26511605Sswallace /* do not automatically block signal */ 26611605Sswallace sa.sa_flags = SA_NODEFER; 26711605Sswallace#ifdef SA_RESETHAND 26811605Sswallace if((signum != IBCS2_SIGILL) && 26911605Sswallace (signum != IBCS2_SIGTRAP) && 27011605Sswallace (signum != IBCS2_SIGPWR)) 27111605Sswallace /* set to SIG_DFL before executing handler */ 27211605Sswallace sa.sa_flags |= SA_RESETHAND; 27311605Sswallace#endif 27411605Sswallace ibcs2_sigset: 275107849Salfred sa.sa_handler = uap->fp; 27611397Sswallace sigemptyset(&sa.sa_mask); 27711397Sswallace#if 0 27811397Sswallace if (signum != SIGALRM) 27911574Sswallace sa.sa_flags |= SA_RESTART; 28011397Sswallace#endif 281113859Sjhb error = kern_sigaction(td, signum, &sa, &osa, 0); 282113859Sjhb if (error != 0) { 28311397Sswallace DPRINTF(("signal: sigaction failed: %d\n", 28411397Sswallace error)); 285113859Sjhb td->td_retval[0] = (int)IBCS2_SIG_ERR; 286113859Sjhb return (error); 28711397Sswallace } 288113859Sjhb td->td_retval[0] = (int)osa.sa_handler; 28920203Sswallace 29020203Sswallace /* special sigset() check */ 291107849Salfred if(IBCS2_SIGCALL(uap->sig) == IBCS2_SIGSET_MASK) { 29271489Sjhb PROC_LOCK(p); 29320203Sswallace /* check to make sure signal is not blocked */ 294112888Sjeff if(sigismember(&td->td_sigmask, signum)) { 29520203Sswallace /* return SIG_HOLD and unblock signal*/ 29683366Sjulian td->td_retval[0] = (int)IBCS2_SIG_HOLD; 297112888Sjeff SIGDELSET(td->td_sigmask, signum); 298112888Sjeff signotify(td); 29920203Sswallace } 30071489Sjhb PROC_UNLOCK(p); 30171489Sjhb } 30220203Sswallace 30311397Sswallace return 0; 30411397Sswallace } 30511397Sswallace 30611397Sswallace case IBCS2_SIGRELSE_MASK: 30711397Sswallace { 30852084Smarcel sigset_t mask; 3093584Ssos 31052084Smarcel SIGEMPTYSET(mask); 31152084Smarcel SIGADDSET(mask, signum); 312113859Sjhb return (kern_sigprocmask(td, SIG_UNBLOCK, &mask, NULL, 313113859Sjhb 0)); 31411397Sswallace } 31511397Sswallace 31611397Sswallace case IBCS2_SIGIGNORE_MASK: 31711397Sswallace { 31811397Sswallace sa.sa_handler = SIG_IGN; 31911397Sswallace sigemptyset(&sa.sa_mask); 32011397Sswallace sa.sa_flags = 0; 321113859Sjhb error = kern_sigaction(td, signum, &sa, NULL, 0); 322113859Sjhb if (error != 0) 32311397Sswallace DPRINTF(("sigignore: sigaction failed\n")); 324113859Sjhb return (error); 32511397Sswallace } 32611397Sswallace 32711397Sswallace case IBCS2_SIGPAUSE_MASK: 32811397Sswallace { 32952084Smarcel sigset_t mask; 3303584Ssos 33171489Sjhb PROC_LOCK(p); 332112888Sjeff mask = td->td_sigmask; 33371489Sjhb PROC_UNLOCK(p); 33452084Smarcel SIGDELSET(mask, signum); 335113859Sjhb return kern_sigsuspend(td, mask); 33611397Sswallace } 33711397Sswallace 3383584Ssos default: 33911397Sswallace return ENOSYS; 3403584Ssos } 3413584Ssos} 3423584Ssos 3433584Ssosint 34483366Sjulianibcs2_sigprocmask(td, uap) 34583366Sjulian register struct thread *td; 34611397Sswallace struct ibcs2_sigprocmask_args *uap; 3473584Ssos{ 34811397Sswallace ibcs2_sigset_t iss; 349113859Sjhb sigset_t oss, nss; 350113859Sjhb sigset_t *nssp; 351113859Sjhb int error, how; 3523584Ssos 353107849Salfred switch (uap->how) { 35411397Sswallace case IBCS2_SIG_BLOCK: 355113859Sjhb how = SIG_BLOCK; 3563584Ssos break; 35711397Sswallace case IBCS2_SIG_UNBLOCK: 358113859Sjhb how = SIG_UNBLOCK; 3593584Ssos break; 36011397Sswallace case IBCS2_SIG_SETMASK: 361113859Sjhb how = SIG_SETMASK; 3623584Ssos break; 3633584Ssos default: 364113859Sjhb return (EINVAL); 3653584Ssos } 366113859Sjhb if (uap->set != NULL) { 367113859Sjhb if ((error = copyin(uap->set, &iss, sizeof(iss))) != 0) 368113859Sjhb return error; 369113859Sjhb ibcs2_to_bsd_sigset(&iss, &nss); 370113859Sjhb nssp = &nss; 371113859Sjhb } else 372113859Sjhb nssp = NULL; 373113859Sjhb error = kern_sigprocmask(td, how, nssp, &oss, 0); 374113859Sjhb if (error == 0 && uap->oset != NULL) { 375113859Sjhb bsd_to_ibcs2_sigset(&oss, &iss); 376113859Sjhb error = copyout(&iss, uap->oset, sizeof(iss)); 377113859Sjhb } 378113859Sjhb return (error); 3793584Ssos} 3803584Ssos 38111397Sswallaceint 38283366Sjulianibcs2_sigpending(td, uap) 38383366Sjulian register struct thread *td; 38411397Sswallace struct ibcs2_sigpending_args *uap; 38511397Sswallace{ 38683366Sjulian struct proc *p = td->td_proc; 38711397Sswallace sigset_t bss; 38811397Sswallace ibcs2_sigset_t iss; 3893584Ssos 39071489Sjhb PROC_LOCK(p); 391112888Sjeff bss = td->td_siglist; 392112888Sjeff SIGSETOR(bss, p->p_siglist); 393112888Sjeff SIGSETAND(bss, td->td_sigmask); 39471489Sjhb PROC_UNLOCK(p); 39511397Sswallace bsd_to_ibcs2_sigset(&bss, &iss); 39611397Sswallace 397107849Salfred return copyout(&iss, uap->mask, sizeof(iss)); 39811397Sswallace} 39911397Sswallace 4003584Ssosint 40183366Sjulianibcs2_sigsuspend(td, uap) 40283366Sjulian register struct thread *td; 40311397Sswallace struct ibcs2_sigsuspend_args *uap; 4043584Ssos{ 40511397Sswallace ibcs2_sigset_t sss; 40611397Sswallace sigset_t bss; 40711397Sswallace int error; 4088876Srgrimes 409107849Salfred if ((error = copyin(uap->mask, &sss, sizeof(sss))) != 0) 41011397Sswallace return error; 41111397Sswallace 41211397Sswallace ibcs2_to_bsd_sigset(&sss, &bss); 413113859Sjhb return kern_sigsuspend(td, bss); 4143584Ssos} 4153584Ssos 4163584Ssosint 41783366Sjulianibcs2_pause(td, uap) 41883366Sjulian register struct thread *td; 41911397Sswallace struct ibcs2_pause_args *uap; 4203584Ssos{ 42152084Smarcel sigset_t mask; 4223584Ssos 423113859Sjhb PROC_LOCK(td->td_proc); 424112888Sjeff mask = td->td_sigmask; 425113859Sjhb PROC_UNLOCK(td->td_proc); 426113859Sjhb return kern_sigsuspend(td, mask); 4273584Ssos} 4283584Ssos 4293584Ssosint 43083366Sjulianibcs2_kill(td, uap) 43183366Sjulian register struct thread *td; 43211397Sswallace struct ibcs2_kill_args *uap; 4333584Ssos{ 43411397Sswallace struct kill_args ka; 4353584Ssos 436121016Stjr if (uap->signo <= 0 || uap->signo > IBCS2_NSIG) 437121016Stjr return (EINVAL); 438107849Salfred ka.pid = uap->pid; 439107849Salfred ka.signum = ibcs2_to_bsd_sig[_SIG_IDX(uap->signo)]; 440225617Skmacy return sys_kill(td, &ka); 4413584Ssos} 442