1: /*
   2:  *	SCCS id	@(#)sigjcl.c	2.1 (Berkeley)	9/4/83
   3:  */
   4: 
   5: #include "param.h"
   6: #include <sys/systm.h>
   7: #include <sys/dir.h>
   8: #include <sys/user.h>
   9: #include <sys/proc.h>
  10: #include <sys/inode.h>
  11: #include <sys/reg.h>
  12: #include <sys/text.h>
  13: #include <sys/seg.h>
  14: #ifdef UCB_METER
  15: #include <sys/vm.h>
  16: #endif
  17: 
  18: /*
  19:  * Priority for tracing
  20:  */
  21: #define IPCPRI  PZERO
  22: 
  23: /*
  24:  * Tracing variables.
  25:  * Used to pass trace command from
  26:  * parent to child being traced.
  27:  * This data base cannot be
  28:  * shared and is locked
  29:  * per user.
  30:  */
  31: struct
  32: {
  33:     int ip_lock;
  34:     int ip_req;
  35:     int *ip_addr;
  36:     int ip_data;
  37: } ipc;
  38: 
  39: /*
  40:  * Send the specified signal to
  41:  * all processes with 'pgrp' as
  42:  * process group.
  43:  * Called by tty*.c for quits and interrupts.
  44:  * Save and restore mapping if needed to access proc at interrupt time
  45:  * (see seg.h).
  46:  */
  47: gsignal(pgrp, sig)
  48: register pgrp;
  49: {
  50:     register struct proc *p;
  51: #ifndef NOKA5
  52:     mapinfo map;
  53: #endif
  54: 
  55:     if(pgrp == 0)
  56:         return;
  57: #ifndef NOKA5
  58:     savemap(map);
  59: #endif
  60:     for(p = &proc[0]; p <= maxproc; p++)
  61:         if(p->p_pgrp == pgrp)
  62:             psignal(p, sig);
  63: #ifndef NOKA5
  64:     restormap(map);
  65: #endif
  66: }
  67: 
  68: /*
  69:  * Send the specified signal to
  70:  * the specified process.
  71:  */
  72: psignal(p, sig)
  73: register struct proc *p;
  74: register int sig;
  75: {
  76:     int s;
  77:     register int (*action)();
  78:     long sigmask;
  79: 
  80:     if((unsigned)sig >= NSIG)
  81:         return;
  82:     sigmask = (1L << (sig-1));
  83: 
  84:     /*
  85: 	 * If proc is traced, always give parent a chance.
  86: 	 * Otherwise get the signal action from the bits in the proc table.
  87: 	 */
  88: #ifndef NONFP
  89:     if (p->p_flag & STRC)
  90: #else
  91:     /*
  92: 	 * Allow normal action on SIGILL for interpreted floating point.
  93: 	 */
  94:     if ((p->p_flag & STRC) && (sig != SIGILL))
  95: #endif
  96:         action = SIG_DFL;
  97:     else {
  98:         s = ((p->p_siga1&sigmask) != 0);
  99:         s <<= 1;
 100:         s |= ((p->p_siga0&sigmask) != 0);
 101:         action = (int(*)())s;
 102:         /*
 103: 		 * If the signal is ignored, we forget about it immediately.
 104: 		 */
 105:         if (action == SIG_IGN)
 106:             return;
 107:     }
 108: #define mask(sig) (1L<<(sig-1))
 109: #define stops   (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU))
 110:     if (sig) {
 111:         p->p_sig |= sigmask;
 112:         switch (sig) {
 113: 
 114:         case SIGCONT:
 115:             p->p_sig &= ~stops;
 116:             break;
 117: 
 118:         case SIGSTOP:
 119:         case SIGTSTP:
 120:         case SIGTTIN:
 121:         case SIGTTOU:
 122:             p->p_sig &= ~mask(SIGCONT);
 123:             break;
 124:         }
 125:     }
 126: #undef  mask
 127: #undef  stops
 128:     /*
 129: 	 * Defer further processing for signals which are held.
 130: 	 */
 131:     if (action == SIG_HOLD)
 132:         return;
 133:     s = spl6();
 134:     switch (p->p_stat) {
 135: 
 136:     case SSLEEP:
 137:         /*
 138: 		 * If process is sleeping at negative priority
 139: 		 * we can't interrupt the sleep... the signal will
 140: 		 * be noticed when the process returns through
 141: 		 * trap() or syscall().
 142: 		 */
 143:         if (p->p_pri <= PZERO)
 144:             goto out;
 145:         /*
 146: 		 * Process is sleeping and traced... make it runnable
 147: 		 * so it can discover the signal in issig() and stop
 148: 		 * for the parent.
 149: 		 */
 150:         if (p->p_flag&STRC)
 151:             goto run;
 152:         switch (sig) {
 153: 
 154:         case SIGSTOP:
 155:         case SIGTSTP:
 156:         case SIGTTIN:
 157:         case SIGTTOU:
 158:             /*
 159: 			 * These are the signals which by default
 160: 			 * stop a process.
 161: 			 */
 162:             if (action != SIG_DFL)
 163:                 goto run;
 164:             /*
 165: 			 * Don't clog system with children of init
 166: 			 * stopped from the keyboard.
 167: 			 */
 168:             if (sig != SIGSTOP && p->p_pptr == &proc[1]) {
 169:                 psignal(p, SIGKILL);
 170:                 p->p_sig &= ~sigmask;
 171:                 return;
 172:             }
 173: #ifdef  VIRUS_VFORK
 174:             /*
 175: 			 * If a child in vfork(), stopping could
 176: 			 * cause deadlock.
 177: 			 */
 178:             if (p->p_flag&SVFORK)
 179:                 goto out;
 180: #endif
 181:             p->p_sig &= ~sigmask;
 182:             p->p_cursig = sig;
 183:             stop(p);
 184:             goto out;
 185: 
 186:         case SIGTINT:
 187:         case SIGCHLD:
 188:             /*
 189: 			 * These signals are special in that they
 190: 			 * don't get propogated... if the process
 191: 			 * isn't interested, forget it.
 192: 			 */
 193:             if (action != SIG_DFL)
 194:                 goto run;
 195:             p->p_sig &= ~sigmask;       /* take it away */
 196:             goto out;
 197: 
 198:         default:
 199:             /*
 200: 			 * All other signals cause the process to run
 201: 			 */
 202:             goto run;
 203:         }
 204:         /*NOTREACHED*/
 205: 
 206:     case SSTOP:
 207:         /*
 208: 		 * If traced process is already stopped,
 209: 		 * then no further action is necessary.
 210: 		 */
 211:         if (p->p_flag&STRC)
 212:             goto out;
 213:         switch (sig) {
 214: 
 215:         case SIGKILL:
 216:             /*
 217: 			 * Kill signal always sets processes running.
 218: 			 */
 219:             goto run;
 220: 
 221:         case SIGCONT:
 222:             /*
 223: 			 * If the process catches SIGCONT, let it handle
 224: 			 * the signal itself.  If it isn't waiting on
 225: 			 * an event, then it goes back to run state.
 226: 			 * Otherwise, process goes back to sleep state.
 227: 			 */
 228:             if (action != SIG_DFL || p->p_wchan == 0)
 229:                 goto run;
 230:             p->p_stat = SSLEEP;
 231:             goto out;
 232: 
 233:         case SIGSTOP:
 234:         case SIGTSTP:
 235:         case SIGTTIN:
 236:         case SIGTTOU:
 237:             /*
 238: 			 * Already stopped, don't need to stop again.
 239: 			 * (If we did the shell could get confused.)
 240: 			 */
 241:             p->p_sig &= ~sigmask;       /* take it away */
 242:             goto out;
 243: 
 244:         default:
 245:             /*
 246: 			 * If process is sleeping interruptibly, then
 247: 			 * unstick it so that when it is continued
 248: 			 * it can look at the signal.
 249: 			 * But don't setrun the process as its not to
 250: 			 * be unstopped by the signal alone.
 251: 			 */
 252:             if (p->p_wchan && p->p_pri > PZERO)
 253:                 unsleep(p);
 254:             goto out;
 255:         }
 256:         /*NOTREACHED*/
 257: 
 258:     default:
 259:         /*
 260: 		 * SRUN, SIDL, SZOMB do nothing with the signal.
 261: 		 * It will either never be noticed, or noticed very soon.
 262: 		 */
 263:         goto out;
 264:     }
 265:     /*NOTREACHED*/
 266: run:
 267:     /*
 268: 	 * Raise priority to at least PUSER.
 269: 	 */
 270:     if (p->p_pri > PUSER)
 271:         p->p_pri = PUSER;
 272:     setrun(p);
 273: out:
 274:     splx(s);
 275: }
 276: 
 277: /*
 278:  * Returns true if the current
 279:  * process has a signal to process.
 280:  * The signal to process is put in p_cursig.
 281:  * This is asked at least once each time a process enters the
 282:  * system (though this can usually be done without actually
 283:  * calling issig by checking the pending signal masks.)
 284:  * A signal does not do anything
 285:  * directly to a process; it sets
 286:  * a flag that asks the process to
 287:  * do something to itself.
 288:  */
 289: issig()
 290: {
 291:     register struct proc *p;
 292:     register int sig;
 293:     long sigbits;
 294: 
 295:     p = u.u_procp;
 296:     for (;;) {
 297:         sigbits = p->p_sig;
 298:         if ((p->p_flag&STRC) == 0)
 299:             sigbits &= ~p->p_ignsig;
 300: #ifdef  VIRUS_VFORK
 301:         if (p->p_flag&SVFORK)
 302: #define bit(a) (1L<<(a-1))
 303:             sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU));
 304: #endif
 305:         if (sigbits == 0)
 306:             break;
 307:         for (sig=1; sig<NSIG; sig++) {
 308:             if (sigbits & 1L)
 309:                 break;
 310:             sigbits >>= 1;
 311:         }
 312:         p->p_sig &= ~(1L << (sig-1));   /* take the signal! */
 313:         p->p_cursig = sig;
 314:         if (p->p_flag&STRC
 315: #ifdef  VIRUS_VFORK
 316:                 && (p->p_flag&SVFORK)==0
 317: #endif
 318: #ifdef  NONFP
 319:                 && sig != SIGILL
 320: #endif
 321:                 ) {
 322:             /*
 323: 			 * If traced, always stop, and stay
 324: 			 * stopped until released by the parent.
 325: 			 */
 326:             do {
 327:                 stop(p);
 328:                 swtch();
 329:             } while (!procxmt() && p->p_flag&STRC);
 330:             /*
 331: 			 * If parent wants us to take the signal,
 332: 			 * then it will leave it in p->p_cursig;
 333: 			 * otherwise we just look for signals again.
 334: 			 */
 335:             sig = p->p_cursig;
 336:             if (sig == 0)
 337:                 continue;
 338:         }
 339:         switch (u.u_signal[sig]) {
 340: 
 341:         case SIG_DFL:
 342:             /*
 343: 			 * Don't take default actions on system processes.
 344: 			 */
 345:             if (p <= &proc[1])
 346:                 break;
 347:             switch (sig) {
 348: 
 349:             case SIGTSTP:
 350:             case SIGTTIN:
 351:             case SIGTTOU:
 352:                 /*
 353: 				 * Children of init aren't allowed to stop
 354: 				 * on signals from the keyboard.
 355: 				 */
 356:                 if (p->p_pptr == &proc[1]) {
 357:                     psignal(p, SIGKILL);
 358:                     continue;
 359:                 }
 360:                 /* fall into ... */
 361: 
 362:             case SIGSTOP:
 363:                 if (p->p_flag&STRC)
 364:                     continue;
 365:                 stop(p);
 366:                 swtch();
 367:                 continue;
 368: 
 369:             case SIGTINT:
 370:             case SIGCONT:
 371:             case SIGCHLD:
 372:                 /*
 373: 				 * These signals are normally not
 374: 				 * sent if the action is the default.
 375: 				 * This can happen only if you reset the
 376: 				 * signal action from an action which was
 377: 				 * not deferred to SIG_DFL before the
 378: 				 * system gets a chance to post the signal.
 379: 				 */
 380:                 continue;       /* == ignore */
 381: 
 382:             default:
 383:                 goto send;
 384:             }
 385:             /*NOTREACHED*/
 386: 
 387:         case SIG_HOLD:
 388:         case SIG_IGN:
 389:             /*
 390: 			 * Masking above should prevent us
 391: 			 * ever trying to take action on a held
 392: 			 * or ignored signal, unless process is traced.
 393: 			 */
 394:             if ((p->p_flag&STRC) == 0)
 395:                 printf("issig\n");
 396:             continue;
 397: 
 398:         default:
 399:             /*
 400: 			 * This signal has an action, let
 401: 			 * psig process it.
 402: 			 */
 403:             goto send;
 404:         }
 405:         /*NOTREACHED*/
 406:     }
 407:     /*
 408: 	 * Didn't find a signal to send.
 409: 	 */
 410:     p->p_cursig = 0;
 411:     return (0);
 412: 
 413: send:
 414:     /*
 415: 	 * Let psig process the signal.
 416: 	 */
 417:     return (sig);
 418: }
 419: 
 420: /*
 421:  * Put the argument process into the stopped
 422:  * state and notify the parent via wakeup and/or signal.
 423:  */
 424: stop(p)
 425:     register struct proc *p;
 426: {
 427: 
 428:     p->p_stat = SSTOP;
 429:     p->p_flag &= ~SWTED;
 430:     wakeup((caddr_t)p->p_pptr);
 431:     /*
 432: 	 * Avoid sending signal to parent if process is traced
 433: 	 */
 434:     if (p->p_flag&STRC)
 435:         return;
 436:     psignal(p->p_pptr, SIGCHLD);
 437: }
 438: /*
 439:  * Perform the action specified by
 440:  * the current signal.
 441:  * The usual sequence is:
 442:  *	if(issig())
 443:  *		psig();
 444:  * The signal bit has already been cleared by issig,
 445:  * and the current signal number stored in p->p_cursig.
 446:  */
 447: psig()
 448: {
 449:     register struct proc *rp = u.u_procp;
 450:     register int n = rp->p_cursig;
 451:     long sigmask = 1L << (n-1);
 452:     register int (*action)();
 453: 
 454:     if (rp->p_cursig == 0)
 455:         panic("psig");
 456: #ifndef NONFP
 457:     if (u.u_fpsaved==0) {
 458:         savfp(&u.u_fps);
 459:         u.u_fpsaved = 1;
 460:     }
 461: #endif
 462:     action = u.u_signal[n];
 463:     if (action != SIG_DFL) {
 464:         if (action == SIG_IGN || action == SIG_HOLD)
 465:             panic("psig action");
 466:         u.u_error = 0;
 467:         /*
 468: 		 * If this catch value indicates automatic holding of
 469: 		 * subsequent signals, set the hold value.
 470: 		 */
 471:         if (SIGISDEFER(action)) {
 472:             (void) _spl6();
 473:             if ((int)SIG_HOLD & 1)
 474:                 rp->p_siga0 |= sigmask;
 475:             else
 476:                 rp->p_siga0 &= ~sigmask;
 477:             if ((int)SIG_HOLD & 2)
 478:                 rp->p_siga1 |= sigmask;
 479:             else
 480:                 rp->p_siga1 &= ~sigmask;
 481:             u.u_signal[n] = SIG_HOLD;
 482:             (void) _spl0();
 483:             action = SIGUNDEFER(action);
 484:         } else if(n != SIGILL && n != SIGTRAP) {
 485:             (void) _spl6();
 486:             if ((int)SIG_DFL & 1)
 487:                 rp->p_siga0 |= sigmask;
 488:             else
 489:                 rp->p_siga0 &= ~sigmask;
 490:             if ((int)SIG_DFL & 2)
 491:                 rp->p_siga1 |= sigmask;
 492:             else
 493:                 rp->p_siga1 &= ~sigmask;
 494:             u.u_signal[n] = SIG_DFL;
 495:             (void) _spl0();
 496:         }
 497:         sendsig(action);
 498:         rp->p_cursig = 0;
 499:         return;
 500:     }
 501:     switch (n) {
 502: 
 503:     case SIGILL:
 504:     case SIGIOT:
 505:     case SIGBUS:
 506:     case SIGQUIT:
 507:     case SIGTRAP:
 508:     case SIGEMT:
 509:     case SIGFPE:
 510:     case SIGSEGV:
 511:     case SIGSYS:
 512:         u.u_arg[0] = n;
 513:         if(core())
 514:             n += 0200;
 515:     }
 516:     exit(n);
 517: }
 518: 
 519: /*
 520:  * Create a core image on the file "core"
 521:  * If you are looking for protection glitches,
 522:  * there are probably a wealth of them here
 523:  * when this occurs to a suid command.
 524:  *
 525:  * It writes USIZE block of the
 526:  * user.h area followed by the entire
 527:  * data+stack segments.
 528:  */
 529: core()
 530: {
 531:     register struct inode *ip;
 532:     register unsigned s;
 533:     extern schar();
 534: 
 535:     u.u_error = 0;
 536: 
 537:     /*
 538: 	 * Disallow dump if setuid/setgid.
 539: 	 */
 540:     if (u.u_gid != u.u_rgid || u.u_uid != u.u_ruid)
 541:         return(0);
 542: 
 543:     u.u_dirp = "core";
 544: #ifndef UCB_SYMLINKS
 545:     ip = namei(schar, CREATE);
 546: #else
 547:     ip = namei(schar, CREATE, 1);
 548: #endif
 549:     if(ip == NULL) {
 550:         if(u.u_error)
 551:             return(0);
 552:         ip = maknode(0666);
 553:         if (ip==NULL)
 554:             return(0);
 555:     }
 556:     /*
 557: 	 * allow dump only if permissions allow, "core" is
 558: 	 * regular file and has exactly one link
 559: 	 */
 560:     if(!access(ip, IWRITE) &&
 561:        (ip->i_mode&IFMT) == IFREG &&
 562:        ip->i_nlink == 1) {
 563:         itrunc(ip);
 564:         u.u_offset = 0;
 565:         u.u_base = (caddr_t)&u;
 566:         u.u_count = ctob(USIZE);
 567:         u.u_segflg = 1;
 568:         writei(ip);
 569: #ifdef  VIRUS_VFORK
 570:         s = u.u_dsize;
 571:         estabur((unsigned)0, s, u.u_ssize, 0, RO);
 572:         u.u_base = 0;
 573:         u.u_count = ctob(s);
 574:         u.u_segflg = 0;
 575:         writei(ip);
 576:         s = u.u_ssize;
 577:         u.u_base = -(ctob(s));
 578:         u.u_count = ctob(s);
 579:         writei(ip);
 580: #else
 581:         s = u.u_procp->p_size - USIZE;
 582:         estabur((unsigned)0, s, (unsigned)0, 0, RO);
 583:         u.u_base = 0;
 584:         u.u_count = ctob(s);
 585:         u.u_segflg = 0;
 586:         writei(ip);
 587: #endif
 588:     }
 589:     iput(ip);
 590:     return(u.u_error==0);
 591: }
 592: 
 593: /*
 594:  * grow the stack to include the SP
 595:  * true return if successful.
 596:  */
 597: 
 598: grow(sp)
 599: unsigned sp;
 600: {
 601:     register si;
 602: #ifndef VIRUS_VFORK
 603:     register i;
 604: #endif
 605:     register struct proc *p;
 606:     register a;
 607: 
 608:     if(sp >= -ctob(u.u_ssize))
 609:         return(0);
 610:     si = (-sp) / ctob(1) - u.u_ssize + SINCR;
 611: 
 612:     /*
 613: 	 * Round the increment back to a segment boundary if necessary.
 614: 	 */
 615:     if (ctos(si + u.u_ssize) > ctos(((-sp) + ctob(1) - 1) / ctob(1)))
 616:         si = stoc(ctos(((-sp) + ctob(1) - 1) / ctob(1))) - u.u_ssize;
 617:     if(si <= 0)
 618:         return(0);
 619:     if(estabur(u.u_tsize, u.u_dsize, u.u_ssize+si, u.u_sep, RO))
 620:         return(0);
 621:     p = u.u_procp;
 622: #ifdef  VIRUS_VFORK
 623:     /*
 624: 	 *  expand will put the stack in the right place;
 625: 	 *  no copy required here.
 626: 	 */
 627:     expand(u.u_ssize+si,S_STACK);
 628:     u.u_ssize += si;
 629:     clear(u.u_procp->p_saddr, si);
 630: 
 631: #else   VIRUS_VFORK
 632:     expand(p->p_size+si);
 633:     a = u.u_procp->p_addr + USIZE + u.u_dsize;
 634:     i = u.u_ssize;
 635:     while (i >= si) {
 636:         i -= si;
 637:         copy(a+i, a+i+si, si);
 638:     }
 639:     copy(a, a+si, i);
 640:     clear(a, si);
 641:     u.u_ssize += si;
 642: #endif	VIRUS_VFORK
 643:     return(1);
 644: }
 645: 
 646: /*
 647:  * sys-trace system call.
 648:  */
 649: ptrace()
 650: {
 651:     register struct proc *p;
 652:     register struct a {
 653:         int data;
 654:         int pid;
 655:         int *addr;
 656:         int req;
 657:     } *uap;
 658: 
 659:     uap = (struct a *)u.u_ap;
 660:     if (uap->req <= 0) {
 661:         u.u_procp->p_flag |= STRC;
 662:         return;
 663:     }
 664:     for (p = proc; p <= maxproc; p++)
 665:         if (p->p_stat == SSTOP && p->p_pid == uap->pid
 666:             && p->p_ppid == u.u_procp->p_pid) {
 667:         while (ipc.ip_lock)
 668:             sleep((caddr_t)&ipc, IPCPRI);
 669:         ipc.ip_lock = p->p_pid;
 670:         ipc.ip_data = uap->data;
 671:         ipc.ip_addr = uap->addr;
 672:         ipc.ip_req = uap->req;
 673:         p->p_flag &= ~SWTED;
 674:         setrun(p);
 675:         while (ipc.ip_req > 0)
 676:             sleep((caddr_t)&ipc, IPCPRI);
 677:         u.u_r.r_val1 = ipc.ip_data;
 678:         if (ipc.ip_req < 0)
 679:             u.u_error = EIO;
 680:         ipc.ip_lock = 0;
 681:         wakeup((caddr_t)&ipc);
 682:         return;
 683:     }
 684: 
 685:     u.u_error = ESRCH;
 686: }
 687: 
 688: /*
 689:  * Code that the child process
 690:  * executes to implement the command
 691:  * of the parent process in tracing.
 692:  */
 693: procxmt()
 694: {
 695:     register int i;
 696:     register *p;
 697:     register struct text *xp;
 698: 
 699:     if (ipc.ip_lock != u.u_procp->p_pid)
 700:         return(0);
 701: #ifdef UCB_METER
 702:     u.u_procp->p_slptime = 0;
 703: #endif
 704:     i = ipc.ip_req;
 705:     ipc.ip_req = 0;
 706:     wakeup((caddr_t)&ipc);
 707:     switch (i) {
 708: 
 709:     /* read user I */
 710:     case 1:
 711: #ifndef NONSEPARATE
 712:         if (fuibyte((caddr_t)ipc.ip_addr) == -1)
 713:             goto error;
 714:         ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
 715:         break;
 716: #endif
 717: 
 718:     /* read user D */
 719:     case 2:
 720:         if (fubyte((caddr_t)ipc.ip_addr) == -1)
 721:             goto error;
 722:         ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
 723:         break;
 724: 
 725:     /* read u */
 726:     case 3:
 727:         i = (int)ipc.ip_addr;
 728:         if (i<0 || i >= ctob(USIZE))
 729:             goto error;
 730:         ipc.ip_data = ((physadr)&u)->r[i/sizeof(int)];
 731:         break;
 732: 
 733:     /* write user I */
 734:     /* Must set up to allow writing */
 735:     case 4:
 736:         /*
 737: 		 * If text, must assure exclusive use
 738: 		 */
 739:         if (xp = u.u_procp->p_textp) {
 740:             if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
 741:                 goto error;
 742:             xp->x_iptr->i_flag &= ~ITEXT;
 743:         }
 744:         estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RW);
 745:         i = suiword((caddr_t)ipc.ip_addr, 0);
 746:         suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
 747:         estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RO);
 748:         if (i<0)
 749:             goto error;
 750:         if (xp)
 751:             xp->x_flag |= XWRIT;
 752:         break;
 753: 
 754:     /* write user D */
 755:     case 5:
 756:         if (suword((caddr_t)ipc.ip_addr, 0) < 0)
 757:             goto error;
 758:         suword((caddr_t)ipc.ip_addr, ipc.ip_data);
 759:         break;
 760: 
 761:     /* write u */
 762:     case 6:
 763:         i = (int)ipc.ip_addr;
 764:         p = (int *)&((physadr)&u)->r[i/sizeof(int)];
 765: #ifndef NONFP
 766:         if (p >= (int *)&u.u_fps && p < (int *)&u.u_fps.u_fpregs[6])
 767:             goto ok;
 768: #endif
 769:         for (i=0; i<8; i++)
 770:             if (p == &u.u_ar0[regloc[i]])
 771:                 goto ok;
 772:         if (p == &u.u_ar0[RPS]) {
 773:             ipc.ip_data |= PS_CURMOD | PS_PRVMOD;   /* user space */
 774:             ipc.ip_data &= ~PS_USERCLR;     /* priority 0 */
 775:             goto ok;
 776:         }
 777: #ifdef  MENLO_OVLY
 778:         if ((p == &u.u_ovdata.uo_curov) && ((ipc.ip_data >= 0) &&
 779:             (ipc.ip_data <= NOVL) && u.u_ovdata.uo_ovbase)) {
 780:             u.u_ovdata.uo_curov = ipc.ip_data;
 781:             choverlay();
 782:             break;
 783:         }
 784: #endif
 785:         goto error;
 786: 
 787:     ok:
 788:         *p = ipc.ip_data;
 789:         break;
 790: 
 791:     /* set signal and continue */
 792:     /*  one version causes a trace-trap */
 793:     case 9:
 794:         u.u_ar0[RPS] |= PS_T;
 795:         /* FALL THROUGH TO ... */
 796:     case 7:
 797:         if ((int)ipc.ip_addr != 1)
 798:             u.u_ar0[PC] = (int)ipc.ip_addr;
 799:         if (ipc.ip_data > NSIG)
 800:             goto error;
 801:         u.u_procp->p_cursig = ipc.ip_data;
 802:         return(1);
 803: 
 804:     /* force exit */
 805:     case 8:
 806:         exit(u.u_procp->p_cursig);
 807:         /*NOTREACHED*/
 808: 
 809:     default:
 810:     error:
 811:         ipc.ip_req = -1;
 812:     }
 813:     return(0);
 814: }

Defined functions

core defined in line 529; used 1 times
grow defined in line 598; used 2 times
issig defined in line 289; used 4 times
procxmt defined in line 693; used 1 times
psig defined in line 447; used 3 times
ptrace defined in line 649; used 2 times
stop defined in line 424; used 3 times

Defined struct's

a defined in line 652; used 2 times
  • in line 659(2)

Defined macros

IPCPRI defined in line 21; used 2 times
bit defined in line 302; used 4 times
  • in line 303(4)
mask defined in line 108; used 6 times
stops defined in line 109; used 2 times

Usage of this include

sigjcl.c used 1 times
Last modified: 1983-09-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1350
Valid CSS Valid XHTML 1.0 Strict