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
setsigvec defined in line 116; used 1 times
sigaction defined in line 64; used 2 times
sigaltstack defined in line 305; used 2 times
siginit defined in line 191; used 1 times
sigpending defined in line 255; used 2 times
sigprocmask defined in line 210; used 2 times
sigsuspend defined in line 278; used 2 times
sigwait defined in line 345; used 2 times

Defined struct's

a defined in line 348; used 12 times

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: 3743
Valid CSS Valid XHTML 1.0 Strict