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