1*16692Smckusick /* kern_sig.c 6.4 84/07/08 */ 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" 247421Sroot 2512951Ssam #define mask(s) (1 << ((s)-1)) 2612951Ssam #define cantmask (mask(SIGKILL)|mask(SIGCONT)|mask(SIGSTOP)) 2712951Ssam 287499Sroot sigvec() 297421Sroot { 3012951Ssam register struct a { 3112882Ssam int signo; 3212951Ssam struct sigvec *nsv; 3312951Ssam struct sigvec *osv; 3412882Ssam } *uap = (struct a *)u.u_ap; 3512951Ssam struct sigvec vec; 3612951Ssam register struct sigvec *sv; 3712882Ssam register int sig; 387421Sroot 3912882Ssam sig = uap->signo; 4012951Ssam if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) { 4112882Ssam u.u_error = EINVAL; 4212882Ssam return; 4312882Ssam } 4412951Ssam sv = &vec; 4512951Ssam if (uap->osv) { 4612951Ssam sv->sv_handler = u.u_signal[sig]; 4712951Ssam sv->sv_mask = u.u_sigmask[sig]; 4812951Ssam sv->sv_onstack = (u.u_sigonstack & mask(sig)) != 0; 4912951Ssam u.u_error = 5012951Ssam copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 5112951Ssam if (u.u_error) 5212951Ssam return; 5312951Ssam } 5412951Ssam if (uap->nsv) { 5512951Ssam u.u_error = 5612951Ssam copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 5712951Ssam if (u.u_error) 5812951Ssam return; 5912951Ssam if (sig == SIGCONT && sv->sv_handler == SIG_IGN) { 6012951Ssam u.u_error = EINVAL; 6112951Ssam return; 6212951Ssam } 6312951Ssam setsigvec(sig, sv); 6412951Ssam } 657421Sroot } 667421Sroot 6712951Ssam setsigvec(sig, sv) 6812951Ssam int sig; 6912951Ssam register struct sigvec *sv; 7012882Ssam { 7112882Ssam register struct proc *p; 7212951Ssam register int bit; 7312882Ssam 7412951Ssam bit = mask(sig); 7512882Ssam p = u.u_procp; 7612882Ssam /* 7712882Ssam * Change setting atomically. 7812882Ssam */ 7912882Ssam (void) spl6(); 8012951Ssam u.u_signal[sig] = sv->sv_handler; 8112951Ssam u.u_sigmask[sig] = sv->sv_mask &~ cantmask; 8212951Ssam if (sv->sv_onstack) 8312951Ssam u.u_sigonstack |= bit; 8412951Ssam else 8512951Ssam u.u_sigonstack &= ~bit; 8612951Ssam if (sv->sv_handler == SIG_IGN) { 8712951Ssam p->p_sig &= ~bit; /* never to be seen again */ 8812951Ssam p->p_sigignore |= bit; 8912951Ssam p->p_sigcatch &= ~bit; 9012882Ssam } else { 9112951Ssam p->p_sigignore &= ~bit; 9212951Ssam if (sv->sv_handler == SIG_DFL) 9312951Ssam p->p_sigcatch &= ~bit; 9412882Ssam else 9512951Ssam p->p_sigcatch |= bit; 9612882Ssam } 9712882Ssam (void) spl0(); 9812882Ssam } 9912882Ssam 1007499Sroot sigblock() 1017421Sroot { 10212882Ssam struct a { 10312951Ssam int sigmask; 10412882Ssam } *uap = (struct a *)u.u_ap; 10512951Ssam register struct proc *p = u.u_procp; 1067499Sroot 10712882Ssam (void) spl6(); 10812882Ssam u.u_r.r_val1 = p->p_sigmask; 10912951Ssam p->p_sigmask |= uap->sigmask &~ cantmask; 11012882Ssam (void) spl0(); 1117499Sroot } 1127499Sroot 1137499Sroot sigsetmask() 1147499Sroot { 11512882Ssam struct a { 11612951Ssam int sigmask; 11712882Ssam } *uap = (struct a *)u.u_ap; 11812882Ssam register struct proc *p = u.u_procp; 1197499Sroot 12012882Ssam (void) spl6(); 12112882Ssam u.u_r.r_val1 = p->p_sigmask; 12212951Ssam p->p_sigmask = uap->sigmask &~ cantmask; 12312882Ssam (void) spl0(); 1247499Sroot } 1257499Sroot 1267499Sroot sigpause() 1277499Sroot { 12812882Ssam struct a { 12912951Ssam int sigmask; 13012882Ssam } *uap = (struct a *)u.u_ap; 13112882Ssam register struct proc *p = u.u_procp; 1327499Sroot 13312882Ssam /* 13412882Ssam * When returning from sigpause, we want 13512882Ssam * the old mask to be restored after the 13612882Ssam * signal handler has finished. Thus, we 13712882Ssam * save it here and mark the proc structure 13812882Ssam * to indicate this (should be in u.). 13912882Ssam */ 14012882Ssam u.u_oldmask = p->p_sigmask; 14112882Ssam p->p_flag |= SOMASK; 14212951Ssam p->p_sigmask = uap->sigmask &~ cantmask; 14312882Ssam for (;;) 14412882Ssam sleep((caddr_t)&u, PSLEP); 14512882Ssam /*NOTREACHED*/ 1467499Sroot } 14712951Ssam #undef cantmask 14812951Ssam #undef mask 1497499Sroot 1507499Sroot sigstack() 1517499Sroot { 15212951Ssam register struct a { 15312951Ssam struct sigstack *nss; 15412951Ssam struct sigstack *oss; 15512882Ssam } *uap = (struct a *)u.u_ap; 15612951Ssam struct sigstack ss; 1577499Sroot 15812951Ssam if (uap->oss) { 15912951Ssam u.u_error = copyout((caddr_t)&u.u_sigstack, (caddr_t)uap->oss, 16012951Ssam sizeof (struct sigstack)); 16112951Ssam if (u.u_error) 16212951Ssam return; 16312951Ssam } 16412951Ssam if (uap->nss) { 16512951Ssam u.u_error = 16612951Ssam copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss)); 16712951Ssam if (u.u_error == 0) 16812951Ssam u.u_sigstack = ss; 16912951Ssam } 1707499Sroot } 1717499Sroot 17213227Ssam /* KILL SHOULD BE UPDATED */ 17313227Ssam 1748032Sroot kill() 1758032Sroot { 17612882Ssam register struct a { 17712882Ssam int pid; 17812882Ssam int signo; 17912882Ssam } *uap = (struct a *)u.u_ap; 1808032Sroot 18113227Ssam u.u_error = kill1(uap->signo < 0, 18213227Ssam uap->signo < 0 ? -uap->signo : uap->signo, uap->pid); 1838032Sroot } 1848032Sroot 1858032Sroot killpg() 1868032Sroot { 1879989Ssam register struct a { 1889989Ssam int pgrp; 1899989Ssam int signo; 1909989Ssam } *uap = (struct a *)u.u_ap; 1918032Sroot 19212750Ssam u.u_error = kill1(1, uap->signo, uap->pgrp); 1938032Sroot } 1948032Sroot 19512882Ssam /* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ 19612882Ssam 19712750Ssam kill1(ispgrp, signo, who) 1989989Ssam int ispgrp, signo, who; 1999989Ssam { 2009989Ssam register struct proc *p; 2019989Ssam int f, priv = 0; 2029989Ssam 20312835Ssam if (signo < 0 || signo > NSIG) 2049989Ssam return (EINVAL); 2059989Ssam if (who > 0 && !ispgrp) { 2069989Ssam p = pfind(who); 20714926Smckusick if (p == 0) 2089989Ssam return (ESRCH); 20914926Smckusick if (u.u_uid && u.u_uid != p->p_uid) 21014926Smckusick return (EPERM); 21112835Ssam if (signo) 21212835Ssam psignal(p, signo); 2139989Ssam return (0); 2147421Sroot } 2159989Ssam if (who == -1 && u.u_uid == 0) 2169989Ssam priv++, who = 0, ispgrp = 1; /* like sending to pgrp */ 2179989Ssam else if (who == 0) { 2187421Sroot /* 2197421Sroot * Zero process id means send to my process group. 2207421Sroot */ 2219989Ssam ispgrp = 1; 2229989Ssam who = u.u_procp->p_pgrp; 2239989Ssam if (who == 0) 2249989Ssam return (EINVAL); 2257421Sroot } 22616531Skarels for (f = 0, p = allproc; p != NULL; p = p->p_nxt) { 2279989Ssam if (!ispgrp) { 2289989Ssam if (p->p_pid != who) 2297421Sroot continue; 2309989Ssam } else if (p->p_pgrp != who && priv == 0 || p->p_ppid == 0 || 2319989Ssam (p->p_flag&SSYS) || (priv && p == u.u_procp)) 2327421Sroot continue; 2337421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 2349989Ssam (signo != SIGCONT || !inferior(p))) 2357421Sroot continue; 2367421Sroot f++; 23712835Ssam if (signo) 23812835Ssam psignal(p, signo); 2397421Sroot } 24012750Ssam return (f == 0 ? ESRCH : 0); 2417421Sroot } 2427421Sroot 2437421Sroot /* 2447421Sroot * Send the specified signal to 2457421Sroot * all processes with 'pgrp' as 2467421Sroot * process group. 2477421Sroot */ 2487421Sroot gsignal(pgrp, sig) 2497421Sroot register int pgrp; 2507421Sroot { 2517421Sroot register struct proc *p; 2527421Sroot 2537421Sroot if (pgrp == 0) 2547421Sroot return; 25516531Skarels for (p = allproc; p != NULL; p = p->p_nxt) 2567421Sroot if (p->p_pgrp == pgrp) 2577421Sroot psignal(p, sig); 2587421Sroot } 2597421Sroot 2607421Sroot /* 2617421Sroot * Send the specified signal to 2627421Sroot * the specified process. 2637421Sroot */ 2647421Sroot psignal(p, sig) 2657421Sroot register struct proc *p; 2667421Sroot register int sig; 2677421Sroot { 2687421Sroot register int s; 2697421Sroot register int (*action)(); 27012882Ssam int sigmask; 2717421Sroot 2727421Sroot if ((unsigned)sig >= NSIG) 2737421Sroot return; 27412882Ssam sigmask = 1 << (sig-1); 2757421Sroot 2767421Sroot /* 2777421Sroot * If proc is traced, always give parent a chance. 2787421Sroot */ 2797421Sroot if (p->p_flag & STRC) 2807421Sroot action = SIG_DFL; 2817421Sroot else { 2827421Sroot /* 28312882Ssam * If the signal is being ignored, 28412882Ssam * then we forget about it immediately. 2857421Sroot */ 28612882Ssam if (p->p_sigignore & sigmask) 2877421Sroot return; 28812882Ssam if (p->p_sigmask & sigmask) 28912882Ssam action = SIG_HOLD; 29012882Ssam else if (p->p_sigcatch & sigmask) 29112882Ssam action = SIG_CATCH; 29212882Ssam else 29312882Ssam action = SIG_DFL; 2947421Sroot } 2957421Sroot #define mask(sig) (1<<(sig-1)) 2967421Sroot #define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU)) 2977421Sroot if (sig) { 2987421Sroot p->p_sig |= sigmask; 2997421Sroot switch (sig) { 3007421Sroot 3017421Sroot case SIGTERM: 30212882Ssam if ((p->p_flag&STRC) || action != SIG_DFL) 3037421Sroot break; 3047421Sroot /* fall into ... */ 3057421Sroot 3067421Sroot case SIGKILL: 3077421Sroot if (p->p_nice > NZERO) 3087421Sroot p->p_nice = NZERO; 3097421Sroot break; 3107421Sroot 3117421Sroot case SIGCONT: 3127421Sroot p->p_sig &= ~stops; 3137421Sroot break; 3147421Sroot 3157421Sroot case SIGSTOP: 3167421Sroot case SIGTSTP: 3177421Sroot case SIGTTIN: 3187421Sroot case SIGTTOU: 3197421Sroot p->p_sig &= ~mask(SIGCONT); 3207421Sroot break; 3217421Sroot } 3227421Sroot } 3237421Sroot #undef mask 3247421Sroot #undef stops 3257421Sroot /* 3267421Sroot * Defer further processing for signals which are held. 3277421Sroot */ 3287421Sroot if (action == SIG_HOLD) 3297421Sroot return; 3307421Sroot s = spl6(); 3317421Sroot switch (p->p_stat) { 3327421Sroot 3337421Sroot case SSLEEP: 3347421Sroot /* 3357421Sroot * If process is sleeping at negative priority 3367421Sroot * we can't interrupt the sleep... the signal will 3377421Sroot * be noticed when the process returns through 3387421Sroot * trap() or syscall(). 3397421Sroot */ 3407421Sroot if (p->p_pri <= PZERO) 3417421Sroot goto out; 3427421Sroot /* 3437421Sroot * Process is sleeping and traced... make it runnable 3447421Sroot * so it can discover the signal in issig() and stop 3457421Sroot * for the parent. 3467421Sroot */ 3477421Sroot if (p->p_flag&STRC) 3487421Sroot goto run; 3497421Sroot switch (sig) { 3507421Sroot 3517421Sroot case SIGSTOP: 3527421Sroot case SIGTSTP: 3537421Sroot case SIGTTIN: 3547421Sroot case SIGTTOU: 3557421Sroot /* 3567421Sroot * These are the signals which by default 3577421Sroot * stop a process. 3587421Sroot */ 3597421Sroot if (action != SIG_DFL) 3607421Sroot goto run; 3617421Sroot /* 3627421Sroot * Don't clog system with children of init 3637421Sroot * stopped from the keyboard. 3647421Sroot */ 3657421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 3667421Sroot psignal(p, SIGKILL); 3677421Sroot p->p_sig &= ~sigmask; 3687421Sroot splx(s); 3697421Sroot return; 3707421Sroot } 3717421Sroot /* 3727421Sroot * If a child in vfork(), stopping could 3737421Sroot * cause deadlock. 3747421Sroot */ 3757421Sroot if (p->p_flag&SVFORK) 3767421Sroot goto out; 3777421Sroot p->p_sig &= ~sigmask; 3787421Sroot p->p_cursig = sig; 3797421Sroot stop(p); 3807421Sroot goto out; 3817421Sroot 3827421Sroot case SIGIO: 3837421Sroot case SIGURG: 3847421Sroot case SIGCHLD: 3857421Sroot /* 3867421Sroot * These signals are special in that they 3877421Sroot * don't get propogated... if the process 3887421Sroot * isn't interested, forget it. 3897421Sroot */ 3907421Sroot if (action != SIG_DFL) 3917421Sroot goto run; 3927421Sroot p->p_sig &= ~sigmask; /* take it away */ 3937421Sroot goto out; 3947421Sroot 3957421Sroot default: 3967421Sroot /* 3977421Sroot * All other signals cause the process to run 3987421Sroot */ 3997421Sroot goto run; 4007421Sroot } 4017421Sroot /*NOTREACHED*/ 4027421Sroot 4037421Sroot case SSTOP: 4047421Sroot /* 4057421Sroot * If traced process is already stopped, 4067421Sroot * then no further action is necessary. 4077421Sroot */ 4087421Sroot if (p->p_flag&STRC) 4097421Sroot goto out; 4107421Sroot switch (sig) { 4117421Sroot 4127421Sroot case SIGKILL: 4137421Sroot /* 4147421Sroot * Kill signal always sets processes running. 4157421Sroot */ 4167421Sroot goto run; 4177421Sroot 4187421Sroot case SIGCONT: 4197421Sroot /* 4207421Sroot * If the process catches SIGCONT, let it handle 4217421Sroot * the signal itself. If it isn't waiting on 4227421Sroot * an event, then it goes back to run state. 4237421Sroot * Otherwise, process goes back to sleep state. 4247421Sroot */ 4257421Sroot if (action != SIG_DFL || p->p_wchan == 0) 4267421Sroot goto run; 4277421Sroot p->p_stat = SSLEEP; 4287421Sroot goto out; 4297421Sroot 4307421Sroot case SIGSTOP: 4317421Sroot case SIGTSTP: 4327421Sroot case SIGTTIN: 4337421Sroot case SIGTTOU: 4347421Sroot /* 4357421Sroot * Already stopped, don't need to stop again. 4367421Sroot * (If we did the shell could get confused.) 4377421Sroot */ 4387421Sroot p->p_sig &= ~sigmask; /* take it away */ 4397421Sroot goto out; 4407421Sroot 4417421Sroot default: 4427421Sroot /* 4437421Sroot * If process is sleeping interruptibly, then 4447421Sroot * unstick it so that when it is continued 4457421Sroot * it can look at the signal. 4467421Sroot * But don't setrun the process as its not to 4477421Sroot * be unstopped by the signal alone. 4487421Sroot */ 4497421Sroot if (p->p_wchan && p->p_pri > PZERO) 4507421Sroot unsleep(p); 4517421Sroot goto out; 4527421Sroot } 4537421Sroot /*NOTREACHED*/ 4547421Sroot 4557421Sroot default: 4567421Sroot /* 4577421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 4587421Sroot * other than kicking ourselves if we are running. 4597421Sroot * It will either never be noticed, or noticed very soon. 4607421Sroot */ 4617421Sroot if (p == u.u_procp && !noproc) 4628444Sroot #include "../vax/mtpr.h" 4637421Sroot aston(); 4647421Sroot goto out; 4657421Sroot } 4667421Sroot /*NOTREACHED*/ 4677421Sroot run: 4687421Sroot /* 4697421Sroot * Raise priority to at least PUSER. 4707421Sroot */ 4717421Sroot if (p->p_pri > PUSER) 4727421Sroot if ((p != u.u_procp || noproc) && p->p_stat == SRUN && 4737421Sroot (p->p_flag & SLOAD)) { 4747421Sroot remrq(p); 4757421Sroot p->p_pri = PUSER; 4767421Sroot setrq(p); 4777421Sroot } else 4787421Sroot p->p_pri = PUSER; 4797421Sroot setrun(p); 4807421Sroot out: 4817421Sroot splx(s); 4827421Sroot } 4837421Sroot 4847421Sroot /* 4857421Sroot * Returns true if the current 4867421Sroot * process has a signal to process. 4877421Sroot * The signal to process is put in p_cursig. 4887421Sroot * This is asked at least once each time a process enters the 4897421Sroot * system (though this can usually be done without actually 4907421Sroot * calling issig by checking the pending signal masks.) 4917421Sroot * A signal does not do anything 4927421Sroot * directly to a process; it sets 4937421Sroot * a flag that asks the process to 4947421Sroot * do something to itself. 4957421Sroot */ 4967421Sroot issig() 4977421Sroot { 4987421Sroot register struct proc *p; 4997421Sroot register int sig; 50012882Ssam int sigbits, sigmask; 5017421Sroot 5027421Sroot p = u.u_procp; 5037421Sroot for (;;) { 50414782Ssam sigbits = p->p_sig &~ p->p_sigmask; 5057421Sroot if ((p->p_flag&STRC) == 0) 50614782Ssam sigbits &= ~p->p_sigignore; 5077421Sroot if (p->p_flag&SVFORK) 5087421Sroot #define bit(a) (1<<(a-1)) 5097421Sroot sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 5107421Sroot if (sigbits == 0) 5117421Sroot break; 51212882Ssam sig = ffs(sigbits); 51312882Ssam sigmask = 1 << (sig-1); 5147421Sroot p->p_sig &= ~sigmask; /* take the signal! */ 5157421Sroot p->p_cursig = sig; 51612882Ssam if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) { 5177421Sroot /* 5187421Sroot * If traced, always stop, and stay 5197421Sroot * stopped until released by the parent. 5207421Sroot */ 5217421Sroot do { 5227421Sroot stop(p); 5237421Sroot swtch(); 5247421Sroot } while (!procxmt() && p->p_flag&STRC); 5257421Sroot 5267421Sroot /* 52714782Ssam * If the traced bit got turned off, 52814782Ssam * then put the signal taken above back into p_sig 52914782Ssam * and go back up to the top to rescan signals. 53014782Ssam * This ensures that p_sig* and u_signal are consistent. 5317421Sroot */ 53214782Ssam if ((p->p_flag&STRC) == 0) { 5337421Sroot p->p_sig |= sigmask; 5347421Sroot continue; 5357421Sroot } 5367421Sroot 5377421Sroot /* 5387421Sroot * If parent wants us to take the signal, 5397421Sroot * then it will leave it in p->p_cursig; 5407421Sroot * otherwise we just look for signals again. 5417421Sroot */ 5427421Sroot sig = p->p_cursig; 5437421Sroot if (sig == 0) 5447421Sroot continue; 54514782Ssam 54614782Ssam /* 54714782Ssam * If signal is being masked put it back 54814782Ssam * into p_sig and look for other signals. 54914782Ssam */ 55014782Ssam sigmask = 1 << (sig-1); 55114782Ssam if (p->p_sigmask & sigmask) { 55214782Ssam p->p_sig |= sigmask; 55314782Ssam continue; 55414782Ssam } 5557421Sroot } 5567421Sroot switch (u.u_signal[sig]) { 5577421Sroot 5587421Sroot case SIG_DFL: 5597421Sroot /* 5607421Sroot * Don't take default actions on system processes. 5617421Sroot */ 5627421Sroot if (p->p_ppid == 0) 5637421Sroot break; 5647421Sroot switch (sig) { 5657421Sroot 5667421Sroot case SIGTSTP: 5677421Sroot case SIGTTIN: 5687421Sroot case SIGTTOU: 5697421Sroot /* 5707421Sroot * Children of init aren't allowed to stop 5717421Sroot * on signals from the keyboard. 5727421Sroot */ 5737421Sroot if (p->p_pptr == &proc[1]) { 5747421Sroot psignal(p, SIGKILL); 5757421Sroot continue; 5767421Sroot } 5777421Sroot /* fall into ... */ 5787421Sroot 5797421Sroot case SIGSTOP: 5807421Sroot if (p->p_flag&STRC) 5817421Sroot continue; 5827421Sroot stop(p); 5837421Sroot swtch(); 5847421Sroot continue; 5857421Sroot 5867421Sroot case SIGCONT: 5877421Sroot case SIGCHLD: 58812882Ssam case SIGURG: 58912951Ssam case SIGIO: 5907421Sroot /* 5917421Sroot * These signals are normally not 5927421Sroot * sent if the action is the default. 5937421Sroot */ 5947421Sroot continue; /* == ignore */ 5957421Sroot 5967421Sroot default: 5977421Sroot goto send; 5987421Sroot } 5997421Sroot /*NOTREACHED*/ 6007421Sroot 6017421Sroot case SIG_HOLD: 6027421Sroot case SIG_IGN: 6037421Sroot /* 6047421Sroot * Masking above should prevent us 6057421Sroot * ever trying to take action on a held 6067421Sroot * or ignored signal, unless process is traced. 6077421Sroot */ 6087421Sroot if ((p->p_flag&STRC) == 0) 6097421Sroot printf("issig\n"); 6107421Sroot continue; 6117421Sroot 6127421Sroot default: 6137421Sroot /* 6147421Sroot * This signal has an action, let 6157421Sroot * psig process it. 6167421Sroot */ 6177421Sroot goto send; 6187421Sroot } 6197421Sroot /*NOTREACHED*/ 6207421Sroot } 6217421Sroot /* 6227421Sroot * Didn't find a signal to send. 6237421Sroot */ 6247421Sroot p->p_cursig = 0; 6257421Sroot return (0); 6267421Sroot 6277421Sroot send: 6287421Sroot /* 6297421Sroot * Let psig process the signal. 6307421Sroot */ 6317421Sroot return (sig); 6327421Sroot } 6337421Sroot 6347421Sroot /* 6357421Sroot * Put the argument process into the stopped 6367421Sroot * state and notify the parent via wakeup and/or signal. 6377421Sroot */ 6387421Sroot stop(p) 6397421Sroot register struct proc *p; 6407421Sroot { 6417421Sroot 6427421Sroot p->p_stat = SSTOP; 6437421Sroot p->p_flag &= ~SWTED; 6447421Sroot wakeup((caddr_t)p->p_pptr); 6457421Sroot /* 6467421Sroot * Avoid sending signal to parent if process is traced 6477421Sroot */ 6487421Sroot if (p->p_flag&STRC) 6497421Sroot return; 6507421Sroot psignal(p->p_pptr, SIGCHLD); 6517421Sroot } 6527421Sroot 6537421Sroot /* 6547421Sroot * Perform the action specified by 6557421Sroot * the current signal. 6567421Sroot * The usual sequence is: 6577421Sroot * if (issig()) 6587421Sroot * psig(); 6597421Sroot * The signal bit has already been cleared by issig, 6607421Sroot * and the current signal number stored in p->p_cursig. 6617421Sroot */ 6627421Sroot psig() 6637421Sroot { 66412882Ssam register struct proc *p = u.u_procp; 66512882Ssam register int sig = p->p_cursig; 66612882Ssam int sigmask = 1 << (sig - 1), returnmask; 6677421Sroot register int (*action)(); 6687421Sroot 66912882Ssam if (sig == 0) 6707421Sroot panic("psig"); 67112882Ssam action = u.u_signal[sig]; 6727421Sroot if (action != SIG_DFL) { 67312882Ssam if (action == SIG_IGN || (p->p_sigmask & sigmask)) 6747421Sroot panic("psig action"); 6757421Sroot u.u_error = 0; 6767421Sroot /* 67712882Ssam * Set the new mask value and also defer further 67812882Ssam * occurences of this signal (unless we're simulating 67912882Ssam * the old signal facilities). 68012882Ssam * 68112882Ssam * Special case: user has done a sigpause. Here the 68212882Ssam * current mask is not of interest, but rather the 68312882Ssam * mask from before the sigpause is what we want restored 68412882Ssam * after the signal processing is completed. 6857421Sroot */ 68612882Ssam (void) spl6(); 68712882Ssam if (p->p_flag & SOUSIG) { 68812882Ssam if (sig != SIGILL && sig != SIGTRAP) { 68912882Ssam u.u_signal[sig] = SIG_DFL; 69012882Ssam p->p_sigcatch &= ~sigmask; 69112882Ssam } 69212882Ssam sigmask = 0; 6937421Sroot } 69412882Ssam if (p->p_flag & SOMASK) { 69512882Ssam returnmask = u.u_oldmask; 69612882Ssam p->p_flag &= ~SOMASK; 69712882Ssam } else 69812882Ssam returnmask = p->p_sigmask; 69912951Ssam p->p_sigmask |= u.u_sigmask[sig] | sigmask; 70012882Ssam (void) spl0(); 7018032Sroot u.u_ru.ru_nsignals++; 70212882Ssam sendsig(action, sig, returnmask); 70312882Ssam p->p_cursig = 0; 7047421Sroot return; 7057421Sroot } 7067421Sroot u.u_acflag |= AXSIG; 70712882Ssam switch (sig) { 7087421Sroot 7097421Sroot case SIGILL: 7107421Sroot case SIGIOT: 7117421Sroot case SIGBUS: 7127421Sroot case SIGQUIT: 7137421Sroot case SIGTRAP: 7147421Sroot case SIGEMT: 7157421Sroot case SIGFPE: 7167421Sroot case SIGSEGV: 7177421Sroot case SIGSYS: 71812882Ssam u.u_arg[0] = sig; 7197421Sroot if (core()) 72012882Ssam sig += 0200; 7217421Sroot } 72212882Ssam exit(sig); 7237421Sroot } 7247421Sroot 7257421Sroot /* 7267421Sroot * Create a core image on the file "core" 7277421Sroot * If you are looking for protection glitches, 7287421Sroot * there are probably a wealth of them here 7297421Sroot * when this occurs to a suid command. 7307421Sroot * 7317421Sroot * It writes UPAGES block of the 7327421Sroot * user.h area followed by the entire 7337421Sroot * data+stack segments. 7347421Sroot */ 7357421Sroot core() 7367421Sroot { 7377421Sroot register struct inode *ip; 738*16692Smckusick register struct nameidata *ndp = &u.u_nd; 7397421Sroot 74012639Ssam if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid) 7417818Sroot return (0); 7428032Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= 7438032Sroot u.u_rlimit[RLIMIT_CORE].rlim_cur) 7447421Sroot return (0); 7457421Sroot u.u_error = 0; 746*16692Smckusick ndp->ni_nameiop = CREATE | FOLLOW; 747*16692Smckusick ndp->ni_segflg = UIO_SYSSPACE; 748*16692Smckusick ndp->ni_dirp = "core"; 749*16692Smckusick ip = namei(ndp); 7507421Sroot if (ip == NULL) { 7517421Sroot if (u.u_error) 7527421Sroot return (0); 753*16692Smckusick ip = maknode(0644, ndp); 7547421Sroot if (ip==NULL) 7557421Sroot return (0); 7567421Sroot } 7577818Sroot if (access(ip, IWRITE) || 7587818Sroot (ip->i_mode&IFMT) != IFREG || 7597818Sroot ip->i_nlink != 1) { 7607421Sroot u.u_error = EFAULT; 7617818Sroot goto out; 7627818Sroot } 7639160Ssam itrunc(ip, (u_long)0); 7647818Sroot u.u_acflag |= ACORE; 76512882Ssam u.u_error = rdwri(UIO_WRITE, ip, 76612882Ssam (caddr_t)&u, 76712882Ssam ctob(UPAGES), 76812882Ssam 0, 1, (int *)0); 7698101Sroot if (u.u_error == 0) 7708644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7718967Sroot (caddr_t)ctob(dptov(u.u_procp, 0)), 7728967Sroot ctob(u.u_dsize), 7738644Sroot ctob(UPAGES), 0, (int *)0); 7748101Sroot if (u.u_error == 0) 7758644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7768967Sroot (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)), 7778967Sroot ctob(u.u_ssize), 7788644Sroot ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0); 7797818Sroot out: 7807421Sroot iput(ip); 7817818Sroot return (u.u_error == 0); 7827421Sroot } 783