1*7818Sroot /* kern_sig.c 5.4 82/08/22 */ 27421Sroot 37421Sroot #include "../h/param.h" 47421Sroot #include "../h/systm.h" 57421Sroot #include "../h/dir.h" 67421Sroot #include "../h/user.h" 77421Sroot #include "../h/reg.h" 87421Sroot #include "../h/inode.h" 97421Sroot #include "../h/proc.h" 107421Sroot #include "../h/clock.h" 117421Sroot #include "../h/mtpr.h" 127421Sroot #include "../h/timeb.h" 137421Sroot #include "../h/times.h" 147421Sroot #include "../h/conf.h" 157421Sroot #include "../h/buf.h" 167421Sroot #include "../h/mount.h" 177421Sroot #include "../h/text.h" 187421Sroot #include "../h/seg.h" 197421Sroot #include "../h/pte.h" 207421Sroot #include "../h/psl.h" 217421Sroot #include "../h/vm.h" 227421Sroot #include "../h/vlimit.h" 237421Sroot #include "../h/acct.h" 24*7818Sroot #include "../h/uio.h" 257421Sroot 267499Sroot /* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ 277499Sroot 287499Sroot sigvec() 297421Sroot { 307421Sroot 317421Sroot } 327421Sroot 337499Sroot sigblock() 347421Sroot { 357499Sroot 367499Sroot } 377499Sroot 387499Sroot sigsetmask() 397499Sroot { 407499Sroot 417499Sroot } 427499Sroot 437499Sroot sigpause() 447499Sroot { 457499Sroot 467499Sroot } 477499Sroot 487499Sroot sigstack() 497499Sroot { 507499Sroot 517499Sroot } 527499Sroot 537499Sroot /* BEGIN DEFUNCT */ 547499Sroot okill() 557499Sroot { 567421Sroot register struct proc *p; 577421Sroot register a, sig; 587421Sroot register struct a { 597421Sroot int pid; 607421Sroot int signo; 617421Sroot } *uap; 627421Sroot int f, priv; 637421Sroot 647421Sroot uap = (struct a *)u.u_ap; 657421Sroot f = 0; 667421Sroot a = uap->pid; 677421Sroot priv = 0; 687421Sroot sig = uap->signo; 697421Sroot if (sig < 0) 707421Sroot /* 717421Sroot * A negative signal means send to process group. 727421Sroot */ 737421Sroot uap->signo = -uap->signo; 747421Sroot if (uap->signo == 0 || uap->signo > NSIG) { 757421Sroot u.u_error = EINVAL; 767421Sroot return; 777421Sroot } 787421Sroot if (a > 0 && sig > 0) { 797421Sroot p = pfind(a); 807421Sroot if (p == 0 || u.u_uid && u.u_uid != p->p_uid) { 817421Sroot u.u_error = ESRCH; 827421Sroot return; 837421Sroot } 847421Sroot psignal(p, uap->signo); 857421Sroot return; 867421Sroot } 877421Sroot if (a==-1 && u.u_uid==0) { 887421Sroot priv++; 897421Sroot a = 0; 907421Sroot sig = -1; /* like sending to pgrp */ 917421Sroot } else if (a==0) { 927421Sroot /* 937421Sroot * Zero process id means send to my process group. 947421Sroot */ 957421Sroot sig = -1; 967421Sroot a = u.u_procp->p_pgrp; 977421Sroot if (a == 0) { 987421Sroot u.u_error = EINVAL; 997421Sroot return; 1007421Sroot } 1017421Sroot } 1027421Sroot for(p = proc; p < procNPROC; p++) { 1037421Sroot if (p->p_stat == NULL) 1047421Sroot continue; 1057421Sroot if (sig > 0) { 1067421Sroot if (p->p_pid != a) 1077421Sroot continue; 1087421Sroot } else if (p->p_pgrp!=a && priv==0 || p->p_ppid==0 || 1097421Sroot (p->p_flag&SSYS) || (priv && p==u.u_procp)) 1107421Sroot continue; 1117421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 1127421Sroot (uap->signo != SIGCONT || !inferior(p))) 1137421Sroot continue; 1147421Sroot f++; 1157421Sroot psignal(p, uap->signo); 1167421Sroot } 1177421Sroot if (f == 0) 1187421Sroot u.u_error = ESRCH; 1197421Sroot } 1207421Sroot 1217499Sroot ossig() 1227499Sroot { 1237499Sroot register int (*f)(); 1247499Sroot struct a { 1257499Sroot int signo; 1267499Sroot int (*fun)(); 1277499Sroot } *uap; 1287499Sroot register struct proc *p = u.u_procp; 1297499Sroot register a; 1307499Sroot long sigmask; 1317421Sroot 1327499Sroot uap = (struct a *)u.u_ap; 1337499Sroot a = uap->signo & SIGNUMMASK; 1347499Sroot f = uap->fun; 1357499Sroot if (a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP || 1367499Sroot a==SIGCONT && (f == SIG_IGN || f == SIG_HOLD)) { 1377499Sroot u.u_error = EINVAL; 1387499Sroot return; 1397499Sroot } 1407499Sroot if ((uap->signo &~ SIGNUMMASK) || (f != SIG_DFL && f != SIG_IGN && 1417499Sroot SIGISDEFER(f))) 1427499Sroot u.u_procp->p_flag |= SNUSIG; 1437499Sroot /* 1447499Sroot * Don't clobber registers if we are to simulate 1457499Sroot * a ret+rti. 1467499Sroot */ 1477499Sroot if ((uap->signo&SIGDORTI) == 0) 1487499Sroot u.u_r.r_val1 = (int)u.u_signal[a]; 1497499Sroot /* 1507499Sroot * Change setting atomically. 1517499Sroot */ 1527499Sroot (void) spl6(); 1537499Sroot sigmask = 1L << (a-1); 1547499Sroot if (u.u_signal[a] == SIG_IGN) 1557499Sroot p->p_sig &= ~sigmask; /* never to be seen again */ 1567499Sroot u.u_signal[a] = f; 1577499Sroot if (f != SIG_DFL && f != SIG_IGN && f != SIG_HOLD) 1587499Sroot f = SIG_CATCH; 1597499Sroot if ((int)f & 1) 1607499Sroot p->p_siga0 |= sigmask; 1617499Sroot else 1627499Sroot p->p_siga0 &= ~sigmask; 1637499Sroot if ((int)f & 2) 1647499Sroot p->p_siga1 |= sigmask; 1657499Sroot else 1667499Sroot p->p_siga1 &= ~sigmask; 1677499Sroot (void) spl0(); 1687499Sroot /* 1697499Sroot * Now handle options. 1707499Sroot */ 1717499Sroot if (uap->signo & SIGDOPAUSE) { 1727499Sroot /* 1737499Sroot * Simulate a PDP11 style wait instrution which 1747499Sroot * atomically lowers priority, enables interrupts 1757499Sroot * and hangs. 1767499Sroot */ 1777499Sroot opause(); 1787499Sroot /*NOTREACHED*/ 1797499Sroot } 1807499Sroot if (uap->signo & SIGDORTI) 1817499Sroot u.u_eosys = SIMULATERTI; 1827499Sroot } 1837421Sroot 1847421Sroot /* 1857421Sroot * Send the specified signal to 1867421Sroot * all processes with 'pgrp' as 1877421Sroot * process group. 1887421Sroot * Called by tty.c for quits and 1897421Sroot * interrupts. 1907421Sroot */ 1917421Sroot gsignal(pgrp, sig) 1927421Sroot register int pgrp; 1937421Sroot { 1947421Sroot register struct proc *p; 1957421Sroot 1967421Sroot if (pgrp == 0) 1977421Sroot return; 1987421Sroot for(p = proc; p < procNPROC; p++) 1997421Sroot if (p->p_pgrp == pgrp) 2007421Sroot psignal(p, sig); 2017421Sroot } 2027421Sroot 2037421Sroot /* 2047421Sroot * Send the specified signal to 2057421Sroot * the specified process. 2067421Sroot */ 2077421Sroot psignal(p, sig) 2087421Sroot register struct proc *p; 2097421Sroot register int sig; 2107421Sroot { 2117421Sroot register int s; 2127421Sroot register int (*action)(); 2137421Sroot long sigmask; 2147421Sroot 2157421Sroot if ((unsigned)sig >= NSIG) 2167421Sroot return; 2177421Sroot sigmask = (1L << (sig-1)); 2187421Sroot 2197421Sroot /* 2207421Sroot * If proc is traced, always give parent a chance. 2217421Sroot * Otherwise get the signal action from the bits in the proc table. 2227421Sroot */ 2237421Sroot if (p->p_flag & STRC) 2247421Sroot action = SIG_DFL; 2257421Sroot else { 2267421Sroot s = (p->p_siga1&sigmask) != 0; 2277421Sroot s <<= 1; 2287421Sroot s |= (p->p_siga0&sigmask) != 0; 2297421Sroot action = (int(*)())s; 2307421Sroot /* 2317421Sroot * If the signal is ignored, we forget about it immediately. 2327421Sroot */ 2337421Sroot if (action == SIG_IGN) 2347421Sroot return; 2357421Sroot } 2367421Sroot #define mask(sig) (1<<(sig-1)) 2377421Sroot #define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU)) 2387421Sroot if (sig) { 2397421Sroot p->p_sig |= sigmask; 2407421Sroot switch (sig) { 2417421Sroot 2427421Sroot case SIGTERM: 2437421Sroot if ((p->p_flag&STRC) != 0 || action != SIG_DFL) 2447421Sroot break; 2457421Sroot /* fall into ... */ 2467421Sroot 2477421Sroot case SIGKILL: 2487421Sroot if (p->p_nice > NZERO) 2497421Sroot p->p_nice = NZERO; 2507421Sroot break; 2517421Sroot 2527421Sroot case SIGCONT: 2537421Sroot p->p_sig &= ~stops; 2547421Sroot break; 2557421Sroot 2567421Sroot case SIGSTOP: 2577421Sroot case SIGTSTP: 2587421Sroot case SIGTTIN: 2597421Sroot case SIGTTOU: 2607421Sroot p->p_sig &= ~mask(SIGCONT); 2617421Sroot break; 2627421Sroot } 2637421Sroot } 2647421Sroot #undef mask 2657421Sroot #undef stops 2667421Sroot /* 2677421Sroot * Defer further processing for signals which are held. 2687421Sroot */ 2697421Sroot if (action == SIG_HOLD) 2707421Sroot return; 2717421Sroot s = spl6(); 2727421Sroot switch (p->p_stat) { 2737421Sroot 2747421Sroot case SSLEEP: 2757421Sroot /* 2767421Sroot * If process is sleeping at negative priority 2777421Sroot * we can't interrupt the sleep... the signal will 2787421Sroot * be noticed when the process returns through 2797421Sroot * trap() or syscall(). 2807421Sroot */ 2817421Sroot if (p->p_pri <= PZERO) 2827421Sroot goto out; 2837421Sroot /* 2847421Sroot * Process is sleeping and traced... make it runnable 2857421Sroot * so it can discover the signal in issig() and stop 2867421Sroot * for the parent. 2877421Sroot */ 2887421Sroot if (p->p_flag&STRC) 2897421Sroot goto run; 2907421Sroot switch (sig) { 2917421Sroot 2927421Sroot case SIGSTOP: 2937421Sroot case SIGTSTP: 2947421Sroot case SIGTTIN: 2957421Sroot case SIGTTOU: 2967421Sroot /* 2977421Sroot * These are the signals which by default 2987421Sroot * stop a process. 2997421Sroot */ 3007421Sroot if (action != SIG_DFL) 3017421Sroot goto run; 3027421Sroot /* 3037421Sroot * Don't clog system with children of init 3047421Sroot * stopped from the keyboard. 3057421Sroot */ 3067421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 3077421Sroot psignal(p, SIGKILL); 3087421Sroot p->p_sig &= ~sigmask; 3097421Sroot splx(s); 3107421Sroot return; 3117421Sroot } 3127421Sroot /* 3137421Sroot * If a child in vfork(), stopping could 3147421Sroot * cause deadlock. 3157421Sroot */ 3167421Sroot if (p->p_flag&SVFORK) 3177421Sroot goto out; 3187421Sroot p->p_sig &= ~sigmask; 3197421Sroot p->p_cursig = sig; 3207421Sroot stop(p); 3217421Sroot goto out; 3227421Sroot 3237421Sroot case SIGIO: 3247421Sroot case SIGURG: 3257421Sroot case SIGCHLD: 3267421Sroot /* 3277421Sroot * These signals are special in that they 3287421Sroot * don't get propogated... if the process 3297421Sroot * isn't interested, forget it. 3307421Sroot */ 3317421Sroot if (action != SIG_DFL) 3327421Sroot goto run; 3337421Sroot p->p_sig &= ~sigmask; /* take it away */ 3347421Sroot goto out; 3357421Sroot 3367421Sroot default: 3377421Sroot /* 3387421Sroot * All other signals cause the process to run 3397421Sroot */ 3407421Sroot goto run; 3417421Sroot } 3427421Sroot /*NOTREACHED*/ 3437421Sroot 3447421Sroot case SSTOP: 3457421Sroot /* 3467421Sroot * If traced process is already stopped, 3477421Sroot * then no further action is necessary. 3487421Sroot */ 3497421Sroot if (p->p_flag&STRC) 3507421Sroot goto out; 3517421Sroot switch (sig) { 3527421Sroot 3537421Sroot case SIGKILL: 3547421Sroot /* 3557421Sroot * Kill signal always sets processes running. 3567421Sroot */ 3577421Sroot goto run; 3587421Sroot 3597421Sroot case SIGCONT: 3607421Sroot /* 3617421Sroot * If the process catches SIGCONT, let it handle 3627421Sroot * the signal itself. If it isn't waiting on 3637421Sroot * an event, then it goes back to run state. 3647421Sroot * Otherwise, process goes back to sleep state. 3657421Sroot */ 3667421Sroot if (action != SIG_DFL || p->p_wchan == 0) 3677421Sroot goto run; 3687421Sroot p->p_stat = SSLEEP; 3697421Sroot goto out; 3707421Sroot 3717421Sroot case SIGSTOP: 3727421Sroot case SIGTSTP: 3737421Sroot case SIGTTIN: 3747421Sroot case SIGTTOU: 3757421Sroot /* 3767421Sroot * Already stopped, don't need to stop again. 3777421Sroot * (If we did the shell could get confused.) 3787421Sroot */ 3797421Sroot p->p_sig &= ~sigmask; /* take it away */ 3807421Sroot goto out; 3817421Sroot 3827421Sroot default: 3837421Sroot /* 3847421Sroot * If process is sleeping interruptibly, then 3857421Sroot * unstick it so that when it is continued 3867421Sroot * it can look at the signal. 3877421Sroot * But don't setrun the process as its not to 3887421Sroot * be unstopped by the signal alone. 3897421Sroot */ 3907421Sroot if (p->p_wchan && p->p_pri > PZERO) 3917421Sroot unsleep(p); 3927421Sroot goto out; 3937421Sroot } 3947421Sroot /*NOTREACHED*/ 3957421Sroot 3967421Sroot default: 3977421Sroot /* 3987421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 3997421Sroot * other than kicking ourselves if we are running. 4007421Sroot * It will either never be noticed, or noticed very soon. 4017421Sroot */ 4027421Sroot if (p == u.u_procp && !noproc) 4037421Sroot aston(); 4047421Sroot goto out; 4057421Sroot } 4067421Sroot /*NOTREACHED*/ 4077421Sroot run: 4087421Sroot /* 4097421Sroot * Raise priority to at least PUSER. 4107421Sroot */ 4117421Sroot if (p->p_pri > PUSER) 4127421Sroot if ((p != u.u_procp || noproc) && p->p_stat == SRUN && 4137421Sroot (p->p_flag & SLOAD)) { 4147421Sroot remrq(p); 4157421Sroot p->p_pri = PUSER; 4167421Sroot setrq(p); 4177421Sroot } else 4187421Sroot p->p_pri = PUSER; 4197421Sroot setrun(p); 4207421Sroot out: 4217421Sroot splx(s); 4227421Sroot } 4237421Sroot 4247421Sroot /* 4257421Sroot * Returns true if the current 4267421Sroot * process has a signal to process. 4277421Sroot * The signal to process is put in p_cursig. 4287421Sroot * This is asked at least once each time a process enters the 4297421Sroot * system (though this can usually be done without actually 4307421Sroot * calling issig by checking the pending signal masks.) 4317421Sroot * A signal does not do anything 4327421Sroot * directly to a process; it sets 4337421Sroot * a flag that asks the process to 4347421Sroot * do something to itself. 4357421Sroot */ 4367421Sroot issig() 4377421Sroot { 4387421Sroot register struct proc *p; 4397421Sroot register int sig; 4407421Sroot long sigbits; 4417421Sroot long sigmask; 4427421Sroot 4437421Sroot p = u.u_procp; 4447421Sroot for (;;) { 4457421Sroot sigbits = p->p_sig; 4467421Sroot if ((p->p_flag&STRC) == 0) 4477421Sroot sigbits &= ~p->p_ignsig; 4487421Sroot if (p->p_flag&SVFORK) 4497421Sroot #define bit(a) (1<<(a-1)) 4507421Sroot sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 4517421Sroot if (sigbits == 0) 4527421Sroot break; 4537421Sroot sig = ffs((int)sigbits); 4547421Sroot sigmask = 1L << (sig-1); 4557421Sroot p->p_sig &= ~sigmask; /* take the signal! */ 4567421Sroot p->p_cursig = sig; 4577421Sroot if (p->p_flag&STRC && (p->p_flag&SVFORK)==0) { 4587421Sroot /* 4597421Sroot * If traced, always stop, and stay 4607421Sroot * stopped until released by the parent. 4617421Sroot */ 4627421Sroot do { 4637421Sroot stop(p); 4647421Sroot swtch(); 4657421Sroot } while (!procxmt() && p->p_flag&STRC); 4667421Sroot 4677421Sroot /* 4687421Sroot * If the traced bit got turned off, 4697421Sroot * then put the signal taken above back into p_sig 4707421Sroot * and go back up to the top to rescan signals. 4717421Sroot * This ensures that siga0 and u_signal are consistent. 4727421Sroot */ 4737421Sroot if ((p->p_flag&STRC) == 0) { 4747421Sroot p->p_sig |= sigmask; 4757421Sroot continue; 4767421Sroot } 4777421Sroot 4787421Sroot /* 4797421Sroot * If parent wants us to take the signal, 4807421Sroot * then it will leave it in p->p_cursig; 4817421Sroot * otherwise we just look for signals again. 4827421Sroot */ 4837421Sroot sig = p->p_cursig; 4847421Sroot if (sig == 0) 4857421Sroot continue; 4867421Sroot } 4877421Sroot switch (u.u_signal[sig]) { 4887421Sroot 4897421Sroot case SIG_DFL: 4907421Sroot /* 4917421Sroot * Don't take default actions on system processes. 4927421Sroot */ 4937421Sroot if (p->p_ppid == 0) 4947421Sroot break; 4957421Sroot switch (sig) { 4967421Sroot 4977421Sroot case SIGTSTP: 4987421Sroot case SIGTTIN: 4997421Sroot case SIGTTOU: 5007421Sroot /* 5017421Sroot * Children of init aren't allowed to stop 5027421Sroot * on signals from the keyboard. 5037421Sroot */ 5047421Sroot if (p->p_pptr == &proc[1]) { 5057421Sroot psignal(p, SIGKILL); 5067421Sroot continue; 5077421Sroot } 5087421Sroot /* fall into ... */ 5097421Sroot 5107421Sroot case SIGSTOP: 5117421Sroot if (p->p_flag&STRC) 5127421Sroot continue; 5137421Sroot stop(p); 5147421Sroot swtch(); 5157421Sroot continue; 5167421Sroot 5177421Sroot case SIGCONT: 5187421Sroot case SIGCHLD: 5197421Sroot /* 5207421Sroot * These signals are normally not 5217421Sroot * sent if the action is the default. 5227421Sroot */ 5237421Sroot continue; /* == ignore */ 5247421Sroot 5257421Sroot default: 5267421Sroot goto send; 5277421Sroot } 5287421Sroot /*NOTREACHED*/ 5297421Sroot 5307421Sroot case SIG_HOLD: 5317421Sroot case SIG_IGN: 5327421Sroot /* 5337421Sroot * Masking above should prevent us 5347421Sroot * ever trying to take action on a held 5357421Sroot * or ignored signal, unless process is traced. 5367421Sroot */ 5377421Sroot if ((p->p_flag&STRC) == 0) 5387421Sroot printf("issig\n"); 5397421Sroot continue; 5407421Sroot 5417421Sroot default: 5427421Sroot /* 5437421Sroot * This signal has an action, let 5447421Sroot * psig process it. 5457421Sroot */ 5467421Sroot goto send; 5477421Sroot } 5487421Sroot /*NOTREACHED*/ 5497421Sroot } 5507421Sroot /* 5517421Sroot * Didn't find a signal to send. 5527421Sroot */ 5537421Sroot p->p_cursig = 0; 5547421Sroot return (0); 5557421Sroot 5567421Sroot send: 5577421Sroot /* 5587421Sroot * Let psig process the signal. 5597421Sroot */ 5607421Sroot return (sig); 5617421Sroot } 5627421Sroot 5637421Sroot /* 5647421Sroot * Put the argument process into the stopped 5657421Sroot * state and notify the parent via wakeup and/or signal. 5667421Sroot */ 5677421Sroot stop(p) 5687421Sroot register struct proc *p; 5697421Sroot { 5707421Sroot 5717421Sroot p->p_stat = SSTOP; 5727421Sroot p->p_flag &= ~SWTED; 5737421Sroot wakeup((caddr_t)p->p_pptr); 5747421Sroot /* 5757421Sroot * Avoid sending signal to parent if process is traced 5767421Sroot */ 5777421Sroot if (p->p_flag&STRC) 5787421Sroot return; 5797421Sroot psignal(p->p_pptr, SIGCHLD); 5807421Sroot } 5817421Sroot 5827421Sroot /* 5837421Sroot * Perform the action specified by 5847421Sroot * the current signal. 5857421Sroot * The usual sequence is: 5867421Sroot * if (issig()) 5877421Sroot * psig(); 5887421Sroot * The signal bit has already been cleared by issig, 5897421Sroot * and the current signal number stored in p->p_cursig. 5907421Sroot */ 5917421Sroot psig() 5927421Sroot { 5937421Sroot register struct proc *rp = u.u_procp; 5947421Sroot register int n = rp->p_cursig; 5957421Sroot long sigmask = 1L << (n-1); 5967421Sroot register int (*action)(); 5977421Sroot 5987421Sroot if (rp->p_cursig == 0) 5997421Sroot panic("psig"); 6007421Sroot action = u.u_signal[n]; 6017421Sroot if (action != SIG_DFL) { 6027421Sroot if (action == SIG_IGN || action == SIG_HOLD) 6037421Sroot panic("psig action"); 6047421Sroot u.u_error = 0; 6057421Sroot if (n != SIGILL && n != SIGTRAP) 6067421Sroot u.u_signal[n] = 0; 6077421Sroot /* 6087421Sroot * If this catch value indicates automatic holding of 6097421Sroot * subsequent signals, set the hold value. 6107421Sroot */ 6117421Sroot if (SIGISDEFER(action)) { 6127421Sroot (void) spl6(); 6137421Sroot if ((int)SIG_HOLD & 1) 6147421Sroot rp->p_siga0 |= sigmask; 6157421Sroot else 6167421Sroot rp->p_siga0 &= ~sigmask; 6177421Sroot if ((int)SIG_HOLD & 2) 6187421Sroot rp->p_siga1 |= sigmask; 6197421Sroot else 6207421Sroot rp->p_siga1 &= ~sigmask; 6217421Sroot u.u_signal[n] = SIG_HOLD; 6227421Sroot (void) spl0(); 6237421Sroot action = SIGUNDEFER(action); 6247421Sroot } 6257421Sroot sendsig(action, n); 6267421Sroot rp->p_cursig = 0; 6277421Sroot return; 6287421Sroot } 6297421Sroot u.u_acflag |= AXSIG; 6307421Sroot switch (n) { 6317421Sroot 6327421Sroot case SIGILL: 6337421Sroot case SIGIOT: 6347421Sroot case SIGBUS: 6357421Sroot case SIGQUIT: 6367421Sroot case SIGTRAP: 6377421Sroot case SIGEMT: 6387421Sroot case SIGFPE: 6397421Sroot case SIGSEGV: 6407421Sroot case SIGSYS: 6417421Sroot u.u_arg[0] = n; 6427421Sroot if (core()) 6437421Sroot n += 0200; 6447421Sroot } 6457421Sroot exit(n); 6467421Sroot } 6477421Sroot 6487421Sroot #ifdef unneeded 6497421Sroot int corestop = 0; 6507421Sroot #endif 6517421Sroot /* 6527421Sroot * Create a core image on the file "core" 6537421Sroot * If you are looking for protection glitches, 6547421Sroot * there are probably a wealth of them here 6557421Sroot * when this occurs to a suid command. 6567421Sroot * 6577421Sroot * It writes UPAGES block of the 6587421Sroot * user.h area followed by the entire 6597421Sroot * data+stack segments. 6607421Sroot */ 6617421Sroot core() 6627421Sroot { 6637421Sroot register struct inode *ip; 6647421Sroot extern schar(); 6657421Sroot 6667421Sroot #ifdef unneeded 6677421Sroot if (corestop) { 6687421Sroot int i; 6697421Sroot for (i = 0; i < 10; i++) 6707421Sroot if (u.u_comm[i]) 6717421Sroot putchar(u.u_comm[i], 0); 6727421Sroot printf(", uid %d\n", u.u_uid); 6737421Sroot if (corestop&2) 6747421Sroot asm("halt"); 6757421Sroot } 6767421Sroot #endif 6777421Sroot if (u.u_uid != u.u_ruid) 678*7818Sroot return (0); 6797421Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= u.u_limit[LIM_CORE]) 6807421Sroot return (0); 6817421Sroot u.u_error = 0; 6827421Sroot u.u_dirp = "core"; 6837421Sroot ip = namei(schar, 1, 1); 6847421Sroot if (ip == NULL) { 6857421Sroot if (u.u_error) 6867421Sroot return (0); 6877421Sroot ip = maknode(0666); 6887421Sroot if (ip==NULL) 6897421Sroot return (0); 6907421Sroot } 691*7818Sroot if (access(ip, IWRITE) || 692*7818Sroot (ip->i_mode&IFMT) != IFREG || 693*7818Sroot ip->i_nlink != 1) { 6947421Sroot u.u_error = EFAULT; 695*7818Sroot goto out; 696*7818Sroot } 697*7818Sroot itrunc(ip, 0); 698*7818Sroot u.u_acflag |= ACORE; 699*7818Sroot u.u_error =rdwri(UIO_WRITE, ip, 700*7818Sroot (caddr_t)&u, ctob(UPAGES), 701*7818Sroot 0, 1, (int *)0); 702*7818Sroot if (u.u_error) 703*7818Sroot rdwri(UIO_WRITE, ip, 704*7818Sroot (caddr_t)ctob(u.u_tsize), ctob(u.u_dsize), 705*7818Sroot ctob(UPAGES), 0, (int *)0); 706*7818Sroot if (u.u_error) 707*7818Sroot rdwri(UIO_WRITE, ip, 708*7818Sroot (caddr_t)(USRSTACK-ctob(u.u_ssize)), ctob(u.u_ssize), 709*7818Sroot ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0); 710*7818Sroot out: 7117421Sroot iput(ip); 712*7818Sroot return (u.u_error == 0); 7137421Sroot } 714*7818Sroot 7157421Sroot /* 7167499Sroot * alarm clock signal 7177421Sroot */ 7187499Sroot oalarm() 7197421Sroot { 7207421Sroot register struct proc *p; 7217499Sroot register c; 7227421Sroot register struct a { 7237499Sroot int deltat; 7247421Sroot } *uap; 7257421Sroot 7267421Sroot uap = (struct a *)u.u_ap; 7277499Sroot p = u.u_procp; 7287499Sroot c = p->p_clktim; 7297499Sroot p->p_clktim = uap->deltat; 7307499Sroot u.u_r.r_val1 = c; 7317421Sroot } 7327421Sroot 7337421Sroot /* 7347499Sroot * indefinite wait. 7357499Sroot * no one should wakeup(&u) 7367421Sroot */ 7377499Sroot opause() 7387421Sroot { 7397421Sroot 7407499Sroot for (;;) 7417499Sroot sleep((caddr_t)&u, PSLEP); 7427499Sroot } 7437421Sroot 744