|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* Copyright (c) 1995-1998 Apple Computer, Inc. All Rights Reserved */ ! 26: /* ! 27: * Copyright (c) 1982, 1986, 1989, 1991, 1993 ! 28: * The Regents of the University of California. All rights reserved. ! 29: * (c) UNIX System Laboratories, Inc. ! 30: * All or some portions of this file are derived from material licensed ! 31: * to the University of California by American Telephone and Telegraph ! 32: * Co. or Unix System Laboratories, Inc. and are reproduced herein with ! 33: * the permission of UNIX System Laboratories, Inc. ! 34: * ! 35: * Redistribution and use in source and binary forms, with or without ! 36: * modification, are permitted provided that the following conditions ! 37: * are met: ! 38: * 1. Redistributions of source code must retain the above copyright ! 39: * notice, this list of conditions and the following disclaimer. ! 40: * 2. Redistributions in binary form must reproduce the above copyright ! 41: * notice, this list of conditions and the following disclaimer in the ! 42: * documentation and/or other materials provided with the distribution. ! 43: * 3. All advertising materials mentioning features or use of this software ! 44: * must display the following acknowledgement: ! 45: * This product includes software developed by the University of ! 46: * California, Berkeley and its contributors. ! 47: * 4. Neither the name of the University nor the names of its contributors ! 48: * may be used to endorse or promote products derived from this software ! 49: * without specific prior written permission. ! 50: * ! 51: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 52: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 53: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 54: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 55: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 56: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 57: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 58: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 59: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 60: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 61: * SUCH DAMAGE. ! 62: * ! 63: * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 ! 64: */ ! 65: ! 66: #define SIGPROP /* include signal properties table */ ! 67: #include <sys/param.h> ! 68: #include <sys/signalvar.h> ! 69: #include <sys/resourcevar.h> ! 70: #include <sys/namei.h> ! 71: #include <sys/vnode.h> ! 72: #include <sys/proc.h> ! 73: #include <sys/systm.h> ! 74: #include <sys/timeb.h> ! 75: #include <sys/times.h> ! 76: #include <sys/buf.h> ! 77: #include <sys/acct.h> ! 78: #include <sys/file.h> ! 79: #include <sys/kernel.h> ! 80: #include <sys/wait.h> ! 81: #include <sys/ktrace.h> ! 82: #include <sys/syslog.h> ! 83: #include <sys/stat.h> ! 84: ! 85: #include <sys/mount.h> ! 86: ! 87: #include <machine/cpu.h> ! 88: #include <machine/spl.h> ! 89: ! 90: #include <sys/vm.h> ! 91: #include <sys/user.h> /* for coredump */ ! 92: ! 93: void stop __P((struct proc *p)); ! 94: int cansignal __P((struct proc *, struct pcred *, struct proc *, int)); ! 95: int killpg1 __P((struct proc *, int, int, int)); ! 96: void sigexit __P((struct proc *, int)); ! 97: void setsigvec __P((struct proc *, int, struct sigaction *)); ! 98: void exit1 __P((struct proc *, int)); ! 99: ! 100: /* ! 101: * Can process p, with pcred pc, send the signal signum to process q? ! 102: */ ! 103: int ! 104: cansignal(p, pc, q, signum) ! 105: struct proc *p; ! 106: struct pcred *pc; ! 107: struct proc *q; ! 108: int signum; ! 109: { ! 110: if (pc->pc_ucred->cr_uid == 0) ! 111: return (1); /* root can always signal */ ! 112: ! 113: if (signum == SIGCONT && q->p_session == p->p_session) ! 114: return (1); /* SIGCONT in session */ ! 115: ! 116: /* ! 117: * Using kill(), only certain signals can be sent to setugid ! 118: * child processes ! 119: */ ! 120: if (q->p_flag & P_SUGID) { ! 121: switch (signum) { ! 122: case 0: ! 123: case SIGKILL: ! 124: case SIGINT: ! 125: case SIGTERM: ! 126: case SIGSTOP: ! 127: case SIGTTIN: ! 128: case SIGTTOU: ! 129: case SIGTSTP: ! 130: case SIGHUP: ! 131: case SIGUSR1: ! 132: case SIGUSR2: ! 133: if (pc->p_ruid == q->p_cred->p_ruid || ! 134: pc->pc_ucred->cr_uid == q->p_cred->p_ruid || ! 135: pc->p_ruid == q->p_ucred->cr_uid || ! 136: pc->pc_ucred->cr_uid == q->p_ucred->cr_uid) ! 137: return (1); ! 138: } ! 139: return (0); ! 140: } ! 141: ! 142: /* XXX ! 143: * because the P_SUGID test exists, this has extra tests which ! 144: * could be removed. ! 145: */ ! 146: if (pc->p_ruid == q->p_cred->p_ruid || ! 147: pc->p_ruid == q->p_cred->p_svuid || ! 148: pc->pc_ucred->cr_uid == q->p_cred->p_ruid || ! 149: pc->pc_ucred->cr_uid == q->p_cred->p_svuid || ! 150: pc->p_ruid == q->p_ucred->cr_uid || ! 151: pc->pc_ucred->cr_uid == q->p_ucred->cr_uid) ! 152: return (1); ! 153: return (0); ! 154: } ! 155: ! 156: struct sigaction_args { ! 157: int signum; ! 158: struct sigaction *nsa; ! 159: struct sigaction *osa; ! 160: }; ! 161: /* ARGSUSED */ ! 162: int ! 163: sigaction(p, uap, retval) ! 164: struct proc *p; ! 165: register struct sigaction_args *uap; ! 166: register_t *retval; ! 167: { ! 168: struct sigaction vec; ! 169: register struct sigaction *sa; ! 170: register struct sigacts *ps = p->p_sigacts; ! 171: register int signum; ! 172: int bit, error; ! 173: ! 174: signum = uap->signum; ! 175: if (signum <= 0 || signum >= NSIG || ! 176: signum == SIGKILL || signum == SIGSTOP) ! 177: return (EINVAL); ! 178: sa = &vec; ! 179: if (uap->osa) { ! 180: sa->sa_handler = ps->ps_sigact[signum]; ! 181: sa->sa_mask = ps->ps_catchmask[signum]; ! 182: bit = sigmask(signum); ! 183: sa->sa_flags = 0; ! 184: if ((ps->ps_sigonstack & bit) != 0) ! 185: sa->sa_flags |= SA_ONSTACK; ! 186: if ((ps->ps_sigintr & bit) == 0) ! 187: sa->sa_flags |= SA_RESTART; ! 188: if (p->p_flag & P_NOCLDSTOP) ! 189: sa->sa_flags |= SA_NOCLDSTOP; ! 190: if (error = copyout((caddr_t)sa, (caddr_t)uap->osa, ! 191: sizeof (vec))) ! 192: return (error); ! 193: } ! 194: if (uap->nsa) { ! 195: if (error = copyin((caddr_t)uap->nsa, (caddr_t)sa, ! 196: sizeof (vec))) ! 197: return (error); ! 198: setsigvec(p, signum, sa); ! 199: } ! 200: return (0); ! 201: } ! 202: ! 203: void ! 204: setsigvec(p, signum, sa) ! 205: register struct proc *p; ! 206: int signum; ! 207: register struct sigaction *sa; ! 208: { ! 209: register struct sigacts *ps = p->p_sigacts; ! 210: register int bit; ! 211: ! 212: bit = sigmask(signum); ! 213: /* ! 214: * Change setting atomically. ! 215: */ ! 216: (void) splhigh(); ! 217: simple_lock(&p->siglock); ! 218: ps->ps_sigact[signum] = sa->sa_handler; ! 219: ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask; ! 220: if ((sa->sa_flags & SA_RESTART) == 0) ! 221: ps->ps_sigintr |= bit; ! 222: else ! 223: ps->ps_sigintr &= ~bit; ! 224: if (sa->sa_flags & SA_ONSTACK) ! 225: ps->ps_sigonstack |= bit; ! 226: else ! 227: ps->ps_sigonstack &= ~bit; ! 228: if (sa->sa_flags & SA_USERTRAMP) ! 229: ps->ps_usertramp |= bit; ! 230: else ! 231: ps->ps_usertramp &= ~bit; ! 232: if (signum == SIGCHLD) { ! 233: if (sa->sa_flags & SA_NOCLDSTOP) ! 234: p->p_flag |= P_NOCLDSTOP; ! 235: else ! 236: p->p_flag &= ~P_NOCLDSTOP; ! 237: } ! 238: /* ! 239: * Set bit in p_sigignore for signals that are set to SIG_IGN, ! 240: * and for signals set to SIG_DFL where the default is to ignore. ! 241: * However, don't put SIGCONT in p_sigignore, ! 242: * as we have to restart the process. ! 243: */ ! 244: if (sa->sa_handler == SIG_IGN || ! 245: (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) { ! 246: p->p_siglist &= ~bit; /* never to be seen again */ ! 247: /* ! 248: * If this is a thread signal, clean out the ! 249: * threads as well. ! 250: */ ! 251: if (bit & threadmask) { ! 252: register task_t task = p->task; ! 253: register queue_head_t *list; ! 254: register thread_t thread; ! 255: ! 256: list = &(task->thread_list); ! 257: task_lock(task); ! 258: thread = (thread_t) queue_first(list); ! 259: while (!queue_end(list, (queue_entry_t) thread)) { ! 260: thread->_uthread->uu_sig &= ~bit; ! 261: thread = (thread_t) ! 262: queue_next(&thread->thread_list); ! 263: } ! 264: task_unlock(task); ! 265: } ! 266: if (signum != SIGCONT) ! 267: p->p_sigignore |= bit; /* easier in psignal */ ! 268: p->p_sigcatch &= ~bit; ! 269: } else { ! 270: p->p_sigignore &= ~bit; ! 271: if (sa->sa_handler == SIG_DFL) ! 272: p->p_sigcatch &= ~bit; ! 273: else ! 274: p->p_sigcatch |= bit; ! 275: } ! 276: simple_unlock(&p->siglock); ! 277: (void) spl0(); ! 278: } ! 279: ! 280: /* ! 281: * Initialize signal state for process 0; ! 282: * set to ignore signals that are ignored by default. ! 283: */ ! 284: void ! 285: siginit(p) ! 286: struct proc *p; ! 287: { ! 288: register int i; ! 289: ! 290: for (i = 0; i < NSIG; i++) ! 291: if (sigprop[i] & SA_IGNORE && i != SIGCONT) ! 292: p->p_sigignore |= sigmask(i); ! 293: } ! 294: ! 295: /* ! 296: * Reset signals for an exec of the specified process. ! 297: */ ! 298: void ! 299: execsigs(p) ! 300: register struct proc *p; ! 301: { ! 302: register struct sigacts *ps = p->p_sigacts; ! 303: register int nc, mask; ! 304: ! 305: /* ! 306: * Reset caught signals. Held signals remain held ! 307: * through p_sigmask (unless they were caught, ! 308: * and are now ignored by default). ! 309: */ ! 310: while (p->p_sigcatch) { ! 311: nc = ffs((long)p->p_sigcatch); ! 312: mask = sigmask(nc); ! 313: p->p_sigcatch &= ~mask; ! 314: if (sigprop[nc] & SA_IGNORE) { ! 315: if (nc != SIGCONT) ! 316: p->p_sigignore |= mask; ! 317: p->p_siglist &= ~mask; ! 318: } ! 319: ps->ps_sigact[nc] = SIG_DFL; ! 320: } ! 321: /* ! 322: * Reset stack state to the user stack. ! 323: * Clear set of signals caught on the signal stack. ! 324: */ ! 325: ps->ps_sigstk.ss_flags = SA_DISABLE; ! 326: ps->ps_sigstk.ss_size = 0; ! 327: ps->ps_sigstk.ss_sp = 0; ! 328: ps->ps_flags = 0; ! 329: } ! 330: ! 331: /* ! 332: * Manipulate signal mask. ! 333: * Note that we receive new mask, not pointer, ! 334: * and return old mask as return value; ! 335: * the library stub does the rest. ! 336: */ ! 337: struct sigprocmask_args { ! 338: int how; ! 339: sigset_t mask; ! 340: }; ! 341: int ! 342: sigprocmask(p, uap, retval) ! 343: register struct proc *p; ! 344: struct sigprocmask_args *uap; ! 345: register_t *retval; ! 346: { ! 347: int error = 0; ! 348: ! 349: *retval = p->p_sigmask; ! 350: (void) splhigh(); ! 351: ! 352: switch (uap->how) { ! 353: case SIG_BLOCK: ! 354: p->p_sigmask |= uap->mask &~ sigcantmask; ! 355: break; ! 356: ! 357: case SIG_UNBLOCK: ! 358: p->p_sigmask &= ~(uap->mask); ! 359: break; ! 360: ! 361: case SIG_SETMASK: ! 362: p->p_sigmask = uap->mask &~ sigcantmask; ! 363: break; ! 364: ! 365: default: ! 366: error = EINVAL; ! 367: break; ! 368: } ! 369: (void) spl0(); ! 370: return (error); ! 371: } ! 372: ! 373: /* ARGSUSED */ ! 374: int ! 375: sigpending(p, uap, retval) ! 376: struct proc *p; ! 377: void *uap; ! 378: register_t *retval; ! 379: { ! 380: ! 381: *retval = p->p_siglist; ! 382: return (0); ! 383: } ! 384: ! 385: #if COMPAT_43 ! 386: /* ! 387: * Generalized interface signal handler, 4.3-compatible. ! 388: */ ! 389: struct osigvec_args { ! 390: int signum; ! 391: struct sigvec *nsv; ! 392: struct sigvec *osv; ! 393: }; ! 394: /* ARGSUSED */ ! 395: int ! 396: osigvec(p, uap, retval) ! 397: struct proc *p; ! 398: register struct osigvec_args *uap; ! 399: register_t *retval; ! 400: { ! 401: struct sigvec vec; ! 402: register struct sigacts *ps = p->p_sigacts; ! 403: register struct sigvec *sv; ! 404: register int signum; ! 405: int bit, error; ! 406: ! 407: signum = uap->signum; ! 408: if (signum <= 0 || signum >= NSIG || ! 409: signum == SIGKILL || signum == SIGSTOP) ! 410: return (EINVAL); ! 411: sv = &vec; ! 412: if (uap->osv) { ! 413: *(sig_t *)&sv->sv_handler = ps->ps_sigact[signum]; ! 414: sv->sv_mask = ps->ps_catchmask[signum]; ! 415: bit = sigmask(signum); ! 416: sv->sv_flags = 0; ! 417: if ((ps->ps_sigonstack & bit) != 0) ! 418: sv->sv_flags |= SV_ONSTACK; ! 419: if ((ps->ps_sigintr & bit) != 0) ! 420: sv->sv_flags |= SV_INTERRUPT; ! 421: if (p->p_flag & P_NOCLDSTOP) ! 422: sv->sv_flags |= SA_NOCLDSTOP; ! 423: if (error = copyout((caddr_t)sv, (caddr_t)uap->osv, ! 424: sizeof (vec))) ! 425: return (error); ! 426: } ! 427: if (uap->nsv) { ! 428: if (error = copyin((caddr_t)uap->nsv, (caddr_t)sv, ! 429: sizeof (vec))) ! 430: return (error); ! 431: sv->sv_flags ^= SA_RESTART; /* opposite of SV_INTERRUPT */ ! 432: setsigvec(p, signum, (struct sigaction *)sv); ! 433: } ! 434: return (0); ! 435: } ! 436: ! 437: struct osigblock_args { ! 438: int mask; ! 439: }; ! 440: int ! 441: osigblock(p, uap, retval) ! 442: register struct proc *p; ! 443: struct osigblock_args *uap; ! 444: register_t *retval; ! 445: { ! 446: ! 447: (void) splhigh(); ! 448: *retval = p->p_sigmask; ! 449: p->p_sigmask |= uap->mask &~ sigcantmask; ! 450: (void) spl0(); ! 451: return (0); ! 452: } ! 453: ! 454: struct osigsetmask_args { ! 455: int mask; ! 456: }; ! 457: int ! 458: osigsetmask(p, uap, retval) ! 459: struct proc *p; ! 460: struct osigsetmask_args *uap; ! 461: register_t *retval; ! 462: { ! 463: ! 464: (void) splhigh(); ! 465: *retval = p->p_sigmask; ! 466: p->p_sigmask = uap->mask &~ sigcantmask; ! 467: (void) spl0(); ! 468: return (0); ! 469: } ! 470: #endif /* COMPAT_43 */ ! 471: ! 472: /* ! 473: * Suspend process until signal, providing mask to be set ! 474: * in the meantime. Note nonstandard calling convention: ! 475: * libc stub passes mask, not pointer, to save a copyin. ! 476: */ ! 477: struct sigsuspend_args { ! 478: int mask; ! 479: }; ! 480: /* ARGSUSED */ ! 481: int ! 482: sigsuspend(p, uap, retval) ! 483: register struct proc *p; ! 484: struct sigsuspend_args *uap; ! 485: register_t *retval; ! 486: { ! 487: register struct sigacts *ps = p->p_sigacts; ! 488: ! 489: /* ! 490: * When returning from sigpause, we want ! 491: * the old mask to be restored after the ! 492: * signal handler has finished. Thus, we ! 493: * save it here and mark the sigacts structure ! 494: * to indicate this. ! 495: */ ! 496: ps->ps_oldmask = p->p_sigmask; ! 497: ps->ps_flags |= SAS_OLDMASK; ! 498: p->p_sigmask = uap->mask &~ sigcantmask; ! 499: (void) tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0); ! 500: /* always return EINTR rather than ERESTART... */ ! 501: return (EINTR); ! 502: } ! 503: ! 504: #if COMPAT_43 ! 505: struct osigstack_args { ! 506: struct sigstack *nss; ! 507: struct sigstack *oss; ! 508: }; ! 509: /* ARGSUSED */ ! 510: int ! 511: osigstack(p, uap, retval) ! 512: struct proc *p; ! 513: register struct osigstack_args *uap; ! 514: register_t *retval; ! 515: { ! 516: struct sigstack ss; ! 517: struct sigacts *psp; ! 518: int error = 0; ! 519: ! 520: psp = p->p_sigacts; ! 521: ss.ss_sp = psp->ps_sigstk.ss_sp; ! 522: ss.ss_onstack = psp->ps_sigstk.ss_flags & SA_ONSTACK; ! 523: if (uap->oss && (error = copyout((caddr_t)&ss, ! 524: (caddr_t)uap->oss, sizeof (struct sigstack)))) ! 525: return (error); ! 526: if (uap->nss && (error = copyin((caddr_t)uap->nss, ! 527: (caddr_t)&ss, sizeof (ss))) == 0) { ! 528: psp->ps_sigstk.ss_sp = ss.ss_sp; ! 529: psp->ps_sigstk.ss_size = 0; ! 530: psp->ps_sigstk.ss_flags |= ss.ss_onstack & SA_ONSTACK; ! 531: psp->ps_flags |= SAS_ALTSTACK; ! 532: } ! 533: return (error); ! 534: } ! 535: #endif /* COMPAT_43 */ ! 536: ! 537: struct sigaltstack_args { ! 538: struct sigaltstack *nss; ! 539: struct sigaltstack *oss; ! 540: }; ! 541: /* ARGSUSED */ ! 542: int ! 543: sigaltstack(p, uap, retval) ! 544: struct proc *p; ! 545: register struct sigaltstack_args *uap; ! 546: register_t *retval; ! 547: { ! 548: struct sigacts *psp; ! 549: struct sigaltstack ss; ! 550: int error; ! 551: ! 552: psp = p->p_sigacts; ! 553: if ((psp->ps_flags & SAS_ALTSTACK) == 0) ! 554: psp->ps_sigstk.ss_flags |= SA_DISABLE; ! 555: if (uap->oss && (error = copyout((caddr_t)&psp->ps_sigstk, ! 556: (caddr_t)uap->oss, sizeof (struct sigaltstack)))) ! 557: return (error); ! 558: if (uap->nss == 0) ! 559: return (0); ! 560: if (error = copyin((caddr_t)uap->nss, (caddr_t)&ss, ! 561: sizeof (ss))) ! 562: return (error); ! 563: if (ss.ss_flags & SA_DISABLE) { ! 564: if (psp->ps_sigstk.ss_flags & SA_ONSTACK) ! 565: return (EINVAL); ! 566: psp->ps_flags &= ~SAS_ALTSTACK; ! 567: psp->ps_sigstk.ss_flags = ss.ss_flags; ! 568: return (0); ! 569: } ! 570: if (ss.ss_size < MINSIGSTKSZ) ! 571: return (ENOMEM); ! 572: psp->ps_flags |= SAS_ALTSTACK; ! 573: psp->ps_sigstk= ss; ! 574: return (0); ! 575: } ! 576: ! 577: struct kill_args { ! 578: int pid; ! 579: int signum; ! 580: }; ! 581: /* ARGSUSED */ ! 582: int ! 583: kill(cp, uap, retval) ! 584: register struct proc *cp; ! 585: register struct kill_args *uap; ! 586: register_t *retval; ! 587: { ! 588: register struct proc *p; ! 589: register struct pcred *pc = cp->p_cred; ! 590: ! 591: if ((u_int)uap->signum >= NSIG) ! 592: return (EINVAL); ! 593: if (uap->pid > 0) { ! 594: /* kill single process */ ! 595: if ((p = pfind(uap->pid)) == NULL) ! 596: return (ESRCH); ! 597: if (!cansignal(cp, pc, p, uap->signum)) ! 598: return (EPERM); ! 599: if (uap->signum) ! 600: psignal(p, uap->signum); ! 601: return (0); ! 602: } ! 603: switch (uap->pid) { ! 604: case -1: /* broadcast signal */ ! 605: return (killpg1(cp, uap->signum, 0, 1)); ! 606: case 0: /* signal own process group */ ! 607: return (killpg1(cp, uap->signum, 0, 0)); ! 608: default: /* negative explicit process group */ ! 609: return (killpg1(cp, uap->signum, -(uap->pid), 0)); ! 610: } ! 611: /* NOTREACHED */ ! 612: } ! 613: ! 614: #if COMPAT_43 ! 615: struct okillpg_args { ! 616: int pgid; ! 617: int signum; ! 618: }; ! 619: /* ARGSUSED */ ! 620: int ! 621: okillpg(p, uap, retval) ! 622: struct proc *p; ! 623: register struct okillpg_args *uap; ! 624: register_t *retval; ! 625: { ! 626: ! 627: if ((u_int)uap->signum >= NSIG) ! 628: return (EINVAL); ! 629: return (killpg1(p, uap->signum, uap->pgid, 0)); ! 630: } ! 631: #endif /* COMPAT_43 */ ! 632: ! 633: /* ! 634: * Common code for kill process group/broadcast kill. ! 635: * cp is calling process. ! 636: */ ! 637: int ! 638: killpg1(cp, signum, pgid, all) ! 639: register struct proc *cp; ! 640: int signum, pgid, all; ! 641: { ! 642: register struct proc *p; ! 643: register struct pcred *pc = cp->p_cred; ! 644: struct pgrp *pgrp; ! 645: int nfound = 0; ! 646: ! 647: if (all) ! 648: /* ! 649: * broadcast ! 650: */ ! 651: for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { ! 652: if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || ! 653: p == cp || !cansignal(cp, pc, p, signum)) ! 654: continue; ! 655: nfound++; ! 656: if (signum) ! 657: psignal(p, signum); ! 658: } ! 659: else { ! 660: if (pgid == 0) ! 661: /* ! 662: * zero pgid means send to my process group. ! 663: */ ! 664: pgrp = cp->p_pgrp; ! 665: else { ! 666: pgrp = pgfind(pgid); ! 667: if (pgrp == NULL) ! 668: return (ESRCH); ! 669: } ! 670: for (p = pgrp->pg_members.lh_first; p != 0; ! 671: p = p->p_pglist.le_next) { ! 672: if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || ! 673: p->p_stat == SZOMB || ! 674: !cansignal(cp, pc, p, signum)) ! 675: continue; ! 676: nfound++; ! 677: if (signum) ! 678: psignal(p, signum); ! 679: } ! 680: } ! 681: return (nfound ? 0 : ESRCH); ! 682: } ! 683: ! 684: /* ! 685: * Send a signal to a process group. ! 686: */ ! 687: void ! 688: gsignal(pgid, signum) ! 689: int pgid, signum; ! 690: { ! 691: struct pgrp *pgrp; ! 692: ! 693: if (pgid && (pgrp = pgfind(pgid))) ! 694: pgsignal(pgrp, signum, 0); ! 695: } ! 696: ! 697: /* ! 698: * Send a signal to a process group. If checktty is 1, ! 699: * limit to members which have a controlling terminal. ! 700: */ ! 701: void ! 702: pgsignal(pgrp, signum, checkctty) ! 703: struct pgrp *pgrp; ! 704: int signum, checkctty; ! 705: { ! 706: register struct proc *p; ! 707: ! 708: if (pgrp) ! 709: for (p = pgrp->pg_members.lh_first; p != 0; ! 710: p = p->p_pglist.le_next) ! 711: if (checkctty == 0 || p->p_flag & P_CONTROLT) ! 712: psignal(p, signum); ! 713: } ! 714: ! 715: /* ! 716: * Send a signal caused by a trap to a specific thread. ! 717: */ ! 718: void ! 719: threadsignal(thread, signum, code) ! 720: struct thread *thread; ! 721: register int signum; ! 722: u_long code; ! 723: { ! 724: register struct uthread *uth = thread->_uthread; ! 725: register struct proc *p = thread->task->proc; ! 726: int mask; ! 727: ! 728: if ((u_int)signum >= NSIG || signum == 0) ! 729: return; ! 730: ! 731: mask = sigmask(signum); ! 732: if ((mask & threadmask) == 0) ! 733: return; ! 734: ! 735: if (!(p->p_flag & P_TRACED) && (p->p_sigignore & mask)) ! 736: return; ! 737: ! 738: simple_lock(&p->siglock); ! 739: uth->uu_sig |= mask; ! 740: uth->uu_code = code; ! 741: simple_unlock(&p->siglock); ! 742: } ! 743: ! 744: /* ! 745: * Send the signal to the process. If the signal has an action, the action ! 746: * is usually performed by the target process rather than the caller; we add ! 747: * the signal to the set of pending signals for the process. ! 748: * ! 749: * Exceptions: ! 750: * o When a stop signal is sent to a sleeping process that takes the ! 751: * default action, the process is stopped without awakening it. ! 752: * o SIGCONT restarts stopped processes (or puts them back to sleep) ! 753: * regardless of the signal action (eg, blocked or ignored). ! 754: * ! 755: * Other ignored signals are discarded immediately. ! 756: */ ! 757: void ! 758: psignal(p, signum) ! 759: register struct proc *p; ! 760: register int signum; ! 761: { ! 762: register int s, prop; ! 763: register sig_t action; ! 764: register thread_t sig_thread; ! 765: register task_t sig_task; ! 766: register thread_t cur_thread; ! 767: int mask; ! 768: ! 769: if ((u_int)signum >= NSIG || signum == 0) ! 770: panic("psignal signal number"); ! 771: mask = sigmask(signum); ! 772: prop = sigprop[signum]; ! 773: ! 774: /* ! 775: * We will need the task pointer later. Grab it now to ! 776: * check for a zombie process. Also don't send signals ! 777: * to kernel internal tasks. ! 778: */ ! 779: if (((sig_task = p->task) == TASK_NULL) || sig_task->kernel_vm_space) ! 780: return; ! 781: ! 782: /* ! 783: * If proc is traced, always give parent a chance. ! 784: */ ! 785: if (p->p_flag & P_TRACED) ! 786: action = SIG_DFL; ! 787: else { ! 788: /* ! 789: * If the signal is being ignored, ! 790: * then we forget about it immediately. ! 791: * (Note: we don't set SIGCONT in p_sigignore, ! 792: * and if it is set to SIG_IGN, ! 793: * action will be SIG_DFL here.) ! 794: */ ! 795: if (p->p_sigignore & mask) ! 796: return; ! 797: if (p->p_sigmask & mask) ! 798: action = SIG_HOLD; ! 799: else if (p->p_sigcatch & mask) ! 800: action = SIG_CATCH; ! 801: else ! 802: action = SIG_DFL; ! 803: } ! 804: ! 805: if (p->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) && ! 806: (p->p_flag & P_TRACED) == 0) ! 807: p->p_nice = NZERO; ! 808: ! 809: if (prop & SA_CONT) ! 810: p->p_siglist &= ~stopsigmask; ! 811: ! 812: if (prop & SA_STOP) { ! 813: /* ! 814: * If sending a tty stop signal to a member of an orphaned ! 815: * process group, discard the signal here if the action ! 816: * is default; don't stop the process below if sleeping, ! 817: * and don't clear any pending SIGCONT. ! 818: */ ! 819: if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 && ! 820: action == SIG_DFL) ! 821: return; ! 822: p->p_siglist &= ~contsigmask; ! 823: } ! 824: p->p_siglist |= mask; ! 825: ! 826: /* ! 827: * Defer further processing for signals which are held, ! 828: * except that stopped processes must be continued by SIGCONT. ! 829: */ ! 830: if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP)) ! 831: return; ! 832: ! 833: /* ! 834: * Deliver the signal to the first thread in the task. This ! 835: * allows single threaded applications which use signals to ! 836: * be able to be linked with multithreaded libraries. We have ! 837: * an implicit reference to the current_thread, but need ! 838: * an explicit one otherwise. The thread reference keeps ! 839: * the corresponding task data structures around too. This ! 840: * reference is released by thread_deallocate_interrupt ! 841: * because psignal() can be called from interrupt level). ! 842: */ ! 843: ! 844: s = splhigh(); ! 845: ! 846: cur_thread = current_thread(); ! 847: ! 848: /* ! 849: * This is a mess. The thread_list_lock is a special ! 850: * lock that excludes insert and delete operations ! 851: * on the task's thread list for our benefit (can't ! 852: * grab task lock because we might be at interrupt ! 853: * level). Check if there are any threads in the ! 854: * task. If there aren't, sending it a signal ! 855: * isn't going to work very well, so just return. ! 856: */ ! 857: simple_lock(&sig_task->thread_list_lock); ! 858: if (queue_empty(&sig_task->thread_list)) { ! 859: simple_unlock(&sig_task->thread_list_lock); ! 860: (void) splx(s); ! 861: return; ! 862: } ! 863: sig_thread = (thread_t) queue_first(&sig_task->thread_list); ! 864: if (sig_thread != cur_thread) ! 865: thread_reference(sig_thread); ! 866: simple_unlock(&sig_task->thread_list_lock); ! 867: ! 868: /* ! 869: * SIGKILL priority twiddling moved here from above because ! 870: * it needs sig_thread. Could merge it into large switch ! 871: * below if we didn't care about priority for tracing ! 872: * as SIGKILL's action is always SIG_DFL. ! 873: */ ! 874: if ((signum == SIGKILL) && (p->p_nice > NZERO)) { ! 875: p->p_nice = NZERO; ! 876: thread_max_priority(sig_thread, sig_thread->processor_set, ! 877: BASEPRI_USER); ! 878: thread_priority(sig_thread, BASEPRI_USER, FALSE); ! 879: } ! 880: ! 881: /* ! 882: * Process is traced - wake it up (if not already ! 883: * stopped) so that it can discover the signal in ! 884: * issig() and stop for the parent. ! 885: */ ! 886: if (p->p_flag & P_TRACED) { ! 887: if (p->p_stat != SSTOP) ! 888: goto run; ! 889: else ! 890: goto out; ! 891: } ! 892: ! 893: if (action != SIG_DFL) { ! 894: /* ! 895: * User wants to catch the signal. ! 896: * Wake up the thread, but don't un-suspend it ! 897: * (except for SIGCONT). ! 898: */ ! 899: if (prop & SA_CONT) ! 900: (void) task_resume(sig_task); ! 901: goto run; ! 902: } else { ! 903: /* Default action - varies */ ! 904: ! 905: if (mask & stopsigmask) { ! 906: /* ! 907: * These are the signals which by default ! 908: * stop a process. ! 909: * ! 910: * Don't clog system with children of init ! 911: * stopped from the keyboard. ! 912: */ ! 913: if (!(prop & SA_STOP) && p->p_pptr == initproc) { ! 914: psignal(p, SIGKILL); ! 915: p->p_siglist &= ~mask; ! 916: goto out; ! 917: } ! 918: /* ! 919: * Stop the task. ! 920: */ ! 921: if ((sig_thread->state & TH_RUN) == 0) { ! 922: /* ! 923: * If task hasn't already been stopped by ! 924: * a signal, stop it. ! 925: */ ! 926: p->p_siglist &= ~mask; ! 927: if (sig_task->user_stop_count == 0) { ! 928: /* ! 929: * p_cursig must not be set, because ! 930: * it will be psig()'d if it is not ! 931: * zero, and the signal is being ! 932: * handled here. But save the signal ! 933: * in p_stopsig so WUNTRACED ! 934: * option to wait can find it. ! 935: */ ! 936: p->p_xstat = signum; ! 937: if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0) ! 938: psignal(p->p_pptr, SIGCHLD); ! 939: stop(p); ! 940: } ! 941: goto out; ! 942: } ! 943: else { ! 944: if ((p == current_proc()) && (p->p_stat != SZOMB)) ! 945: ast_on(cpu_number(), AST_UNIX); ! 946: goto out; ! 947: } ! 948: } ! 949: ! 950: switch (signum) { ! 951: /* ! 952: * Signals ignored by default have been dealt ! 953: * with already, since their bits are on in ! 954: * p_sigignore. ! 955: */ ! 956: ! 957: case SIGKILL: ! 958: /* ! 959: * Kill signal always sets process running and ! 960: * unsuspends it. ! 961: */ ! 962: while (sig_task->user_stop_count > 0) ! 963: (void) task_resume(sig_task); ! 964: /* ! 965: * Process will be running after 'run' ! 966: */ ! 967: p->p_stat = SRUN; ! 968: ! 969: /* ! 970: * Break it out of user wait, as well. ! 971: */ ! 972: while (sig_thread->user_stop_count > 0) ! 973: (void) thread_resume(sig_thread); ! 974: ! 975: /* ! 976: * Clear system wait if possible. The ! 977: * THREAD_SHOULD_TERMINATE is overkill, but ! 978: * saves us from potentially buggy code elsewhere. ! 979: */ ! 980: clear_wait(sig_thread, THREAD_SHOULD_TERMINATE, FALSE); ! 981: #if MACH_HOST ! 982: /* ! 983: * Make sure it can run. ! 984: */ ! 985: if (sig_thread->processor_set->empty) ! 986: thread_assign(sig_thread, &default_pset); ! 987: #endif ! 988: /* ! 989: * If we're delivering the signal to some other ! 990: * thread, that thread might be stuck in an ! 991: * exception. Break it out. Can't call ! 992: * thread_exception_abort from high spl, but ! 993: * SIGKILL can't be sent from interrupt level, so ! 994: * it's ok to drop spl. Can call thread_deallocate ! 995: * for same reason. ! 996: */ ! 997: splx(s); ! 998: if (sig_thread != cur_thread) { ! 999: mach_msg_abort_rpc(sig_thread); ! 1000: thread_deallocate(sig_thread); ! 1001: } ! 1002: return; ! 1003: ! 1004: case SIGCONT: ! 1005: /* ! 1006: * Let the process run. If it's sleeping on an ! 1007: * event, it remains so. ! 1008: */ ! 1009: (void) task_resume(sig_task); ! 1010: p->p_stat = SRUN; ! 1011: goto out; ! 1012: ! 1013: default: ! 1014: /* ! 1015: * All other signals wake up the process, but don't ! 1016: * resume it. ! 1017: */ ! 1018: goto run; ! 1019: } ! 1020: } ! 1021: /*NOTREACHED*/ ! 1022: run: ! 1023: /* ! 1024: * If we're being traced (possibly because someone attached us ! 1025: * while we were stopped), check for a signal from the debugger. ! 1026: */ ! 1027: if (p->p_stat == SSTOP) { ! 1028: if ((p->p_flag & P_TRACED) != 0 && p->p_xstat != 0) ! 1029: p->p_siglist |= sigmask(p->p_xstat); ! 1030: } ! 1031: ! 1032: /* ! 1033: * setrunnable(p) in BSD ! 1034: */ ! 1035: ! 1036: p->p_stat = SRUN; ! 1037: ! 1038: /* ! 1039: * Wake up the thread if it is interruptible. ! 1040: */ ! 1041: clear_wait(sig_thread, THREAD_INTERRUPTED, TRUE); ! 1042: out: ! 1043: splx(s); ! 1044: if (sig_thread != cur_thread) ! 1045: thread_deallocate_interrupt(sig_thread); ! 1046: } ! 1047: ! 1048: __inline__ void ! 1049: sig_lock_to_exit( ! 1050: struct proc *p) ! 1051: { ! 1052: thread_t self = current_thread(); ! 1053: ! 1054: p->exit_thread = self; ! 1055: simple_unlock(&p->siglock); ! 1056: (void) task_hold(p->task); ! 1057: (void) task_dowait(p->task, FALSE); ! 1058: } ! 1059: ! 1060: __inline__ int ! 1061: sig_try_lock( ! 1062: struct proc *p) ! 1063: { ! 1064: thread_t self = current_thread(); ! 1065: ! 1066: simple_lock(&p->siglock); ! 1067: while (p->sigwait || p->exit_thread) { ! 1068: simple_unlock(&p->siglock); ! 1069: if (p->exit_thread) { ! 1070: if (p->exit_thread == self) { ! 1071: /* ! 1072: * Already exiting - no signals. ! 1073: */ ! 1074: return 0; ! 1075: } ! 1076: else { ! 1077: /* ! 1078: * Another thread has called exit - ! 1079: * stop (until terminate request). ! 1080: */ ! 1081: thread_hold(self); ! 1082: } ! 1083: } ! 1084: thread_block_with_continuation((void (*)(void)) 0); ! 1085: if (thread_should_halt(self)) { ! 1086: /* ! 1087: * Terminate request - clean up. ! 1088: */ ! 1089: return -1; ! 1090: } ! 1091: simple_lock(&p->siglock); ! 1092: } ! 1093: ! 1094: return 1; ! 1095: } ! 1096: ! 1097: /* ! 1098: * If the current process has received a signal (should be caught or cause ! 1099: * termination, should interrupt current syscall), return the signal number. ! 1100: * Stop signals with default action are processed immediately, then cleared; ! 1101: * they aren't returned. This is checked after each entry to the system for ! 1102: * a syscall or trap (though this can usually be done without calling issignal ! 1103: * by checking the pending signal masks in the CURSIG macro.) The normal call ! 1104: * sequence is ! 1105: * ! 1106: * while (signum = CURSIG(curproc)) ! 1107: * postsig(signum); ! 1108: */ ! 1109: int ! 1110: issignal(p) ! 1111: register struct proc *p; ! 1112: { ! 1113: register int signum, mask, prop, sigbits; ! 1114: task_t task = p->task; ! 1115: thread_t initial_thread; ! 1116: thread_t cur_thread; ! 1117: int s; ! 1118: ! 1119: #if DIAGNOSTIC ! 1120: /* ! 1121: * This must be called on master cpu ! 1122: */ ! 1123: if (cpu_number() != master_cpu) ! 1124: panic("issig not on master"); ! 1125: #endif /* DIAGNOSTIC */ ! 1126: ! 1127: /* ! 1128: * Try to grab the signal lock. ! 1129: */ ! 1130: if (sig_try_lock(p) <= 0) ! 1131: return (0); ! 1132: ! 1133: /* ! 1134: * only allow delivery of process signals (asynchronous) ! 1135: * to the initial thread. This is the first thread in ! 1136: * the tasks thread list. ! 1137: */ ! 1138: s = splsched(); ! 1139: simple_lock(&task->thread_list_lock); ! 1140: initial_thread = (thread_t)queue_first(&task->thread_list); ! 1141: simple_unlock(&task->thread_list_lock); ! 1142: splx(s); ! 1143: cur_thread = current_thread(); ! 1144: ! 1145: for(;;) { ! 1146: sigbits = (cur_thread->_uthread->uu_sig |p->p_siglist) & ~p->p_sigmask; ! 1147: ! 1148: for (;;) { ! 1149: if (p->p_flag & P_PPWAIT) ! 1150: sigbits &= ~stopsigmask; ! 1151: if (sigbits == 0) { /* no signal to send */ ! 1152: simple_unlock(&p->siglock); ! 1153: return (0); ! 1154: } ! 1155: signum = ffs((long)sigbits); ! 1156: mask = sigmask(signum); ! 1157: prop = sigprop[signum]; ! 1158: ! 1159: if (mask & threadmask) { ! 1160: /* we can take this signal */ ! 1161: cur_thread->_uthread->uu_sig &= ~mask; ! 1162: break; ! 1163: } else { ! 1164: if (cur_thread != initial_thread) ! 1165: sigbits &= ~mask; ! 1166: else ! 1167: break; ! 1168: } ! 1169: } ! 1170: ! 1171: /* ! 1172: * We should see pending but ignored signals ! 1173: * only if P_TRACED was on when they were posted. ! 1174: */ ! 1175: if (mask & p->p_sigignore && (p->p_flag & P_TRACED) == 0) { ! 1176: p->p_siglist &= ~mask; /* take the signal! */ ! 1177: continue; ! 1178: } ! 1179: if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) { ! 1180: register int hold; ! 1181: register task_t task; ! 1182: /* ! 1183: * If traced, always stop, and stay ! 1184: * stopped until released by the debugger. ! 1185: */ ! 1186: ! 1187: if (p->p_flag & P_FSTRACE) { ! 1188: #if PROCFS ! 1189: /* procfs debugging */ ! 1190: p->p_stat = SSTOP; ! 1191: wakeup((caddr_t)p); ! 1192: #error need to implement ! 1193: panic("procfs debugging"); ! 1194: #endif ! 1195: } else { ! 1196: /* ptrace debugging */ ! 1197: p->p_xstat = signum; ! 1198: psignal(p->p_pptr, SIGCHLD); ! 1199: pcb_synch(cur_thread); ! 1200: /* ! 1201: * XXX Have to really stop for debuggers; ! 1202: * XXX stop() doesn't do the right thing. ! 1203: * XXX Inline the task_suspend because we ! 1204: * XXX have to diddle Unix state in the ! 1205: * XXX middle of it. ! 1206: */ ! 1207: task = p->task; ! 1208: hold = FALSE; ! 1209: task_lock(task); ! 1210: if ((task->user_stop_count)++ == 0) ! 1211: hold = TRUE; ! 1212: task_unlock(task); ! 1213: ! 1214: if (hold) { ! 1215: (void) task_hold(task); ! 1216: thread_reference(cur_thread); ! 1217: p->sigwait = TRUE; ! 1218: p->sigwait_thread = cur_thread; ! 1219: simple_unlock(&p->siglock); ! 1220: (void) task_dowait(task, TRUE); ! 1221: thread_hold(current_thread()); ! 1222: } ! 1223: else { ! 1224: thread_reference(cur_thread); ! 1225: p->sigwait = TRUE; ! 1226: p->sigwait_thread = cur_thread; ! 1227: simple_unlock(&p->siglock); ! 1228: } ! 1229: p->p_stat = SSTOP; ! 1230: p->p_flag &= ~P_WAITED; ! 1231: wakeup((caddr_t)p->p_pptr); ! 1232: thread_block(); ! 1233: simple_lock(&p->siglock); ! 1234: p->sigwait = FALSE; ! 1235: p->sigwait_thread = NULL; ! 1236: thread_deallocate(cur_thread); ! 1237: ! 1238: /* ! 1239: * We get here only if task ! 1240: * is continued or killed. Kill condition ! 1241: * is signalled by adding NSIG to p_cursig. ! 1242: * Pass original p_cursig as exit value in ! 1243: * this case. ! 1244: */ ! 1245: if (p->p_siglist & sigmask(SIGKILL)) { ! 1246: /* ! 1247: * Wait event may still be outstanding; ! 1248: * clear it, since sig_lock_to_exit will ! 1249: * wait. ! 1250: */ ! 1251: clear_wait(current_thread(), ! 1252: THREAD_INTERRUPTED, ! 1253: FALSE); ! 1254: sig_lock_to_exit(p); ! 1255: /* ! 1256: * Since this thread will be resumed ! 1257: * to allow the current syscall to ! 1258: * be completed, must save u_qsave ! 1259: * before calling exit(). (Since exit() ! 1260: * calls closef() which can trash u_qsave.) ! 1261: */ ! 1262: exit1(p,signum); ! 1263: } ! 1264: ! 1265: /* ! 1266: * We may have to quit ! 1267: */ ! 1268: if (thread_should_halt(current_thread())) { ! 1269: simple_unlock(&p->siglock); ! 1270: return(0); ! 1271: } ! 1272: ! 1273: p->p_siglist &= ~mask; /* clear the old signal */ ! 1274: ! 1275: /* ! 1276: * If the traced bit got turned off, go back up ! 1277: * to the top to rescan signals. This ensures ! 1278: * that p_sig* and ps_sigact are consistent. ! 1279: */ ! 1280: if ((p->p_flag & P_TRACED) == 0) { ! 1281: if (mask & threadmask) ! 1282: cur_thread->_uthread->uu_sig |= mask; ! 1283: else ! 1284: p->p_siglist |= mask; ! 1285: continue; ! 1286: } ! 1287: ! 1288: /* ! 1289: * If parent wants us to take the signal, ! 1290: * then it will leave it in p->p_xstat; ! 1291: * otherwise we just look for signals again. ! 1292: */ ! 1293: signum = p->p_xstat; ! 1294: if (signum == 0) ! 1295: continue; ! 1296: /* ! 1297: * Put the new signal into p_siglist. If the ! 1298: * signal is being masked, look for other signals. ! 1299: */ ! 1300: mask = sigmask(signum); ! 1301: if (mask & threadmask) ! 1302: cur_thread->_uthread->uu_sig |= mask; ! 1303: else ! 1304: p->p_siglist |= mask; ! 1305: if (p->p_sigmask & mask) ! 1306: continue; ! 1307: } ! 1308: } ! 1309: ! 1310: /* ! 1311: * Decide whether the signal should be returned. ! 1312: * Return the signal's number, or fall through ! 1313: * to clear it from the pending mask. ! 1314: */ ! 1315: ! 1316: switch ((long)p->p_sigacts->ps_sigact[signum]) { ! 1317: ! 1318: case (long)SIG_DFL: ! 1319: /* ! 1320: * Don't take default actions on system processes. ! 1321: */ ! 1322: if (p->p_pptr->p_pid == 0) { ! 1323: #if DIAGNOSTIC ! 1324: /* ! 1325: * Are you sure you want to ignore SIGSEGV ! 1326: * in init? XXX ! 1327: */ ! 1328: printf("Process (pid %d) got signal %d\n", ! 1329: p->p_pid, signum); ! 1330: #endif ! 1331: break; /* == ignore */ ! 1332: } ! 1333: ! 1334: /* ! 1335: * If there is a pending stop signal to process ! 1336: * with default action, stop here, ! 1337: * then clear the signal. However, ! 1338: * if process is member of an orphaned ! 1339: * process group, ignore tty stop signals. ! 1340: */ ! 1341: if (prop & SA_STOP) { ! 1342: if (p->p_flag & P_TRACED || ! 1343: (p->p_pgrp->pg_jobc == 0 && ! 1344: prop & SA_TTYSTOP)) ! 1345: break; /* == ignore */ ! 1346: p->p_xstat = signum; ! 1347: stop(p); ! 1348: if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0) ! 1349: psignal(p->p_pptr, SIGCHLD); ! 1350: thread_reference(cur_thread); ! 1351: p->sigwait = TRUE; ! 1352: p->sigwait_thread = cur_thread; ! 1353: simple_unlock(&p->siglock); ! 1354: thread_block(); ! 1355: simple_lock(&p->siglock); ! 1356: p->sigwait = FALSE; ! 1357: p->sigwait_thread = NULL; ! 1358: thread_deallocate(cur_thread); ! 1359: /* ! 1360: * We may have to quit ! 1361: */ ! 1362: if (thread_should_halt(current_thread())) { ! 1363: simple_unlock(&p->siglock); ! 1364: return(0); ! 1365: } ! 1366: break; ! 1367: } else if (prop & SA_IGNORE) { ! 1368: /* ! 1369: * Except for SIGCONT, shouldn't get here. ! 1370: * Default action is to ignore; drop it. ! 1371: */ ! 1372: break; /* == ignore */ ! 1373: } else { ! 1374: simple_unlock(&p->siglock); ! 1375: return (signum); ! 1376: } ! 1377: /*NOTREACHED*/ ! 1378: ! 1379: case (long)SIG_IGN: ! 1380: /* ! 1381: * Masking above should prevent us ever trying ! 1382: * to take action on an ignored signal other ! 1383: * than SIGCONT, unless process is traced. ! 1384: */ ! 1385: if ((prop & SA_CONT) == 0 && ! 1386: (p->p_flag & P_TRACED) == 0) ! 1387: printf("issignal\n"); ! 1388: break; /* == ignore */ ! 1389: ! 1390: default: ! 1391: /* ! 1392: * This signal has an action, let ! 1393: * postsig() process it. ! 1394: */ ! 1395: simple_unlock(&p->siglock); ! 1396: return (signum); ! 1397: } ! 1398: p->p_siglist &= ~mask; /* take the signal! */ ! 1399: } ! 1400: /* NOTREACHED */ ! 1401: } ! 1402: ! 1403: /* ! 1404: * Put the argument process into the stopped state and notify the parent ! 1405: * via wakeup. Signals are handled elsewhere. The process must not be ! 1406: * on the run queue. ! 1407: */ ! 1408: void ! 1409: stop(p) ! 1410: register struct proc *p; ! 1411: { ! 1412: ! 1413: /* ! 1414: * Call special task_suspend routine, ! 1415: * because this routine is called from interrupts ! 1416: * (psignal) and cannot sleep. ! 1417: */ ! 1418: (void) task_suspend_nowait(p->task); /*XXX*/ ! 1419: ! 1420: p->p_stat = SSTOP; ! 1421: p->p_flag &= ~P_WAITED; ! 1422: wakeup((caddr_t)p->p_pptr); ! 1423: } ! 1424: ! 1425: /* ! 1426: * Take the action for the specified signal ! 1427: * from the current set of pending signals. ! 1428: */ ! 1429: void ! 1430: postsig(signum) ! 1431: register int signum; ! 1432: { ! 1433: register struct proc *p = current_proc(); ! 1434: register struct sigacts *ps = p->p_sigacts; ! 1435: register sig_t action; ! 1436: u_long code; ! 1437: int mask, returnmask; ! 1438: ! 1439: #if DIAGNOSTIC ! 1440: if (signum == 0) ! 1441: panic("postsig"); ! 1442: /* ! 1443: * This must be called on master cpu ! 1444: */ ! 1445: if (cpu_number() != master_cpu) ! 1446: panic("psig not on master"); ! 1447: #endif ! 1448: ! 1449: /* ! 1450: * Try to grab the signal lock. ! 1451: */ ! 1452: if (sig_try_lock(p) <= 0) ! 1453: return; ! 1454: ! 1455: mask = sigmask(signum); ! 1456: p->p_siglist &= ~mask; ! 1457: action = ps->ps_sigact[signum]; ! 1458: #if KTRACE ! 1459: if (KTRPOINT(p, KTR_PSIG)) ! 1460: ktrpsig(p->p_tracep, ! 1461: signum, action, ps->ps_flags & SAS_OLDMASK ? ! 1462: ps->ps_oldmask : p->p_sigmask, 0); ! 1463: #endif ! 1464: if (action == SIG_DFL) { ! 1465: /* ! 1466: * Default action, where the default is to kill ! 1467: * the process. (Other cases were ignored above.) ! 1468: */ ! 1469: /* called with sig_lock() held */ ! 1470: sigexit(p, signum); ! 1471: /* NOTREACHED */ ! 1472: } else { ! 1473: /* ! 1474: * If we get here, the signal must be caught. ! 1475: */ ! 1476: #if DIAGNOSTIC ! 1477: if (action == SIG_IGN || (p->p_sigmask & mask)) ! 1478: log(LOG_WARNING, ! 1479: "postsig: processing masked or ignored signal\n"); ! 1480: #endif ! 1481: /* ! 1482: * Set the new mask value and also defer further ! 1483: * occurences of this signal. ! 1484: * ! 1485: * Special case: user has done a sigpause. Here the ! 1486: * current mask is not of interest, but rather the ! 1487: * mask from before the sigpause is what we want ! 1488: * restored after the signal processing is completed. ! 1489: */ ! 1490: (void) splhigh(); ! 1491: if (ps->ps_flags & SAS_OLDMASK) { ! 1492: returnmask = ps->ps_oldmask; ! 1493: ps->ps_flags &= ~SAS_OLDMASK; ! 1494: } else ! 1495: returnmask = p->p_sigmask; ! 1496: p->p_sigmask |= ps->ps_catchmask[signum] | mask; ! 1497: if (ps->ps_sig != signum) { ! 1498: code = 0; ! 1499: } else { ! 1500: code = ps->ps_code; ! 1501: ps->ps_code = 0; ! 1502: } ! 1503: simple_unlock(&p->siglock); ! 1504: (void) spl0(); ! 1505: p->p_stats->p_ru.ru_nsignals++; ! 1506: sendsig(p, action, signum, returnmask, code); ! 1507: } ! 1508: } ! 1509: ! 1510: /* ! 1511: * Force the current process to exit with the specified signal, dumping core ! 1512: * if appropriate. We bypass the normal tests for masked and caught signals, ! 1513: * allowing unrecoverable failures to terminate the process without changing ! 1514: * signal state. Mark the accounting record with the signal termination. ! 1515: * If dumping core, save the signal number for the debugger. Calls exit and ! 1516: * does not return. ! 1517: */ ! 1518: void ! 1519: sigexit(p, signum) ! 1520: register struct proc *p; ! 1521: int signum; ! 1522: { ! 1523: ! 1524: sig_lock_to_exit(p); ! 1525: p->p_acflag |= AXSIG; ! 1526: if (sigprop[signum] & SA_CORE) { ! 1527: p->p_sigacts->ps_sig = signum; ! 1528: if (coredump(p) == 0) ! 1529: signum |= WCOREFLAG; ! 1530: } ! 1531: exit1(p, W_EXITCODE(0, signum)); ! 1532: /* NOTREACHED */ ! 1533: } ! 1534:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.