1*9989Ssam /* kern_sig.c 5.15 82/12/28 */ 27421Sroot 39755Ssam #include "../machine/reg.h" 49755Ssam #include "../machine/pte.h" 59755Ssam #include "../machine/psl.h" 69755Ssam 77421Sroot #include "../h/param.h" 87421Sroot #include "../h/systm.h" 97421Sroot #include "../h/dir.h" 107421Sroot #include "../h/user.h" 117421Sroot #include "../h/inode.h" 127421Sroot #include "../h/proc.h" 137421Sroot #include "../h/timeb.h" 147421Sroot #include "../h/times.h" 157421Sroot #include "../h/conf.h" 167421Sroot #include "../h/buf.h" 177421Sroot #include "../h/mount.h" 187421Sroot #include "../h/text.h" 197421Sroot #include "../h/seg.h" 207421Sroot #include "../h/vm.h" 217421Sroot #include "../h/acct.h" 227818Sroot #include "../h/uio.h" 238117Sroot #include "../h/kernel.h" 249160Ssam #include "../h/nami.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 538764Sroot #ifdef notdef 548032Sroot kill() 558032Sroot { 568032Sroot 578032Sroot } 588764Sroot #endif 598032Sroot 60*9989Ssam /* TEMPORARY */ 618032Sroot killpg() 628032Sroot { 63*9989Ssam register struct a { 64*9989Ssam int pgrp; 65*9989Ssam int signo; 66*9989Ssam } *uap = (struct a *)u.u_ap; 678032Sroot 68*9989Ssam u.u_error = okill1(1, uap->signo, uap->pgrp); 698032Sroot } 708032Sroot 717499Sroot /* BEGIN DEFUNCT */ 727499Sroot okill() 737499Sroot { 747421Sroot register struct a { 757421Sroot int pid; 767421Sroot int signo; 77*9989Ssam } *uap = (struct a *)u.u_ap; 787421Sroot 79*9989Ssam u.u_error = okill1(uap->signo < 0, 80*9989Ssam uap->signo < 0 ? -uap->signo : uap->signo, uap->pid); 81*9989Ssam } 82*9989Ssam 83*9989Ssam okill1(ispgrp, signo, who) 84*9989Ssam int ispgrp, signo, who; 85*9989Ssam { 86*9989Ssam register struct proc *p; 87*9989Ssam int f, priv = 0; 88*9989Ssam 89*9989Ssam if (signo == 0 || signo > NSIG) 90*9989Ssam return (EINVAL); 91*9989Ssam if (who > 0 && !ispgrp) { 92*9989Ssam p = pfind(who); 93*9989Ssam if (p == 0 || u.u_uid && u.u_uid != p->p_uid) 94*9989Ssam return (ESRCH); 95*9989Ssam psignal(p, signo); 96*9989Ssam return (0); 977421Sroot } 98*9989Ssam if (who == -1 && u.u_uid == 0) 99*9989Ssam priv++, who = 0, ispgrp = 1; /* like sending to pgrp */ 100*9989Ssam else if (who == 0) { 1017421Sroot /* 1027421Sroot * Zero process id means send to my process group. 1037421Sroot */ 104*9989Ssam ispgrp = 1; 105*9989Ssam who = u.u_procp->p_pgrp; 106*9989Ssam if (who == 0) 107*9989Ssam return (EINVAL); 1087421Sroot } 109*9989Ssam for (f = 0, p = proc; p < procNPROC; p++) { 1107421Sroot if (p->p_stat == NULL) 1117421Sroot continue; 112*9989Ssam if (!ispgrp) { 113*9989Ssam if (p->p_pid != who) 1147421Sroot continue; 115*9989Ssam } else if (p->p_pgrp != who && priv == 0 || p->p_ppid == 0 || 116*9989Ssam (p->p_flag&SSYS) || (priv && p == u.u_procp)) 1177421Sroot continue; 1187421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 119*9989Ssam (signo != SIGCONT || !inferior(p))) 1207421Sroot continue; 1217421Sroot f++; 122*9989Ssam psignal(p, signo); 1237421Sroot } 124*9989Ssam return (f == 0? ESRCH : 0); 1257421Sroot } 1267421Sroot 1277499Sroot ossig() 1287499Sroot { 1297499Sroot register int (*f)(); 1307499Sroot struct a { 1317499Sroot int signo; 1327499Sroot int (*fun)(); 1337499Sroot } *uap; 1347499Sroot register struct proc *p = u.u_procp; 1357499Sroot register a; 1367499Sroot long sigmask; 1377421Sroot 1387499Sroot uap = (struct a *)u.u_ap; 1397499Sroot a = uap->signo & SIGNUMMASK; 1407499Sroot f = uap->fun; 1417499Sroot if (a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP || 1427499Sroot a==SIGCONT && (f == SIG_IGN || f == SIG_HOLD)) { 1437499Sroot u.u_error = EINVAL; 1447499Sroot return; 1457499Sroot } 1467499Sroot if ((uap->signo &~ SIGNUMMASK) || (f != SIG_DFL && f != SIG_IGN && 1477499Sroot SIGISDEFER(f))) 1487499Sroot u.u_procp->p_flag |= SNUSIG; 1497499Sroot /* 1507499Sroot * Don't clobber registers if we are to simulate 1517499Sroot * a ret+rti. 1527499Sroot */ 1537499Sroot if ((uap->signo&SIGDORTI) == 0) 1547499Sroot u.u_r.r_val1 = (int)u.u_signal[a]; 1557499Sroot /* 1567499Sroot * Change setting atomically. 1577499Sroot */ 1587499Sroot (void) spl6(); 1597499Sroot sigmask = 1L << (a-1); 1609858Ssam if (f == SIG_IGN) 1617499Sroot p->p_sig &= ~sigmask; /* never to be seen again */ 1627499Sroot u.u_signal[a] = f; 1637499Sroot if (f != SIG_DFL && f != SIG_IGN && f != SIG_HOLD) 1647499Sroot f = SIG_CATCH; 1657499Sroot if ((int)f & 1) 1667499Sroot p->p_siga0 |= sigmask; 1677499Sroot else 1687499Sroot p->p_siga0 &= ~sigmask; 1697499Sroot if ((int)f & 2) 1707499Sroot p->p_siga1 |= sigmask; 1717499Sroot else 1727499Sroot p->p_siga1 &= ~sigmask; 1737499Sroot (void) spl0(); 1747499Sroot /* 1757499Sroot * Now handle options. 1767499Sroot */ 1777499Sroot if (uap->signo & SIGDOPAUSE) { 1787499Sroot /* 1797499Sroot * Simulate a PDP11 style wait instrution which 1807499Sroot * atomically lowers priority, enables interrupts 1817499Sroot * and hangs. 1827499Sroot */ 1837499Sroot opause(); 1847499Sroot /*NOTREACHED*/ 1857499Sroot } 1867499Sroot if (uap->signo & SIGDORTI) 1877499Sroot u.u_eosys = SIMULATERTI; 1887499Sroot } 1897421Sroot 1907421Sroot /* 1917421Sroot * Send the specified signal to 1927421Sroot * all processes with 'pgrp' as 1937421Sroot * process group. 1947421Sroot * Called by tty.c for quits and 1957421Sroot * interrupts. 1967421Sroot */ 1977421Sroot gsignal(pgrp, sig) 1987421Sroot register int pgrp; 1997421Sroot { 2007421Sroot register struct proc *p; 2017421Sroot 2027421Sroot if (pgrp == 0) 2037421Sroot return; 2047421Sroot for(p = proc; p < procNPROC; p++) 2057421Sroot if (p->p_pgrp == pgrp) 2067421Sroot psignal(p, sig); 2077421Sroot } 2087421Sroot 2097421Sroot /* 2107421Sroot * Send the specified signal to 2117421Sroot * the specified process. 2127421Sroot */ 2137421Sroot psignal(p, sig) 2147421Sroot register struct proc *p; 2157421Sroot register int sig; 2167421Sroot { 2177421Sroot register int s; 2187421Sroot register int (*action)(); 2197421Sroot long sigmask; 2207421Sroot 2217421Sroot if ((unsigned)sig >= NSIG) 2227421Sroot return; 2237421Sroot sigmask = (1L << (sig-1)); 2247421Sroot 2257421Sroot /* 2267421Sroot * If proc is traced, always give parent a chance. 2277421Sroot * Otherwise get the signal action from the bits in the proc table. 2287421Sroot */ 2297421Sroot if (p->p_flag & STRC) 2307421Sroot action = SIG_DFL; 2317421Sroot else { 2327421Sroot s = (p->p_siga1&sigmask) != 0; 2337421Sroot s <<= 1; 2347421Sroot s |= (p->p_siga0&sigmask) != 0; 2357421Sroot action = (int(*)())s; 2367421Sroot /* 2377421Sroot * If the signal is ignored, we forget about it immediately. 2387421Sroot */ 2397421Sroot if (action == SIG_IGN) 2407421Sroot return; 2417421Sroot } 2427421Sroot #define mask(sig) (1<<(sig-1)) 2437421Sroot #define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU)) 2447421Sroot if (sig) { 2457421Sroot p->p_sig |= sigmask; 2467421Sroot switch (sig) { 2477421Sroot 2487421Sroot case SIGTERM: 2497421Sroot if ((p->p_flag&STRC) != 0 || action != SIG_DFL) 2507421Sroot break; 2517421Sroot /* fall into ... */ 2527421Sroot 2537421Sroot case SIGKILL: 2547421Sroot if (p->p_nice > NZERO) 2557421Sroot p->p_nice = NZERO; 2567421Sroot break; 2577421Sroot 2587421Sroot case SIGCONT: 2597421Sroot p->p_sig &= ~stops; 2607421Sroot break; 2617421Sroot 2627421Sroot case SIGSTOP: 2637421Sroot case SIGTSTP: 2647421Sroot case SIGTTIN: 2657421Sroot case SIGTTOU: 2667421Sroot p->p_sig &= ~mask(SIGCONT); 2677421Sroot break; 2687421Sroot } 2697421Sroot } 2707421Sroot #undef mask 2717421Sroot #undef stops 2727421Sroot /* 2737421Sroot * Defer further processing for signals which are held. 2747421Sroot */ 2757421Sroot if (action == SIG_HOLD) 2767421Sroot return; 2777421Sroot s = spl6(); 2787421Sroot switch (p->p_stat) { 2797421Sroot 2807421Sroot case SSLEEP: 2817421Sroot /* 2827421Sroot * If process is sleeping at negative priority 2837421Sroot * we can't interrupt the sleep... the signal will 2847421Sroot * be noticed when the process returns through 2857421Sroot * trap() or syscall(). 2867421Sroot */ 2877421Sroot if (p->p_pri <= PZERO) 2887421Sroot goto out; 2897421Sroot /* 2907421Sroot * Process is sleeping and traced... make it runnable 2917421Sroot * so it can discover the signal in issig() and stop 2927421Sroot * for the parent. 2937421Sroot */ 2947421Sroot if (p->p_flag&STRC) 2957421Sroot goto run; 2967421Sroot switch (sig) { 2977421Sroot 2987421Sroot case SIGSTOP: 2997421Sroot case SIGTSTP: 3007421Sroot case SIGTTIN: 3017421Sroot case SIGTTOU: 3027421Sroot /* 3037421Sroot * These are the signals which by default 3047421Sroot * stop a process. 3057421Sroot */ 3067421Sroot if (action != SIG_DFL) 3077421Sroot goto run; 3087421Sroot /* 3097421Sroot * Don't clog system with children of init 3107421Sroot * stopped from the keyboard. 3117421Sroot */ 3127421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 3137421Sroot psignal(p, SIGKILL); 3147421Sroot p->p_sig &= ~sigmask; 3157421Sroot splx(s); 3167421Sroot return; 3177421Sroot } 3187421Sroot /* 3197421Sroot * If a child in vfork(), stopping could 3207421Sroot * cause deadlock. 3217421Sroot */ 3227421Sroot if (p->p_flag&SVFORK) 3237421Sroot goto out; 3247421Sroot p->p_sig &= ~sigmask; 3257421Sroot p->p_cursig = sig; 3267421Sroot stop(p); 3277421Sroot goto out; 3287421Sroot 3297421Sroot case SIGIO: 3307421Sroot case SIGURG: 3317421Sroot case SIGCHLD: 3327421Sroot /* 3337421Sroot * These signals are special in that they 3347421Sroot * don't get propogated... if the process 3357421Sroot * isn't interested, forget it. 3367421Sroot */ 3377421Sroot if (action != SIG_DFL) 3387421Sroot goto run; 3397421Sroot p->p_sig &= ~sigmask; /* take it away */ 3407421Sroot goto out; 3417421Sroot 3427421Sroot default: 3437421Sroot /* 3447421Sroot * All other signals cause the process to run 3457421Sroot */ 3467421Sroot goto run; 3477421Sroot } 3487421Sroot /*NOTREACHED*/ 3497421Sroot 3507421Sroot case SSTOP: 3517421Sroot /* 3527421Sroot * If traced process is already stopped, 3537421Sroot * then no further action is necessary. 3547421Sroot */ 3557421Sroot if (p->p_flag&STRC) 3567421Sroot goto out; 3577421Sroot switch (sig) { 3587421Sroot 3597421Sroot case SIGKILL: 3607421Sroot /* 3617421Sroot * Kill signal always sets processes running. 3627421Sroot */ 3637421Sroot goto run; 3647421Sroot 3657421Sroot case SIGCONT: 3667421Sroot /* 3677421Sroot * If the process catches SIGCONT, let it handle 3687421Sroot * the signal itself. If it isn't waiting on 3697421Sroot * an event, then it goes back to run state. 3707421Sroot * Otherwise, process goes back to sleep state. 3717421Sroot */ 3727421Sroot if (action != SIG_DFL || p->p_wchan == 0) 3737421Sroot goto run; 3747421Sroot p->p_stat = SSLEEP; 3757421Sroot goto out; 3767421Sroot 3777421Sroot case SIGSTOP: 3787421Sroot case SIGTSTP: 3797421Sroot case SIGTTIN: 3807421Sroot case SIGTTOU: 3817421Sroot /* 3827421Sroot * Already stopped, don't need to stop again. 3837421Sroot * (If we did the shell could get confused.) 3847421Sroot */ 3857421Sroot p->p_sig &= ~sigmask; /* take it away */ 3867421Sroot goto out; 3877421Sroot 3887421Sroot default: 3897421Sroot /* 3907421Sroot * If process is sleeping interruptibly, then 3917421Sroot * unstick it so that when it is continued 3927421Sroot * it can look at the signal. 3937421Sroot * But don't setrun the process as its not to 3947421Sroot * be unstopped by the signal alone. 3957421Sroot */ 3967421Sroot if (p->p_wchan && p->p_pri > PZERO) 3977421Sroot unsleep(p); 3987421Sroot goto out; 3997421Sroot } 4007421Sroot /*NOTREACHED*/ 4017421Sroot 4027421Sroot default: 4037421Sroot /* 4047421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 4057421Sroot * other than kicking ourselves if we are running. 4067421Sroot * It will either never be noticed, or noticed very soon. 4077421Sroot */ 4087421Sroot if (p == u.u_procp && !noproc) 4098444Sroot #include "../vax/mtpr.h" 4107421Sroot aston(); 4117421Sroot goto out; 4127421Sroot } 4137421Sroot /*NOTREACHED*/ 4147421Sroot run: 4157421Sroot /* 4167421Sroot * Raise priority to at least PUSER. 4177421Sroot */ 4187421Sroot if (p->p_pri > PUSER) 4197421Sroot if ((p != u.u_procp || noproc) && p->p_stat == SRUN && 4207421Sroot (p->p_flag & SLOAD)) { 4217421Sroot remrq(p); 4227421Sroot p->p_pri = PUSER; 4237421Sroot setrq(p); 4247421Sroot } else 4257421Sroot p->p_pri = PUSER; 4267421Sroot setrun(p); 4277421Sroot out: 4287421Sroot splx(s); 4297421Sroot } 4307421Sroot 4317421Sroot /* 4327421Sroot * Returns true if the current 4337421Sroot * process has a signal to process. 4347421Sroot * The signal to process is put in p_cursig. 4357421Sroot * This is asked at least once each time a process enters the 4367421Sroot * system (though this can usually be done without actually 4377421Sroot * calling issig by checking the pending signal masks.) 4387421Sroot * A signal does not do anything 4397421Sroot * directly to a process; it sets 4407421Sroot * a flag that asks the process to 4417421Sroot * do something to itself. 4427421Sroot */ 4437421Sroot issig() 4447421Sroot { 4457421Sroot register struct proc *p; 4467421Sroot register int sig; 4477421Sroot long sigbits; 4487421Sroot long sigmask; 4497421Sroot 4507421Sroot p = u.u_procp; 4517421Sroot for (;;) { 4527421Sroot sigbits = p->p_sig; 4537421Sroot if ((p->p_flag&STRC) == 0) 4547421Sroot sigbits &= ~p->p_ignsig; 4557421Sroot if (p->p_flag&SVFORK) 4567421Sroot #define bit(a) (1<<(a-1)) 4577421Sroot sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 4587421Sroot if (sigbits == 0) 4597421Sroot break; 4607421Sroot sig = ffs((int)sigbits); 4617421Sroot sigmask = 1L << (sig-1); 4627421Sroot p->p_sig &= ~sigmask; /* take the signal! */ 4637421Sroot p->p_cursig = sig; 4647421Sroot if (p->p_flag&STRC && (p->p_flag&SVFORK)==0) { 4657421Sroot /* 4667421Sroot * If traced, always stop, and stay 4677421Sroot * stopped until released by the parent. 4687421Sroot */ 4697421Sroot do { 4707421Sroot stop(p); 4717421Sroot swtch(); 4727421Sroot } while (!procxmt() && p->p_flag&STRC); 4737421Sroot 4747421Sroot /* 4757421Sroot * If the traced bit got turned off, 4767421Sroot * then put the signal taken above back into p_sig 4777421Sroot * and go back up to the top to rescan signals. 4787421Sroot * This ensures that siga0 and u_signal are consistent. 4797421Sroot */ 4807421Sroot if ((p->p_flag&STRC) == 0) { 4817421Sroot p->p_sig |= sigmask; 4827421Sroot continue; 4837421Sroot } 4847421Sroot 4857421Sroot /* 4867421Sroot * If parent wants us to take the signal, 4877421Sroot * then it will leave it in p->p_cursig; 4887421Sroot * otherwise we just look for signals again. 4897421Sroot */ 4907421Sroot sig = p->p_cursig; 4917421Sroot if (sig == 0) 4927421Sroot continue; 4937421Sroot } 4947421Sroot switch (u.u_signal[sig]) { 4957421Sroot 4967421Sroot case SIG_DFL: 4977421Sroot /* 4987421Sroot * Don't take default actions on system processes. 4997421Sroot */ 5007421Sroot if (p->p_ppid == 0) 5017421Sroot break; 5027421Sroot switch (sig) { 5037421Sroot 5047421Sroot case SIGTSTP: 5057421Sroot case SIGTTIN: 5067421Sroot case SIGTTOU: 5077421Sroot /* 5087421Sroot * Children of init aren't allowed to stop 5097421Sroot * on signals from the keyboard. 5107421Sroot */ 5117421Sroot if (p->p_pptr == &proc[1]) { 5127421Sroot psignal(p, SIGKILL); 5137421Sroot continue; 5147421Sroot } 5157421Sroot /* fall into ... */ 5167421Sroot 5177421Sroot case SIGSTOP: 5187421Sroot if (p->p_flag&STRC) 5197421Sroot continue; 5207421Sroot stop(p); 5217421Sroot swtch(); 5227421Sroot continue; 5237421Sroot 5247421Sroot case SIGCONT: 5257421Sroot case SIGCHLD: 5267421Sroot /* 5277421Sroot * These signals are normally not 5287421Sroot * sent if the action is the default. 5297421Sroot */ 5307421Sroot continue; /* == ignore */ 5317421Sroot 5327421Sroot default: 5337421Sroot goto send; 5347421Sroot } 5357421Sroot /*NOTREACHED*/ 5367421Sroot 5377421Sroot case SIG_HOLD: 5387421Sroot case SIG_IGN: 5397421Sroot /* 5407421Sroot * Masking above should prevent us 5417421Sroot * ever trying to take action on a held 5427421Sroot * or ignored signal, unless process is traced. 5437421Sroot */ 5447421Sroot if ((p->p_flag&STRC) == 0) 5457421Sroot printf("issig\n"); 5467421Sroot continue; 5477421Sroot 5487421Sroot default: 5497421Sroot /* 5507421Sroot * This signal has an action, let 5517421Sroot * psig process it. 5527421Sroot */ 5537421Sroot goto send; 5547421Sroot } 5557421Sroot /*NOTREACHED*/ 5567421Sroot } 5577421Sroot /* 5587421Sroot * Didn't find a signal to send. 5597421Sroot */ 5607421Sroot p->p_cursig = 0; 5617421Sroot return (0); 5627421Sroot 5637421Sroot send: 5647421Sroot /* 5657421Sroot * Let psig process the signal. 5667421Sroot */ 5677421Sroot return (sig); 5687421Sroot } 5697421Sroot 5707421Sroot /* 5717421Sroot * Put the argument process into the stopped 5727421Sroot * state and notify the parent via wakeup and/or signal. 5737421Sroot */ 5747421Sroot stop(p) 5757421Sroot register struct proc *p; 5767421Sroot { 5777421Sroot 5787421Sroot p->p_stat = SSTOP; 5797421Sroot p->p_flag &= ~SWTED; 5807421Sroot wakeup((caddr_t)p->p_pptr); 5817421Sroot /* 5827421Sroot * Avoid sending signal to parent if process is traced 5837421Sroot */ 5847421Sroot if (p->p_flag&STRC) 5857421Sroot return; 5867421Sroot psignal(p->p_pptr, SIGCHLD); 5877421Sroot } 5887421Sroot 5897421Sroot /* 5907421Sroot * Perform the action specified by 5917421Sroot * the current signal. 5927421Sroot * The usual sequence is: 5937421Sroot * if (issig()) 5947421Sroot * psig(); 5957421Sroot * The signal bit has already been cleared by issig, 5967421Sroot * and the current signal number stored in p->p_cursig. 5977421Sroot */ 5987421Sroot psig() 5997421Sroot { 6007421Sroot register struct proc *rp = u.u_procp; 6017421Sroot register int n = rp->p_cursig; 6027421Sroot long sigmask = 1L << (n-1); 6037421Sroot register int (*action)(); 6047421Sroot 6057421Sroot if (rp->p_cursig == 0) 6067421Sroot panic("psig"); 6077421Sroot action = u.u_signal[n]; 6087421Sroot if (action != SIG_DFL) { 6097421Sroot if (action == SIG_IGN || action == SIG_HOLD) 6107421Sroot panic("psig action"); 6117421Sroot u.u_error = 0; 6127421Sroot if (n != SIGILL && n != SIGTRAP) 6137421Sroot u.u_signal[n] = 0; 6147421Sroot /* 6157421Sroot * If this catch value indicates automatic holding of 6167421Sroot * subsequent signals, set the hold value. 6177421Sroot */ 6187421Sroot if (SIGISDEFER(action)) { 6197421Sroot (void) spl6(); 6207421Sroot if ((int)SIG_HOLD & 1) 6217421Sroot rp->p_siga0 |= sigmask; 6227421Sroot else 6237421Sroot rp->p_siga0 &= ~sigmask; 6247421Sroot if ((int)SIG_HOLD & 2) 6257421Sroot rp->p_siga1 |= sigmask; 6267421Sroot else 6277421Sroot rp->p_siga1 &= ~sigmask; 6287421Sroot u.u_signal[n] = SIG_HOLD; 6297421Sroot (void) spl0(); 6307421Sroot action = SIGUNDEFER(action); 6317421Sroot } 6328032Sroot u.u_ru.ru_nsignals++; 6337421Sroot sendsig(action, n); 6347421Sroot rp->p_cursig = 0; 6357421Sroot return; 6367421Sroot } 6377421Sroot u.u_acflag |= AXSIG; 6387421Sroot switch (n) { 6397421Sroot 6407421Sroot case SIGILL: 6417421Sroot case SIGIOT: 6427421Sroot case SIGBUS: 6437421Sroot case SIGQUIT: 6447421Sroot case SIGTRAP: 6457421Sroot case SIGEMT: 6467421Sroot case SIGFPE: 6477421Sroot case SIGSEGV: 6487421Sroot case SIGSYS: 6497421Sroot u.u_arg[0] = n; 6507421Sroot if (core()) 6517421Sroot n += 0200; 6527421Sroot } 6537421Sroot exit(n); 6547421Sroot } 6557421Sroot 6567421Sroot #ifdef unneeded 6577421Sroot int corestop = 0; 6587421Sroot #endif 6597421Sroot /* 6607421Sroot * Create a core image on the file "core" 6617421Sroot * If you are looking for protection glitches, 6627421Sroot * there are probably a wealth of them here 6637421Sroot * when this occurs to a suid command. 6647421Sroot * 6657421Sroot * It writes UPAGES block of the 6667421Sroot * user.h area followed by the entire 6677421Sroot * data+stack segments. 6687421Sroot */ 6697421Sroot core() 6707421Sroot { 6717421Sroot register struct inode *ip; 6727421Sroot extern schar(); 6737421Sroot 6747421Sroot #ifdef unneeded 6757421Sroot if (corestop) { 6767421Sroot int i; 6777421Sroot for (i = 0; i < 10; i++) 6787421Sroot if (u.u_comm[i]) 6797421Sroot putchar(u.u_comm[i], 0); 6807421Sroot printf(", uid %d\n", u.u_uid); 6817421Sroot if (corestop&2) 6827421Sroot asm("halt"); 6837421Sroot } 6847421Sroot #endif 6857421Sroot if (u.u_uid != u.u_ruid) 6867818Sroot return (0); 6878032Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= 6888032Sroot u.u_rlimit[RLIMIT_CORE].rlim_cur) 6897421Sroot return (0); 6907421Sroot u.u_error = 0; 6917421Sroot u.u_dirp = "core"; 6929160Ssam ip = namei(schar, CREATE, 1); 6937421Sroot if (ip == NULL) { 6947421Sroot if (u.u_error) 6957421Sroot return (0); 6967421Sroot ip = maknode(0666); 6977421Sroot if (ip==NULL) 6987421Sroot return (0); 6997421Sroot } 7007818Sroot if (access(ip, IWRITE) || 7017818Sroot (ip->i_mode&IFMT) != IFREG || 7027818Sroot ip->i_nlink != 1) { 7037421Sroot u.u_error = EFAULT; 7047818Sroot goto out; 7057818Sroot } 7069160Ssam itrunc(ip, (u_long)0); 7077818Sroot u.u_acflag |= ACORE; 7088967Sroot /* if (u.u_error == 0) */ 7098967Sroot u.u_error = rdwri(UIO_WRITE, ip, 7108967Sroot (caddr_t)&u, 7118967Sroot ctob(UPAGES), 7128967Sroot 0, 1, (int *)0); 7138101Sroot if (u.u_error == 0) 7148644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7158967Sroot (caddr_t)ctob(dptov(u.u_procp, 0)), 7168967Sroot ctob(u.u_dsize), 7178644Sroot ctob(UPAGES), 0, (int *)0); 7188101Sroot if (u.u_error == 0) 7198644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7208967Sroot (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)), 7218967Sroot ctob(u.u_ssize), 7228644Sroot ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0); 7237818Sroot out: 7247421Sroot iput(ip); 7257818Sroot return (u.u_error == 0); 7267421Sroot } 727