# 2.11BSD#431 - /usr/src/sys/sys/kern_sig2.c

##### Functions

    fatalsig          X
    setsigvec         X
    sigaction         X
    sigaltstack       X
    siginit           X
    sigpending        X
    sigprocmask       X
    sigsuspend        X
    sigwait           X

##### Macros

    SIGPROP           X

##### struct's

    a                 X

       1: /*
       2:  * Copyright (c) 1982, 1986, 1989, 1991, 1993
       3:  *	The Regents of the University of California.  All rights reserved.
       4:  * (c) UNIX System Laboratories, Inc.
       5:  * All or some portions of this file are derived from material licensed
       6:  * to the University of California by American Telephone and Telegraph
       7:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
       8:  * the permission of UNIX System Laboratories, Inc.
       9:  *
      10:  * Redistribution and use in source and binary forms, with or without
      11:  * modification, are permitted provided that the following conditions
      12:  * are met:
      13:  * 1. Redistributions of source code must retain the above copyright
      14:  *    notice, this list of conditions and the following disclaimer.
      15:  * 2. Redistributions in binary form must reproduce the above copyright
      16:  *    notice, this list of conditions and the following disclaimer in the
      17:  *    documentation and/or other materials provided with the distribution.
      18:  * 3. All advertising materials mentioning features or use of this software
      19:  *    must display the following acknowledgement:
      20:  *	This product includes software developed by the University of
      21:  *	California, Berkeley and its contributors.
      22:  * 4. Neither the name of the University nor the names of its contributors
      23:  *    may be used to endorse or promote products derived from this software
      24:  *    without specific prior written permission.
      25:  *
      26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      36:  * SUCH DAMAGE.
      37:  *
      38:  *	@(#)kern_sig.c	8.14.2 (2.11BSD) 1999/9/9
      39:  */
      40:
      41: /*
      42:  * This module is a hacked down version of kern_sig.c from 4.4BSD.  The
      43:  * original signal handling code is still present in 2.11's kern_sig.c.  This
      44:  * was done because large modules are very hard to fit into the kernel's
      45:  * overlay structure.  A smaller kern_sig2.c fits more easily into an overlaid
      46:  * kernel.
      47: */
      48:
      49: #define SIGPROP     /* include signal properties table */
      50: #include <sys/param.h>
      51: #include <sys/signal.h>
      52: #include <sys/signalvar.h>
      53: #include <sys/dir.h>
      54: #include <sys/namei.h>
      55: #include <sys/time.h>
      56: #include <sys/resource.h>
      57: #include <sys/proc.h>
      58: #include <sys/systm.h>
      59: #include <sys/kernel.h>
      60: #include <sys/user.h>       /* for coredump */
      61:
      62: static void stop();
      63:
      64: int
      65: sigaction()
      66: {
      67:     register struct a {
      68:         int (*sigtramp)();
      69:         int signum;
      70:         struct  sigaction *nsa;
      71:         struct  sigaction *osa;
      72:         } *uap = (struct a *)u.u_ap;
      73:     struct sigaction vec;
      74:     register struct sigaction *sa;
      75:     register int signum;
      76:     u_long bit;
      77:     int error = 0;
      78:
      79:     u.u_pcb.pcb_sigc = uap->sigtramp;   /* save trampoline address */
      80:
      81:     signum = uap->signum;
      82:     if (signum <= 0 || signum >= NSIG)
      83:         {
      84:         error = EINVAL;
      85:         goto out;
      86:         }
      87:     if (uap->nsa && (signum == SIGKILL || signum == SIGSTOP))
      88:         {
      89:         error = EINVAL;
      90:         goto out;
      91:         }
      92:     sa = &vec;
      93:     if (uap->osa) {
      94:         sa->sa_handler = u.u_signal[signum];
      95:         sa->sa_mask = u.u_sigmask[signum];
      96:         bit = sigmask(signum);
      97:         sa->sa_flags = 0;
      98:         if ((u.u_sigonstack & bit) != 0)
      99:             sa->sa_flags |= SA_ONSTACK;
     100:         if ((u.u_sigintr & bit) == 0)
     101:             sa->sa_flags |= SA_RESTART;
     102:         if (u.u_procp->p_flag & P_NOCLDSTOP)
     103:             sa->sa_flags |= SA_NOCLDSTOP;
     104:         if ((error = copyout(sa, uap->osa, sizeof(vec))) != 0)
     105:             goto out;
     106:     }
     107:     if (uap->nsa) {
     108:         if ((error = copyin(uap->nsa, sa, sizeof(vec))) != 0)
     109:             goto out;
     110:         setsigvec(signum, sa);
     111:     }
     112: out:
     113:     return(u.u_error = error);
     114: }
     115:
     116: void
     117: setsigvec(signum, sa)
     118:     int signum;
     119:     register struct sigaction *sa;
     120: {
     121:     unsigned long bit;
     122:     register struct proc *p = u.u_procp;
     123:
     124:     bit = sigmask(signum);
     125:     /*
     126: 	 * Change setting atomically.
     127: 	 */
     128:     (void) splhigh();
     129:     u.u_signal[signum] = sa->sa_handler;
     130:     u.u_sigmask[signum] = sa->sa_mask &~ sigcantmask;
     131:     if ((sa->sa_flags & SA_RESTART) == 0)
     132:         u.u_sigintr |= bit;
     133:     else
     134:         u.u_sigintr &= ~bit;
     135:     if (sa->sa_flags & SA_ONSTACK)
     136:         u.u_sigonstack |= bit;
     137:     else
     138:         u.u_sigonstack &= ~bit;
     139:     if (signum == SIGCHLD) {
     140:         if (sa->sa_flags & SA_NOCLDSTOP)
     141:             p->p_flag |= P_NOCLDSTOP;
     142:         else
     143:             p->p_flag &= ~P_NOCLDSTOP;
     144:     }
     145:     /*
     146: 	 * Set bit in p_sigignore for signals that are set to SIG_IGN,
     147: 	 * and for signals set to SIG_DFL where the default is to ignore.
     148: 	 * However, don't put SIGCONT in p_sigignore,
     149: 	 * as we have to restart the process.
     150: 	 */
     151:     if (sa->sa_handler == SIG_IGN ||
     152:         (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
     153:         p->p_sig &= ~bit;       /* never to be seen again */
     154:         if (signum != SIGCONT)
     155:             p->p_sigignore |= bit;  /* easier in psignal */
     156:         p->p_sigcatch &= ~bit;
     157:     } else {
     158:         p->p_sigignore &= ~bit;
     159:         if (sa->sa_handler == SIG_DFL)
     160:             p->p_sigcatch &= ~bit;
     161:         else
     162:             p->p_sigcatch |= bit;
     163:     }
     164:     (void) spl0();
     165: }
     166:
     167: /*
     168:  * Kill current process with the specified signal in an uncatchable manner;
     169:  * used when process is too confused to continue, or we are unable to
     170:  * reconstruct the process state safely.
     171:  */
     172: void
     173: fatalsig(signum)
     174:     int signum;
     175: {
     176:     unsigned long mask;
     177:     register struct proc *p = u.u_procp;
     178:
     179:     u.u_signal[signum] = SIG_DFL;
     180:     mask = sigmask(signum);
     181:     p->p_sigignore &= ~mask;
     182:     p->p_sigcatch &= ~mask;
     183:     p->p_sigmask &= ~mask;
     184:     psignal(p, signum);
     185: }
     186:
     187: /*
     188:  * Initialize signal state for process 0;
     189:  * set to ignore signals that are ignored by default.
     190:  */
     191: void
     192: siginit(p)
     193:     register struct proc *p;
     194: {
     195:     register int i;
     196:
     197:     for (i = 0; i < NSIG; i++)
     198:         if (sigprop[i] & SA_IGNORE && i != SIGCONT)
     199:             p->p_sigignore |= sigmask(i);
     200: }
     201:
     202: /*
     203:  * Manipulate signal mask.
     204:  * Unlike 4.4BSD we do not receive a pointer to the new and old mask areas and
     205:  * do a copyin/copyout instead of storing indirectly thru a 'retval' parameter.
     206:  * This is because we have to return both an error indication (which is 16 bits)
     207:  * _AND_ the new mask (which is 32 bits).  Can't do both at the same time with
     208:  * the 2BSD syscall return mechanism.
     209:  */
     210: int
     211: sigprocmask()
     212: {
     213:     register struct a {
     214:         int how;
     215:         sigset_t *set;
     216:         sigset_t *oset;
     217:         } *uap = (struct a *)u.u_ap;
     218:     int error = 0;
     219:     sigset_t oldmask, newmask;
     220:     register struct proc *p = u.u_procp;
     221:
     222:     oldmask = p->p_sigmask;
     223:     if  (!uap->set) /* No new mask, go possibly return old mask */
     224:         goto out;
     225:     if  (error = copyin(uap->set, &newmask, sizeof (newmask)))
     226:         goto out;
     227:     (void) splhigh();
     228:
     229:     switch (uap->how) {
     230:     case SIG_BLOCK:
     231:         p->p_sigmask |= (newmask &~ sigcantmask);
     232:         break;
     233:     case SIG_UNBLOCK:
     234:         p->p_sigmask &= ~newmask;
     235:         break;
     236:     case SIG_SETMASK:
     237:         p->p_sigmask = newmask &~ sigcantmask;
     238:         break;
     239:     default:
     240:         error = EINVAL;
     241:         break;
     242:     }
     243:     (void) spl0();
     244: out:
     245:     if  (error == 0 && uap->oset)
     246:         error = copyout(&oldmask, uap->oset, sizeof (oldmask));
     247:     return (u.u_error = error);
     248: }
     249:
     250: /*
     251:  * sigpending and sigsuspend use the standard calling sequence unlike 4.4 which
     252:  * used a nonstandard (mask instead of pointer) calling convention.
     253: */
     254:
     255: int
     256: sigpending()
     257:     {
     258:     register struct a
     259:         {
     260:         struct sigset_t *set;
     261:         } *uap = (struct a *)u.u_ap;
     262:     register int error = 0;
     263:     struct  proc *p = u.u_procp;
     264:
     265:     if  (uap->set)
     266:         error = copyout((caddr_t)&p->p_sig, (caddr_t)uap->set,
     267:                 sizeof (p->p_sig));
     268:     else
     269:         error = EINVAL;
     270:     return(u.u_error = error);
     271:     }
     272:
     273: /*
     274:  * sigsuspend is supposed to always return EINTR so we ignore errors on the
     275:  * copyin by assuming a mask of 0.
     276: */
     277:
     278: int
     279: sigsuspend()
     280:     {
     281:     register struct a
     282:         {
     283:         struct sigset_t *set;
     284:         } *uap = (struct a *)u.u_ap;
     285:     sigset_t nmask;
     286:     struct proc *p = u.u_procp;
     287:     int error;
     288:
     289:     if  (uap->set && (error = copyin(uap->set, &nmask, sizeof (nmask))))
     290:         nmask = 0;
     291: /*
     292:  * When returning from sigsuspend, we want the old mask to be restored
     293:  * after the signal handler has finished.  Thus, we save it here and set
     294:  * a flag to indicate this.
     295: */
     296:     u.u_oldmask = p->p_sigmask;
     297:     u.u_psflags |= SAS_OLDMASK;
     298:     p->p_sigmask = nmask &~ sigcantmask;
     299:     while   (tsleep((caddr_t)&u, PPAUSE|PCATCH, 0) == 0)
     300:         ;
     301:     /* always return EINTR rather than ERESTART */
     302:     return(u.u_error = EINTR);
     303:     }
     304:
     305: int
     306: sigaltstack()
     307: {
     308:     register struct a {
     309:         struct sigaltstack * nss;
     310:         struct sigaltstack * oss;
     311:     } *uap = (struct a *)u.u_ap;
     312:     struct sigaltstack ss;
     313:     int error = 0;
     314:
     315:     if ((u.u_psflags & SAS_ALTSTACK) == 0)
     316:         u.u_sigstk.ss_flags |= SA_DISABLE;
     317:     if (uap->oss && (error = copyout((caddr_t)&u.u_sigstk,
     318:         (caddr_t)uap->oss, sizeof (struct sigaltstack))))
     319:         goto out;
     320:     if (uap->nss == 0)
     321:         goto out;
     322:     if ((error = copyin(uap->nss, &ss, sizeof(ss))) != 0)
     323:         goto out;
     324:     if (ss.ss_flags & SA_DISABLE) {
     325:         if (u.u_sigstk.ss_flags & SA_ONSTACK)
     326:             {
     327:             error = EINVAL;
     328:             goto out;
     329:             }
     330:         u.u_psflags &= ~SAS_ALTSTACK;
     331:         u.u_sigstk.ss_flags = ss.ss_flags;
     332:         goto out;
     333:     }
     334:     if (ss.ss_size < MINSIGSTKSZ)
     335:         {
     336:         error = ENOMEM;
     337:         goto out;
     338:         }
     339:     u.u_psflags |= SAS_ALTSTACK;
     340:     u.u_sigstk = ss;
     341: out:
     342:     return(u.u_error = error);
     343: }
     344:
     345: int
     346: sigwait()
     347:     {
     348:     register struct a {
     349:         sigset_t *set;
     350:         int *sig;
     351:         } *uap = (struct a *)u.u_ap;
     352:     sigset_t wanted, sigsavail;
     353:     register struct proc *p = u.u_procp;
     354:     int signo, error;
     355:
     356:     if  (uap->set == 0 || uap->sig == 0)
     357:         {
     358:         error = EINVAL;
     359:         goto out;
     360:         }
     361:     if  (error = copyin(uap->set, &wanted, sizeof (sigset_t)))
     362:         goto out;
     363:
     364:     wanted |= sigcantmask;
     365:     while   ((sigsavail = (wanted & p->p_sig)) == 0)
     366:         tsleep(&u.u_signal[0], PPAUSE | PCATCH, 0);
     367:
     368:     if  (sigsavail & sigcantmask)
     369:         {
     370:         error = EINTR;
     371:         goto out;
     372:         }
     373:
     374:     signo = ffs(sigsavail);
     375:     p->p_sig &= ~sigmask(signo);
     376:     error = copyout(&signo, uap->sig, sizeof (int));
     377: out:
     378:     return(u.u_error = error);
     379:     }

#### Defined functions

fatalsig defined in line 172; used 1 times

- in /usr/src/sys/pdp/machdep.c line 86

setsigvec defined in line 116; used 1 times

- in line 110

sigaction defined in line 64; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 33, 141

sigaltstack defined in line 305; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 33, 145

siginit defined in line 191; used 1 times

- in /usr/src/sys/sys/init_main.c line 90

sigpending defined in line 255; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 33, 144

sigprocmask defined in line 210; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 33, 142

sigsuspend defined in line 278; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 33, 217

sigwait defined in line 345; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 34, 166

#### Defined struct's

a defined in line 348; used 12 times

- in line 72(2), 217(2), 261(2), 284(2), 311(2), 351(2)

#### Defined macros

SIGPROP defined in line 49; never used

Last modified: 1999-09-10 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1067 |