123374Smckusick /* 2*29094Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323374Smckusick * All rights reserved. The Berkeley software License Agreement 423374Smckusick * specifies the terms and conditions for redistribution. 523374Smckusick * 6*29094Smckusick * @(#)kern_sig.c 7.1 (Berkeley) 06/05/86 723374Smckusick */ 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)) 3126276Skarels #define stopsigmask (sigmask(SIGSTOP)|sigmask(SIGTSTP)| \ 3226276Skarels sigmask(SIGTTIN)|sigmask(SIGTTOU)) 3312951Ssam 3417013Smckusick /* 3517013Smckusick * Generalized interface signal handler. 3617013Smckusick */ 377499Sroot sigvec() 387421Sroot { 3912951Ssam register struct a { 4012882Ssam int signo; 4112951Ssam struct sigvec *nsv; 4212951Ssam struct sigvec *osv; 4312882Ssam } *uap = (struct a *)u.u_ap; 4412951Ssam struct sigvec vec; 4512951Ssam register struct sigvec *sv; 4612882Ssam register int sig; 4718308Smckusick int bit; 487421Sroot 4912882Ssam sig = uap->signo; 5012951Ssam if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) { 5112882Ssam u.u_error = EINVAL; 5212882Ssam return; 5312882Ssam } 5412951Ssam sv = &vec; 5512951Ssam if (uap->osv) { 5612951Ssam sv->sv_handler = u.u_signal[sig]; 5712951Ssam sv->sv_mask = u.u_sigmask[sig]; 5818308Smckusick bit = sigmask(sig); 5918308Smckusick sv->sv_flags = 0; 6018308Smckusick if ((u.u_sigonstack & bit) != 0) 6118308Smckusick sv->sv_flags |= SV_ONSTACK; 6218308Smckusick if ((u.u_sigintr & bit) != 0) 6318308Smckusick sv->sv_flags |= SV_INTERRUPT; 6412951Ssam u.u_error = 6512951Ssam copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 6612951Ssam if (u.u_error) 6712951Ssam return; 6812951Ssam } 6912951Ssam if (uap->nsv) { 7012951Ssam u.u_error = 7112951Ssam copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 7212951Ssam if (u.u_error) 7312951Ssam return; 7412951Ssam if (sig == SIGCONT && sv->sv_handler == SIG_IGN) { 7512951Ssam u.u_error = EINVAL; 7612951Ssam return; 7712951Ssam } 7812951Ssam setsigvec(sig, sv); 7912951Ssam } 807421Sroot } 817421Sroot 8212951Ssam setsigvec(sig, sv) 8312951Ssam int sig; 8412951Ssam register struct sigvec *sv; 8512882Ssam { 8612882Ssam register struct proc *p; 8712951Ssam register int bit; 8812882Ssam 8917153Sbloom bit = sigmask(sig); 9012882Ssam p = u.u_procp; 9112882Ssam /* 9212882Ssam * Change setting atomically. 9312882Ssam */ 9417153Sbloom (void) splhigh(); 9512951Ssam u.u_signal[sig] = sv->sv_handler; 9612951Ssam u.u_sigmask[sig] = sv->sv_mask &~ cantmask; 9718308Smckusick if (sv->sv_flags & SV_INTERRUPT) 9818308Smckusick u.u_sigintr |= bit; 9918308Smckusick else 10018308Smckusick u.u_sigintr &= ~bit; 10118308Smckusick if (sv->sv_flags & SV_ONSTACK) 10212951Ssam u.u_sigonstack |= bit; 10312951Ssam else 10412951Ssam u.u_sigonstack &= ~bit; 10512951Ssam if (sv->sv_handler == SIG_IGN) { 10612951Ssam p->p_sig &= ~bit; /* never to be seen again */ 10712951Ssam p->p_sigignore |= bit; 10812951Ssam p->p_sigcatch &= ~bit; 10912882Ssam } else { 11012951Ssam p->p_sigignore &= ~bit; 11112951Ssam if (sv->sv_handler == SIG_DFL) 11212951Ssam p->p_sigcatch &= ~bit; 11312882Ssam else 11412951Ssam p->p_sigcatch |= bit; 11512882Ssam } 11612882Ssam (void) spl0(); 11712882Ssam } 11812882Ssam 1197499Sroot sigblock() 1207421Sroot { 12112882Ssam struct a { 12217153Sbloom int mask; 12312882Ssam } *uap = (struct a *)u.u_ap; 12412951Ssam register struct proc *p = u.u_procp; 1257499Sroot 12617153Sbloom (void) splhigh(); 12712882Ssam u.u_r.r_val1 = p->p_sigmask; 12817153Sbloom p->p_sigmask |= uap->mask &~ cantmask; 12912882Ssam (void) spl0(); 1307499Sroot } 1317499Sroot 1327499Sroot sigsetmask() 1337499Sroot { 13412882Ssam struct a { 13517153Sbloom int mask; 13612882Ssam } *uap = (struct a *)u.u_ap; 13712882Ssam register struct proc *p = u.u_procp; 1387499Sroot 13917153Sbloom (void) splhigh(); 14012882Ssam u.u_r.r_val1 = p->p_sigmask; 14117153Sbloom p->p_sigmask = uap->mask &~ cantmask; 14212882Ssam (void) spl0(); 1437499Sroot } 1447499Sroot 1457499Sroot sigpause() 1467499Sroot { 14712882Ssam struct a { 14817153Sbloom int mask; 14912882Ssam } *uap = (struct a *)u.u_ap; 15012882Ssam register struct proc *p = u.u_procp; 1517499Sroot 15212882Ssam /* 15312882Ssam * When returning from sigpause, we want 15412882Ssam * the old mask to be restored after the 15512882Ssam * signal handler has finished. Thus, we 15612882Ssam * save it here and mark the proc structure 15712882Ssam * to indicate this (should be in u.). 15812882Ssam */ 15912882Ssam u.u_oldmask = p->p_sigmask; 16012882Ssam p->p_flag |= SOMASK; 16117153Sbloom p->p_sigmask = uap->mask &~ cantmask; 16212882Ssam for (;;) 16312882Ssam sleep((caddr_t)&u, PSLEP); 16412882Ssam /*NOTREACHED*/ 1657499Sroot } 16612951Ssam #undef cantmask 1677499Sroot 1687499Sroot sigstack() 1697499Sroot { 17012951Ssam register struct a { 17112951Ssam struct sigstack *nss; 17212951Ssam struct sigstack *oss; 17312882Ssam } *uap = (struct a *)u.u_ap; 17412951Ssam struct sigstack ss; 1757499Sroot 17612951Ssam if (uap->oss) { 17712951Ssam u.u_error = copyout((caddr_t)&u.u_sigstack, (caddr_t)uap->oss, 17812951Ssam sizeof (struct sigstack)); 17912951Ssam if (u.u_error) 18012951Ssam return; 18112951Ssam } 18212951Ssam if (uap->nss) { 18312951Ssam u.u_error = 18412951Ssam copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss)); 18512951Ssam if (u.u_error == 0) 18612951Ssam u.u_sigstack = ss; 18712951Ssam } 1887499Sroot } 1897499Sroot 1908032Sroot kill() 1918032Sroot { 19212882Ssam register struct a { 19312882Ssam int pid; 19412882Ssam int signo; 19512882Ssam } *uap = (struct a *)u.u_ap; 19618336Smckusick register struct proc *p; 1978032Sroot 19818336Smckusick if (uap->signo < 0 || uap->signo > NSIG) { 19918336Smckusick u.u_error = EINVAL; 20018336Smckusick return; 20118336Smckusick } 20218336Smckusick if (uap->pid > 0) { 20318336Smckusick /* kill single process */ 20418336Smckusick p = pfind(uap->pid); 20518336Smckusick if (p == 0) { 20618336Smckusick u.u_error = ESRCH; 20718336Smckusick return; 20818336Smckusick } 20918336Smckusick if (u.u_uid && u.u_uid != p->p_uid) 21018336Smckusick u.u_error = EPERM; 21118336Smckusick else if (uap->signo) 21218336Smckusick psignal(p, uap->signo); 21318336Smckusick return; 21418336Smckusick } 21518336Smckusick switch (uap->pid) { 21618336Smckusick case -1: /* broadcast signal */ 21720998Smckusick u.u_error = killpg1(uap->signo, 0, 1); 21818336Smckusick break; 21918336Smckusick case 0: /* signal own process group */ 22018336Smckusick u.u_error = killpg1(uap->signo, 0, 0); 22118336Smckusick break; 22218336Smckusick default: /* negative explicit process group */ 22318336Smckusick u.u_error = killpg1(uap->signo, -uap->pid, 0); 22418336Smckusick break; 22518336Smckusick } 22618336Smckusick return; 2278032Sroot } 2288032Sroot 2298032Sroot killpg() 2308032Sroot { 2319989Ssam register struct a { 2329989Ssam int pgrp; 2339989Ssam int signo; 2349989Ssam } *uap = (struct a *)u.u_ap; 2358032Sroot 23618336Smckusick if (uap->signo < 0 || uap->signo > NSIG) { 23718336Smckusick u.u_error = EINVAL; 23818336Smckusick return; 23918336Smckusick } 24018336Smckusick u.u_error = killpg1(uap->signo, uap->pgrp, 0); 2418032Sroot } 2428032Sroot 24312882Ssam /* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ 24412882Ssam 24518336Smckusick killpg1(signo, pgrp, all) 24618336Smckusick int signo, pgrp, all; 2479989Ssam { 2489989Ssam register struct proc *p; 24918336Smckusick int f, error = 0; 2509989Ssam 25118336Smckusick if (!all && pgrp == 0) { 2527421Sroot /* 2537421Sroot * Zero process id means send to my process group. 2547421Sroot */ 25518336Smckusick pgrp = u.u_procp->p_pgrp; 25618336Smckusick if (pgrp == 0) 25720998Smckusick return (ESRCH); 2587421Sroot } 25916531Skarels for (f = 0, p = allproc; p != NULL; p = p->p_nxt) { 26018336Smckusick if ((p->p_pgrp != pgrp && !all) || p->p_ppid == 0 || 26118336Smckusick (p->p_flag&SSYS) || (all && p == u.u_procp)) 2627421Sroot continue; 2637421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 26418336Smckusick (signo != SIGCONT || !inferior(p))) { 26520998Smckusick if (!all) 26620998Smckusick error = EPERM; 2677421Sroot continue; 26818336Smckusick } 26920998Smckusick f++; 27012835Ssam if (signo) 27112835Ssam psignal(p, signo); 2727421Sroot } 27324420Skarels return (error ? error : (f == 0 ? ESRCH : 0)); 2747421Sroot } 2757421Sroot 2767421Sroot /* 2777421Sroot * Send the specified signal to 2787421Sroot * all processes with 'pgrp' as 2797421Sroot * process group. 2807421Sroot */ 2817421Sroot gsignal(pgrp, sig) 2827421Sroot register int pgrp; 2837421Sroot { 2847421Sroot register struct proc *p; 2857421Sroot 2867421Sroot if (pgrp == 0) 2877421Sroot return; 28816531Skarels for (p = allproc; p != NULL; p = p->p_nxt) 2897421Sroot if (p->p_pgrp == pgrp) 2907421Sroot psignal(p, sig); 2917421Sroot } 2927421Sroot 2937421Sroot /* 2947421Sroot * Send the specified signal to 2957421Sroot * the specified process. 2967421Sroot */ 2977421Sroot psignal(p, sig) 2987421Sroot register struct proc *p; 2997421Sroot register int sig; 3007421Sroot { 3017421Sroot register int s; 3027421Sroot register int (*action)(); 30317153Sbloom int mask; 3047421Sroot 3057421Sroot if ((unsigned)sig >= NSIG) 3067421Sroot return; 30717153Sbloom mask = sigmask(sig); 3087421Sroot 3097421Sroot /* 3107421Sroot * If proc is traced, always give parent a chance. 3117421Sroot */ 3127421Sroot if (p->p_flag & STRC) 3137421Sroot action = SIG_DFL; 3147421Sroot else { 3157421Sroot /* 31612882Ssam * If the signal is being ignored, 31712882Ssam * then we forget about it immediately. 3187421Sroot */ 31917153Sbloom if (p->p_sigignore & mask) 3207421Sroot return; 32117153Sbloom if (p->p_sigmask & mask) 32212882Ssam action = SIG_HOLD; 32317153Sbloom else if (p->p_sigcatch & mask) 32412882Ssam action = SIG_CATCH; 32512882Ssam else 32612882Ssam action = SIG_DFL; 3277421Sroot } 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: 34326276Skarels p->p_sig &= ~stopsigmask; 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 /* 3557421Sroot * Defer further processing for signals which are held. 3567421Sroot */ 3577421Sroot if (action == SIG_HOLD) 3587421Sroot return; 35917153Sbloom s = splhigh(); 3607421Sroot switch (p->p_stat) { 3617421Sroot 3627421Sroot case SSLEEP: 3637421Sroot /* 3647421Sroot * If process is sleeping at negative priority 3657421Sroot * we can't interrupt the sleep... the signal will 3667421Sroot * be noticed when the process returns through 3677421Sroot * trap() or syscall(). 3687421Sroot */ 3697421Sroot if (p->p_pri <= PZERO) 3707421Sroot goto out; 3717421Sroot /* 3727421Sroot * Process is sleeping and traced... make it runnable 3737421Sroot * so it can discover the signal in issig() and stop 3747421Sroot * for the parent. 3757421Sroot */ 3767421Sroot if (p->p_flag&STRC) 3777421Sroot goto run; 3787421Sroot switch (sig) { 3797421Sroot 3807421Sroot case SIGSTOP: 3817421Sroot case SIGTSTP: 3827421Sroot case SIGTTIN: 3837421Sroot case SIGTTOU: 3847421Sroot /* 3857421Sroot * These are the signals which by default 3867421Sroot * stop a process. 3877421Sroot */ 3887421Sroot if (action != SIG_DFL) 3897421Sroot goto run; 3907421Sroot /* 3917421Sroot * Don't clog system with children of init 3927421Sroot * stopped from the keyboard. 3937421Sroot */ 3947421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 3957421Sroot psignal(p, SIGKILL); 39617153Sbloom p->p_sig &= ~mask; 3977421Sroot splx(s); 3987421Sroot return; 3997421Sroot } 4007421Sroot /* 4017421Sroot * If a child in vfork(), stopping could 4027421Sroot * cause deadlock. 4037421Sroot */ 4047421Sroot if (p->p_flag&SVFORK) 4057421Sroot goto out; 40617153Sbloom p->p_sig &= ~mask; 4077421Sroot p->p_cursig = sig; 40818331Skarels psignal(p->p_pptr, SIGCHLD); 4097421Sroot stop(p); 4107421Sroot goto out; 4117421Sroot 4127421Sroot case SIGIO: 4137421Sroot case SIGURG: 4147421Sroot case SIGCHLD: 41517597Sbloom case SIGWINCH: 4167421Sroot /* 4177421Sroot * These signals are special in that they 4187421Sroot * don't get propogated... if the process 4197421Sroot * isn't interested, forget it. 4207421Sroot */ 4217421Sroot if (action != SIG_DFL) 4227421Sroot goto run; 42317153Sbloom p->p_sig &= ~mask; /* take it away */ 4247421Sroot goto out; 4257421Sroot 4267421Sroot default: 4277421Sroot /* 4287421Sroot * All other signals cause the process to run 4297421Sroot */ 4307421Sroot goto run; 4317421Sroot } 4327421Sroot /*NOTREACHED*/ 4337421Sroot 4347421Sroot case SSTOP: 4357421Sroot /* 4367421Sroot * If traced process is already stopped, 4377421Sroot * then no further action is necessary. 4387421Sroot */ 4397421Sroot if (p->p_flag&STRC) 4407421Sroot goto out; 4417421Sroot switch (sig) { 4427421Sroot 4437421Sroot case SIGKILL: 4447421Sroot /* 4457421Sroot * Kill signal always sets processes running. 4467421Sroot */ 4477421Sroot goto run; 4487421Sroot 4497421Sroot case SIGCONT: 4507421Sroot /* 4517421Sroot * If the process catches SIGCONT, let it handle 4527421Sroot * the signal itself. If it isn't waiting on 4537421Sroot * an event, then it goes back to run state. 4547421Sroot * Otherwise, process goes back to sleep state. 4557421Sroot */ 4567421Sroot if (action != SIG_DFL || p->p_wchan == 0) 4577421Sroot goto run; 4587421Sroot p->p_stat = SSLEEP; 4597421Sroot goto out; 4607421Sroot 4617421Sroot case SIGSTOP: 4627421Sroot case SIGTSTP: 4637421Sroot case SIGTTIN: 4647421Sroot case SIGTTOU: 4657421Sroot /* 4667421Sroot * Already stopped, don't need to stop again. 4677421Sroot * (If we did the shell could get confused.) 4687421Sroot */ 46917153Sbloom p->p_sig &= ~mask; /* take it away */ 4707421Sroot goto out; 4717421Sroot 4727421Sroot default: 4737421Sroot /* 4747421Sroot * If process is sleeping interruptibly, then 4757421Sroot * unstick it so that when it is continued 4767421Sroot * it can look at the signal. 4777421Sroot * But don't setrun the process as its not to 4787421Sroot * be unstopped by the signal alone. 4797421Sroot */ 4807421Sroot if (p->p_wchan && p->p_pri > PZERO) 4817421Sroot unsleep(p); 4827421Sroot goto out; 4837421Sroot } 4847421Sroot /*NOTREACHED*/ 4857421Sroot 4867421Sroot default: 4877421Sroot /* 4887421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 4897421Sroot * other than kicking ourselves if we are running. 4907421Sroot * It will either never be noticed, or noticed very soon. 4917421Sroot */ 4927421Sroot if (p == u.u_procp && !noproc) 4938444Sroot #include "../vax/mtpr.h" 4947421Sroot aston(); 4957421Sroot goto out; 4967421Sroot } 4977421Sroot /*NOTREACHED*/ 4987421Sroot run: 4997421Sroot /* 5007421Sroot * Raise priority to at least PUSER. 5017421Sroot */ 5027421Sroot if (p->p_pri > PUSER) 50317399Skarels p->p_pri = PUSER; 5047421Sroot setrun(p); 5057421Sroot out: 5067421Sroot splx(s); 5077421Sroot } 5087421Sroot 5097421Sroot /* 5107421Sroot * Returns true if the current 5117421Sroot * process has a signal to process. 5127421Sroot * The signal to process is put in p_cursig. 5137421Sroot * This is asked at least once each time a process enters the 5147421Sroot * system (though this can usually be done without actually 5157421Sroot * calling issig by checking the pending signal masks.) 5167421Sroot * A signal does not do anything 5177421Sroot * directly to a process; it sets 5187421Sroot * a flag that asks the process to 5197421Sroot * do something to itself. 5207421Sroot */ 5217421Sroot issig() 5227421Sroot { 5237421Sroot register struct proc *p; 5247421Sroot register int sig; 52517153Sbloom int sigbits, mask; 5267421Sroot 5277421Sroot p = u.u_procp; 5287421Sroot for (;;) { 52914782Ssam sigbits = p->p_sig &~ p->p_sigmask; 5307421Sroot if ((p->p_flag&STRC) == 0) 53114782Ssam sigbits &= ~p->p_sigignore; 5327421Sroot if (p->p_flag&SVFORK) 53326276Skarels sigbits &= ~stopsigmask; 5347421Sroot if (sigbits == 0) 5357421Sroot break; 53626354Skarels sig = ffs((long)sigbits); 53717153Sbloom mask = sigmask(sig); 53817153Sbloom p->p_sig &= ~mask; /* take the signal! */ 5397421Sroot p->p_cursig = sig; 54012882Ssam if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) { 5417421Sroot /* 5427421Sroot * If traced, always stop, and stay 5437421Sroot * stopped until released by the parent. 5447421Sroot */ 54518331Skarels psignal(p->p_pptr, SIGCHLD); 5467421Sroot do { 5477421Sroot stop(p); 5487421Sroot swtch(); 5497421Sroot } while (!procxmt() && p->p_flag&STRC); 5507421Sroot 5517421Sroot /* 55214782Ssam * If the traced bit got turned off, 55314782Ssam * then put the signal taken above back into p_sig 55414782Ssam * and go back up to the top to rescan signals. 55514782Ssam * This ensures that p_sig* and u_signal are consistent. 5567421Sroot */ 55714782Ssam if ((p->p_flag&STRC) == 0) { 55817153Sbloom p->p_sig |= mask; 5597421Sroot continue; 5607421Sroot } 5617421Sroot 5627421Sroot /* 5637421Sroot * If parent wants us to take the signal, 5647421Sroot * then it will leave it in p->p_cursig; 5657421Sroot * otherwise we just look for signals again. 5667421Sroot */ 5677421Sroot sig = p->p_cursig; 5687421Sroot if (sig == 0) 5697421Sroot continue; 57014782Ssam 57114782Ssam /* 57214782Ssam * If signal is being masked put it back 57314782Ssam * into p_sig and look for other signals. 57414782Ssam */ 57517153Sbloom mask = sigmask(sig); 57617153Sbloom if (p->p_sigmask & mask) { 57717153Sbloom p->p_sig |= mask; 57814782Ssam continue; 57914782Ssam } 5807421Sroot } 58124901Skarels switch ((int)u.u_signal[sig]) { 5827421Sroot 5837421Sroot case SIG_DFL: 5847421Sroot /* 5857421Sroot * Don't take default actions on system processes. 5867421Sroot */ 5877421Sroot if (p->p_ppid == 0) 5887421Sroot break; 5897421Sroot switch (sig) { 5907421Sroot 5917421Sroot case SIGTSTP: 5927421Sroot case SIGTTIN: 5937421Sroot case SIGTTOU: 5947421Sroot /* 5957421Sroot * Children of init aren't allowed to stop 5967421Sroot * on signals from the keyboard. 5977421Sroot */ 5987421Sroot if (p->p_pptr == &proc[1]) { 5997421Sroot psignal(p, SIGKILL); 6007421Sroot continue; 6017421Sroot } 6027421Sroot /* fall into ... */ 6037421Sroot 6047421Sroot case SIGSTOP: 6057421Sroot if (p->p_flag&STRC) 6067421Sroot continue; 60718331Skarels psignal(p->p_pptr, SIGCHLD); 6087421Sroot stop(p); 6097421Sroot swtch(); 6107421Sroot continue; 6117421Sroot 6127421Sroot case SIGCONT: 6137421Sroot case SIGCHLD: 61412882Ssam case SIGURG: 61512951Ssam case SIGIO: 61617597Sbloom case SIGWINCH: 6177421Sroot /* 6187421Sroot * These signals are normally not 6197421Sroot * sent if the action is the default. 6207421Sroot */ 6217421Sroot continue; /* == ignore */ 6227421Sroot 6237421Sroot default: 6247421Sroot goto send; 6257421Sroot } 6267421Sroot /*NOTREACHED*/ 6277421Sroot 6287421Sroot case SIG_HOLD: 6297421Sroot case SIG_IGN: 6307421Sroot /* 6317421Sroot * Masking above should prevent us 6327421Sroot * ever trying to take action on a held 6337421Sroot * or ignored signal, unless process is traced. 6347421Sroot */ 6357421Sroot if ((p->p_flag&STRC) == 0) 6367421Sroot printf("issig\n"); 6377421Sroot continue; 6387421Sroot 6397421Sroot default: 6407421Sroot /* 6417421Sroot * This signal has an action, let 6427421Sroot * psig process it. 6437421Sroot */ 6447421Sroot goto send; 6457421Sroot } 6467421Sroot /*NOTREACHED*/ 6477421Sroot } 6487421Sroot /* 6497421Sroot * Didn't find a signal to send. 6507421Sroot */ 6517421Sroot p->p_cursig = 0; 6527421Sroot return (0); 6537421Sroot 6547421Sroot send: 6557421Sroot /* 6567421Sroot * Let psig process the signal. 6577421Sroot */ 6587421Sroot return (sig); 6597421Sroot } 6607421Sroot 6617421Sroot /* 6627421Sroot * Put the argument process into the stopped 66318331Skarels * state and notify the parent via wakeup. 66418331Skarels * Signals are handled elsewhere. 6657421Sroot */ 6667421Sroot stop(p) 6677421Sroot register struct proc *p; 6687421Sroot { 6697421Sroot 6707421Sroot p->p_stat = SSTOP; 6717421Sroot p->p_flag &= ~SWTED; 6727421Sroot wakeup((caddr_t)p->p_pptr); 6737421Sroot } 6747421Sroot 6757421Sroot /* 6767421Sroot * Perform the action specified by 6777421Sroot * the current signal. 6787421Sroot * The usual sequence is: 6797421Sroot * if (issig()) 6807421Sroot * psig(); 6817421Sroot * The signal bit has already been cleared by issig, 6827421Sroot * and the current signal number stored in p->p_cursig. 6837421Sroot */ 6847421Sroot psig() 6857421Sroot { 68612882Ssam register struct proc *p = u.u_procp; 68712882Ssam register int sig = p->p_cursig; 68817153Sbloom int mask = sigmask(sig), returnmask; 6897421Sroot register int (*action)(); 6907421Sroot 69112882Ssam if (sig == 0) 6927421Sroot panic("psig"); 69312882Ssam action = u.u_signal[sig]; 6947421Sroot if (action != SIG_DFL) { 69517153Sbloom if (action == SIG_IGN || (p->p_sigmask & mask)) 6967421Sroot panic("psig action"); 6977421Sroot u.u_error = 0; 6987421Sroot /* 69912882Ssam * Set the new mask value and also defer further 70012882Ssam * occurences of this signal (unless we're simulating 70112882Ssam * the old signal facilities). 70212882Ssam * 70312882Ssam * Special case: user has done a sigpause. Here the 70412882Ssam * current mask is not of interest, but rather the 70512882Ssam * mask from before the sigpause is what we want restored 70612882Ssam * after the signal processing is completed. 7077421Sroot */ 70817153Sbloom (void) splhigh(); 70912882Ssam if (p->p_flag & SOUSIG) { 71012882Ssam if (sig != SIGILL && sig != SIGTRAP) { 71112882Ssam u.u_signal[sig] = SIG_DFL; 71217153Sbloom p->p_sigcatch &= ~mask; 71312882Ssam } 71417153Sbloom mask = 0; 7157421Sroot } 71612882Ssam if (p->p_flag & SOMASK) { 71712882Ssam returnmask = u.u_oldmask; 71812882Ssam p->p_flag &= ~SOMASK; 71912882Ssam } else 72012882Ssam returnmask = p->p_sigmask; 72117153Sbloom p->p_sigmask |= u.u_sigmask[sig] | mask; 72212882Ssam (void) spl0(); 7238032Sroot u.u_ru.ru_nsignals++; 72412882Ssam sendsig(action, sig, returnmask); 72512882Ssam p->p_cursig = 0; 7267421Sroot return; 7277421Sroot } 7287421Sroot u.u_acflag |= AXSIG; 72912882Ssam switch (sig) { 7307421Sroot 7317421Sroot case SIGILL: 7327421Sroot case SIGIOT: 7337421Sroot case SIGBUS: 7347421Sroot case SIGQUIT: 7357421Sroot case SIGTRAP: 7367421Sroot case SIGEMT: 7377421Sroot case SIGFPE: 7387421Sroot case SIGSEGV: 7397421Sroot case SIGSYS: 74012882Ssam u.u_arg[0] = sig; 7417421Sroot if (core()) 74212882Ssam sig += 0200; 7437421Sroot } 74412882Ssam exit(sig); 7457421Sroot } 7467421Sroot 7477421Sroot /* 7487421Sroot * Create a core image on the file "core" 7497421Sroot * If you are looking for protection glitches, 7507421Sroot * there are probably a wealth of them here 7517421Sroot * when this occurs to a suid command. 7527421Sroot * 7537421Sroot * It writes UPAGES block of the 7547421Sroot * user.h area followed by the entire 7557421Sroot * data+stack segments. 7567421Sroot */ 7577421Sroot core() 7587421Sroot { 7597421Sroot register struct inode *ip; 76016692Smckusick register struct nameidata *ndp = &u.u_nd; 7617421Sroot 76212639Ssam if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid) 7637818Sroot return (0); 7648032Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= 7658032Sroot u.u_rlimit[RLIMIT_CORE].rlim_cur) 7667421Sroot return (0); 76721016Smckusick if (u.u_procp->p_textp && access(u.u_procp->p_textp->x_iptr, IREAD)) 76821016Smckusick return (0); 7697421Sroot u.u_error = 0; 77016692Smckusick ndp->ni_nameiop = CREATE | FOLLOW; 77116692Smckusick ndp->ni_segflg = UIO_SYSSPACE; 77216692Smckusick ndp->ni_dirp = "core"; 77316692Smckusick ip = namei(ndp); 7747421Sroot if (ip == NULL) { 7757421Sroot if (u.u_error) 7767421Sroot return (0); 77716692Smckusick ip = maknode(0644, ndp); 7787421Sroot if (ip==NULL) 7797421Sroot return (0); 7807421Sroot } 7817818Sroot if (access(ip, IWRITE) || 7827818Sroot (ip->i_mode&IFMT) != IFREG || 7837818Sroot ip->i_nlink != 1) { 7847421Sroot u.u_error = EFAULT; 7857818Sroot goto out; 7867818Sroot } 7879160Ssam itrunc(ip, (u_long)0); 7887818Sroot u.u_acflag |= ACORE; 78912882Ssam u.u_error = rdwri(UIO_WRITE, ip, 79012882Ssam (caddr_t)&u, 79112882Ssam ctob(UPAGES), 79226354Skarels (off_t)0, 1, (int *)0); 7938101Sroot if (u.u_error == 0) 7948644Sroot u.u_error = rdwri(UIO_WRITE, ip, 7958967Sroot (caddr_t)ctob(dptov(u.u_procp, 0)), 79626354Skarels (int)ctob(u.u_dsize), 79726354Skarels (off_t)ctob(UPAGES), 0, (int *)0); 7988101Sroot if (u.u_error == 0) 7998644Sroot u.u_error = rdwri(UIO_WRITE, ip, 8008967Sroot (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)), 80126354Skarels (int)ctob(u.u_ssize), 80226354Skarels (off_t)ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0); 8037818Sroot out: 8047421Sroot iput(ip); 8057818Sroot return (u.u_error == 0); 8067421Sroot } 807