1*23374Smckusick /* 2*23374Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23374Smckusick * All rights reserved. The Berkeley software License Agreement 4*23374Smckusick * specifies the terms and conditions for redistribution. 5*23374Smckusick * 6*23374Smckusick * @(#)kern_sig.c 6.17 (Berkeley) 06/08/85 7*23374Smckusick */ 87421Sroot 99755Ssam #include "../machine/reg.h" 109755Ssam #include "../machine/pte.h" 119755Ssam #include "../machine/psl.h" 129755Ssam 1317092Sbloom #include "param.h" 1417092Sbloom #include "systm.h" 1517092Sbloom #include "dir.h" 1617092Sbloom #include "user.h" 1717092Sbloom #include "inode.h" 1817092Sbloom #include "proc.h" 1917092Sbloom #include "timeb.h" 2017092Sbloom #include "times.h" 2117092Sbloom #include "buf.h" 2217092Sbloom #include "mount.h" 2317092Sbloom #include "text.h" 2417092Sbloom #include "seg.h" 2517092Sbloom #include "vm.h" 2617092Sbloom #include "acct.h" 2717092Sbloom #include "uio.h" 2817092Sbloom #include "kernel.h" 297421Sroot 3017153Sbloom #define cantmask (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)) 3112951Ssam 3217013Smckusick /* 3317013Smckusick * Generalized interface signal handler. 3417013Smckusick */ 357499Sroot sigvec() 367421Sroot { 3712951Ssam register struct a { 3812882Ssam int signo; 3912951Ssam struct sigvec *nsv; 4012951Ssam struct sigvec *osv; 4112882Ssam } *uap = (struct a *)u.u_ap; 4212951Ssam struct sigvec vec; 4312951Ssam register struct sigvec *sv; 4412882Ssam register int sig; 4518308Smckusick int bit; 467421Sroot 4712882Ssam sig = uap->signo; 4812951Ssam if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) { 4912882Ssam u.u_error = EINVAL; 5012882Ssam return; 5112882Ssam } 5212951Ssam sv = &vec; 5312951Ssam if (uap->osv) { 5412951Ssam sv->sv_handler = u.u_signal[sig]; 5512951Ssam sv->sv_mask = u.u_sigmask[sig]; 5618308Smckusick bit = sigmask(sig); 5718308Smckusick sv->sv_flags = 0; 5818308Smckusick if ((u.u_sigonstack & bit) != 0) 5918308Smckusick sv->sv_flags |= SV_ONSTACK; 6018308Smckusick if ((u.u_sigintr & bit) != 0) 6118308Smckusick sv->sv_flags |= SV_INTERRUPT; 6212951Ssam u.u_error = 6312951Ssam copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 6412951Ssam if (u.u_error) 6512951Ssam return; 6612951Ssam } 6712951Ssam if (uap->nsv) { 6812951Ssam u.u_error = 6912951Ssam copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 7012951Ssam if (u.u_error) 7112951Ssam return; 7212951Ssam if (sig == SIGCONT && sv->sv_handler == SIG_IGN) { 7312951Ssam u.u_error = EINVAL; 7412951Ssam return; 7512951Ssam } 7612951Ssam setsigvec(sig, sv); 7712951Ssam } 787421Sroot } 797421Sroot 8012951Ssam setsigvec(sig, sv) 8112951Ssam int sig; 8212951Ssam register struct sigvec *sv; 8312882Ssam { 8412882Ssam register struct proc *p; 8512951Ssam register int bit; 8612882Ssam 8717153Sbloom bit = sigmask(sig); 8812882Ssam p = u.u_procp; 8912882Ssam /* 9012882Ssam * Change setting atomically. 9112882Ssam */ 9217153Sbloom (void) splhigh(); 9312951Ssam u.u_signal[sig] = sv->sv_handler; 9412951Ssam u.u_sigmask[sig] = sv->sv_mask &~ cantmask; 9518308Smckusick if (sv->sv_flags & SV_INTERRUPT) 9618308Smckusick u.u_sigintr |= bit; 9718308Smckusick else 9818308Smckusick u.u_sigintr &= ~bit; 9918308Smckusick if (sv->sv_flags & SV_ONSTACK) 10012951Ssam u.u_sigonstack |= bit; 10112951Ssam else 10212951Ssam u.u_sigonstack &= ~bit; 10312951Ssam if (sv->sv_handler == SIG_IGN) { 10412951Ssam p->p_sig &= ~bit; /* never to be seen again */ 10512951Ssam p->p_sigignore |= bit; 10612951Ssam p->p_sigcatch &= ~bit; 10712882Ssam } else { 10812951Ssam p->p_sigignore &= ~bit; 10912951Ssam if (sv->sv_handler == SIG_DFL) 11012951Ssam p->p_sigcatch &= ~bit; 11112882Ssam else 11212951Ssam p->p_sigcatch |= bit; 11312882Ssam } 11412882Ssam (void) spl0(); 11512882Ssam } 11612882Ssam 1177499Sroot sigblock() 1187421Sroot { 11912882Ssam struct a { 12017153Sbloom int mask; 12112882Ssam } *uap = (struct a *)u.u_ap; 12212951Ssam register struct proc *p = u.u_procp; 1237499Sroot 12417153Sbloom (void) splhigh(); 12512882Ssam u.u_r.r_val1 = p->p_sigmask; 12617153Sbloom p->p_sigmask |= uap->mask &~ cantmask; 12712882Ssam (void) spl0(); 1287499Sroot } 1297499Sroot 1307499Sroot sigsetmask() 1317499Sroot { 13212882Ssam struct a { 13317153Sbloom int mask; 13412882Ssam } *uap = (struct a *)u.u_ap; 13512882Ssam register struct proc *p = u.u_procp; 1367499Sroot 13717153Sbloom (void) splhigh(); 13812882Ssam u.u_r.r_val1 = p->p_sigmask; 13917153Sbloom p->p_sigmask = uap->mask &~ cantmask; 14012882Ssam (void) spl0(); 1417499Sroot } 1427499Sroot 1437499Sroot sigpause() 1447499Sroot { 14512882Ssam struct a { 14617153Sbloom int mask; 14712882Ssam } *uap = (struct a *)u.u_ap; 14812882Ssam register struct proc *p = u.u_procp; 1497499Sroot 15012882Ssam /* 15112882Ssam * When returning from sigpause, we want 15212882Ssam * the old mask to be restored after the 15312882Ssam * signal handler has finished. Thus, we 15412882Ssam * save it here and mark the proc structure 15512882Ssam * to indicate this (should be in u.). 15612882Ssam */ 15712882Ssam u.u_oldmask = p->p_sigmask; 15812882Ssam p->p_flag |= SOMASK; 15917153Sbloom p->p_sigmask = uap->mask &~ cantmask; 16012882Ssam for (;;) 16112882Ssam sleep((caddr_t)&u, PSLEP); 16212882Ssam /*NOTREACHED*/ 1637499Sroot } 16412951Ssam #undef cantmask 1657499Sroot 1667499Sroot sigstack() 1677499Sroot { 16812951Ssam register struct a { 16912951Ssam struct sigstack *nss; 17012951Ssam struct sigstack *oss; 17112882Ssam } *uap = (struct a *)u.u_ap; 17212951Ssam struct sigstack ss; 1737499Sroot 17412951Ssam if (uap->oss) { 17512951Ssam u.u_error = copyout((caddr_t)&u.u_sigstack, (caddr_t)uap->oss, 17612951Ssam sizeof (struct sigstack)); 17712951Ssam if (u.u_error) 17812951Ssam return; 17912951Ssam } 18012951Ssam if (uap->nss) { 18112951Ssam u.u_error = 18212951Ssam copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss)); 18312951Ssam if (u.u_error == 0) 18412951Ssam u.u_sigstack = ss; 18512951Ssam } 1867499Sroot } 1877499Sroot 1888032Sroot kill() 1898032Sroot { 19012882Ssam register struct a { 19112882Ssam int pid; 19212882Ssam int signo; 19312882Ssam } *uap = (struct a *)u.u_ap; 19418336Smckusick register struct proc *p; 1958032Sroot 19618336Smckusick if (uap->signo < 0 || uap->signo > NSIG) { 19718336Smckusick u.u_error = EINVAL; 19818336Smckusick return; 19918336Smckusick } 20018336Smckusick if (uap->pid > 0) { 20118336Smckusick /* kill single process */ 20218336Smckusick p = pfind(uap->pid); 20318336Smckusick if (p == 0) { 20418336Smckusick u.u_error = ESRCH; 20518336Smckusick return; 20618336Smckusick } 20718336Smckusick if (u.u_uid && u.u_uid != p->p_uid) 20818336Smckusick u.u_error = EPERM; 20918336Smckusick else if (uap->signo) 21018336Smckusick psignal(p, uap->signo); 21118336Smckusick return; 21218336Smckusick } 21318336Smckusick switch (uap->pid) { 21418336Smckusick case -1: /* broadcast signal */ 21520998Smckusick u.u_error = killpg1(uap->signo, 0, 1); 21618336Smckusick break; 21718336Smckusick case 0: /* signal own process group */ 21818336Smckusick u.u_error = killpg1(uap->signo, 0, 0); 21918336Smckusick break; 22018336Smckusick default: /* negative explicit process group */ 22118336Smckusick u.u_error = killpg1(uap->signo, -uap->pid, 0); 22218336Smckusick break; 22318336Smckusick } 22418336Smckusick return; 2258032Sroot } 2268032Sroot 2278032Sroot killpg() 2288032Sroot { 2299989Ssam register struct a { 2309989Ssam int pgrp; 2319989Ssam int signo; 2329989Ssam } *uap = (struct a *)u.u_ap; 2338032Sroot 23418336Smckusick if (uap->signo < 0 || uap->signo > NSIG) { 23518336Smckusick u.u_error = EINVAL; 23618336Smckusick return; 23718336Smckusick } 23818336Smckusick u.u_error = killpg1(uap->signo, uap->pgrp, 0); 2398032Sroot } 2408032Sroot 24112882Ssam /* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ 24212882Ssam 24318336Smckusick killpg1(signo, pgrp, all) 24418336Smckusick int signo, pgrp, all; 2459989Ssam { 2469989Ssam register struct proc *p; 24718336Smckusick int f, error = 0; 2489989Ssam 24918336Smckusick if (!all && pgrp == 0) { 2507421Sroot /* 2517421Sroot * Zero process id means send to my process group. 2527421Sroot */ 25318336Smckusick pgrp = u.u_procp->p_pgrp; 25418336Smckusick if (pgrp == 0) 25520998Smckusick return (ESRCH); 2567421Sroot } 25716531Skarels for (f = 0, p = allproc; p != NULL; p = p->p_nxt) { 25818336Smckusick if ((p->p_pgrp != pgrp && !all) || p->p_ppid == 0 || 25918336Smckusick (p->p_flag&SSYS) || (all && p == u.u_procp)) 2607421Sroot continue; 2617421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 26218336Smckusick (signo != SIGCONT || !inferior(p))) { 26320998Smckusick if (!all) 26420998Smckusick error = EPERM; 2657421Sroot continue; 26618336Smckusick } 26720998Smckusick f++; 26812835Ssam if (signo) 26912835Ssam psignal(p, signo); 2707421Sroot } 27118336Smckusick return (f == 0 ? ESRCH : error); 2727421Sroot } 2737421Sroot 2747421Sroot /* 2757421Sroot * Send the specified signal to 2767421Sroot * all processes with 'pgrp' as 2777421Sroot * process group. 2787421Sroot */ 2797421Sroot gsignal(pgrp, sig) 2807421Sroot register int pgrp; 2817421Sroot { 2827421Sroot register struct proc *p; 2837421Sroot 2847421Sroot if (pgrp == 0) 2857421Sroot return; 28616531Skarels for (p = allproc; p != NULL; p = p->p_nxt) 2877421Sroot if (p->p_pgrp == pgrp) 2887421Sroot psignal(p, sig); 2897421Sroot } 2907421Sroot 2917421Sroot /* 2927421Sroot * Send the specified signal to 2937421Sroot * the specified process. 2947421Sroot */ 2957421Sroot psignal(p, sig) 2967421Sroot register struct proc *p; 2977421Sroot register int sig; 2987421Sroot { 2997421Sroot register int s; 3007421Sroot register int (*action)(); 30117153Sbloom int mask; 3027421Sroot 3037421Sroot if ((unsigned)sig >= NSIG) 3047421Sroot return; 30517153Sbloom mask = sigmask(sig); 3067421Sroot 3077421Sroot /* 3087421Sroot * If proc is traced, always give parent a chance. 3097421Sroot */ 3107421Sroot if (p->p_flag & STRC) 3117421Sroot action = SIG_DFL; 3127421Sroot else { 3137421Sroot /* 31412882Ssam * If the signal is being ignored, 31512882Ssam * then we forget about it immediately. 3167421Sroot */ 31717153Sbloom if (p->p_sigignore & mask) 3187421Sroot return; 31917153Sbloom if (p->p_sigmask & mask) 32012882Ssam action = SIG_HOLD; 32117153Sbloom else if (p->p_sigcatch & mask) 32212882Ssam action = SIG_CATCH; 32312882Ssam else 32412882Ssam action = SIG_DFL; 3257421Sroot } 32617153Sbloom #define stops (sigmask(SIGSTOP)|sigmask(SIGTSTP)| \ 32717153Sbloom sigmask(SIGTTIN)|sigmask(SIGTTOU)) 3287421Sroot if (sig) { 32917153Sbloom p->p_sig |= mask; 3307421Sroot switch (sig) { 3317421Sroot 3327421Sroot case SIGTERM: 33312882Ssam if ((p->p_flag&STRC) || action != SIG_DFL) 3347421Sroot break; 3357421Sroot /* fall into ... */ 3367421Sroot 3377421Sroot case SIGKILL: 3387421Sroot if (p->p_nice > NZERO) 3397421Sroot p->p_nice = NZERO; 3407421Sroot break; 3417421Sroot 3427421Sroot case SIGCONT: 3437421Sroot p->p_sig &= ~stops; 3447421Sroot break; 3457421Sroot 3467421Sroot case SIGSTOP: 3477421Sroot case SIGTSTP: 3487421Sroot case SIGTTIN: 3497421Sroot case SIGTTOU: 35017153Sbloom p->p_sig &= ~sigmask(SIGCONT); 3517421Sroot break; 3527421Sroot } 3537421Sroot } 3547421Sroot #undef stops 3557421Sroot /* 3567421Sroot * Defer further processing for signals which are held. 3577421Sroot */ 3587421Sroot if (action == SIG_HOLD) 3597421Sroot return; 36017153Sbloom s = splhigh(); 3617421Sroot switch (p->p_stat) { 3627421Sroot 3637421Sroot case SSLEEP: 3647421Sroot /* 3657421Sroot * If process is sleeping at negative priority 3667421Sroot * we can't interrupt the sleep... the signal will 3677421Sroot * be noticed when the process returns through 3687421Sroot * trap() or syscall(). 3697421Sroot */ 3707421Sroot if (p->p_pri <= PZERO) 3717421Sroot goto out; 3727421Sroot /* 3737421Sroot * Process is sleeping and traced... make it runnable 3747421Sroot * so it can discover the signal in issig() and stop 3757421Sroot * for the parent. 3767421Sroot */ 3777421Sroot if (p->p_flag&STRC) 3787421Sroot goto run; 3797421Sroot switch (sig) { 3807421Sroot 3817421Sroot case SIGSTOP: 3827421Sroot case SIGTSTP: 3837421Sroot case SIGTTIN: 3847421Sroot case SIGTTOU: 3857421Sroot /* 3867421Sroot * These are the signals which by default 3877421Sroot * stop a process. 3887421Sroot */ 3897421Sroot if (action != SIG_DFL) 3907421Sroot goto run; 3917421Sroot /* 3927421Sroot * Don't clog system with children of init 3937421Sroot * stopped from the keyboard. 3947421Sroot */ 3957421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 3967421Sroot psignal(p, SIGKILL); 39717153Sbloom p->p_sig &= ~mask; 3987421Sroot splx(s); 3997421Sroot return; 4007421Sroot } 4017421Sroot /* 4027421Sroot * If a child in vfork(), stopping could 4037421Sroot * cause deadlock. 4047421Sroot */ 4057421Sroot if (p->p_flag&SVFORK) 4067421Sroot goto out; 40717153Sbloom p->p_sig &= ~mask; 4087421Sroot p->p_cursig = sig; 40918331Skarels psignal(p->p_pptr, SIGCHLD); 4107421Sroot stop(p); 4117421Sroot goto out; 4127421Sroot 4137421Sroot case SIGIO: 4147421Sroot case SIGURG: 4157421Sroot case SIGCHLD: 41617597Sbloom case SIGWINCH: 4177421Sroot /* 4187421Sroot * These signals are special in that they 4197421Sroot * don't get propogated... if the process 4207421Sroot * isn't interested, forget it. 4217421Sroot */ 4227421Sroot if (action != SIG_DFL) 4237421Sroot goto run; 42417153Sbloom p->p_sig &= ~mask; /* take it away */ 4257421Sroot goto out; 4267421Sroot 4277421Sroot default: 4287421Sroot /* 4297421Sroot * All other signals cause the process to run 4307421Sroot */ 4317421Sroot goto run; 4327421Sroot } 4337421Sroot /*NOTREACHED*/ 4347421Sroot 4357421Sroot case SSTOP: 4367421Sroot /* 4377421Sroot * If traced process is already stopped, 4387421Sroot * then no further action is necessary. 4397421Sroot */ 4407421Sroot if (p->p_flag&STRC) 4417421Sroot goto out; 4427421Sroot switch (sig) { 4437421Sroot 4447421Sroot case SIGKILL: 4457421Sroot /* 4467421Sroot * Kill signal always sets processes running. 4477421Sroot */ 4487421Sroot goto run; 4497421Sroot 4507421Sroot case SIGCONT: 4517421Sroot /* 4527421Sroot * If the process catches SIGCONT, let it handle 4537421Sroot * the signal itself. If it isn't waiting on 4547421Sroot * an event, then it goes back to run state. 4557421Sroot * Otherwise, process goes back to sleep state. 4567421Sroot */ 4577421Sroot if (action != SIG_DFL || p->p_wchan == 0) 4587421Sroot goto run; 4597421Sroot p->p_stat = SSLEEP; 4607421Sroot goto out; 4617421Sroot 4627421Sroot case SIGSTOP: 4637421Sroot case SIGTSTP: 4647421Sroot case SIGTTIN: 4657421Sroot case SIGTTOU: 4667421Sroot /* 4677421Sroot * Already stopped, don't need to stop again. 4687421Sroot * (If we did the shell could get confused.) 4697421Sroot */ 47017153Sbloom p->p_sig &= ~mask; /* take it away */ 4717421Sroot goto out; 4727421Sroot 4737421Sroot default: 4747421Sroot /* 4757421Sroot * If process is sleeping interruptibly, then 4767421Sroot * unstick it so that when it is continued 4777421Sroot * it can look at the signal. 4787421Sroot * But don't setrun the process as its not to 4797421Sroot * be unstopped by the signal alone. 4807421Sroot */ 4817421Sroot if (p->p_wchan && p->p_pri > PZERO) 4827421Sroot unsleep(p); 4837421Sroot goto out; 4847421Sroot } 4857421Sroot /*NOTREACHED*/ 4867421Sroot 4877421Sroot default: 4887421Sroot /* 4897421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 4907421Sroot * other than kicking ourselves if we are running. 4917421Sroot * It will either never be noticed, or noticed very soon. 4927421Sroot */ 4937421Sroot if (p == u.u_procp && !noproc) 4948444Sroot #include "../vax/mtpr.h" 4957421Sroot aston(); 4967421Sroot goto out; 4977421Sroot } 4987421Sroot /*NOTREACHED*/ 4997421Sroot run: 5007421Sroot /* 5017421Sroot * Raise priority to at least PUSER. 5027421Sroot */ 5037421Sroot if (p->p_pri > PUSER) 50417399Skarels p->p_pri = PUSER; 5057421Sroot setrun(p); 5067421Sroot out: 5077421Sroot splx(s); 5087421Sroot } 5097421Sroot 5107421Sroot /* 5117421Sroot * Returns true if the current 5127421Sroot * process has a signal to process. 5137421Sroot * The signal to process is put in p_cursig. 5147421Sroot * This is asked at least once each time a process enters the 5157421Sroot * system (though this can usually be done without actually 5167421Sroot * calling issig by checking the pending signal masks.) 5177421Sroot * A signal does not do anything 5187421Sroot * directly to a process; it sets 5197421Sroot * a flag that asks the process to 5207421Sroot * do something to itself. 5217421Sroot */ 5227421Sroot issig() 5237421Sroot { 5247421Sroot register struct proc *p; 5257421Sroot register int sig; 52617153Sbloom int sigbits, mask; 5277421Sroot 5287421Sroot p = u.u_procp; 5297421Sroot for (;;) { 53014782Ssam sigbits = p->p_sig &~ p->p_sigmask; 5317421Sroot if ((p->p_flag&STRC) == 0) 53214782Ssam sigbits &= ~p->p_sigignore; 5337421Sroot if (p->p_flag&SVFORK) 5347421Sroot #define bit(a) (1<<(a-1)) 5357421Sroot sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 5367421Sroot if (sigbits == 0) 5377421Sroot break; 53812882Ssam sig = ffs(sigbits); 53917153Sbloom mask = sigmask(sig); 54017153Sbloom p->p_sig &= ~mask; /* take the signal! */ 5417421Sroot p->p_cursig = sig; 54212882Ssam if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) { 5437421Sroot /* 5447421Sroot * If traced, always stop, and stay 5457421Sroot * stopped until released by the parent. 5467421Sroot */ 54718331Skarels psignal(p->p_pptr, SIGCHLD); 5487421Sroot do { 5497421Sroot stop(p); 5507421Sroot swtch(); 5517421Sroot } while (!procxmt() && p->p_flag&STRC); 5527421Sroot 5537421Sroot /* 55414782Ssam * If the traced bit got turned off, 55514782Ssam * then put the signal taken above back into p_sig 55614782Ssam * and go back up to the top to rescan signals. 55714782Ssam * This ensures that p_sig* and u_signal are consistent. 5587421Sroot */ 55914782Ssam if ((p->p_flag&STRC) == 0) { 56017153Sbloom p->p_sig |= mask; 5617421Sroot continue; 5627421Sroot } 5637421Sroot 5647421Sroot /* 5657421Sroot * If parent wants us to take the signal, 5667421Sroot * then it will leave it in p->p_cursig; 5677421Sroot * otherwise we just look for signals again. 5687421Sroot */ 5697421Sroot sig = p->p_cursig; 5707421Sroot if (sig == 0) 5717421Sroot continue; 57214782Ssam 57314782Ssam /* 57414782Ssam * If signal is being masked put it back 57514782Ssam * into p_sig and look for other signals. 57614782Ssam */ 57717153Sbloom mask = sigmask(sig); 57817153Sbloom if (p->p_sigmask & mask) { 57917153Sbloom p->p_sig |= mask; 58014782Ssam continue; 58114782Ssam } 5827421Sroot } 5837421Sroot switch (u.u_signal[sig]) { 5847421Sroot 5857421Sroot case SIG_DFL: 5867421Sroot /* 5877421Sroot * Don't take default actions on system processes. 5887421Sroot */ 5897421Sroot if (p->p_ppid == 0) 5907421Sroot break; 5917421Sroot switch (sig) { 5927421Sroot 5937421Sroot case SIGTSTP: 5947421Sroot case SIGTTIN: 5957421Sroot case SIGTTOU: 5967421Sroot /* 5977421Sroot * Children of init aren't allowed to stop 5987421Sroot * on signals from the keyboard. 5997421Sroot */ 6007421Sroot if (p->p_pptr == &proc[1]) { 6017421Sroot psignal(p, SIGKILL); 6027421Sroot continue; 6037421Sroot } 6047421Sroot /* fall into ... */ 6057421Sroot 6067421Sroot case SIGSTOP: 6077421Sroot if (p->p_flag&STRC) 6087421Sroot continue; 60918331Skarels psignal(p->p_pptr, SIGCHLD); 6107421Sroot stop(p); 6117421Sroot swtch(); 6127421Sroot continue; 6137421Sroot 6147421Sroot case SIGCONT: 6157421Sroot case SIGCHLD: 61612882Ssam case SIGURG: 61712951Ssam case SIGIO: 61817597Sbloom case SIGWINCH: 6197421Sroot /* 6207421Sroot * These signals are normally not 6217421Sroot * sent if the action is the default. 6227421Sroot */ 6237421Sroot continue; /* == ignore */ 6247421Sroot 6257421Sroot default: 6267421Sroot goto send; 6277421Sroot } 6287421Sroot /*NOTREACHED*/ 6297421Sroot 6307421Sroot case SIG_HOLD: 6317421Sroot case SIG_IGN: 6327421Sroot /* 6337421Sroot * Masking above should prevent us 6347421Sroot * ever trying to take action on a held 6357421Sroot * or ignored signal, unless process is traced. 6367421Sroot */ 6377421Sroot if ((p->p_flag&STRC) == 0) 6387421Sroot printf("issig\n"); 6397421Sroot continue; 6407421Sroot 6417421Sroot default: 6427421Sroot /* 6437421Sroot * This signal has an action, let 6447421Sroot * psig process it. 6457421Sroot */ 6467421Sroot goto send; 6477421Sroot } 6487421Sroot /*NOTREACHED*/ 6497421Sroot } 6507421Sroot /* 6517421Sroot * Didn't find a signal to send. 6527421Sroot */ 6537421Sroot p->p_cursig = 0; 6547421Sroot return (0); 6557421Sroot 6567421Sroot send: 6577421Sroot /* 6587421Sroot * Let psig process the signal. 6597421Sroot */ 6607421Sroot return (sig); 6617421Sroot } 6627421Sroot 6637421Sroot /* 6647421Sroot * Put the argument process into the stopped 66518331Skarels * state and notify the parent via wakeup. 66618331Skarels * Signals are handled elsewhere. 6677421Sroot */ 6687421Sroot stop(p) 6697421Sroot register struct proc *p; 6707421Sroot { 6717421Sroot 6727421Sroot p->p_stat = SSTOP; 6737421Sroot p->p_flag &= ~SWTED; 6747421Sroot wakeup((caddr_t)p->p_pptr); 6757421Sroot } 6767421Sroot 6777421Sroot /* 6787421Sroot * Perform the action specified by 6797421Sroot * the current signal. 6807421Sroot * The usual sequence is: 6817421Sroot * if (issig()) 6827421Sroot * psig(); 6837421Sroot * The signal bit has already been cleared by issig, 6847421Sroot * and the current signal number stored in p->p_cursig. 6857421Sroot */ 6867421Sroot psig() 6877421Sroot { 68812882Ssam register struct proc *p = u.u_procp; 68912882Ssam register int sig = p->p_cursig; 69017153Sbloom int mask = sigmask(sig), returnmask; 6917421Sroot register int (*action)(); 6927421Sroot 69312882Ssam if (sig == 0) 6947421Sroot panic("psig"); 69512882Ssam action = u.u_signal[sig]; 6967421Sroot if (action != SIG_DFL) { 69717153Sbloom if (action == SIG_IGN || (p->p_sigmask & mask)) 6987421Sroot panic("psig action"); 6997421Sroot u.u_error = 0; 7007421Sroot /* 70112882Ssam * Set the new mask value and also defer further 70212882Ssam * occurences of this signal (unless we're simulating 70312882Ssam * the old signal facilities). 70412882Ssam * 70512882Ssam * Special case: user has done a sigpause. Here the 70612882Ssam * current mask is not of interest, but rather the 70712882Ssam * mask from before the sigpause is what we want restored 70812882Ssam * after the signal processing is completed. 7097421Sroot */ 71017153Sbloom (void) splhigh(); 71112882Ssam if (p->p_flag & SOUSIG) { 71212882Ssam if (sig != SIGILL && sig != SIGTRAP) { 71312882Ssam u.u_signal[sig] = SIG_DFL; 71417153Sbloom p->p_sigcatch &= ~mask; 71512882Ssam } 71617153Sbloom mask = 0; 7177421Sroot } 71812882Ssam if (p->p_flag & SOMASK) { 71912882Ssam returnmask = u.u_oldmask; 72012882Ssam p->p_flag &= ~SOMASK; 72112882Ssam } else 72212882Ssam returnmask = p->p_sigmask; 72317153Sbloom p->p_sigmask |= u.u_sigmask[sig] | mask; 72412882Ssam (void) spl0(); 7258032Sroot u.u_ru.ru_nsignals++; 72612882Ssam sendsig(action, sig, returnmask); 72712882Ssam p->p_cursig = 0; 7287421Sroot return; 7297421Sroot } 7307421Sroot u.u_acflag |= AXSIG; 73112882Ssam switch (sig) { 7327421Sroot 7337421Sroot case SIGILL: 7347421Sroot case SIGIOT: 7357421Sroot case SIGBUS: 7367421Sroot case SIGQUIT: 7377421Sroot case SIGTRAP: 7387421Sroot case SIGEMT: 7397421Sroot case SIGFPE: 7407421Sroot case SIGSEGV: 7417421Sroot case SIGSYS: 74212882Ssam u.u_arg[0] = sig; 7437421Sroot if (core()) 74412882Ssam sig += 0200; 7457421Sroot } 74612882Ssam exit(sig); 7477421Sroot } 7487421Sroot 7497421Sroot /* 7507421Sroot * Create a core image on the file "core" 7517421Sroot * If you are looking for protection glitches, 7527421Sroot * there are probably a wealth of them here 7537421Sroot * when this occurs to a suid command. 7547421Sroot * 7557421Sroot * It writes UPAGES block of the 7567421Sroot * user.h area followed by the entire 7577421Sroot * data+stack segments. 7587421Sroot */ 7597421Sroot core() 7607421Sroot { 7617421Sroot register struct inode *ip; 76216692Smckusick register struct nameidata *ndp = &u.u_nd; 7637421Sroot 76412639Ssam if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid) 7657818Sroot return (0); 7668032Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= 7678032Sroot u.u_rlimit[RLIMIT_CORE].rlim_cur) 7687421Sroot return (0); 76921016Smckusick if (u.u_procp->p_textp && access(u.u_procp->p_textp->x_iptr, IREAD)) 77021016Smckusick return (0); 7717421Sroot u.u_error = 0; 77216692Smckusick ndp->ni_nameiop = CREATE | FOLLOW; 77316692Smckusick ndp->ni_segflg = UIO_SYSSPACE; 77416692Smckusick ndp->ni_dirp = "core"; 77516692Smckusick ip = namei(ndp); 7767421Sroot if (ip == NULL) { 7777421Sroot if (u.u_error) 7787421Sroot return (0); 77916692Smckusick ip = maknode(0644, ndp); 7807421Sroot if (ip==NULL) 7817421Sroot return (0); 7827421Sroot } 7837818Sroot if (access(ip, IWRITE) || 7847818Sroot (ip->i_mode&IFMT) != IFREG || 7857818Sroot ip->i_nlink != 1) { 7867421Sroot u.u_error = EFAULT; 7877818Sroot goto out; 7887818Sroot } 7899160Ssam itrunc(ip, (u_long)0); 7907818Sroot u.u_acflag |= ACORE; 79112882Ssam u.u_error = rdwri(UIO_WRITE, ip, 79212882Ssam (caddr_t)&u, 79312882Ssam ctob(UPAGES), 79412882Ssam 0, 1, (int *)0); 7958101Sroot if (u.u_error == 0) 7968644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7978967Sroot (caddr_t)ctob(dptov(u.u_procp, 0)), 7988967Sroot ctob(u.u_dsize), 7998644Sroot ctob(UPAGES), 0, (int *)0); 8008101Sroot if (u.u_error == 0) 8018644Sroot u.u_error = rdwri(UIO_WRITE, ip, 8028967Sroot (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)), 8038967Sroot ctob(u.u_ssize), 8048644Sroot ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0); 8057818Sroot out: 8067421Sroot iput(ip); 8077818Sroot return (u.u_error == 0); 8087421Sroot } 809