|
|
1.1 ! root 1: /* $Header: /kernel/kersrc/coh.386/RCS/sig.c,v 1.2 92/08/04 12:34:36 bin Exp Locker: bin $ */ ! 2: /* (lgl- ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * COHERENT Version 2.3.37 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: -lgl) */ ! 15: /* ! 16: * Coherent. ! 17: * Signal handling. ! 18: * ! 19: * $Log: sig.c,v $ ! 20: * Revision 1.2 92/08/04 12:34:36 bin ! 21: * changed for ker 59 ! 22: * ! 23: * Revision 1.2 92/01/06 12:00:24 hal ! 24: * Compile with cc.mwc. ! 25: * ! 26: * Revision 1.1 88/03/24 16:14:24 src ! 27: * Initial revision ! 28: * ! 29: * 87/11/05 Allan Cornish /usr/src/sys/coh/sig.c ! 30: * New seg struct now used to allow extended addressing. ! 31: * ! 32: * 86/11/19 Allan Cornish /usr/src/sys/coh/sig.c ! 33: * sigdump() initializes the (new) (IO).io_flag field to 0. ! 34: */ ! 35: #include <sys/coherent.h> ! 36: #include <errno.h> ! 37: #include <sys/ino.h> ! 38: #include <sys/inode.h> ! 39: #include <sys/io.h> ! 40: #include <sys/proc.h> ! 41: #include <sys/ptrace.h> ! 42: #include <sys/sched.h> ! 43: #include <sys/seg.h> ! 44: #include <signal.h> ! 45: ! 46: /* ! 47: * Set up the action to be taken on a signal. ! 48: */ ! 49: usigsys(signal, func) ! 50: int signal; ! 51: register void (*func)(); ! 52: { ! 53: register PROC *pp; ! 54: register sig_t s; ! 55: register int (*old_sig)(); ! 56: int sigtype; ! 57: ! 58: sigtype = signal & ~0xFF; ! 59: signal ^= sigtype; ! 60: ! 61: pp = SELF; ! 62: if (signal<=0 || signal>NSIG || signal==SIGKILL) { ! 63: u.u_error = EINVAL; ! 64: return; ! 65: } ! 66: ! 67: /* ! 68: * In order to avoid runaway, don't allow user to set ! 69: * handler for SIGSEGV to anything but SIG_DFL. ! 70: * ! 71: * We should do something more sophisticated, like detecting ! 72: * two SEGV's in a row and then killing the process. ! 73: */ ! 74: if (signal == SIGSEGV && func != SIG_DFL) { ! 75: u.u_error = EINVAL; ! 76: return; ! 77: } ! 78: ! 79: if (sigtype==SIGDEFER || sigtype==0) { ! 80: if (func==SIG_IGN) ! 81: sigtype = SIGIGNORE; ! 82: if (func==SIG_HOLD) ! 83: sigtype = SIGHOLD; ! 84: } ! 85: ! 86: s = (sig_t)1 << --signal; ! 87: if (pp->p_isig&s) ! 88: old_sig = SIG_IGN; ! 89: else if (pp->p_hsig&s) ! 90: old_sig = SIG_HOLD; ! 91: else ! 92: old_sig = u.u_sfunc[signal]; ! 93: ! 94: switch (sigtype) { ! 95: case SIGHOLD: ! 96: pp->p_hsig |= s; ! 97: break; ! 98: case SIGRELSE: ! 99: pp->p_hsig &= ~s; ! 100: if (nondsig()) { ! 101: T_PIGGY( 0x100, printf("a(s)"); ); ! 102: actvsig(); ! 103: } ! 104: case SIGIGNORE: ! 105: pp->p_dfsig &= ~s; /* No longer defaulted. */ ! 106: pp->p_isig |= s; /* Mark signal as ignored. */ ! 107: pp->p_ssig &= ~s; /* Turn off any pending signal. */ ! 108: break; ! 109: case 0: /* old system entry */ ! 110: case SIGDEFER: /* new system entry */ ! 111: u.u_sigreturn = (void (*)())u.u_regl[EDX]; ! 112: u.u_sfunc[signal] = func; ! 113: /* ! 114: * Be sure to mark the signal as defaulted or not. ! 115: */ ! 116: if (SIG_DFL == func) { ! 117: pp->p_dfsig |= s; ! 118: } else { ! 119: pp->p_dfsig &= ~s; ! 120: } ! 121: /* ! 122: * The signal is no longer ignored or held, and ! 123: * any pending signal is lost. ! 124: */ ! 125: pp->p_isig &= ~s; ! 126: pp->p_hsig &= ~s; ! 127: pp->p_ssig &= ~s; ! 128: if (sigtype==SIGDEFER) ! 129: pp->p_dsig |= s; ! 130: else ! 131: pp->p_dsig &= ~s; ! 132: break; ! 133: /* SIGPAUSE not done yet */ ! 134: default: ! 135: u.u_error = SIGSYS; ! 136: break; ! 137: } ! 138: return old_sig; ! 139: } ! 140: ! 141: ! 142: /* ! 143: * Send a signal to the process `pp'. ! 144: */ ! 145: sendsig(sig, pp) ! 146: register unsigned sig; ! 147: register PROC *pp; ! 148: { ! 149: register sig_t f; ! 150: register int s; ! 151: ! 152: ! 153: T_PIGGY( 0x40000000, ! 154: printf("<send sig: %d, id: %d, state: %x, flags: %x, event: %x>", ! 155: sig, pp->p_pid, pp->p_state, pp->p_flags, pp->p_event); ! 156: ); /* T_PIGGY() */ ! 157: ! 158: /* ! 159: * Convert the signal to a bit position. ! 160: */ ! 161: f = ((sig_t)1) << (sig-1); ! 162: ! 163: /* ! 164: * If the signal is ignored, do nothing. ! 165: */ ! 166: if (pp->p_isig&f) { ! 167: return; ! 168: } ! 169: ! 170: /* ! 171: * This bit causes SIGCHLD to be ignored here in sendsig(). ! 172: */ ! 173: T_PIGGY( 0x10000000, { ! 174: if (SIGCHLD == sig) { ! 175: printf("SIGCHLD ignored, "); ! 176: return; ! 177: } ! 178: } ! 179: ); ! 180: ! 181: /* ! 182: * I do not understand delayed or held signals. ! 183: */ ! 184: if ((pp->p_ssig & f) && (pp->p_hsig|pp->p_dsig) & f) ! 185: return; ! 186: ! 187: /* ! 188: * Acutally send the signal by flagging the needed bit. ! 189: */ ! 190: pp->p_ssig |= f; ! 191: ! 192: /* ! 193: * If the process is sleeping, wake it up so that ! 194: * it can process this signal. ! 195: */ ! 196: if (pp->p_state == PSSLEEP) { ! 197: s = sphi(); ! 198: pp->p_lback->p_lforw = pp->p_lforw; ! 199: pp->p_lforw->p_lback = pp->p_lback; ! 200: addu(pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK); ! 201: setrun(pp); ! 202: spl(s); ! 203: } ! 204: } ! 205: ! 206: /* ! 207: * Return signal number if we have a non ignored or delayed signal, else zero. ! 208: */ ! 209: nondsig() ! 210: { ! 211: register PROC *pp; ! 212: register sig_t mask; ! 213: register int signo; ! 214: ! 215: pp = SELF; ! 216: signo = 0; ! 217: /* ! 218: * Turn off all ignored signals. ! 219: */ ! 220: pp->p_ssig &= ~pp->p_isig; ! 221: /* ! 222: * If any signals have arrived, but which are not held, ! 223: * figure out what they are. ! 224: */ ! 225: if (pp->p_ssig&~pp->p_hsig) { ! 226: /* ! 227: * There is at least one signal. Extract its number ! 228: * from the signal bits. ! 229: */ ! 230: mask = (sig_t) 1; ! 231: signo += 1; ! 232: while (((pp->p_ssig&~pp->p_hsig) & mask) == 0) { ! 233: mask <<= 1; ! 234: signo += 1; ! 235: } ! 236: } ! 237: return (signo); ! 238: } ! 239: ! 240: /* ! 241: * If we have a signal that isn't ignored, activate it. ! 242: */ ! 243: actvsig() ! 244: { ! 245: register int n; ! 246: register PROC *pp; ! 247: register int (*func)(); ! 248: sig_t s; ! 249: ! 250: ! 251: /* ! 252: * Fetch an unprocessed signal. ! 253: * Return if there are none. ! 254: */ ! 255: if ((n = nondsig()) == 0) ! 256: return; ! 257: ! 258: T_PIGGY( 0x40000, { ! 259: if (SIGCHLD == n) { ! 260: printf("-"); ! 261: return; ! 262: } ! 263: } ); ! 264: ! 265: pp = SELF; ! 266: ! 267: /* ! 268: * Reset the signal to indicate that it has been processed. ! 269: */ ! 270: --n; ! 271: pp->p_ssig &= ~((sig_t)1<<n); ! 272: ! 273: /* ! 274: * Fetch the user function that goes with this signal. ! 275: */ ! 276: func = u.u_sfunc[n]; ! 277: ! 278: /* ! 279: * Store the signal number in the u area. This is how ! 280: * a core dump records the death signal. ! 281: */ ! 282: u.u_signo = ++n; ! 283: ! 284: /* ! 285: * If the signal is not defaulted, go run the requested ! 286: * function. ! 287: */ ! 288: if (func != SIG_DFL) { ! 289: if (XMODE_286) ! 290: oldsigstart(n, func); ! 291: else ! 292: msigstart(n, func); ! 293: return; ! 294: } ! 295: ! 296: /* ! 297: * ASSERTION: the signal being processed is SIG_DFL'd. ! 298: */ ! 299: ! 300: /* ! 301: * msysgen() is a nop for COHERENT 4.0. The comment in the ! 302: * assembly code is "Nothing useful to save". ! 303: */ ! 304: msysgen(u.u_sysgen); ! 305: ! 306: /* ! 307: * Do something special for traced processes. (?) ! 308: */ ! 309: if (pp->p_flags&PFTRAC) { ! 310: pp->p_flags |= PFWAIT; ! 311: n = ptret(); ! 312: pp->p_flags &= ~(PFWAIT|PFSTOP); ! 313: if (n == 0) ! 314: return; ! 315: } ! 316: ! 317: /* ! 318: * Some signals cause a core file to be written. ! 319: */ ! 320: switch(n) { ! 321: case SIGQUIT: ! 322: case SIGILL: ! 323: case SIGTRAP: ! 324: case SIGABRT: ! 325: case SIGFPE: ! 326: case SIGSEGV: ! 327: case SIGSYS: ! 328: if (sigdump()) ! 329: n |= 0200; ! 330: break; ! 331: } ! 332: pexit(n); ! 333: } ! 334: ! 335: /* ! 336: * Create a dump of ourselves onto the file `core'. ! 337: */ ! 338: sigdump() ! 339: { ! 340: register INODE *ip; ! 341: register SR *srp; ! 342: register SEG * sp; ! 343: register int n; ! 344: register paddr_t ssize; ! 345: extern int DUMP_LIM; ! 346: ! 347: if (SELF->p_flags&PFNDMP) ! 348: return (0); ! 349: u.u_io.io_seg = IOSYS; ! 350: u.u_io.io_flag = 0; ! 351: /* Make the core with the real owners */ ! 352: schizo(); ! 353: if (ftoi("core", 'c')) { ! 354: schizo(); ! 355: return (0); ! 356: } ! 357: if ((ip=u.u_cdiri) == NULL) { ! 358: if ((ip=imake(IFREG|0644, 0)) == NULL) { ! 359: schizo(); ! 360: return (0); ! 361: } ! 362: } else { ! 363: if ((ip->i_mode&IFMT)!=IFREG ! 364: || iaccess(ip, IPW)==0 ! 365: || getment(ip->i_dev, 1)==NULL) { ! 366: idetach(ip); ! 367: schizo(); ! 368: return (0); ! 369: } ! 370: iclear(ip); ! 371: } ! 372: schizo(); ! 373: u.u_error = 0; ! 374: u.u_io.io_seek = 0; ! 375: for (srp=u.u_segl; u.u_error==0 && srp<&u.u_segl[NUSEG]; srp++) { ! 376: if ((sp = srp->sr_segp)==NULL || (srp->sr_flag&SRFDUMP)==0) ! 377: continue; ! 378: u.u_io.io_seg = IOPHY; ! 379: u.u_io.io.pbase = MAPIO(sp->s_vmem, 0); ! 380: u.u_io.io_flag = 0; ! 381: ssize = sp->s_size; ! 382: if (ssize > DUMP_LIM) { ! 383: printf("seg %d truncated from %d to %d bytes\n", ! 384: srp-u.u_segl, ssize, DUMP_LIM); ! 385: ssize = DUMP_LIM; ! 386: } ! 387: sp->s_lrefc++; ! 388: while (u.u_error == 0 && ssize != 0) { ! 389: n = ssize > SCHUNK ? SCHUNK : ssize; ! 390: u.u_io.io_ioc = n; ! 391: iwrite(ip, &u.u_io); ! 392: u.u_io.io.pbase += n; ! 393: ssize -= (paddr_t)n; ! 394: } ! 395: sp->s_lrefc--; ! 396: } ! 397: idetach(ip); ! 398: return (u.u_error==0); ! 399: } ! 400: ! 401: /* ! 402: * Send a ptrace command to the child. ! 403: */ ! 404: ptset(req, pid, addr, data) ! 405: unsigned req; ! 406: int *addr; ! 407: { ! 408: ! 409: register PROC *pp; ! 410: ! 411: lock(pnxgate); ! 412: for (pp=procq.p_nforw; pp!=&procq; pp=pp->p_nforw) ! 413: if (pp->p_pid == pid) ! 414: break; ! 415: unlock(pnxgate); ! 416: if (pp==&procq || (pp->p_flags&PFSTOP)==0 || pp->p_ppid!=SELF->p_pid){ ! 417: u.u_error = ESRCH; ! 418: return; ! 419: } ! 420: lock(pts.pt_gate); ! 421: pts.pt_req = req; ! 422: pts.pt_pid = pid; ! 423: pts.pt_addr = addr; ! 424: pts.pt_data = data; ! 425: pts.pt_errs = 0; ! 426: pts.pt_rval = 0; ! 427: pts.pt_busy = 1; ! 428: wakeup((char *)&pts.pt_req); ! 429: while (pts.pt_busy) { ! 430: v_sleep((char *)&pts.pt_busy, CVPTSET, IVPTSET, SVPTSET, "ptrace"); ! 431: /* Send a ptrace command to the child. */ ! 432: } ! 433: u.u_error = pts.pt_errs; ! 434: unlock(pts.pt_gate); ! 435: return (pts.pt_rval); ! 436: } ! 437: ! 438: /* ! 439: * This routine is called when a child that is being traced receives a signal ! 440: * that is not caught or ignored. It follows up on any requests by the parent ! 441: * and returns when done. ! 442: */ ! 443: ptret() ! 444: { ! 445: register PROC *pp; ! 446: register PROC *pp1; ! 447: register int sign; ! 448: unsigned off; ! 449: ! 450: pp = SELF; ! 451: next: ! 452: u.u_error = 0; ! 453: if (pp->p_ppid == 1) ! 454: return (SIGKILL); ! 455: sign = -1; ! 456: lock(pnxgate); ! 457: pp1 = &procq; ! 458: for (;;) { ! 459: if ((pp1=pp1->p_nforw) == &procq) { ! 460: sign = SIGKILL; ! 461: break; ! 462: } ! 463: if (pp1->p_pid != pp->p_ppid) ! 464: continue; ! 465: if (pp1->p_state == PSSLEEP) ! 466: wakeup((char *)pp1); ! 467: break; ! 468: } ! 469: unlock(pnxgate); ! 470: while (sign < 0) { ! 471: if (pts.pt_busy==0 || pp->p_pid!=pts.pt_pid) { ! 472: v_sleep((char *)&pts.pt_req, CVPTRET, IVPTRET, SVPTRET, "ptret"); ! 473: /* Something about signals to a traced child. */ ! 474: goto next; ! 475: } ! 476: switch (pts.pt_req) { ! 477: case 1: ! 478: if (XMODE_286) { ! 479: pts.pt_rval = getuwd(NBPS+pts.pt_addr); ! 480: break; ! 481: } ! 482: case 2: ! 483: pts.pt_rval = getuwd(pts.pt_addr); ! 484: break; ! 485: case 3: ! 486: off = (unsigned)pts.pt_addr; ! 487: if (off < UPASIZE) ! 488: pts.pt_rval = *(int *)((char *)&u+off); ! 489: else ! 490: u.u_error = EINVAL; ! 491: break; ! 492: case 4: ! 493: if (XMODE_286) { ! 494: putuwd(NBPS+pts.pt_addr, pts.pt_data); ! 495: break; ! 496: } ! 497: case 5: ! 498: putuwd(pts.pt_addr, pts.pt_data); ! 499: break; ! 500: case 6: ! 501: if (msetuof(pts.pt_addr, pts.pt_data) == 0) ! 502: u.u_error = EINVAL; ! 503: break; ! 504: case 7: ! 505: goto sig; ! 506: case 8: ! 507: sign = SIGKILL; ! 508: break; ! 509: case 9: ! 510: msigsin(); ! 511: sig: ! 512: if (pts.pt_data<0 || pts.pt_data>NSIG) { ! 513: u.u_error = EINVAL; ! 514: break; ! 515: } ! 516: sign = pts.pt_data; ! 517: if (pts.pt_addr != SIG_IGN) ! 518: msetppc((vaddr_t)pts.pt_addr); ! 519: break; ! 520: default: ! 521: u.u_error = EINVAL; ! 522: } ! 523: if ((pts.pt_errs=u.u_error) == EFAULT) ! 524: pts.pt_errs = EINVAL; ! 525: pts.pt_busy = 0; ! 526: wakeup((char *)&pts.pt_busy); ! 527: } ! 528: return (sign); ! 529: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.