1*14926Smckusick /* kern_sig.c 6.2 83/09/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" 249160Ssam #include "../h/nami.h" 257421Sroot 2612951Ssam #define mask(s) (1 << ((s)-1)) 2712951Ssam #define cantmask (mask(SIGKILL)|mask(SIGCONT)|mask(SIGSTOP)) 2812951Ssam 297499Sroot sigvec() 307421Sroot { 3112951Ssam register struct a { 3212882Ssam int signo; 3312951Ssam struct sigvec *nsv; 3412951Ssam struct sigvec *osv; 3512882Ssam } *uap = (struct a *)u.u_ap; 3612951Ssam struct sigvec vec; 3712951Ssam register struct sigvec *sv; 3812882Ssam register int sig; 397421Sroot 4012882Ssam sig = uap->signo; 4112951Ssam if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) { 4212882Ssam u.u_error = EINVAL; 4312882Ssam return; 4412882Ssam } 4512951Ssam sv = &vec; 4612951Ssam if (uap->osv) { 4712951Ssam sv->sv_handler = u.u_signal[sig]; 4812951Ssam sv->sv_mask = u.u_sigmask[sig]; 4912951Ssam sv->sv_onstack = (u.u_sigonstack & mask(sig)) != 0; 5012951Ssam u.u_error = 5112951Ssam copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 5212951Ssam if (u.u_error) 5312951Ssam return; 5412951Ssam } 5512951Ssam if (uap->nsv) { 5612951Ssam u.u_error = 5712951Ssam copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 5812951Ssam if (u.u_error) 5912951Ssam return; 6012951Ssam if (sig == SIGCONT && sv->sv_handler == SIG_IGN) { 6112951Ssam u.u_error = EINVAL; 6212951Ssam return; 6312951Ssam } 6412951Ssam setsigvec(sig, sv); 6512951Ssam } 667421Sroot } 677421Sroot 6812951Ssam setsigvec(sig, sv) 6912951Ssam int sig; 7012951Ssam register struct sigvec *sv; 7112882Ssam { 7212882Ssam register struct proc *p; 7312951Ssam register int bit; 7412882Ssam 7512951Ssam bit = mask(sig); 7612882Ssam p = u.u_procp; 7712882Ssam /* 7812882Ssam * Change setting atomically. 7912882Ssam */ 8012882Ssam (void) spl6(); 8112951Ssam u.u_signal[sig] = sv->sv_handler; 8212951Ssam u.u_sigmask[sig] = sv->sv_mask &~ cantmask; 8312951Ssam if (sv->sv_onstack) 8412951Ssam u.u_sigonstack |= bit; 8512951Ssam else 8612951Ssam u.u_sigonstack &= ~bit; 8712951Ssam if (sv->sv_handler == SIG_IGN) { 8812951Ssam p->p_sig &= ~bit; /* never to be seen again */ 8912951Ssam p->p_sigignore |= bit; 9012951Ssam p->p_sigcatch &= ~bit; 9112882Ssam } else { 9212951Ssam p->p_sigignore &= ~bit; 9312951Ssam if (sv->sv_handler == SIG_DFL) 9412951Ssam p->p_sigcatch &= ~bit; 9512882Ssam else 9612951Ssam p->p_sigcatch |= bit; 9712882Ssam } 9812882Ssam (void) spl0(); 9912882Ssam } 10012882Ssam 1017499Sroot sigblock() 1027421Sroot { 10312882Ssam struct a { 10412951Ssam int sigmask; 10512882Ssam } *uap = (struct a *)u.u_ap; 10612951Ssam register struct proc *p = u.u_procp; 1077499Sroot 10812882Ssam (void) spl6(); 10912882Ssam u.u_r.r_val1 = p->p_sigmask; 11012951Ssam p->p_sigmask |= uap->sigmask &~ cantmask; 11112882Ssam (void) spl0(); 1127499Sroot } 1137499Sroot 1147499Sroot sigsetmask() 1157499Sroot { 11612882Ssam struct a { 11712951Ssam int sigmask; 11812882Ssam } *uap = (struct a *)u.u_ap; 11912882Ssam register struct proc *p = u.u_procp; 1207499Sroot 12112882Ssam (void) spl6(); 12212882Ssam u.u_r.r_val1 = p->p_sigmask; 12312951Ssam p->p_sigmask = uap->sigmask &~ cantmask; 12412882Ssam (void) spl0(); 1257499Sroot } 1267499Sroot 1277499Sroot sigpause() 1287499Sroot { 12912882Ssam struct a { 13012951Ssam int sigmask; 13112882Ssam } *uap = (struct a *)u.u_ap; 13212882Ssam register struct proc *p = u.u_procp; 1337499Sroot 13412882Ssam /* 13512882Ssam * When returning from sigpause, we want 13612882Ssam * the old mask to be restored after the 13712882Ssam * signal handler has finished. Thus, we 13812882Ssam * save it here and mark the proc structure 13912882Ssam * to indicate this (should be in u.). 14012882Ssam */ 14112882Ssam u.u_oldmask = p->p_sigmask; 14212882Ssam p->p_flag |= SOMASK; 14312951Ssam p->p_sigmask = uap->sigmask &~ cantmask; 14412882Ssam for (;;) 14512882Ssam sleep((caddr_t)&u, PSLEP); 14612882Ssam /*NOTREACHED*/ 1477499Sroot } 14812951Ssam #undef cantmask 14912951Ssam #undef mask 1507499Sroot 1517499Sroot sigstack() 1527499Sroot { 15312951Ssam register struct a { 15412951Ssam struct sigstack *nss; 15512951Ssam struct sigstack *oss; 15612882Ssam } *uap = (struct a *)u.u_ap; 15712951Ssam struct sigstack ss; 1587499Sroot 15912951Ssam if (uap->oss) { 16012951Ssam u.u_error = copyout((caddr_t)&u.u_sigstack, (caddr_t)uap->oss, 16112951Ssam sizeof (struct sigstack)); 16212951Ssam if (u.u_error) 16312951Ssam return; 16412951Ssam } 16512951Ssam if (uap->nss) { 16612951Ssam u.u_error = 16712951Ssam copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss)); 16812951Ssam if (u.u_error == 0) 16912951Ssam u.u_sigstack = ss; 17012951Ssam } 1717499Sroot } 1727499Sroot 17313227Ssam /* KILL SHOULD BE UPDATED */ 17413227Ssam 1758032Sroot kill() 1768032Sroot { 17712882Ssam register struct a { 17812882Ssam int pid; 17912882Ssam int signo; 18012882Ssam } *uap = (struct a *)u.u_ap; 1818032Sroot 18213227Ssam u.u_error = kill1(uap->signo < 0, 18313227Ssam uap->signo < 0 ? -uap->signo : uap->signo, uap->pid); 1848032Sroot } 1858032Sroot 1868032Sroot killpg() 1878032Sroot { 1889989Ssam register struct a { 1899989Ssam int pgrp; 1909989Ssam int signo; 1919989Ssam } *uap = (struct a *)u.u_ap; 1928032Sroot 19312750Ssam u.u_error = kill1(1, uap->signo, uap->pgrp); 1948032Sroot } 1958032Sroot 19612882Ssam /* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ 19712882Ssam 19812750Ssam kill1(ispgrp, signo, who) 1999989Ssam int ispgrp, signo, who; 2009989Ssam { 2019989Ssam register struct proc *p; 2029989Ssam int f, priv = 0; 2039989Ssam 20412835Ssam if (signo < 0 || signo > NSIG) 2059989Ssam return (EINVAL); 2069989Ssam if (who > 0 && !ispgrp) { 2079989Ssam p = pfind(who); 208*14926Smckusick if (p == 0) 2099989Ssam return (ESRCH); 210*14926Smckusick if (u.u_uid && u.u_uid != p->p_uid) 211*14926Smckusick return (EPERM); 21212835Ssam if (signo) 21312835Ssam psignal(p, signo); 2149989Ssam return (0); 2157421Sroot } 2169989Ssam if (who == -1 && u.u_uid == 0) 2179989Ssam priv++, who = 0, ispgrp = 1; /* like sending to pgrp */ 2189989Ssam else if (who == 0) { 2197421Sroot /* 2207421Sroot * Zero process id means send to my process group. 2217421Sroot */ 2229989Ssam ispgrp = 1; 2239989Ssam who = u.u_procp->p_pgrp; 2249989Ssam if (who == 0) 2259989Ssam return (EINVAL); 2267421Sroot } 2279989Ssam for (f = 0, p = proc; p < procNPROC; p++) { 2287421Sroot if (p->p_stat == NULL) 2297421Sroot continue; 2309989Ssam if (!ispgrp) { 2319989Ssam if (p->p_pid != who) 2327421Sroot continue; 2339989Ssam } else if (p->p_pgrp != who && priv == 0 || p->p_ppid == 0 || 2349989Ssam (p->p_flag&SSYS) || (priv && p == u.u_procp)) 2357421Sroot continue; 2367421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 2379989Ssam (signo != SIGCONT || !inferior(p))) 2387421Sroot continue; 2397421Sroot f++; 24012835Ssam if (signo) 24112835Ssam psignal(p, signo); 2427421Sroot } 24312750Ssam return (f == 0 ? ESRCH : 0); 2447421Sroot } 2457421Sroot 2467421Sroot /* 2477421Sroot * Send the specified signal to 2487421Sroot * all processes with 'pgrp' as 2497421Sroot * process group. 2507421Sroot */ 2517421Sroot gsignal(pgrp, sig) 2527421Sroot register int pgrp; 2537421Sroot { 2547421Sroot register struct proc *p; 2557421Sroot 2567421Sroot if (pgrp == 0) 2577421Sroot return; 2587421Sroot for(p = proc; p < procNPROC; p++) 2597421Sroot if (p->p_pgrp == pgrp) 2607421Sroot psignal(p, sig); 2617421Sroot } 2627421Sroot 2637421Sroot /* 2647421Sroot * Send the specified signal to 2657421Sroot * the specified process. 2667421Sroot */ 2677421Sroot psignal(p, sig) 2687421Sroot register struct proc *p; 2697421Sroot register int sig; 2707421Sroot { 2717421Sroot register int s; 2727421Sroot register int (*action)(); 27312882Ssam int sigmask; 2747421Sroot 2757421Sroot if ((unsigned)sig >= NSIG) 2767421Sroot return; 27712882Ssam sigmask = 1 << (sig-1); 2787421Sroot 2797421Sroot /* 2807421Sroot * If proc is traced, always give parent a chance. 2817421Sroot */ 2827421Sroot if (p->p_flag & STRC) 2837421Sroot action = SIG_DFL; 2847421Sroot else { 2857421Sroot /* 28612882Ssam * If the signal is being ignored, 28712882Ssam * then we forget about it immediately. 2887421Sroot */ 28912882Ssam if (p->p_sigignore & sigmask) 2907421Sroot return; 29112882Ssam if (p->p_sigmask & sigmask) 29212882Ssam action = SIG_HOLD; 29312882Ssam else if (p->p_sigcatch & sigmask) 29412882Ssam action = SIG_CATCH; 29512882Ssam else 29612882Ssam action = SIG_DFL; 2977421Sroot } 2987421Sroot #define mask(sig) (1<<(sig-1)) 2997421Sroot #define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU)) 3007421Sroot if (sig) { 3017421Sroot p->p_sig |= sigmask; 3027421Sroot switch (sig) { 3037421Sroot 3047421Sroot case SIGTERM: 30512882Ssam if ((p->p_flag&STRC) || action != SIG_DFL) 3067421Sroot break; 3077421Sroot /* fall into ... */ 3087421Sroot 3097421Sroot case SIGKILL: 3107421Sroot if (p->p_nice > NZERO) 3117421Sroot p->p_nice = NZERO; 3127421Sroot break; 3137421Sroot 3147421Sroot case SIGCONT: 3157421Sroot p->p_sig &= ~stops; 3167421Sroot break; 3177421Sroot 3187421Sroot case SIGSTOP: 3197421Sroot case SIGTSTP: 3207421Sroot case SIGTTIN: 3217421Sroot case SIGTTOU: 3227421Sroot p->p_sig &= ~mask(SIGCONT); 3237421Sroot break; 3247421Sroot } 3257421Sroot } 3267421Sroot #undef mask 3277421Sroot #undef stops 3287421Sroot /* 3297421Sroot * Defer further processing for signals which are held. 3307421Sroot */ 3317421Sroot if (action == SIG_HOLD) 3327421Sroot return; 3337421Sroot s = spl6(); 3347421Sroot switch (p->p_stat) { 3357421Sroot 3367421Sroot case SSLEEP: 3377421Sroot /* 3387421Sroot * If process is sleeping at negative priority 3397421Sroot * we can't interrupt the sleep... the signal will 3407421Sroot * be noticed when the process returns through 3417421Sroot * trap() or syscall(). 3427421Sroot */ 3437421Sroot if (p->p_pri <= PZERO) 3447421Sroot goto out; 3457421Sroot /* 3467421Sroot * Process is sleeping and traced... make it runnable 3477421Sroot * so it can discover the signal in issig() and stop 3487421Sroot * for the parent. 3497421Sroot */ 3507421Sroot if (p->p_flag&STRC) 3517421Sroot goto run; 3527421Sroot switch (sig) { 3537421Sroot 3547421Sroot case SIGSTOP: 3557421Sroot case SIGTSTP: 3567421Sroot case SIGTTIN: 3577421Sroot case SIGTTOU: 3587421Sroot /* 3597421Sroot * These are the signals which by default 3607421Sroot * stop a process. 3617421Sroot */ 3627421Sroot if (action != SIG_DFL) 3637421Sroot goto run; 3647421Sroot /* 3657421Sroot * Don't clog system with children of init 3667421Sroot * stopped from the keyboard. 3677421Sroot */ 3687421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 3697421Sroot psignal(p, SIGKILL); 3707421Sroot p->p_sig &= ~sigmask; 3717421Sroot splx(s); 3727421Sroot return; 3737421Sroot } 3747421Sroot /* 3757421Sroot * If a child in vfork(), stopping could 3767421Sroot * cause deadlock. 3777421Sroot */ 3787421Sroot if (p->p_flag&SVFORK) 3797421Sroot goto out; 3807421Sroot p->p_sig &= ~sigmask; 3817421Sroot p->p_cursig = sig; 3827421Sroot stop(p); 3837421Sroot goto out; 3847421Sroot 3857421Sroot case SIGIO: 3867421Sroot case SIGURG: 3877421Sroot case SIGCHLD: 3887421Sroot /* 3897421Sroot * These signals are special in that they 3907421Sroot * don't get propogated... if the process 3917421Sroot * isn't interested, forget it. 3927421Sroot */ 3937421Sroot if (action != SIG_DFL) 3947421Sroot goto run; 3957421Sroot p->p_sig &= ~sigmask; /* take it away */ 3967421Sroot goto out; 3977421Sroot 3987421Sroot default: 3997421Sroot /* 4007421Sroot * All other signals cause the process to run 4017421Sroot */ 4027421Sroot goto run; 4037421Sroot } 4047421Sroot /*NOTREACHED*/ 4057421Sroot 4067421Sroot case SSTOP: 4077421Sroot /* 4087421Sroot * If traced process is already stopped, 4097421Sroot * then no further action is necessary. 4107421Sroot */ 4117421Sroot if (p->p_flag&STRC) 4127421Sroot goto out; 4137421Sroot switch (sig) { 4147421Sroot 4157421Sroot case SIGKILL: 4167421Sroot /* 4177421Sroot * Kill signal always sets processes running. 4187421Sroot */ 4197421Sroot goto run; 4207421Sroot 4217421Sroot case SIGCONT: 4227421Sroot /* 4237421Sroot * If the process catches SIGCONT, let it handle 4247421Sroot * the signal itself. If it isn't waiting on 4257421Sroot * an event, then it goes back to run state. 4267421Sroot * Otherwise, process goes back to sleep state. 4277421Sroot */ 4287421Sroot if (action != SIG_DFL || p->p_wchan == 0) 4297421Sroot goto run; 4307421Sroot p->p_stat = SSLEEP; 4317421Sroot goto out; 4327421Sroot 4337421Sroot case SIGSTOP: 4347421Sroot case SIGTSTP: 4357421Sroot case SIGTTIN: 4367421Sroot case SIGTTOU: 4377421Sroot /* 4387421Sroot * Already stopped, don't need to stop again. 4397421Sroot * (If we did the shell could get confused.) 4407421Sroot */ 4417421Sroot p->p_sig &= ~sigmask; /* take it away */ 4427421Sroot goto out; 4437421Sroot 4447421Sroot default: 4457421Sroot /* 4467421Sroot * If process is sleeping interruptibly, then 4477421Sroot * unstick it so that when it is continued 4487421Sroot * it can look at the signal. 4497421Sroot * But don't setrun the process as its not to 4507421Sroot * be unstopped by the signal alone. 4517421Sroot */ 4527421Sroot if (p->p_wchan && p->p_pri > PZERO) 4537421Sroot unsleep(p); 4547421Sroot goto out; 4557421Sroot } 4567421Sroot /*NOTREACHED*/ 4577421Sroot 4587421Sroot default: 4597421Sroot /* 4607421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 4617421Sroot * other than kicking ourselves if we are running. 4627421Sroot * It will either never be noticed, or noticed very soon. 4637421Sroot */ 4647421Sroot if (p == u.u_procp && !noproc) 4658444Sroot #include "../vax/mtpr.h" 4667421Sroot aston(); 4677421Sroot goto out; 4687421Sroot } 4697421Sroot /*NOTREACHED*/ 4707421Sroot run: 4717421Sroot /* 4727421Sroot * Raise priority to at least PUSER. 4737421Sroot */ 4747421Sroot if (p->p_pri > PUSER) 4757421Sroot if ((p != u.u_procp || noproc) && p->p_stat == SRUN && 4767421Sroot (p->p_flag & SLOAD)) { 4777421Sroot remrq(p); 4787421Sroot p->p_pri = PUSER; 4797421Sroot setrq(p); 4807421Sroot } else 4817421Sroot p->p_pri = PUSER; 4827421Sroot setrun(p); 4837421Sroot out: 4847421Sroot splx(s); 4857421Sroot } 4867421Sroot 4877421Sroot /* 4887421Sroot * Returns true if the current 4897421Sroot * process has a signal to process. 4907421Sroot * The signal to process is put in p_cursig. 4917421Sroot * This is asked at least once each time a process enters the 4927421Sroot * system (though this can usually be done without actually 4937421Sroot * calling issig by checking the pending signal masks.) 4947421Sroot * A signal does not do anything 4957421Sroot * directly to a process; it sets 4967421Sroot * a flag that asks the process to 4977421Sroot * do something to itself. 4987421Sroot */ 4997421Sroot issig() 5007421Sroot { 5017421Sroot register struct proc *p; 5027421Sroot register int sig; 50312882Ssam int sigbits, sigmask; 5047421Sroot 5057421Sroot p = u.u_procp; 5067421Sroot for (;;) { 50714782Ssam sigbits = p->p_sig &~ p->p_sigmask; 5087421Sroot if ((p->p_flag&STRC) == 0) 50914782Ssam sigbits &= ~p->p_sigignore; 5107421Sroot if (p->p_flag&SVFORK) 5117421Sroot #define bit(a) (1<<(a-1)) 5127421Sroot sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 5137421Sroot if (sigbits == 0) 5147421Sroot break; 51512882Ssam sig = ffs(sigbits); 51612882Ssam sigmask = 1 << (sig-1); 5177421Sroot p->p_sig &= ~sigmask; /* take the signal! */ 5187421Sroot p->p_cursig = sig; 51912882Ssam if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) { 5207421Sroot /* 5217421Sroot * If traced, always stop, and stay 5227421Sroot * stopped until released by the parent. 5237421Sroot */ 5247421Sroot do { 5257421Sroot stop(p); 5267421Sroot swtch(); 5277421Sroot } while (!procxmt() && p->p_flag&STRC); 5287421Sroot 5297421Sroot /* 53014782Ssam * If the traced bit got turned off, 53114782Ssam * then put the signal taken above back into p_sig 53214782Ssam * and go back up to the top to rescan signals. 53314782Ssam * This ensures that p_sig* and u_signal are consistent. 5347421Sroot */ 53514782Ssam if ((p->p_flag&STRC) == 0) { 5367421Sroot p->p_sig |= sigmask; 5377421Sroot continue; 5387421Sroot } 5397421Sroot 5407421Sroot /* 5417421Sroot * If parent wants us to take the signal, 5427421Sroot * then it will leave it in p->p_cursig; 5437421Sroot * otherwise we just look for signals again. 5447421Sroot */ 5457421Sroot sig = p->p_cursig; 5467421Sroot if (sig == 0) 5477421Sroot continue; 54814782Ssam 54914782Ssam /* 55014782Ssam * If signal is being masked put it back 55114782Ssam * into p_sig and look for other signals. 55214782Ssam */ 55314782Ssam sigmask = 1 << (sig-1); 55414782Ssam if (p->p_sigmask & sigmask) { 55514782Ssam p->p_sig |= sigmask; 55614782Ssam continue; 55714782Ssam } 5587421Sroot } 5597421Sroot switch (u.u_signal[sig]) { 5607421Sroot 5617421Sroot case SIG_DFL: 5627421Sroot /* 5637421Sroot * Don't take default actions on system processes. 5647421Sroot */ 5657421Sroot if (p->p_ppid == 0) 5667421Sroot break; 5677421Sroot switch (sig) { 5687421Sroot 5697421Sroot case SIGTSTP: 5707421Sroot case SIGTTIN: 5717421Sroot case SIGTTOU: 5727421Sroot /* 5737421Sroot * Children of init aren't allowed to stop 5747421Sroot * on signals from the keyboard. 5757421Sroot */ 5767421Sroot if (p->p_pptr == &proc[1]) { 5777421Sroot psignal(p, SIGKILL); 5787421Sroot continue; 5797421Sroot } 5807421Sroot /* fall into ... */ 5817421Sroot 5827421Sroot case SIGSTOP: 5837421Sroot if (p->p_flag&STRC) 5847421Sroot continue; 5857421Sroot stop(p); 5867421Sroot swtch(); 5877421Sroot continue; 5887421Sroot 5897421Sroot case SIGCONT: 5907421Sroot case SIGCHLD: 59112882Ssam case SIGURG: 59212951Ssam case SIGIO: 5937421Sroot /* 5947421Sroot * These signals are normally not 5957421Sroot * sent if the action is the default. 5967421Sroot */ 5977421Sroot continue; /* == ignore */ 5987421Sroot 5997421Sroot default: 6007421Sroot goto send; 6017421Sroot } 6027421Sroot /*NOTREACHED*/ 6037421Sroot 6047421Sroot case SIG_HOLD: 6057421Sroot case SIG_IGN: 6067421Sroot /* 6077421Sroot * Masking above should prevent us 6087421Sroot * ever trying to take action on a held 6097421Sroot * or ignored signal, unless process is traced. 6107421Sroot */ 6117421Sroot if ((p->p_flag&STRC) == 0) 6127421Sroot printf("issig\n"); 6137421Sroot continue; 6147421Sroot 6157421Sroot default: 6167421Sroot /* 6177421Sroot * This signal has an action, let 6187421Sroot * psig process it. 6197421Sroot */ 6207421Sroot goto send; 6217421Sroot } 6227421Sroot /*NOTREACHED*/ 6237421Sroot } 6247421Sroot /* 6257421Sroot * Didn't find a signal to send. 6267421Sroot */ 6277421Sroot p->p_cursig = 0; 6287421Sroot return (0); 6297421Sroot 6307421Sroot send: 6317421Sroot /* 6327421Sroot * Let psig process the signal. 6337421Sroot */ 6347421Sroot return (sig); 6357421Sroot } 6367421Sroot 6377421Sroot /* 6387421Sroot * Put the argument process into the stopped 6397421Sroot * state and notify the parent via wakeup and/or signal. 6407421Sroot */ 6417421Sroot stop(p) 6427421Sroot register struct proc *p; 6437421Sroot { 6447421Sroot 6457421Sroot p->p_stat = SSTOP; 6467421Sroot p->p_flag &= ~SWTED; 6477421Sroot wakeup((caddr_t)p->p_pptr); 6487421Sroot /* 6497421Sroot * Avoid sending signal to parent if process is traced 6507421Sroot */ 6517421Sroot if (p->p_flag&STRC) 6527421Sroot return; 6537421Sroot psignal(p->p_pptr, SIGCHLD); 6547421Sroot } 6557421Sroot 6567421Sroot /* 6577421Sroot * Perform the action specified by 6587421Sroot * the current signal. 6597421Sroot * The usual sequence is: 6607421Sroot * if (issig()) 6617421Sroot * psig(); 6627421Sroot * The signal bit has already been cleared by issig, 6637421Sroot * and the current signal number stored in p->p_cursig. 6647421Sroot */ 6657421Sroot psig() 6667421Sroot { 66712882Ssam register struct proc *p = u.u_procp; 66812882Ssam register int sig = p->p_cursig; 66912882Ssam int sigmask = 1 << (sig - 1), returnmask; 6707421Sroot register int (*action)(); 6717421Sroot 67212882Ssam if (sig == 0) 6737421Sroot panic("psig"); 67412882Ssam action = u.u_signal[sig]; 6757421Sroot if (action != SIG_DFL) { 67612882Ssam if (action == SIG_IGN || (p->p_sigmask & sigmask)) 6777421Sroot panic("psig action"); 6787421Sroot u.u_error = 0; 6797421Sroot /* 68012882Ssam * Set the new mask value and also defer further 68112882Ssam * occurences of this signal (unless we're simulating 68212882Ssam * the old signal facilities). 68312882Ssam * 68412882Ssam * Special case: user has done a sigpause. Here the 68512882Ssam * current mask is not of interest, but rather the 68612882Ssam * mask from before the sigpause is what we want restored 68712882Ssam * after the signal processing is completed. 6887421Sroot */ 68912882Ssam (void) spl6(); 69012882Ssam if (p->p_flag & SOUSIG) { 69112882Ssam if (sig != SIGILL && sig != SIGTRAP) { 69212882Ssam u.u_signal[sig] = SIG_DFL; 69312882Ssam p->p_sigcatch &= ~sigmask; 69412882Ssam } 69512882Ssam sigmask = 0; 6967421Sroot } 69712882Ssam if (p->p_flag & SOMASK) { 69812882Ssam returnmask = u.u_oldmask; 69912882Ssam p->p_flag &= ~SOMASK; 70012882Ssam } else 70112882Ssam returnmask = p->p_sigmask; 70212951Ssam p->p_sigmask |= u.u_sigmask[sig] | sigmask; 70312882Ssam (void) spl0(); 7048032Sroot u.u_ru.ru_nsignals++; 70512882Ssam sendsig(action, sig, returnmask); 70612882Ssam p->p_cursig = 0; 7077421Sroot return; 7087421Sroot } 7097421Sroot u.u_acflag |= AXSIG; 71012882Ssam switch (sig) { 7117421Sroot 7127421Sroot case SIGILL: 7137421Sroot case SIGIOT: 7147421Sroot case SIGBUS: 7157421Sroot case SIGQUIT: 7167421Sroot case SIGTRAP: 7177421Sroot case SIGEMT: 7187421Sroot case SIGFPE: 7197421Sroot case SIGSEGV: 7207421Sroot case SIGSYS: 72112882Ssam u.u_arg[0] = sig; 7227421Sroot if (core()) 72312882Ssam sig += 0200; 7247421Sroot } 72512882Ssam exit(sig); 7267421Sroot } 7277421Sroot 7287421Sroot /* 7297421Sroot * Create a core image on the file "core" 7307421Sroot * If you are looking for protection glitches, 7317421Sroot * there are probably a wealth of them here 7327421Sroot * when this occurs to a suid command. 7337421Sroot * 7347421Sroot * It writes UPAGES block of the 7357421Sroot * user.h area followed by the entire 7367421Sroot * data+stack segments. 7377421Sroot */ 7387421Sroot core() 7397421Sroot { 7407421Sroot register struct inode *ip; 7417421Sroot extern schar(); 7427421Sroot 74312639Ssam if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid) 7447818Sroot return (0); 7458032Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= 7468032Sroot u.u_rlimit[RLIMIT_CORE].rlim_cur) 7477421Sroot return (0); 7487421Sroot u.u_error = 0; 7497421Sroot u.u_dirp = "core"; 7509160Ssam ip = namei(schar, CREATE, 1); 7517421Sroot if (ip == NULL) { 7527421Sroot if (u.u_error) 7537421Sroot return (0); 75412639Ssam ip = maknode(0644); 7557421Sroot if (ip==NULL) 7567421Sroot return (0); 7577421Sroot } 7587818Sroot if (access(ip, IWRITE) || 7597818Sroot (ip->i_mode&IFMT) != IFREG || 7607818Sroot ip->i_nlink != 1) { 7617421Sroot u.u_error = EFAULT; 7627818Sroot goto out; 7637818Sroot } 7649160Ssam itrunc(ip, (u_long)0); 7657818Sroot u.u_acflag |= ACORE; 76612882Ssam u.u_error = rdwri(UIO_WRITE, ip, 76712882Ssam (caddr_t)&u, 76812882Ssam ctob(UPAGES), 76912882Ssam 0, 1, (int *)0); 7708101Sroot if (u.u_error == 0) 7718644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7728967Sroot (caddr_t)ctob(dptov(u.u_procp, 0)), 7738967Sroot ctob(u.u_dsize), 7748644Sroot ctob(UPAGES), 0, (int *)0); 7758101Sroot if (u.u_error == 0) 7768644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7778967Sroot (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)), 7788967Sroot ctob(u.u_ssize), 7798644Sroot ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0); 7807818Sroot out: 7817421Sroot iput(ip); 7827818Sroot return (u.u_error == 0); 7837421Sroot } 784