123374Smckusick /* 237580Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 337580Smckusick * All rights reserved. 423374Smckusick * 537580Smckusick * Redistribution and use in source and binary forms are permitted 637580Smckusick * provided that the above copyright notice and this paragraph are 737580Smckusick * duplicated in all such forms and that any documentation, 837580Smckusick * advertising materials, and other materials related to such 937580Smckusick * distribution and use acknowledge that the software was developed 1037580Smckusick * by the University of California, Berkeley. The name of the 1137580Smckusick * University may not be used to endorse or promote products derived 1237580Smckusick * from this software without specific prior written permission. 1337580Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1437580Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1537580Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1637580Smckusick * 17*37581Smckusick * @(#)kern_sig.c 7.6 (Berkeley) 05/01/89 1823374Smckusick */ 197421Sroot 2017092Sbloom #include "param.h" 2117092Sbloom #include "systm.h" 2217092Sbloom #include "dir.h" 2337580Smckusick #include "ucred.h" 2417092Sbloom #include "user.h" 2537580Smckusick #include "vnode.h" 2617092Sbloom #include "proc.h" 2717092Sbloom #include "timeb.h" 2817092Sbloom #include "times.h" 2917092Sbloom #include "buf.h" 3017092Sbloom #include "mount.h" 3117092Sbloom #include "text.h" 3217092Sbloom #include "seg.h" 3317092Sbloom #include "vm.h" 3417092Sbloom #include "acct.h" 3517092Sbloom #include "uio.h" 3637580Smckusick #include "file.h" 3717092Sbloom #include "kernel.h" 387421Sroot 39*37581Smckusick #include "machine/reg.h" 40*37581Smckusick #include "machine/pte.h" 41*37581Smckusick #include "machine/psl.h" 42*37581Smckusick #include "machine/mtpr.h" 43*37581Smckusick 4417153Sbloom #define cantmask (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)) 4526276Skarels #define stopsigmask (sigmask(SIGSTOP)|sigmask(SIGTSTP)| \ 4626276Skarels sigmask(SIGTTIN)|sigmask(SIGTTOU)) 4712951Ssam 4817013Smckusick /* 4917013Smckusick * Generalized interface signal handler. 5017013Smckusick */ 517499Sroot sigvec() 527421Sroot { 5312951Ssam register struct a { 5412882Ssam int signo; 5512951Ssam struct sigvec *nsv; 5612951Ssam struct sigvec *osv; 5712882Ssam } *uap = (struct a *)u.u_ap; 5812951Ssam struct sigvec vec; 5912951Ssam register struct sigvec *sv; 6012882Ssam register int sig; 6118308Smckusick int bit; 627421Sroot 6312882Ssam sig = uap->signo; 6412951Ssam if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) { 6512882Ssam u.u_error = EINVAL; 6612882Ssam return; 6712882Ssam } 6812951Ssam sv = &vec; 6912951Ssam if (uap->osv) { 7012951Ssam sv->sv_handler = u.u_signal[sig]; 7112951Ssam sv->sv_mask = u.u_sigmask[sig]; 7218308Smckusick bit = sigmask(sig); 7318308Smckusick sv->sv_flags = 0; 7418308Smckusick if ((u.u_sigonstack & bit) != 0) 7518308Smckusick sv->sv_flags |= SV_ONSTACK; 7618308Smckusick if ((u.u_sigintr & bit) != 0) 7718308Smckusick sv->sv_flags |= SV_INTERRUPT; 7812951Ssam u.u_error = 7912951Ssam copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 8012951Ssam if (u.u_error) 8112951Ssam return; 8212951Ssam } 8312951Ssam if (uap->nsv) { 8412951Ssam u.u_error = 8512951Ssam copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 8612951Ssam if (u.u_error) 8712951Ssam return; 8812951Ssam if (sig == SIGCONT && sv->sv_handler == SIG_IGN) { 8912951Ssam u.u_error = EINVAL; 9012951Ssam return; 9112951Ssam } 9212951Ssam setsigvec(sig, sv); 9312951Ssam } 947421Sroot } 957421Sroot 9612951Ssam setsigvec(sig, sv) 9712951Ssam int sig; 9812951Ssam register struct sigvec *sv; 9912882Ssam { 10012882Ssam register struct proc *p; 10112951Ssam register int bit; 10212882Ssam 10317153Sbloom bit = sigmask(sig); 10412882Ssam p = u.u_procp; 10512882Ssam /* 10612882Ssam * Change setting atomically. 10712882Ssam */ 10817153Sbloom (void) splhigh(); 10912951Ssam u.u_signal[sig] = sv->sv_handler; 11012951Ssam u.u_sigmask[sig] = sv->sv_mask &~ cantmask; 11118308Smckusick if (sv->sv_flags & SV_INTERRUPT) 11218308Smckusick u.u_sigintr |= bit; 11318308Smckusick else 11418308Smckusick u.u_sigintr &= ~bit; 11518308Smckusick if (sv->sv_flags & SV_ONSTACK) 11612951Ssam u.u_sigonstack |= bit; 11712951Ssam else 11812951Ssam u.u_sigonstack &= ~bit; 11912951Ssam if (sv->sv_handler == SIG_IGN) { 12012951Ssam p->p_sig &= ~bit; /* never to be seen again */ 12112951Ssam p->p_sigignore |= bit; 12212951Ssam p->p_sigcatch &= ~bit; 12312882Ssam } else { 12412951Ssam p->p_sigignore &= ~bit; 12512951Ssam if (sv->sv_handler == SIG_DFL) 12612951Ssam p->p_sigcatch &= ~bit; 12712882Ssam else 12812951Ssam p->p_sigcatch |= bit; 12912882Ssam } 13012882Ssam (void) spl0(); 13112882Ssam } 13212882Ssam 1337499Sroot sigblock() 1347421Sroot { 13512882Ssam struct a { 13617153Sbloom int mask; 13712882Ssam } *uap = (struct a *)u.u_ap; 13812951Ssam register struct proc *p = u.u_procp; 1397499Sroot 14017153Sbloom (void) splhigh(); 14112882Ssam u.u_r.r_val1 = p->p_sigmask; 14217153Sbloom p->p_sigmask |= uap->mask &~ cantmask; 14312882Ssam (void) spl0(); 1447499Sroot } 1457499Sroot 1467499Sroot sigsetmask() 1477499Sroot { 14812882Ssam struct a { 14917153Sbloom int mask; 15012882Ssam } *uap = (struct a *)u.u_ap; 15112882Ssam register struct proc *p = u.u_procp; 1527499Sroot 15317153Sbloom (void) splhigh(); 15412882Ssam u.u_r.r_val1 = p->p_sigmask; 15517153Sbloom p->p_sigmask = uap->mask &~ cantmask; 15612882Ssam (void) spl0(); 1577499Sroot } 1587499Sroot 1597499Sroot sigpause() 1607499Sroot { 16112882Ssam struct a { 16217153Sbloom int mask; 16312882Ssam } *uap = (struct a *)u.u_ap; 16412882Ssam register struct proc *p = u.u_procp; 1657499Sroot 16612882Ssam /* 16712882Ssam * When returning from sigpause, we want 16812882Ssam * the old mask to be restored after the 16912882Ssam * signal handler has finished. Thus, we 17012882Ssam * save it here and mark the proc structure 17112882Ssam * to indicate this (should be in u.). 17212882Ssam */ 17312882Ssam u.u_oldmask = p->p_sigmask; 17412882Ssam p->p_flag |= SOMASK; 17517153Sbloom p->p_sigmask = uap->mask &~ cantmask; 17612882Ssam for (;;) 17712882Ssam sleep((caddr_t)&u, PSLEP); 17812882Ssam /*NOTREACHED*/ 1797499Sroot } 18012951Ssam #undef cantmask 1817499Sroot 1827499Sroot sigstack() 1837499Sroot { 18412951Ssam register struct a { 18512951Ssam struct sigstack *nss; 18612951Ssam struct sigstack *oss; 18712882Ssam } *uap = (struct a *)u.u_ap; 18812951Ssam struct sigstack ss; 1897499Sroot 19012951Ssam if (uap->oss) { 19112951Ssam u.u_error = copyout((caddr_t)&u.u_sigstack, (caddr_t)uap->oss, 19212951Ssam sizeof (struct sigstack)); 19312951Ssam if (u.u_error) 19412951Ssam return; 19512951Ssam } 19612951Ssam if (uap->nss) { 19712951Ssam u.u_error = 19812951Ssam copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss)); 19912951Ssam if (u.u_error == 0) 20012951Ssam u.u_sigstack = ss; 20112951Ssam } 2027499Sroot } 2037499Sroot 2048032Sroot kill() 2058032Sroot { 20612882Ssam register struct a { 20712882Ssam int pid; 20812882Ssam int signo; 20912882Ssam } *uap = (struct a *)u.u_ap; 21018336Smckusick register struct proc *p; 2118032Sroot 21218336Smckusick if (uap->signo < 0 || uap->signo > NSIG) { 21318336Smckusick u.u_error = EINVAL; 21418336Smckusick return; 21518336Smckusick } 21618336Smckusick if (uap->pid > 0) { 21718336Smckusick /* kill single process */ 21818336Smckusick p = pfind(uap->pid); 21918336Smckusick if (p == 0) { 22018336Smckusick u.u_error = ESRCH; 22118336Smckusick return; 22218336Smckusick } 22318336Smckusick if (u.u_uid && u.u_uid != p->p_uid) 22418336Smckusick u.u_error = EPERM; 22518336Smckusick else if (uap->signo) 22618336Smckusick psignal(p, uap->signo); 22718336Smckusick return; 22818336Smckusick } 22918336Smckusick switch (uap->pid) { 23018336Smckusick case -1: /* broadcast signal */ 23120998Smckusick u.u_error = killpg1(uap->signo, 0, 1); 23218336Smckusick break; 23318336Smckusick case 0: /* signal own process group */ 23418336Smckusick u.u_error = killpg1(uap->signo, 0, 0); 23518336Smckusick break; 23618336Smckusick default: /* negative explicit process group */ 23718336Smckusick u.u_error = killpg1(uap->signo, -uap->pid, 0); 23818336Smckusick break; 23918336Smckusick } 24018336Smckusick return; 2418032Sroot } 2428032Sroot 2438032Sroot killpg() 2448032Sroot { 2459989Ssam register struct a { 246*37581Smckusick int pgid; 2479989Ssam int signo; 2489989Ssam } *uap = (struct a *)u.u_ap; 2498032Sroot 25018336Smckusick if (uap->signo < 0 || uap->signo > NSIG) { 25118336Smckusick u.u_error = EINVAL; 25218336Smckusick return; 25318336Smckusick } 254*37581Smckusick u.u_error = killpg1(uap->signo, uap->pgid, 0); 2558032Sroot } 2568032Sroot 25712882Ssam /* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ 25812882Ssam 259*37581Smckusick killpg1(signo, pgid, all) 260*37581Smckusick int signo, pgid, all; 2619989Ssam { 2629989Ssam register struct proc *p; 263*37581Smckusick struct pgrp *pgrp; 264*37581Smckusick int f = 0, error = 0; 2659989Ssam 266*37581Smckusick 267*37581Smckusick if (all) 268*37581Smckusick /* 269*37581Smckusick * broadcast 2707421Sroot */ 271*37581Smckusick for (p = allproc; p != NULL; p = p->p_nxt) { 272*37581Smckusick if (p->p_ppid == 0 || p->p_flag&SSYS || 273*37581Smckusick p == u.u_procp || 274*37581Smckusick (u.u_uid && u.u_uid != p->p_uid && 275*37581Smckusick !(signo == SIGCONT && inferior(p)))) 276*37581Smckusick continue; 277*37581Smckusick f++; 278*37581Smckusick if (signo) 279*37581Smckusick psignal(p, signo); 280*37581Smckusick } 281*37581Smckusick else { 282*37581Smckusick if (pgid == 0) 283*37581Smckusick /* 284*37581Smckusick * zero pgid means send to my process group. 285*37581Smckusick */ 286*37581Smckusick pgrp = u.u_procp->p_pgrp; 287*37581Smckusick else { 288*37581Smckusick pgrp = pgfind(pgid); 289*37581Smckusick if (pgrp == NULL) 290*37581Smckusick return(ESRCH); 291*37581Smckusick } 292*37581Smckusick if (!(pgrp->pg_jobc) && 293*37581Smckusick (signo==SIGTTIN || signo==SIGTTOU || signo==SIGTSTP)) 294*37581Smckusick return(EPERM); 295*37581Smckusick for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) { 296*37581Smckusick if (p->p_ppid == 0 || p->p_flag&SSYS) 297*37581Smckusick continue; 298*37581Smckusick if (u.u_uid && u.u_uid != p->p_uid && 299*37581Smckusick !(signo == SIGCONT && inferior(p))) { 30020998Smckusick error = EPERM; 301*37581Smckusick continue; 302*37581Smckusick } 303*37581Smckusick f++; 304*37581Smckusick if (signo) 305*37581Smckusick psignal(p, signo); 30618336Smckusick } 3077421Sroot } 30824420Skarels return (error ? error : (f == 0 ? ESRCH : 0)); 3097421Sroot } 3107421Sroot 3117421Sroot /* 3127421Sroot * Send the specified signal to 313*37581Smckusick * all processes with 'pgid' as 3147421Sroot * process group. 3157421Sroot */ 316*37581Smckusick gsignal(pgid, sig) 3177421Sroot { 318*37581Smckusick register struct pgrp *pgrp; 3197421Sroot register struct proc *p; 3207421Sroot 321*37581Smckusick if (!pgid) 3227421Sroot return; 323*37581Smckusick if ((pgrp = pgfind(pgid)) == NULL) 324*37581Smckusick return; 325*37581Smckusick pgsignal(pgrp, sig); 3267421Sroot } 3277421Sroot 328*37581Smckusick pgsignal(pgrp, sig) 329*37581Smckusick register struct pgrp *pgrp; 330*37581Smckusick { 331*37581Smckusick register struct proc *p; 332*37581Smckusick 333*37581Smckusick if (!(pgrp->pg_jobc) && 334*37581Smckusick (sig==SIGTTIN || sig==SIGTTOU || sig==SIGTSTP)) 335*37581Smckusick return; 336*37581Smckusick for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) 337*37581Smckusick psignal(p, sig); 338*37581Smckusick } 339*37581Smckusick 3407421Sroot /* 3417421Sroot * Send the specified signal to 3427421Sroot * the specified process. 3437421Sroot */ 3447421Sroot psignal(p, sig) 3457421Sroot register struct proc *p; 3467421Sroot register int sig; 3477421Sroot { 3487421Sroot register int s; 3497421Sroot register int (*action)(); 35017153Sbloom int mask; 3517421Sroot 3527421Sroot if ((unsigned)sig >= NSIG) 3537421Sroot return; 35417153Sbloom mask = sigmask(sig); 3557421Sroot 3567421Sroot /* 3577421Sroot * If proc is traced, always give parent a chance. 3587421Sroot */ 3597421Sroot if (p->p_flag & STRC) 3607421Sroot action = SIG_DFL; 3617421Sroot else { 3627421Sroot /* 36312882Ssam * If the signal is being ignored, 36412882Ssam * then we forget about it immediately. 3657421Sroot */ 36617153Sbloom if (p->p_sigignore & mask) 3677421Sroot return; 36817153Sbloom if (p->p_sigmask & mask) 36912882Ssam action = SIG_HOLD; 37017153Sbloom else if (p->p_sigcatch & mask) 37112882Ssam action = SIG_CATCH; 37212882Ssam else 37312882Ssam action = SIG_DFL; 3747421Sroot } 3757421Sroot if (sig) { 3767421Sroot switch (sig) { 3777421Sroot 3787421Sroot case SIGTERM: 37912882Ssam if ((p->p_flag&STRC) || action != SIG_DFL) 3807421Sroot break; 3817421Sroot /* fall into ... */ 3827421Sroot 3837421Sroot case SIGKILL: 3847421Sroot if (p->p_nice > NZERO) 3857421Sroot p->p_nice = NZERO; 3867421Sroot break; 3877421Sroot 3887421Sroot case SIGCONT: 38926276Skarels p->p_sig &= ~stopsigmask; 3907421Sroot break; 3917421Sroot 3927421Sroot case SIGTSTP: 3937421Sroot case SIGTTIN: 3947421Sroot case SIGTTOU: 395*37581Smckusick /*FALLTHROUGH*/ 396*37581Smckusick case SIGSTOP: 39717153Sbloom p->p_sig &= ~sigmask(SIGCONT); 3987421Sroot break; 3997421Sroot } 400*37581Smckusick p->p_sig |= mask; 4017421Sroot } 4027421Sroot /* 4037421Sroot * Defer further processing for signals which are held. 4047421Sroot */ 4057421Sroot if (action == SIG_HOLD) 4067421Sroot return; 40717153Sbloom s = splhigh(); 4087421Sroot switch (p->p_stat) { 4097421Sroot 4107421Sroot case SSLEEP: 4117421Sroot /* 4127421Sroot * If process is sleeping at negative priority 4137421Sroot * we can't interrupt the sleep... the signal will 4147421Sroot * be noticed when the process returns through 4157421Sroot * trap() or syscall(). 4167421Sroot */ 4177421Sroot if (p->p_pri <= PZERO) 4187421Sroot goto out; 4197421Sroot /* 4207421Sroot * Process is sleeping and traced... make it runnable 4217421Sroot * so it can discover the signal in issig() and stop 4227421Sroot * for the parent. 4237421Sroot */ 4247421Sroot if (p->p_flag&STRC) 4257421Sroot goto run; 4267421Sroot switch (sig) { 4277421Sroot 4287421Sroot case SIGSTOP: 4297421Sroot case SIGTSTP: 4307421Sroot case SIGTTIN: 4317421Sroot case SIGTTOU: 4327421Sroot /* 4337421Sroot * These are the signals which by default 4347421Sroot * stop a process. 4357421Sroot */ 4367421Sroot if (action != SIG_DFL) 4377421Sroot goto run; 4387421Sroot /* 4397421Sroot * If a child in vfork(), stopping could 4407421Sroot * cause deadlock. 4417421Sroot */ 4427421Sroot if (p->p_flag&SVFORK) 4437421Sroot goto out; 44417153Sbloom p->p_sig &= ~mask; 4457421Sroot p->p_cursig = sig; 44618331Skarels psignal(p->p_pptr, SIGCHLD); 4477421Sroot stop(p); 4487421Sroot goto out; 4497421Sroot 4507421Sroot case SIGIO: 4517421Sroot case SIGURG: 4527421Sroot case SIGCHLD: 45317597Sbloom case SIGWINCH: 4547421Sroot /* 4557421Sroot * These signals are special in that they 4567421Sroot * don't get propogated... if the process 4577421Sroot * isn't interested, forget it. 4587421Sroot */ 4597421Sroot if (action != SIG_DFL) 4607421Sroot goto run; 46117153Sbloom p->p_sig &= ~mask; /* take it away */ 4627421Sroot goto out; 4637421Sroot 4647421Sroot default: 4657421Sroot /* 4667421Sroot * All other signals cause the process to run 4677421Sroot */ 4687421Sroot goto run; 4697421Sroot } 4707421Sroot /*NOTREACHED*/ 4717421Sroot 4727421Sroot case SSTOP: 4737421Sroot /* 4747421Sroot * If traced process is already stopped, 4757421Sroot * then no further action is necessary. 4767421Sroot */ 4777421Sroot if (p->p_flag&STRC) 4787421Sroot goto out; 4797421Sroot switch (sig) { 4807421Sroot 4817421Sroot case SIGKILL: 4827421Sroot /* 4837421Sroot * Kill signal always sets processes running. 4847421Sroot */ 4857421Sroot goto run; 4867421Sroot 4877421Sroot case SIGCONT: 4887421Sroot /* 4897421Sroot * If the process catches SIGCONT, let it handle 4907421Sroot * the signal itself. If it isn't waiting on 4917421Sroot * an event, then it goes back to run state. 4927421Sroot * Otherwise, process goes back to sleep state. 4937421Sroot */ 4947421Sroot if (action != SIG_DFL || p->p_wchan == 0) 4957421Sroot goto run; 4967421Sroot p->p_stat = SSLEEP; 4977421Sroot goto out; 4987421Sroot 4997421Sroot case SIGSTOP: 5007421Sroot case SIGTSTP: 5017421Sroot case SIGTTIN: 5027421Sroot case SIGTTOU: 5037421Sroot /* 5047421Sroot * Already stopped, don't need to stop again. 5057421Sroot * (If we did the shell could get confused.) 5067421Sroot */ 50717153Sbloom p->p_sig &= ~mask; /* take it away */ 5087421Sroot goto out; 5097421Sroot 5107421Sroot default: 5117421Sroot /* 5127421Sroot * If process is sleeping interruptibly, then 5137421Sroot * unstick it so that when it is continued 5147421Sroot * it can look at the signal. 5157421Sroot * But don't setrun the process as its not to 5167421Sroot * be unstopped by the signal alone. 5177421Sroot */ 5187421Sroot if (p->p_wchan && p->p_pri > PZERO) 5197421Sroot unsleep(p); 5207421Sroot goto out; 5217421Sroot } 5227421Sroot /*NOTREACHED*/ 5237421Sroot 5247421Sroot default: 5257421Sroot /* 5267421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 5277421Sroot * other than kicking ourselves if we are running. 5287421Sroot * It will either never be noticed, or noticed very soon. 5297421Sroot */ 5307421Sroot if (p == u.u_procp && !noproc) 5317421Sroot aston(); 5327421Sroot goto out; 5337421Sroot } 5347421Sroot /*NOTREACHED*/ 5357421Sroot run: 5367421Sroot /* 5377421Sroot * Raise priority to at least PUSER. 5387421Sroot */ 5397421Sroot if (p->p_pri > PUSER) 54017399Skarels p->p_pri = PUSER; 5417421Sroot setrun(p); 5427421Sroot out: 5437421Sroot splx(s); 5447421Sroot } 5457421Sroot 5467421Sroot /* 5477421Sroot * Returns true if the current 5487421Sroot * process has a signal to process. 5497421Sroot * The signal to process is put in p_cursig. 5507421Sroot * This is asked at least once each time a process enters the 5517421Sroot * system (though this can usually be done without actually 5527421Sroot * calling issig by checking the pending signal masks.) 5537421Sroot * A signal does not do anything 5547421Sroot * directly to a process; it sets 5557421Sroot * a flag that asks the process to 5567421Sroot * do something to itself. 5577421Sroot */ 5587421Sroot issig() 5597421Sroot { 5607421Sroot register struct proc *p; 5617421Sroot register int sig; 56217153Sbloom int sigbits, mask; 5637421Sroot 5647421Sroot p = u.u_procp; 5657421Sroot for (;;) { 56614782Ssam sigbits = p->p_sig &~ p->p_sigmask; 5677421Sroot if ((p->p_flag&STRC) == 0) 56814782Ssam sigbits &= ~p->p_sigignore; 5697421Sroot if (p->p_flag&SVFORK) 57026276Skarels sigbits &= ~stopsigmask; 5717421Sroot if (sigbits == 0) 5727421Sroot break; 57326354Skarels sig = ffs((long)sigbits); 57417153Sbloom mask = sigmask(sig); 57517153Sbloom p->p_sig &= ~mask; /* take the signal! */ 5767421Sroot p->p_cursig = sig; 57712882Ssam if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) { 5787421Sroot /* 5797421Sroot * If traced, always stop, and stay 5807421Sroot * stopped until released by the parent. 5817421Sroot */ 58218331Skarels psignal(p->p_pptr, SIGCHLD); 5837421Sroot do { 5847421Sroot stop(p); 5857421Sroot swtch(); 5867421Sroot } while (!procxmt() && p->p_flag&STRC); 5877421Sroot 5887421Sroot /* 58914782Ssam * If the traced bit got turned off, 59014782Ssam * then put the signal taken above back into p_sig 59114782Ssam * and go back up to the top to rescan signals. 59214782Ssam * This ensures that p_sig* and u_signal are consistent. 5937421Sroot */ 59414782Ssam if ((p->p_flag&STRC) == 0) { 59517153Sbloom p->p_sig |= mask; 5967421Sroot continue; 5977421Sroot } 5987421Sroot 5997421Sroot /* 6007421Sroot * If parent wants us to take the signal, 6017421Sroot * then it will leave it in p->p_cursig; 6027421Sroot * otherwise we just look for signals again. 6037421Sroot */ 6047421Sroot sig = p->p_cursig; 6057421Sroot if (sig == 0) 6067421Sroot continue; 60714782Ssam 60814782Ssam /* 60914782Ssam * If signal is being masked put it back 61014782Ssam * into p_sig and look for other signals. 61114782Ssam */ 61217153Sbloom mask = sigmask(sig); 61317153Sbloom if (p->p_sigmask & mask) { 61417153Sbloom p->p_sig |= mask; 61514782Ssam continue; 61614782Ssam } 6177421Sroot } 61824901Skarels switch ((int)u.u_signal[sig]) { 6197421Sroot 6207421Sroot case SIG_DFL: 6217421Sroot /* 6227421Sroot * Don't take default actions on system processes. 6237421Sroot */ 6247421Sroot if (p->p_ppid == 0) 6257421Sroot break; 6267421Sroot switch (sig) { 6277421Sroot 6287421Sroot case SIGTSTP: 6297421Sroot case SIGTTIN: 6307421Sroot case SIGTTOU: 6317421Sroot case SIGSTOP: 6327421Sroot if (p->p_flag&STRC) 6337421Sroot continue; 63418331Skarels psignal(p->p_pptr, SIGCHLD); 6357421Sroot stop(p); 6367421Sroot swtch(); 6377421Sroot continue; 6387421Sroot 6397421Sroot case SIGCONT: 6407421Sroot case SIGCHLD: 64112882Ssam case SIGURG: 64212951Ssam case SIGIO: 64317597Sbloom case SIGWINCH: 6447421Sroot /* 6457421Sroot * These signals are normally not 6467421Sroot * sent if the action is the default. 6477421Sroot */ 6487421Sroot continue; /* == ignore */ 6497421Sroot 6507421Sroot default: 6517421Sroot goto send; 6527421Sroot } 6537421Sroot /*NOTREACHED*/ 6547421Sroot 6557421Sroot case SIG_HOLD: 6567421Sroot case SIG_IGN: 6577421Sroot /* 6587421Sroot * Masking above should prevent us 6597421Sroot * ever trying to take action on a held 6607421Sroot * or ignored signal, unless process is traced. 6617421Sroot */ 6627421Sroot if ((p->p_flag&STRC) == 0) 6637421Sroot printf("issig\n"); 6647421Sroot continue; 6657421Sroot 6667421Sroot default: 6677421Sroot /* 6687421Sroot * This signal has an action, let 6697421Sroot * psig process it. 6707421Sroot */ 6717421Sroot goto send; 6727421Sroot } 6737421Sroot /*NOTREACHED*/ 6747421Sroot } 6757421Sroot /* 6767421Sroot * Didn't find a signal to send. 6777421Sroot */ 6787421Sroot p->p_cursig = 0; 6797421Sroot return (0); 6807421Sroot 6817421Sroot send: 6827421Sroot /* 6837421Sroot * Let psig process the signal. 6847421Sroot */ 6857421Sroot return (sig); 6867421Sroot } 6877421Sroot 6887421Sroot /* 6897421Sroot * Put the argument process into the stopped 69018331Skarels * state and notify the parent via wakeup. 69118331Skarels * Signals are handled elsewhere. 6927421Sroot */ 6937421Sroot stop(p) 6947421Sroot register struct proc *p; 6957421Sroot { 6967421Sroot 6977421Sroot p->p_stat = SSTOP; 6987421Sroot p->p_flag &= ~SWTED; 6997421Sroot wakeup((caddr_t)p->p_pptr); 7007421Sroot } 7017421Sroot 7027421Sroot /* 7037421Sroot * Perform the action specified by 7047421Sroot * the current signal. 7057421Sroot * The usual sequence is: 7067421Sroot * if (issig()) 7077421Sroot * psig(); 7087421Sroot * The signal bit has already been cleared by issig, 7097421Sroot * and the current signal number stored in p->p_cursig. 7107421Sroot */ 7117421Sroot psig() 7127421Sroot { 71312882Ssam register struct proc *p = u.u_procp; 71412882Ssam register int sig = p->p_cursig; 71517153Sbloom int mask = sigmask(sig), returnmask; 7167421Sroot register int (*action)(); 7177421Sroot 71812882Ssam if (sig == 0) 7197421Sroot panic("psig"); 72012882Ssam action = u.u_signal[sig]; 7217421Sroot if (action != SIG_DFL) { 72217153Sbloom if (action == SIG_IGN || (p->p_sigmask & mask)) 7237421Sroot panic("psig action"); 7247421Sroot u.u_error = 0; 7257421Sroot /* 72612882Ssam * Set the new mask value and also defer further 72712882Ssam * occurences of this signal (unless we're simulating 72812882Ssam * the old signal facilities). 72912882Ssam * 73012882Ssam * Special case: user has done a sigpause. Here the 73112882Ssam * current mask is not of interest, but rather the 73212882Ssam * mask from before the sigpause is what we want restored 73312882Ssam * after the signal processing is completed. 7347421Sroot */ 73517153Sbloom (void) splhigh(); 73612882Ssam if (p->p_flag & SOUSIG) { 73712882Ssam if (sig != SIGILL && sig != SIGTRAP) { 73812882Ssam u.u_signal[sig] = SIG_DFL; 73917153Sbloom p->p_sigcatch &= ~mask; 74012882Ssam } 74117153Sbloom mask = 0; 7427421Sroot } 74312882Ssam if (p->p_flag & SOMASK) { 74412882Ssam returnmask = u.u_oldmask; 74512882Ssam p->p_flag &= ~SOMASK; 74612882Ssam } else 74712882Ssam returnmask = p->p_sigmask; 74817153Sbloom p->p_sigmask |= u.u_sigmask[sig] | mask; 74912882Ssam (void) spl0(); 7508032Sroot u.u_ru.ru_nsignals++; 75112882Ssam sendsig(action, sig, returnmask); 75212882Ssam p->p_cursig = 0; 7537421Sroot return; 7547421Sroot } 7557421Sroot u.u_acflag |= AXSIG; 75612882Ssam switch (sig) { 7577421Sroot 7587421Sroot case SIGILL: 7597421Sroot case SIGIOT: 7607421Sroot case SIGBUS: 7617421Sroot case SIGQUIT: 7627421Sroot case SIGTRAP: 7637421Sroot case SIGEMT: 7647421Sroot case SIGFPE: 7657421Sroot case SIGSEGV: 7667421Sroot case SIGSYS: 76712882Ssam u.u_arg[0] = sig; 76837580Smckusick if (core() == 0) 76912882Ssam sig += 0200; 7707421Sroot } 77112882Ssam exit(sig); 7727421Sroot } 7737421Sroot 7747421Sroot /* 7757421Sroot * Create a core image on the file "core" 7767421Sroot * If you are looking for protection glitches, 7777421Sroot * there are probably a wealth of them here 7787421Sroot * when this occurs to a suid command. 7797421Sroot * 7807421Sroot * It writes UPAGES block of the 7817421Sroot * user.h area followed by the entire 7827421Sroot * data+stack segments. 7837421Sroot */ 7847421Sroot core() 7857421Sroot { 78637580Smckusick register struct vnode *vp, *dvp; 78716692Smckusick register struct nameidata *ndp = &u.u_nd; 78837580Smckusick struct vattr vattr; 78937580Smckusick int error; 7907421Sroot 79112639Ssam if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid) 79237580Smckusick return (EFAULT); 79337580Smckusick if (ctob(UPAGES + u.u_dsize + u.u_ssize) >= 7948032Sroot u.u_rlimit[RLIMIT_CORE].rlim_cur) 79537580Smckusick return (EFAULT); 79637580Smckusick if (u.u_procp->p_textp) { 79737580Smckusick vop_lock(u.u_procp->p_textp->x_vptr); 79837580Smckusick error = vn_access(u.u_procp->p_textp->x_vptr, VREAD, u.u_cred); 79937580Smckusick vop_unlock(u.u_procp->p_textp->x_vptr); 80037580Smckusick if (error) 80137580Smckusick return (EFAULT); 80237580Smckusick } 80316692Smckusick ndp->ni_segflg = UIO_SYSSPACE; 80416692Smckusick ndp->ni_dirp = "core"; 80537580Smckusick if (error = vn_open(ndp, FCREAT|FWRITE, 0644)) 80637580Smckusick return (error); 80737580Smckusick vp = ndp->ni_vp; 80837580Smckusick if (vp->v_type != VREG || 80937580Smckusick vop_getattr(vp, &vattr, u.u_cred) || 81037580Smckusick vattr.va_nlink != 1) { 81137580Smckusick error = EFAULT; 8127818Sroot goto out; 8137818Sroot } 81430290Ssam #ifdef MMAP 81530290Ssam { register int fd; 81630290Ssam /* unmasp funky devices in the user's address space */ 81730290Ssam for (fd = 0; fd < u.u_lastfile; fd++) 81830290Ssam if (u.u_ofile[fd] && (u.u_pofile[fd] & UF_MAPPED)) 81930290Ssam munmapfd(fd); 82030290Ssam } 82130290Ssam #endif 82237580Smckusick vattr_null(&vattr); 82337580Smckusick vattr.va_size = 0; 82437580Smckusick vop_setattr(vp, &vattr, u.u_cred); 8257818Sroot u.u_acflag |= ACORE; 82637580Smckusick error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&u, ctob(UPAGES), (off_t)0, 82737580Smckusick UIO_SYSSPACE, IO_UNIT, (int *)0); 82837580Smckusick if (error == 0) 82937580Smckusick error = vn_rdwr(UIO_WRITE, vp, 8308967Sroot (caddr_t)ctob(dptov(u.u_procp, 0)), 83137580Smckusick (int)ctob(u.u_dsize), (off_t)ctob(UPAGES), 83237580Smckusick UIO_USERSPACE, IO_UNIT, (int *)0); 83337580Smckusick if (error == 0) 83437580Smckusick error = vn_rdwr(UIO_WRITE, vp, 8358967Sroot (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)), 83626354Skarels (int)ctob(u.u_ssize), 83737580Smckusick (off_t)ctob(UPAGES) + ctob(u.u_dsize), 83837580Smckusick UIO_USERSPACE, IO_UNIT, (int *)0); 8397818Sroot out: 84037580Smckusick if (vp) 84137580Smckusick vrele(vp); 84237580Smckusick return (error); 8437421Sroot } 844