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