1*12882Ssam /* kern_sig.c 5.19 83/06/02 */ 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 sigvec() 277421Sroot { 28*12882Ssam struct a { 29*12882Ssam int signo; 30*12882Ssam int (*sighandler)(); 31*12882Ssam int sigmask; 32*12882Ssam } *uap = (struct a *)u.u_ap; 33*12882Ssam register int sig; 347421Sroot 35*12882Ssam sig = uap->signo; 36*12882Ssam if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP || 37*12882Ssam (sig == SIGCONT && uap->sighandler == SIG_IGN)) { 38*12882Ssam u.u_error = EINVAL; 39*12882Ssam return; 40*12882Ssam } 41*12882Ssam setsignal(sig, uap->sighandler, uap->sigmask); 427421Sroot } 437421Sroot 44*12882Ssam setsignal(sig, action, sigmask) 45*12882Ssam int sig, (*action)(), sigmask; 46*12882Ssam { 47*12882Ssam register struct proc *p; 48*12882Ssam register int mask; 49*12882Ssam 50*12882Ssam u.u_r.r_val1 = (int)u.u_signal[sig]; 51*12882Ssam mask = 1 << (sig - 1); 52*12882Ssam p = u.u_procp; 53*12882Ssam /* 54*12882Ssam * Change setting atomically. 55*12882Ssam */ 56*12882Ssam (void) spl6(); 57*12882Ssam u.u_signal[sig] = action; 58*12882Ssam u.u_sigmask[sig] = sigmask; 59*12882Ssam if (action == SIG_IGN) { 60*12882Ssam p->p_sig &= ~mask; /* never to be seen again */ 61*12882Ssam p->p_sigignore |= mask; 62*12882Ssam p->p_sigcatch &= ~mask; 63*12882Ssam } else { 64*12882Ssam p->p_sigignore &= ~mask; 65*12882Ssam if (action == SIG_DFL) 66*12882Ssam p->p_sigcatch &= ~mask; 67*12882Ssam else 68*12882Ssam p->p_sigcatch |= mask; 69*12882Ssam } 70*12882Ssam (void) spl0(); 71*12882Ssam } 72*12882Ssam 737499Sroot sigblock() 747421Sroot { 75*12882Ssam struct a { 76*12882Ssam int mask; 77*12882Ssam } *uap = (struct a *)u.u_ap; 78*12882Ssam struct proc *p = u.u_procp; 797499Sroot 80*12882Ssam (void) spl6(); 81*12882Ssam u.u_r.r_val1 = p->p_sigmask; 82*12882Ssam p->p_sigmask |= uap->mask; 83*12882Ssam (void) spl0(); 847499Sroot } 857499Sroot 867499Sroot sigsetmask() 877499Sroot { 88*12882Ssam struct a { 89*12882Ssam int mask; 90*12882Ssam } *uap = (struct a *)u.u_ap; 91*12882Ssam register struct proc *p = u.u_procp; 927499Sroot 93*12882Ssam (void) spl6(); 94*12882Ssam u.u_r.r_val1 = p->p_sigmask; 95*12882Ssam p->p_sigmask = uap->mask; 96*12882Ssam (void) spl0(); 977499Sroot } 987499Sroot 997499Sroot sigpause() 1007499Sroot { 101*12882Ssam struct a { 102*12882Ssam int mask; 103*12882Ssam } *uap = (struct a *)u.u_ap; 104*12882Ssam register struct proc *p = u.u_procp; 1057499Sroot 106*12882Ssam /* 107*12882Ssam * When returning from sigpause, we want 108*12882Ssam * the old mask to be restored after the 109*12882Ssam * signal handler has finished. Thus, we 110*12882Ssam * save it here and mark the proc structure 111*12882Ssam * to indicate this (should be in u.). 112*12882Ssam */ 113*12882Ssam u.u_oldmask = p->p_sigmask; 114*12882Ssam p->p_flag |= SOMASK; 115*12882Ssam p->p_sigmask = uap->mask; 116*12882Ssam for (;;) 117*12882Ssam sleep((caddr_t)&u, PSLEP); 118*12882Ssam /*NOTREACHED*/ 1197499Sroot } 1207499Sroot 1217499Sroot sigstack() 1227499Sroot { 123*12882Ssam struct a { 124*12882Ssam caddr_t asp; 125*12882Ssam int onsigstack; 126*12882Ssam } *uap = (struct a *)u.u_ap; 1277499Sroot 128*12882Ssam u.u_sigstack = uap->asp; 129*12882Ssam u.u_onsigstack = uap->onsigstack; 1307499Sroot } 1317499Sroot 1328032Sroot kill() 1338032Sroot { 134*12882Ssam register struct a { 135*12882Ssam int pid; 136*12882Ssam int signo; 137*12882Ssam } *uap = (struct a *)u.u_ap; 1388032Sroot 139*12882Ssam u.u_error = kill1(0, uap->signo, uap->pid); 1408032Sroot } 1418032Sroot 1428032Sroot killpg() 1438032Sroot { 1449989Ssam register struct a { 1459989Ssam int pgrp; 1469989Ssam int signo; 1479989Ssam } *uap = (struct a *)u.u_ap; 1488032Sroot 14912750Ssam u.u_error = kill1(1, uap->signo, uap->pgrp); 1508032Sroot } 1518032Sroot 152*12882Ssam /* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ 153*12882Ssam 15412750Ssam kill1(ispgrp, signo, who) 1559989Ssam int ispgrp, signo, who; 1569989Ssam { 1579989Ssam register struct proc *p; 1589989Ssam int f, priv = 0; 1599989Ssam 16012835Ssam if (signo < 0 || signo > NSIG) 1619989Ssam return (EINVAL); 1629989Ssam if (who > 0 && !ispgrp) { 1639989Ssam p = pfind(who); 1649989Ssam if (p == 0 || u.u_uid && u.u_uid != p->p_uid) 1659989Ssam return (ESRCH); 16612835Ssam if (signo) 16712835Ssam psignal(p, signo); 1689989Ssam return (0); 1697421Sroot } 1709989Ssam if (who == -1 && u.u_uid == 0) 1719989Ssam priv++, who = 0, ispgrp = 1; /* like sending to pgrp */ 1729989Ssam else if (who == 0) { 1737421Sroot /* 1747421Sroot * Zero process id means send to my process group. 1757421Sroot */ 1769989Ssam ispgrp = 1; 1779989Ssam who = u.u_procp->p_pgrp; 1789989Ssam if (who == 0) 1799989Ssam return (EINVAL); 1807421Sroot } 1819989Ssam for (f = 0, p = proc; p < procNPROC; p++) { 1827421Sroot if (p->p_stat == NULL) 1837421Sroot continue; 1849989Ssam if (!ispgrp) { 1859989Ssam if (p->p_pid != who) 1867421Sroot continue; 1879989Ssam } else if (p->p_pgrp != who && priv == 0 || p->p_ppid == 0 || 1889989Ssam (p->p_flag&SSYS) || (priv && p == u.u_procp)) 1897421Sroot continue; 1907421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 1919989Ssam (signo != SIGCONT || !inferior(p))) 1927421Sroot continue; 1937421Sroot f++; 19412835Ssam if (signo) 19512835Ssam psignal(p, signo); 1967421Sroot } 19712750Ssam return (f == 0 ? ESRCH : 0); 1987421Sroot } 1997421Sroot 2007421Sroot /* 2017421Sroot * Send the specified signal to 2027421Sroot * all processes with 'pgrp' as 2037421Sroot * process group. 2047421Sroot */ 2057421Sroot gsignal(pgrp, sig) 2067421Sroot register int pgrp; 2077421Sroot { 2087421Sroot register struct proc *p; 2097421Sroot 2107421Sroot if (pgrp == 0) 2117421Sroot return; 2127421Sroot for(p = proc; p < procNPROC; p++) 2137421Sroot if (p->p_pgrp == pgrp) 2147421Sroot psignal(p, sig); 2157421Sroot } 2167421Sroot 2177421Sroot /* 2187421Sroot * Send the specified signal to 2197421Sroot * the specified process. 2207421Sroot */ 2217421Sroot psignal(p, sig) 2227421Sroot register struct proc *p; 2237421Sroot register int sig; 2247421Sroot { 2257421Sroot register int s; 2267421Sroot register int (*action)(); 227*12882Ssam int sigmask; 2287421Sroot 2297421Sroot if ((unsigned)sig >= NSIG) 2307421Sroot return; 231*12882Ssam sigmask = 1 << (sig-1); 2327421Sroot 2337421Sroot /* 2347421Sroot * If proc is traced, always give parent a chance. 2357421Sroot */ 2367421Sroot if (p->p_flag & STRC) 2377421Sroot action = SIG_DFL; 2387421Sroot else { 2397421Sroot /* 240*12882Ssam * If the signal is being ignored, 241*12882Ssam * then we forget about it immediately. 2427421Sroot */ 243*12882Ssam if (p->p_sigignore & sigmask) 2447421Sroot return; 245*12882Ssam if (p->p_sigmask & sigmask) 246*12882Ssam action = SIG_HOLD; 247*12882Ssam else if (p->p_sigcatch & sigmask) 248*12882Ssam action = SIG_CATCH; 249*12882Ssam else 250*12882Ssam action = SIG_DFL; 2517421Sroot } 2527421Sroot #define mask(sig) (1<<(sig-1)) 2537421Sroot #define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU)) 2547421Sroot if (sig) { 2557421Sroot p->p_sig |= sigmask; 2567421Sroot switch (sig) { 2577421Sroot 2587421Sroot case SIGTERM: 259*12882Ssam if ((p->p_flag&STRC) || action != SIG_DFL) 2607421Sroot break; 2617421Sroot /* fall into ... */ 2627421Sroot 2637421Sroot case SIGKILL: 2647421Sroot if (p->p_nice > NZERO) 2657421Sroot p->p_nice = NZERO; 2667421Sroot break; 2677421Sroot 2687421Sroot case SIGCONT: 2697421Sroot p->p_sig &= ~stops; 2707421Sroot break; 2717421Sroot 2727421Sroot case SIGSTOP: 2737421Sroot case SIGTSTP: 2747421Sroot case SIGTTIN: 2757421Sroot case SIGTTOU: 2767421Sroot p->p_sig &= ~mask(SIGCONT); 2777421Sroot break; 2787421Sroot } 2797421Sroot } 2807421Sroot #undef mask 2817421Sroot #undef stops 2827421Sroot /* 2837421Sroot * Defer further processing for signals which are held. 2847421Sroot */ 2857421Sroot if (action == SIG_HOLD) 2867421Sroot return; 2877421Sroot s = spl6(); 2887421Sroot switch (p->p_stat) { 2897421Sroot 2907421Sroot case SSLEEP: 2917421Sroot /* 2927421Sroot * If process is sleeping at negative priority 2937421Sroot * we can't interrupt the sleep... the signal will 2947421Sroot * be noticed when the process returns through 2957421Sroot * trap() or syscall(). 2967421Sroot */ 2977421Sroot if (p->p_pri <= PZERO) 2987421Sroot goto out; 2997421Sroot /* 3007421Sroot * Process is sleeping and traced... make it runnable 3017421Sroot * so it can discover the signal in issig() and stop 3027421Sroot * for the parent. 3037421Sroot */ 3047421Sroot if (p->p_flag&STRC) 3057421Sroot goto run; 3067421Sroot switch (sig) { 3077421Sroot 3087421Sroot case SIGSTOP: 3097421Sroot case SIGTSTP: 3107421Sroot case SIGTTIN: 3117421Sroot case SIGTTOU: 3127421Sroot /* 3137421Sroot * These are the signals which by default 3147421Sroot * stop a process. 3157421Sroot */ 3167421Sroot if (action != SIG_DFL) 3177421Sroot goto run; 3187421Sroot /* 3197421Sroot * Don't clog system with children of init 3207421Sroot * stopped from the keyboard. 3217421Sroot */ 3227421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 3237421Sroot psignal(p, SIGKILL); 3247421Sroot p->p_sig &= ~sigmask; 3257421Sroot splx(s); 3267421Sroot return; 3277421Sroot } 3287421Sroot /* 3297421Sroot * If a child in vfork(), stopping could 3307421Sroot * cause deadlock. 3317421Sroot */ 3327421Sroot if (p->p_flag&SVFORK) 3337421Sroot goto out; 3347421Sroot p->p_sig &= ~sigmask; 3357421Sroot p->p_cursig = sig; 3367421Sroot stop(p); 3377421Sroot goto out; 3387421Sroot 3397421Sroot case SIGIO: 3407421Sroot case SIGURG: 3417421Sroot case SIGCHLD: 3427421Sroot /* 3437421Sroot * These signals are special in that they 3447421Sroot * don't get propogated... if the process 3457421Sroot * isn't interested, forget it. 3467421Sroot */ 3477421Sroot if (action != SIG_DFL) 3487421Sroot goto run; 3497421Sroot p->p_sig &= ~sigmask; /* take it away */ 3507421Sroot goto out; 3517421Sroot 3527421Sroot default: 3537421Sroot /* 3547421Sroot * All other signals cause the process to run 3557421Sroot */ 3567421Sroot goto run; 3577421Sroot } 3587421Sroot /*NOTREACHED*/ 3597421Sroot 3607421Sroot case SSTOP: 3617421Sroot /* 3627421Sroot * If traced process is already stopped, 3637421Sroot * then no further action is necessary. 3647421Sroot */ 3657421Sroot if (p->p_flag&STRC) 3667421Sroot goto out; 3677421Sroot switch (sig) { 3687421Sroot 3697421Sroot case SIGKILL: 3707421Sroot /* 3717421Sroot * Kill signal always sets processes running. 3727421Sroot */ 3737421Sroot goto run; 3747421Sroot 3757421Sroot case SIGCONT: 3767421Sroot /* 3777421Sroot * If the process catches SIGCONT, let it handle 3787421Sroot * the signal itself. If it isn't waiting on 3797421Sroot * an event, then it goes back to run state. 3807421Sroot * Otherwise, process goes back to sleep state. 3817421Sroot */ 3827421Sroot if (action != SIG_DFL || p->p_wchan == 0) 3837421Sroot goto run; 3847421Sroot p->p_stat = SSLEEP; 3857421Sroot goto out; 3867421Sroot 3877421Sroot case SIGSTOP: 3887421Sroot case SIGTSTP: 3897421Sroot case SIGTTIN: 3907421Sroot case SIGTTOU: 3917421Sroot /* 3927421Sroot * Already stopped, don't need to stop again. 3937421Sroot * (If we did the shell could get confused.) 3947421Sroot */ 3957421Sroot p->p_sig &= ~sigmask; /* take it away */ 3967421Sroot goto out; 3977421Sroot 3987421Sroot default: 3997421Sroot /* 4007421Sroot * If process is sleeping interruptibly, then 4017421Sroot * unstick it so that when it is continued 4027421Sroot * it can look at the signal. 4037421Sroot * But don't setrun the process as its not to 4047421Sroot * be unstopped by the signal alone. 4057421Sroot */ 4067421Sroot if (p->p_wchan && p->p_pri > PZERO) 4077421Sroot unsleep(p); 4087421Sroot goto out; 4097421Sroot } 4107421Sroot /*NOTREACHED*/ 4117421Sroot 4127421Sroot default: 4137421Sroot /* 4147421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 4157421Sroot * other than kicking ourselves if we are running. 4167421Sroot * It will either never be noticed, or noticed very soon. 4177421Sroot */ 4187421Sroot if (p == u.u_procp && !noproc) 4198444Sroot #include "../vax/mtpr.h" 4207421Sroot aston(); 4217421Sroot goto out; 4227421Sroot } 4237421Sroot /*NOTREACHED*/ 4247421Sroot run: 4257421Sroot /* 4267421Sroot * Raise priority to at least PUSER. 4277421Sroot */ 4287421Sroot if (p->p_pri > PUSER) 4297421Sroot if ((p != u.u_procp || noproc) && p->p_stat == SRUN && 4307421Sroot (p->p_flag & SLOAD)) { 4317421Sroot remrq(p); 4327421Sroot p->p_pri = PUSER; 4337421Sroot setrq(p); 4347421Sroot } else 4357421Sroot p->p_pri = PUSER; 4367421Sroot setrun(p); 4377421Sroot out: 4387421Sroot splx(s); 4397421Sroot } 4407421Sroot 4417421Sroot /* 4427421Sroot * Returns true if the current 4437421Sroot * process has a signal to process. 4447421Sroot * The signal to process is put in p_cursig. 4457421Sroot * This is asked at least once each time a process enters the 4467421Sroot * system (though this can usually be done without actually 4477421Sroot * calling issig by checking the pending signal masks.) 4487421Sroot * A signal does not do anything 4497421Sroot * directly to a process; it sets 4507421Sroot * a flag that asks the process to 4517421Sroot * do something to itself. 4527421Sroot */ 4537421Sroot issig() 4547421Sroot { 4557421Sroot register struct proc *p; 4567421Sroot register int sig; 457*12882Ssam int sigbits, sigmask; 4587421Sroot 4597421Sroot p = u.u_procp; 4607421Sroot for (;;) { 4617421Sroot sigbits = p->p_sig; 4627421Sroot if ((p->p_flag&STRC) == 0) 463*12882Ssam sigbits &= ~(p->p_sigignore | p->p_sigmask); 4647421Sroot if (p->p_flag&SVFORK) 4657421Sroot #define bit(a) (1<<(a-1)) 4667421Sroot sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 4677421Sroot if (sigbits == 0) 4687421Sroot break; 469*12882Ssam sig = ffs(sigbits); 470*12882Ssam sigmask = 1 << (sig-1); 4717421Sroot p->p_sig &= ~sigmask; /* take the signal! */ 4727421Sroot p->p_cursig = sig; 473*12882Ssam if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) { 4747421Sroot /* 4757421Sroot * If traced, always stop, and stay 4767421Sroot * stopped until released by the parent. 4777421Sroot */ 4787421Sroot do { 4797421Sroot stop(p); 4807421Sroot swtch(); 4817421Sroot } while (!procxmt() && p->p_flag&STRC); 4827421Sroot 4837421Sroot /* 4847421Sroot * If the traced bit got turned off, 4857421Sroot * then put the signal taken above back into p_sig 4867421Sroot * and go back up to the top to rescan signals. 4877421Sroot * This ensures that siga0 and u_signal are consistent. 4887421Sroot */ 4897421Sroot if ((p->p_flag&STRC) == 0) { 4907421Sroot p->p_sig |= sigmask; 4917421Sroot continue; 4927421Sroot } 4937421Sroot 4947421Sroot /* 4957421Sroot * If parent wants us to take the signal, 4967421Sroot * then it will leave it in p->p_cursig; 4977421Sroot * otherwise we just look for signals again. 4987421Sroot */ 4997421Sroot sig = p->p_cursig; 5007421Sroot if (sig == 0) 5017421Sroot continue; 5027421Sroot } 5037421Sroot switch (u.u_signal[sig]) { 5047421Sroot 5057421Sroot case SIG_DFL: 5067421Sroot /* 5077421Sroot * Don't take default actions on system processes. 5087421Sroot */ 5097421Sroot if (p->p_ppid == 0) 5107421Sroot break; 5117421Sroot switch (sig) { 5127421Sroot 5137421Sroot case SIGTSTP: 5147421Sroot case SIGTTIN: 5157421Sroot case SIGTTOU: 5167421Sroot /* 5177421Sroot * Children of init aren't allowed to stop 5187421Sroot * on signals from the keyboard. 5197421Sroot */ 5207421Sroot if (p->p_pptr == &proc[1]) { 5217421Sroot psignal(p, SIGKILL); 5227421Sroot continue; 5237421Sroot } 5247421Sroot /* fall into ... */ 5257421Sroot 5267421Sroot case SIGSTOP: 5277421Sroot if (p->p_flag&STRC) 5287421Sroot continue; 5297421Sroot stop(p); 5307421Sroot swtch(); 5317421Sroot continue; 5327421Sroot 5337421Sroot case SIGCONT: 5347421Sroot case SIGCHLD: 535*12882Ssam case SIGURG: 5367421Sroot /* 5377421Sroot * These signals are normally not 5387421Sroot * sent if the action is the default. 5397421Sroot */ 5407421Sroot continue; /* == ignore */ 5417421Sroot 5427421Sroot default: 5437421Sroot goto send; 5447421Sroot } 5457421Sroot /*NOTREACHED*/ 5467421Sroot 5477421Sroot case SIG_HOLD: 5487421Sroot case SIG_IGN: 5497421Sroot /* 5507421Sroot * Masking above should prevent us 5517421Sroot * ever trying to take action on a held 5527421Sroot * or ignored signal, unless process is traced. 5537421Sroot */ 5547421Sroot if ((p->p_flag&STRC) == 0) 5557421Sroot printf("issig\n"); 5567421Sroot continue; 5577421Sroot 5587421Sroot default: 5597421Sroot /* 5607421Sroot * This signal has an action, let 5617421Sroot * psig process it. 5627421Sroot */ 5637421Sroot goto send; 5647421Sroot } 5657421Sroot /*NOTREACHED*/ 5667421Sroot } 5677421Sroot /* 5687421Sroot * Didn't find a signal to send. 5697421Sroot */ 5707421Sroot p->p_cursig = 0; 5717421Sroot return (0); 5727421Sroot 5737421Sroot send: 5747421Sroot /* 5757421Sroot * Let psig process the signal. 5767421Sroot */ 5777421Sroot return (sig); 5787421Sroot } 5797421Sroot 5807421Sroot /* 5817421Sroot * Put the argument process into the stopped 5827421Sroot * state and notify the parent via wakeup and/or signal. 5837421Sroot */ 5847421Sroot stop(p) 5857421Sroot register struct proc *p; 5867421Sroot { 5877421Sroot 5887421Sroot p->p_stat = SSTOP; 5897421Sroot p->p_flag &= ~SWTED; 5907421Sroot wakeup((caddr_t)p->p_pptr); 5917421Sroot /* 5927421Sroot * Avoid sending signal to parent if process is traced 5937421Sroot */ 5947421Sroot if (p->p_flag&STRC) 5957421Sroot return; 5967421Sroot psignal(p->p_pptr, SIGCHLD); 5977421Sroot } 5987421Sroot 5997421Sroot /* 6007421Sroot * Perform the action specified by 6017421Sroot * the current signal. 6027421Sroot * The usual sequence is: 6037421Sroot * if (issig()) 6047421Sroot * psig(); 6057421Sroot * The signal bit has already been cleared by issig, 6067421Sroot * and the current signal number stored in p->p_cursig. 6077421Sroot */ 6087421Sroot psig() 6097421Sroot { 610*12882Ssam register struct proc *p = u.u_procp; 611*12882Ssam register int sig = p->p_cursig; 612*12882Ssam int sigmask = 1 << (sig - 1), returnmask; 6137421Sroot register int (*action)(); 6147421Sroot 615*12882Ssam if (sig == 0) 6167421Sroot panic("psig"); 617*12882Ssam action = u.u_signal[sig]; 6187421Sroot if (action != SIG_DFL) { 619*12882Ssam if (action == SIG_IGN || (p->p_sigmask & sigmask)) 6207421Sroot panic("psig action"); 6217421Sroot u.u_error = 0; 6227421Sroot /* 623*12882Ssam * Set the new mask value and also defer further 624*12882Ssam * occurences of this signal (unless we're simulating 625*12882Ssam * the old signal facilities). 626*12882Ssam * 627*12882Ssam * Special case: user has done a sigpause. Here the 628*12882Ssam * current mask is not of interest, but rather the 629*12882Ssam * mask from before the sigpause is what we want restored 630*12882Ssam * after the signal processing is completed. 6317421Sroot */ 632*12882Ssam (void) spl6(); 633*12882Ssam if (p->p_flag & SOUSIG) { 634*12882Ssam if (sig != SIGILL && sig != SIGTRAP) { 635*12882Ssam u.u_signal[sig] = SIG_DFL; 636*12882Ssam p->p_sigcatch &= ~sigmask; 637*12882Ssam } 638*12882Ssam sigmask = 0; 6397421Sroot } 640*12882Ssam if (p->p_flag & SOMASK) { 641*12882Ssam returnmask = u.u_oldmask; 642*12882Ssam p->p_flag &= ~SOMASK; 643*12882Ssam } else 644*12882Ssam returnmask = p->p_sigmask; 645*12882Ssam p->p_sigmask = u.u_sigmask[sig] | sigmask; 646*12882Ssam (void) spl0(); 6478032Sroot u.u_ru.ru_nsignals++; 648*12882Ssam sendsig(action, sig, returnmask); 649*12882Ssam p->p_cursig = 0; 6507421Sroot return; 6517421Sroot } 6527421Sroot u.u_acflag |= AXSIG; 653*12882Ssam switch (sig) { 6547421Sroot 6557421Sroot case SIGILL: 6567421Sroot case SIGIOT: 6577421Sroot case SIGBUS: 6587421Sroot case SIGQUIT: 6597421Sroot case SIGTRAP: 6607421Sroot case SIGEMT: 6617421Sroot case SIGFPE: 6627421Sroot case SIGSEGV: 6637421Sroot case SIGSYS: 664*12882Ssam u.u_arg[0] = sig; 6657421Sroot if (core()) 666*12882Ssam sig += 0200; 6677421Sroot } 668*12882Ssam exit(sig); 6697421Sroot } 6707421Sroot 6717421Sroot /* 6727421Sroot * Create a core image on the file "core" 6737421Sroot * If you are looking for protection glitches, 6747421Sroot * there are probably a wealth of them here 6757421Sroot * when this occurs to a suid command. 6767421Sroot * 6777421Sroot * It writes UPAGES block of the 6787421Sroot * user.h area followed by the entire 6797421Sroot * data+stack segments. 6807421Sroot */ 6817421Sroot core() 6827421Sroot { 6837421Sroot register struct inode *ip; 6847421Sroot extern schar(); 6857421Sroot 68612639Ssam if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid) 6877818Sroot return (0); 6888032Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= 6898032Sroot u.u_rlimit[RLIMIT_CORE].rlim_cur) 6907421Sroot return (0); 6917421Sroot u.u_error = 0; 6927421Sroot u.u_dirp = "core"; 6939160Ssam ip = namei(schar, CREATE, 1); 6947421Sroot if (ip == NULL) { 6957421Sroot if (u.u_error) 6967421Sroot return (0); 69712639Ssam ip = maknode(0644); 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 } 7079160Ssam itrunc(ip, (u_long)0); 7087818Sroot u.u_acflag |= ACORE; 709*12882Ssam u.u_error = rdwri(UIO_WRITE, ip, 710*12882Ssam (caddr_t)&u, 711*12882Ssam ctob(UPAGES), 712*12882Ssam 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