1*18336Smckusick /* kern_sig.c 6.13 85/03/13 */ 27421Sroot 39755Ssam #include "../machine/reg.h" 49755Ssam #include "../machine/pte.h" 59755Ssam #include "../machine/psl.h" 69755Ssam 717092Sbloom #include "param.h" 817092Sbloom #include "systm.h" 917092Sbloom #include "dir.h" 1017092Sbloom #include "user.h" 1117092Sbloom #include "inode.h" 1217092Sbloom #include "proc.h" 1317092Sbloom #include "timeb.h" 1417092Sbloom #include "times.h" 1517092Sbloom #include "conf.h" 1617092Sbloom #include "buf.h" 1717092Sbloom #include "mount.h" 1817092Sbloom #include "text.h" 1917092Sbloom #include "seg.h" 2017092Sbloom #include "vm.h" 2117092Sbloom #include "acct.h" 2217092Sbloom #include "uio.h" 2317092Sbloom #include "kernel.h" 247421Sroot 2517153Sbloom #define cantmask (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)) 2612951Ssam 2717013Smckusick /* 2817013Smckusick * Generalized interface signal handler. 2917013Smckusick */ 307499Sroot sigvec() 317421Sroot { 3212951Ssam register struct a { 3312882Ssam int signo; 3412951Ssam struct sigvec *nsv; 3512951Ssam struct sigvec *osv; 3612882Ssam } *uap = (struct a *)u.u_ap; 3712951Ssam struct sigvec vec; 3812951Ssam register struct sigvec *sv; 3912882Ssam register int sig; 4018308Smckusick int bit; 417421Sroot 4212882Ssam sig = uap->signo; 4312951Ssam if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) { 4412882Ssam u.u_error = EINVAL; 4512882Ssam return; 4612882Ssam } 4712951Ssam sv = &vec; 4812951Ssam if (uap->osv) { 4912951Ssam sv->sv_handler = u.u_signal[sig]; 5012951Ssam sv->sv_mask = u.u_sigmask[sig]; 5118308Smckusick bit = sigmask(sig); 5218308Smckusick sv->sv_flags = 0; 5318308Smckusick if ((u.u_sigonstack & bit) != 0) 5418308Smckusick sv->sv_flags |= SV_ONSTACK; 5518308Smckusick if ((u.u_sigintr & bit) != 0) 5618308Smckusick sv->sv_flags |= SV_INTERRUPT; 5712951Ssam u.u_error = 5812951Ssam copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 5912951Ssam if (u.u_error) 6012951Ssam return; 6112951Ssam } 6212951Ssam if (uap->nsv) { 6312951Ssam u.u_error = 6412951Ssam copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 6512951Ssam if (u.u_error) 6612951Ssam return; 6712951Ssam if (sig == SIGCONT && sv->sv_handler == SIG_IGN) { 6812951Ssam u.u_error = EINVAL; 6912951Ssam return; 7012951Ssam } 7112951Ssam setsigvec(sig, sv); 7212951Ssam } 737421Sroot } 747421Sroot 7512951Ssam setsigvec(sig, sv) 7612951Ssam int sig; 7712951Ssam register struct sigvec *sv; 7812882Ssam { 7912882Ssam register struct proc *p; 8012951Ssam register int bit; 8112882Ssam 8217153Sbloom bit = sigmask(sig); 8312882Ssam p = u.u_procp; 8412882Ssam /* 8512882Ssam * Change setting atomically. 8612882Ssam */ 8717153Sbloom (void) splhigh(); 8812951Ssam u.u_signal[sig] = sv->sv_handler; 8912951Ssam u.u_sigmask[sig] = sv->sv_mask &~ cantmask; 9018308Smckusick if (sv->sv_flags & SV_INTERRUPT) 9118308Smckusick u.u_sigintr |= bit; 9218308Smckusick else 9318308Smckusick u.u_sigintr &= ~bit; 9418308Smckusick if (sv->sv_flags & SV_ONSTACK) 9512951Ssam u.u_sigonstack |= bit; 9612951Ssam else 9712951Ssam u.u_sigonstack &= ~bit; 9812951Ssam if (sv->sv_handler == SIG_IGN) { 9912951Ssam p->p_sig &= ~bit; /* never to be seen again */ 10012951Ssam p->p_sigignore |= bit; 10112951Ssam p->p_sigcatch &= ~bit; 10212882Ssam } else { 10312951Ssam p->p_sigignore &= ~bit; 10412951Ssam if (sv->sv_handler == SIG_DFL) 10512951Ssam p->p_sigcatch &= ~bit; 10612882Ssam else 10712951Ssam p->p_sigcatch |= bit; 10812882Ssam } 10912882Ssam (void) spl0(); 11012882Ssam } 11112882Ssam 1127499Sroot sigblock() 1137421Sroot { 11412882Ssam struct a { 11517153Sbloom int mask; 11612882Ssam } *uap = (struct a *)u.u_ap; 11712951Ssam register struct proc *p = u.u_procp; 1187499Sroot 11917153Sbloom (void) splhigh(); 12012882Ssam u.u_r.r_val1 = p->p_sigmask; 12117153Sbloom p->p_sigmask |= uap->mask &~ cantmask; 12212882Ssam (void) spl0(); 1237499Sroot } 1247499Sroot 1257499Sroot sigsetmask() 1267499Sroot { 12712882Ssam struct a { 12817153Sbloom int mask; 12912882Ssam } *uap = (struct a *)u.u_ap; 13012882Ssam register struct proc *p = u.u_procp; 1317499Sroot 13217153Sbloom (void) splhigh(); 13312882Ssam u.u_r.r_val1 = p->p_sigmask; 13417153Sbloom p->p_sigmask = uap->mask &~ cantmask; 13512882Ssam (void) spl0(); 1367499Sroot } 1377499Sroot 1387499Sroot sigpause() 1397499Sroot { 14012882Ssam struct a { 14117153Sbloom int mask; 14212882Ssam } *uap = (struct a *)u.u_ap; 14312882Ssam register struct proc *p = u.u_procp; 1447499Sroot 14512882Ssam /* 14612882Ssam * When returning from sigpause, we want 14712882Ssam * the old mask to be restored after the 14812882Ssam * signal handler has finished. Thus, we 14912882Ssam * save it here and mark the proc structure 15012882Ssam * to indicate this (should be in u.). 15112882Ssam */ 15212882Ssam u.u_oldmask = p->p_sigmask; 15312882Ssam p->p_flag |= SOMASK; 15417153Sbloom p->p_sigmask = uap->mask &~ cantmask; 15512882Ssam for (;;) 15612882Ssam sleep((caddr_t)&u, PSLEP); 15712882Ssam /*NOTREACHED*/ 1587499Sroot } 15912951Ssam #undef cantmask 1607499Sroot 1617499Sroot sigstack() 1627499Sroot { 16312951Ssam register struct a { 16412951Ssam struct sigstack *nss; 16512951Ssam struct sigstack *oss; 16612882Ssam } *uap = (struct a *)u.u_ap; 16712951Ssam struct sigstack ss; 1687499Sroot 16912951Ssam if (uap->oss) { 17012951Ssam u.u_error = copyout((caddr_t)&u.u_sigstack, (caddr_t)uap->oss, 17112951Ssam sizeof (struct sigstack)); 17212951Ssam if (u.u_error) 17312951Ssam return; 17412951Ssam } 17512951Ssam if (uap->nss) { 17612951Ssam u.u_error = 17712951Ssam copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss)); 17812951Ssam if (u.u_error == 0) 17912951Ssam u.u_sigstack = ss; 18012951Ssam } 1817499Sroot } 1827499Sroot 1838032Sroot kill() 1848032Sroot { 18512882Ssam register struct a { 18612882Ssam int pid; 18712882Ssam int signo; 18812882Ssam } *uap = (struct a *)u.u_ap; 189*18336Smckusick register struct proc *p; 1908032Sroot 191*18336Smckusick if (uap->signo < 0 || uap->signo > NSIG) { 192*18336Smckusick u.u_error = EINVAL; 193*18336Smckusick return; 194*18336Smckusick } 195*18336Smckusick if (uap->pid > 0) { 196*18336Smckusick /* kill single process */ 197*18336Smckusick p = pfind(uap->pid); 198*18336Smckusick if (p == 0) { 199*18336Smckusick u.u_error = ESRCH; 200*18336Smckusick return; 201*18336Smckusick } 202*18336Smckusick if (u.u_uid && u.u_uid != p->p_uid) 203*18336Smckusick u.u_error = EPERM; 204*18336Smckusick else if (uap->signo) 205*18336Smckusick psignal(p, uap->signo); 206*18336Smckusick return; 207*18336Smckusick } 208*18336Smckusick switch (uap->pid) { 209*18336Smckusick case -1: /* broadcast signal */ 210*18336Smckusick if (suser()) 211*18336Smckusick u.u_error = killpg1(uap->signo, 0, 1); 212*18336Smckusick break; 213*18336Smckusick case 0: /* signal own process group */ 214*18336Smckusick u.u_error = killpg1(uap->signo, 0, 0); 215*18336Smckusick break; 216*18336Smckusick default: /* negative explicit process group */ 217*18336Smckusick u.u_error = killpg1(uap->signo, -uap->pid, 0); 218*18336Smckusick break; 219*18336Smckusick } 220*18336Smckusick return; 2218032Sroot } 2228032Sroot 2238032Sroot killpg() 2248032Sroot { 2259989Ssam register struct a { 2269989Ssam int pgrp; 2279989Ssam int signo; 2289989Ssam } *uap = (struct a *)u.u_ap; 2298032Sroot 230*18336Smckusick if (uap->signo < 0 || uap->signo > NSIG) { 231*18336Smckusick u.u_error = EINVAL; 232*18336Smckusick return; 233*18336Smckusick } 234*18336Smckusick u.u_error = killpg1(uap->signo, uap->pgrp, 0); 2358032Sroot } 2368032Sroot 23712882Ssam /* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ 23812882Ssam 239*18336Smckusick killpg1(signo, pgrp, all) 240*18336Smckusick int signo, pgrp, all; 2419989Ssam { 2429989Ssam register struct proc *p; 243*18336Smckusick int f, error = 0; 2449989Ssam 245*18336Smckusick if (!all && pgrp == 0) { 2467421Sroot /* 2477421Sroot * Zero process id means send to my process group. 2487421Sroot */ 249*18336Smckusick pgrp = u.u_procp->p_pgrp; 250*18336Smckusick if (pgrp == 0) 2519989Ssam return (EINVAL); 2527421Sroot } 25316531Skarels for (f = 0, p = allproc; p != NULL; p = p->p_nxt) { 254*18336Smckusick if ((p->p_pgrp != pgrp && !all) || p->p_ppid == 0 || 255*18336Smckusick (p->p_flag&SSYS) || (all && p == u.u_procp)) 2567421Sroot continue; 257*18336Smckusick f++; 2587421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 259*18336Smckusick (signo != SIGCONT || !inferior(p))) { 260*18336Smckusick error = EPERM; 2617421Sroot continue; 262*18336Smckusick } 26312835Ssam if (signo) 26412835Ssam psignal(p, signo); 2657421Sroot } 266*18336Smckusick return (f == 0 ? ESRCH : error); 2677421Sroot } 2687421Sroot 2697421Sroot /* 2707421Sroot * Send the specified signal to 2717421Sroot * all processes with 'pgrp' as 2727421Sroot * process group. 2737421Sroot */ 2747421Sroot gsignal(pgrp, sig) 2757421Sroot register int pgrp; 2767421Sroot { 2777421Sroot register struct proc *p; 2787421Sroot 2797421Sroot if (pgrp == 0) 2807421Sroot return; 28116531Skarels for (p = allproc; p != NULL; p = p->p_nxt) 2827421Sroot if (p->p_pgrp == pgrp) 2837421Sroot psignal(p, sig); 2847421Sroot } 2857421Sroot 2867421Sroot /* 2877421Sroot * Send the specified signal to 2887421Sroot * the specified process. 2897421Sroot */ 2907421Sroot psignal(p, sig) 2917421Sroot register struct proc *p; 2927421Sroot register int sig; 2937421Sroot { 2947421Sroot register int s; 2957421Sroot register int (*action)(); 29617153Sbloom int mask; 2977421Sroot 2987421Sroot if ((unsigned)sig >= NSIG) 2997421Sroot return; 30017153Sbloom mask = sigmask(sig); 3017421Sroot 3027421Sroot /* 3037421Sroot * If proc is traced, always give parent a chance. 3047421Sroot */ 3057421Sroot if (p->p_flag & STRC) 3067421Sroot action = SIG_DFL; 3077421Sroot else { 3087421Sroot /* 30912882Ssam * If the signal is being ignored, 31012882Ssam * then we forget about it immediately. 3117421Sroot */ 31217153Sbloom if (p->p_sigignore & mask) 3137421Sroot return; 31417153Sbloom if (p->p_sigmask & mask) 31512882Ssam action = SIG_HOLD; 31617153Sbloom else if (p->p_sigcatch & mask) 31712882Ssam action = SIG_CATCH; 31812882Ssam else 31912882Ssam action = SIG_DFL; 3207421Sroot } 32117153Sbloom #define stops (sigmask(SIGSTOP)|sigmask(SIGTSTP)| \ 32217153Sbloom sigmask(SIGTTIN)|sigmask(SIGTTOU)) 3237421Sroot if (sig) { 32417153Sbloom p->p_sig |= mask; 3257421Sroot switch (sig) { 3267421Sroot 3277421Sroot case SIGTERM: 32812882Ssam if ((p->p_flag&STRC) || action != SIG_DFL) 3297421Sroot break; 3307421Sroot /* fall into ... */ 3317421Sroot 3327421Sroot case SIGKILL: 3337421Sroot if (p->p_nice > NZERO) 3347421Sroot p->p_nice = NZERO; 3357421Sroot break; 3367421Sroot 3377421Sroot case SIGCONT: 3387421Sroot p->p_sig &= ~stops; 3397421Sroot break; 3407421Sroot 3417421Sroot case SIGSTOP: 3427421Sroot case SIGTSTP: 3437421Sroot case SIGTTIN: 3447421Sroot case SIGTTOU: 34517153Sbloom p->p_sig &= ~sigmask(SIGCONT); 3467421Sroot break; 3477421Sroot } 3487421Sroot } 3497421Sroot #undef stops 3507421Sroot /* 3517421Sroot * Defer further processing for signals which are held. 3527421Sroot */ 3537421Sroot if (action == SIG_HOLD) 3547421Sroot return; 35517153Sbloom s = splhigh(); 3567421Sroot switch (p->p_stat) { 3577421Sroot 3587421Sroot case SSLEEP: 3597421Sroot /* 3607421Sroot * If process is sleeping at negative priority 3617421Sroot * we can't interrupt the sleep... the signal will 3627421Sroot * be noticed when the process returns through 3637421Sroot * trap() or syscall(). 3647421Sroot */ 3657421Sroot if (p->p_pri <= PZERO) 3667421Sroot goto out; 3677421Sroot /* 3687421Sroot * Process is sleeping and traced... make it runnable 3697421Sroot * so it can discover the signal in issig() and stop 3707421Sroot * for the parent. 3717421Sroot */ 3727421Sroot if (p->p_flag&STRC) 3737421Sroot goto run; 3747421Sroot switch (sig) { 3757421Sroot 3767421Sroot case SIGSTOP: 3777421Sroot case SIGTSTP: 3787421Sroot case SIGTTIN: 3797421Sroot case SIGTTOU: 3807421Sroot /* 3817421Sroot * These are the signals which by default 3827421Sroot * stop a process. 3837421Sroot */ 3847421Sroot if (action != SIG_DFL) 3857421Sroot goto run; 3867421Sroot /* 3877421Sroot * Don't clog system with children of init 3887421Sroot * stopped from the keyboard. 3897421Sroot */ 3907421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 3917421Sroot psignal(p, SIGKILL); 39217153Sbloom p->p_sig &= ~mask; 3937421Sroot splx(s); 3947421Sroot return; 3957421Sroot } 3967421Sroot /* 3977421Sroot * If a child in vfork(), stopping could 3987421Sroot * cause deadlock. 3997421Sroot */ 4007421Sroot if (p->p_flag&SVFORK) 4017421Sroot goto out; 40217153Sbloom p->p_sig &= ~mask; 4037421Sroot p->p_cursig = sig; 40418331Skarels psignal(p->p_pptr, SIGCHLD); 4057421Sroot stop(p); 4067421Sroot goto out; 4077421Sroot 4087421Sroot case SIGIO: 4097421Sroot case SIGURG: 4107421Sroot case SIGCHLD: 41117597Sbloom case SIGWINCH: 4127421Sroot /* 4137421Sroot * These signals are special in that they 4147421Sroot * don't get propogated... if the process 4157421Sroot * isn't interested, forget it. 4167421Sroot */ 4177421Sroot if (action != SIG_DFL) 4187421Sroot goto run; 41917153Sbloom p->p_sig &= ~mask; /* take it away */ 4207421Sroot goto out; 4217421Sroot 4227421Sroot default: 4237421Sroot /* 4247421Sroot * All other signals cause the process to run 4257421Sroot */ 4267421Sroot goto run; 4277421Sroot } 4287421Sroot /*NOTREACHED*/ 4297421Sroot 4307421Sroot case SSTOP: 4317421Sroot /* 4327421Sroot * If traced process is already stopped, 4337421Sroot * then no further action is necessary. 4347421Sroot */ 4357421Sroot if (p->p_flag&STRC) 4367421Sroot goto out; 4377421Sroot switch (sig) { 4387421Sroot 4397421Sroot case SIGKILL: 4407421Sroot /* 4417421Sroot * Kill signal always sets processes running. 4427421Sroot */ 4437421Sroot goto run; 4447421Sroot 4457421Sroot case SIGCONT: 4467421Sroot /* 4477421Sroot * If the process catches SIGCONT, let it handle 4487421Sroot * the signal itself. If it isn't waiting on 4497421Sroot * an event, then it goes back to run state. 4507421Sroot * Otherwise, process goes back to sleep state. 4517421Sroot */ 4527421Sroot if (action != SIG_DFL || p->p_wchan == 0) 4537421Sroot goto run; 4547421Sroot p->p_stat = SSLEEP; 4557421Sroot goto out; 4567421Sroot 4577421Sroot case SIGSTOP: 4587421Sroot case SIGTSTP: 4597421Sroot case SIGTTIN: 4607421Sroot case SIGTTOU: 4617421Sroot /* 4627421Sroot * Already stopped, don't need to stop again. 4637421Sroot * (If we did the shell could get confused.) 4647421Sroot */ 46517153Sbloom p->p_sig &= ~mask; /* take it away */ 4667421Sroot goto out; 4677421Sroot 4687421Sroot default: 4697421Sroot /* 4707421Sroot * If process is sleeping interruptibly, then 4717421Sroot * unstick it so that when it is continued 4727421Sroot * it can look at the signal. 4737421Sroot * But don't setrun the process as its not to 4747421Sroot * be unstopped by the signal alone. 4757421Sroot */ 4767421Sroot if (p->p_wchan && p->p_pri > PZERO) 4777421Sroot unsleep(p); 4787421Sroot goto out; 4797421Sroot } 4807421Sroot /*NOTREACHED*/ 4817421Sroot 4827421Sroot default: 4837421Sroot /* 4847421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 4857421Sroot * other than kicking ourselves if we are running. 4867421Sroot * It will either never be noticed, or noticed very soon. 4877421Sroot */ 4887421Sroot if (p == u.u_procp && !noproc) 4898444Sroot #include "../vax/mtpr.h" 4907421Sroot aston(); 4917421Sroot goto out; 4927421Sroot } 4937421Sroot /*NOTREACHED*/ 4947421Sroot run: 4957421Sroot /* 4967421Sroot * Raise priority to at least PUSER. 4977421Sroot */ 4987421Sroot if (p->p_pri > PUSER) 49917399Skarels p->p_pri = PUSER; 5007421Sroot setrun(p); 5017421Sroot out: 5027421Sroot splx(s); 5037421Sroot } 5047421Sroot 5057421Sroot /* 5067421Sroot * Returns true if the current 5077421Sroot * process has a signal to process. 5087421Sroot * The signal to process is put in p_cursig. 5097421Sroot * This is asked at least once each time a process enters the 5107421Sroot * system (though this can usually be done without actually 5117421Sroot * calling issig by checking the pending signal masks.) 5127421Sroot * A signal does not do anything 5137421Sroot * directly to a process; it sets 5147421Sroot * a flag that asks the process to 5157421Sroot * do something to itself. 5167421Sroot */ 5177421Sroot issig() 5187421Sroot { 5197421Sroot register struct proc *p; 5207421Sroot register int sig; 52117153Sbloom int sigbits, mask; 5227421Sroot 5237421Sroot p = u.u_procp; 5247421Sroot for (;;) { 52514782Ssam sigbits = p->p_sig &~ p->p_sigmask; 5267421Sroot if ((p->p_flag&STRC) == 0) 52714782Ssam sigbits &= ~p->p_sigignore; 5287421Sroot if (p->p_flag&SVFORK) 5297421Sroot #define bit(a) (1<<(a-1)) 5307421Sroot sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 5317421Sroot if (sigbits == 0) 5327421Sroot break; 53312882Ssam sig = ffs(sigbits); 53417153Sbloom mask = sigmask(sig); 53517153Sbloom p->p_sig &= ~mask; /* take the signal! */ 5367421Sroot p->p_cursig = sig; 53712882Ssam if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) { 5387421Sroot /* 5397421Sroot * If traced, always stop, and stay 5407421Sroot * stopped until released by the parent. 5417421Sroot */ 54218331Skarels psignal(p->p_pptr, SIGCHLD); 5437421Sroot do { 5447421Sroot stop(p); 5457421Sroot swtch(); 5467421Sroot } while (!procxmt() && p->p_flag&STRC); 5477421Sroot 5487421Sroot /* 54914782Ssam * If the traced bit got turned off, 55014782Ssam * then put the signal taken above back into p_sig 55114782Ssam * and go back up to the top to rescan signals. 55214782Ssam * This ensures that p_sig* and u_signal are consistent. 5537421Sroot */ 55414782Ssam if ((p->p_flag&STRC) == 0) { 55517153Sbloom p->p_sig |= mask; 5567421Sroot continue; 5577421Sroot } 5587421Sroot 5597421Sroot /* 5607421Sroot * If parent wants us to take the signal, 5617421Sroot * then it will leave it in p->p_cursig; 5627421Sroot * otherwise we just look for signals again. 5637421Sroot */ 5647421Sroot sig = p->p_cursig; 5657421Sroot if (sig == 0) 5667421Sroot continue; 56714782Ssam 56814782Ssam /* 56914782Ssam * If signal is being masked put it back 57014782Ssam * into p_sig and look for other signals. 57114782Ssam */ 57217153Sbloom mask = sigmask(sig); 57317153Sbloom if (p->p_sigmask & mask) { 57417153Sbloom p->p_sig |= mask; 57514782Ssam continue; 57614782Ssam } 5777421Sroot } 5787421Sroot switch (u.u_signal[sig]) { 5797421Sroot 5807421Sroot case SIG_DFL: 5817421Sroot /* 5827421Sroot * Don't take default actions on system processes. 5837421Sroot */ 5847421Sroot if (p->p_ppid == 0) 5857421Sroot break; 5867421Sroot switch (sig) { 5877421Sroot 5887421Sroot case SIGTSTP: 5897421Sroot case SIGTTIN: 5907421Sroot case SIGTTOU: 5917421Sroot /* 5927421Sroot * Children of init aren't allowed to stop 5937421Sroot * on signals from the keyboard. 5947421Sroot */ 5957421Sroot if (p->p_pptr == &proc[1]) { 5967421Sroot psignal(p, SIGKILL); 5977421Sroot continue; 5987421Sroot } 5997421Sroot /* fall into ... */ 6007421Sroot 6017421Sroot case SIGSTOP: 6027421Sroot if (p->p_flag&STRC) 6037421Sroot continue; 60418331Skarels psignal(p->p_pptr, SIGCHLD); 6057421Sroot stop(p); 6067421Sroot swtch(); 6077421Sroot continue; 6087421Sroot 6097421Sroot case SIGCONT: 6107421Sroot case SIGCHLD: 61112882Ssam case SIGURG: 61212951Ssam case SIGIO: 61317597Sbloom case SIGWINCH: 6147421Sroot /* 6157421Sroot * These signals are normally not 6167421Sroot * sent if the action is the default. 6177421Sroot */ 6187421Sroot continue; /* == ignore */ 6197421Sroot 6207421Sroot default: 6217421Sroot goto send; 6227421Sroot } 6237421Sroot /*NOTREACHED*/ 6247421Sroot 6257421Sroot case SIG_HOLD: 6267421Sroot case SIG_IGN: 6277421Sroot /* 6287421Sroot * Masking above should prevent us 6297421Sroot * ever trying to take action on a held 6307421Sroot * or ignored signal, unless process is traced. 6317421Sroot */ 6327421Sroot if ((p->p_flag&STRC) == 0) 6337421Sroot printf("issig\n"); 6347421Sroot continue; 6357421Sroot 6367421Sroot default: 6377421Sroot /* 6387421Sroot * This signal has an action, let 6397421Sroot * psig process it. 6407421Sroot */ 6417421Sroot goto send; 6427421Sroot } 6437421Sroot /*NOTREACHED*/ 6447421Sroot } 6457421Sroot /* 6467421Sroot * Didn't find a signal to send. 6477421Sroot */ 6487421Sroot p->p_cursig = 0; 6497421Sroot return (0); 6507421Sroot 6517421Sroot send: 6527421Sroot /* 6537421Sroot * Let psig process the signal. 6547421Sroot */ 6557421Sroot return (sig); 6567421Sroot } 6577421Sroot 6587421Sroot /* 6597421Sroot * Put the argument process into the stopped 66018331Skarels * state and notify the parent via wakeup. 66118331Skarels * Signals are handled elsewhere. 6627421Sroot */ 6637421Sroot stop(p) 6647421Sroot register struct proc *p; 6657421Sroot { 6667421Sroot 6677421Sroot p->p_stat = SSTOP; 6687421Sroot p->p_flag &= ~SWTED; 6697421Sroot wakeup((caddr_t)p->p_pptr); 6707421Sroot } 6717421Sroot 6727421Sroot /* 6737421Sroot * Perform the action specified by 6747421Sroot * the current signal. 6757421Sroot * The usual sequence is: 6767421Sroot * if (issig()) 6777421Sroot * psig(); 6787421Sroot * The signal bit has already been cleared by issig, 6797421Sroot * and the current signal number stored in p->p_cursig. 6807421Sroot */ 6817421Sroot psig() 6827421Sroot { 68312882Ssam register struct proc *p = u.u_procp; 68412882Ssam register int sig = p->p_cursig; 68517153Sbloom int mask = sigmask(sig), returnmask; 6867421Sroot register int (*action)(); 6877421Sroot 68812882Ssam if (sig == 0) 6897421Sroot panic("psig"); 69012882Ssam action = u.u_signal[sig]; 6917421Sroot if (action != SIG_DFL) { 69217153Sbloom if (action == SIG_IGN || (p->p_sigmask & mask)) 6937421Sroot panic("psig action"); 6947421Sroot u.u_error = 0; 6957421Sroot /* 69612882Ssam * Set the new mask value and also defer further 69712882Ssam * occurences of this signal (unless we're simulating 69812882Ssam * the old signal facilities). 69912882Ssam * 70012882Ssam * Special case: user has done a sigpause. Here the 70112882Ssam * current mask is not of interest, but rather the 70212882Ssam * mask from before the sigpause is what we want restored 70312882Ssam * after the signal processing is completed. 7047421Sroot */ 70517153Sbloom (void) splhigh(); 70612882Ssam if (p->p_flag & SOUSIG) { 70712882Ssam if (sig != SIGILL && sig != SIGTRAP) { 70812882Ssam u.u_signal[sig] = SIG_DFL; 70917153Sbloom p->p_sigcatch &= ~mask; 71012882Ssam } 71117153Sbloom mask = 0; 7127421Sroot } 71312882Ssam if (p->p_flag & SOMASK) { 71412882Ssam returnmask = u.u_oldmask; 71512882Ssam p->p_flag &= ~SOMASK; 71612882Ssam } else 71712882Ssam returnmask = p->p_sigmask; 71817153Sbloom p->p_sigmask |= u.u_sigmask[sig] | mask; 71912882Ssam (void) spl0(); 7208032Sroot u.u_ru.ru_nsignals++; 72112882Ssam sendsig(action, sig, returnmask); 72212882Ssam p->p_cursig = 0; 7237421Sroot return; 7247421Sroot } 7257421Sroot u.u_acflag |= AXSIG; 72612882Ssam switch (sig) { 7277421Sroot 7287421Sroot case SIGILL: 7297421Sroot case SIGIOT: 7307421Sroot case SIGBUS: 7317421Sroot case SIGQUIT: 7327421Sroot case SIGTRAP: 7337421Sroot case SIGEMT: 7347421Sroot case SIGFPE: 7357421Sroot case SIGSEGV: 7367421Sroot case SIGSYS: 73712882Ssam u.u_arg[0] = sig; 7387421Sroot if (core()) 73912882Ssam sig += 0200; 7407421Sroot } 74112882Ssam exit(sig); 7427421Sroot } 7437421Sroot 7447421Sroot /* 7457421Sroot * Create a core image on the file "core" 7467421Sroot * If you are looking for protection glitches, 7477421Sroot * there are probably a wealth of them here 7487421Sroot * when this occurs to a suid command. 7497421Sroot * 7507421Sroot * It writes UPAGES block of the 7517421Sroot * user.h area followed by the entire 7527421Sroot * data+stack segments. 7537421Sroot */ 7547421Sroot core() 7557421Sroot { 7567421Sroot register struct inode *ip; 75716692Smckusick register struct nameidata *ndp = &u.u_nd; 7587421Sroot 75912639Ssam if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid) 7607818Sroot return (0); 7618032Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= 7628032Sroot u.u_rlimit[RLIMIT_CORE].rlim_cur) 7637421Sroot return (0); 7647421Sroot u.u_error = 0; 76516692Smckusick ndp->ni_nameiop = CREATE | FOLLOW; 76616692Smckusick ndp->ni_segflg = UIO_SYSSPACE; 76716692Smckusick ndp->ni_dirp = "core"; 76816692Smckusick ip = namei(ndp); 7697421Sroot if (ip == NULL) { 7707421Sroot if (u.u_error) 7717421Sroot return (0); 77216692Smckusick ip = maknode(0644, ndp); 7737421Sroot if (ip==NULL) 7747421Sroot return (0); 7757421Sroot } 7767818Sroot if (access(ip, IWRITE) || 7777818Sroot (ip->i_mode&IFMT) != IFREG || 7787818Sroot ip->i_nlink != 1) { 7797421Sroot u.u_error = EFAULT; 7807818Sroot goto out; 7817818Sroot } 7829160Ssam itrunc(ip, (u_long)0); 7837818Sroot u.u_acflag |= ACORE; 78412882Ssam u.u_error = rdwri(UIO_WRITE, ip, 78512882Ssam (caddr_t)&u, 78612882Ssam ctob(UPAGES), 78712882Ssam 0, 1, (int *)0); 7888101Sroot if (u.u_error == 0) 7898644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7908967Sroot (caddr_t)ctob(dptov(u.u_procp, 0)), 7918967Sroot ctob(u.u_dsize), 7928644Sroot ctob(UPAGES), 0, (int *)0); 7938101Sroot if (u.u_error == 0) 7948644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7958967Sroot (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)), 7968967Sroot ctob(u.u_ssize), 7978644Sroot ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0); 7987818Sroot out: 7997421Sroot iput(ip); 8007818Sroot return (u.u_error == 0); 8017421Sroot } 802