From owner-freebsd-arch Sat Oct 5 0:20:58 2002 Delivered-To: freebsd-arch@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 931) id 1839D37B401; Sat, 5 Oct 2002 00:20:22 -0700 (PDT) Date: Sat, 5 Oct 2002 00:20:22 -0700 From: Juli Mallett To: arch@FreeBSD.org Subject: [jmallett@FreeBSD.org: [PATCH] Reliable signal queues, etc., [for review]] Message-ID: <20021005002021.A14635@FreeBSD.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i Organisation: The FreeBSD Project X-Alternate-Addresses: , , , , X-Towel: Yes X-LiveJournal: flata, jmallett X-Negacore: Yes Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Patch description: Make the kernel use reliable signal queues, of a type which provides information on the source of the signal source, sufficient to provide RTS siginfo_t exporting. Signal senders now operate using these info structures, structs called 'ksiginfo', which have been dequeued before being sent. The p_sig and p_code fields have gone away, though their use could *possibly* be replaced by taking the head of the signal queue, in the case of dumping core files, though I am not entirely sure. To accomodate situations where allocation of a 'ksiginfo' is a failure mode (no memory), the destination process is told to exit via a new member of 'struct proc', p_suicide, which tells a process to kill itself next time it goes through userret. It is done this way to prevent a recursive failure case, and to prevent possibly dying with extraneous locks held, as signals are sent from odd places of the kernel. Only i386-related machdep changes are included for the signal senders, but the changes are small enough that I will make them before commit. Testing: Tested on i386 only, but the changes are mostly MI or exact between architectures. I have run this on both my desktop/laptop and on our house fileserver. In the process of stressing signals and edge cases, I've actually managed to run into a few other bugs, but none in this code. I've run a ton of native binaries, including things like GNOME2 and X11. I've also run a good deal of Linux binaries, such as xski, simnow, etc. Also some binary-only FreeBSD applications like p4 and p4d. So far I have yet to run into a kernel or user-space failure case that I have not addressed. Imprvements over what was committed: Various sundry, including some style changes to the subr_sigq.c and ksiginfo.h files from bde. The most notable change is that the most recently sent && lowest numbered signal is sent, in the normal course of events, rather than simply the lowest numbered or most recently sent. This [seems to] satisfy the RTS rules about which signals are delivered first, at least as explained by Garrett Wollman. I have not implemented any KSE-related or userland RTS-related features, though this should *ehlp* both things, and I'm willing to do such. %%% diff -Nrdu -x *CVS* -x *dev* sys/alpha/osf1/osf1_signal.c kernel/alpha/osf1/osf1_signal.c --- sys/alpha/osf1/osf1_signal.c Tue Oct 1 12:15:46 2002 +++ kernel/alpha/osf1/osf1_signal.c Sat Oct 5 01:18:21 2002 @@ -30,7 +30,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/alpha/osf1/osf1_signal.c,v 1.22 2002/10/01 17:15:46 jmallett Exp $ + * $FreeBSD: src/sys/alpha/osf1/osf1_signal.c,v 1.21 2002/10/01 00:07:25 jmallett Exp $ */ #include @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -523,7 +524,7 @@ p = td->td_proc; PROC_LOCK(p); - bss = p->p_siglist; + ksiginfo_to_sigset_t(p, &bss); SIGSETAND(bss, p->p_sigmask); PROC_UNLOCK(p); bsd_to_osf1_sigset(&bss, &oss); diff -Nrdu -x *CVS* -x *dev* sys/compat/linprocfs/linprocfs.c kernel/compat/linprocfs/linprocfs.c --- sys/compat/linprocfs/linprocfs.c Tue Oct 1 12:15:49 2002 +++ kernel/compat/linprocfs/linprocfs.c Sat Oct 5 01:18:43 2002 @@ -38,7 +38,7 @@ * * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 * - * $FreeBSD: src/sys/compat/linprocfs/linprocfs.c,v 1.58 2002/10/01 17:15:49 jmallett Exp $ + * $FreeBSD: src/sys/compat/linprocfs/linprocfs.c,v 1.57 2002/10/01 00:07:25 jmallett Exp $ */ #include @@ -651,7 +651,7 @@ * running on anything but i386, so ignore that for now. */ PROC_LOCK(p); - sbuf_printf(sb, "SigPnd:\t%08x\n", p->p_siglist.__bits[0]); + sbuf_printf(sb, "SigPnd:\t%08x\n", 0); /* XXX */ /* * I can't seem to find out where the signal mask is in * relation to struct proc, so SigBlk is left unimplemented. diff -Nrdu -x *CVS* -x *dev* sys/compat/linux/linux_misc.c kernel/compat/linux/linux_misc.c --- sys/compat/linux/linux_misc.c Tue Oct 1 12:15:50 2002 +++ kernel/compat/linux/linux_misc.c Sat Oct 5 01:18:44 2002 @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/compat/linux/linux_misc.c,v 1.133 2002/10/01 17:15:50 jmallett Exp $ + * $FreeBSD: src/sys/compat/linux/linux_misc.c,v 1.132 2002/10/01 00:07:25 jmallett Exp $ */ #include "opt_mac.h" @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -806,6 +807,7 @@ int linux_wait4(struct thread *td, struct linux_wait4_args *args) { + struct proc *p; struct wait_args /* { int pid; int *status; @@ -821,6 +823,8 @@ (void *)args->rusage); #endif + p = td->td_proc; + tmp.pid = args->pid; tmp.status = args->status; tmp.options = (args->options & (WNOHANG | WUNTRACED)); @@ -832,7 +836,9 @@ if ((error = wait4(td, &tmp)) != 0) return error; - SIGDELSET(td->td_proc->p_siglist, SIGCHLD); + PROC_LOCK(p); + signal_delete(p, NULL, SIGCHLD); + PROC_UNLOCK(p); if (args->status) { if ((error = copyin((caddr_t)args->status, &tmpstat, diff -Nrdu -x *CVS* -x *dev* sys/compat/linux/linux_signal.c kernel/compat/linux/linux_signal.c --- sys/compat/linux/linux_signal.c Tue Oct 1 12:15:50 2002 +++ kernel/compat/linux/linux_signal.c Sat Oct 5 01:18:44 2002 @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/compat/linux/linux_signal.c,v 1.38 2002/10/01 17:15:50 jmallett Exp $ + * $FreeBSD: src/sys/compat/linux/linux_signal.c,v 1.37 2002/10/01 00:07:25 jmallett Exp $ */ #include @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -390,7 +391,7 @@ #endif PROC_LOCK(p); - bset = p->p_siglist; + ksiginfo_to_sigset_t(p, &bset); SIGSETAND(bset, p->p_sigmask); bsd_to_linux_sigset(&bset, &lset); PROC_UNLOCK(p); diff -Nrdu -x *CVS* -x *dev* sys/compat/svr4/svr4_filio.c kernel/compat/svr4/svr4_filio.c --- sys/compat/svr4/svr4_filio.c Tue Oct 1 12:15:50 2002 +++ kernel/compat/svr4/svr4_filio.c Sat Oct 5 01:18:45 2002 @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/compat/svr4/svr4_filio.c,v 1.19 2002/10/01 17:15:50 jmallett Exp $ + * $FreeBSD: src/sys/compat/svr4/svr4_filio.c,v 1.18 2002/10/01 00:07:26 jmallett Exp $ */ #include @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -135,7 +136,9 @@ DPRINTF(("sigmask = 0x%x\n", td->td_proc->p_sigmask)); DPRINTF(("sigignore = 0x%x\n", td->td_proc->p_sigignore)); DPRINTF(("sigcaught = 0x%x\n", td->td_proc->p_sigcatch)); +#if 0 /* XXX - use ksiginfo_to_sigset_t ? */ DPRINTF(("siglist = 0x%x\n", td->td_proc->p_siglist)); +#endif } #if defined(GROTTY_READ_HACK) diff -Nrdu -x *CVS* -x *dev* sys/compat/svr4/svr4_signal.c kernel/compat/svr4/svr4_signal.c --- sys/compat/svr4/svr4_signal.c Tue Oct 1 12:15:50 2002 +++ kernel/compat/svr4/svr4_signal.c Sat Oct 5 01:18:46 2002 @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/compat/svr4/svr4_signal.c,v 1.21 2002/10/01 17:15:50 jmallett Exp $ + * $FreeBSD: src/sys/compat/svr4/svr4_signal.c,v 1.20 2002/10/01 00:07:26 jmallett Exp $ */ #include @@ -565,7 +565,7 @@ if (SCARG(uap, mask) == NULL) return 0; PROC_LOCK(td->td_proc); - bss = td->td_proc->p_siglist; + ksiginfo_to_sigset_t(td->td_proc, &bss); SIGSETAND(bss, td->td_proc->p_sigmask); PROC_UNLOCK(td->td_proc); bsd_to_svr4_sigset(&bss, &sss); diff -Nrdu -x *CVS* -x *dev* sys/fs/procfs/procfs_ctl.c kernel/fs/procfs/procfs_ctl.c --- sys/fs/procfs/procfs_ctl.c Tue Oct 1 12:15:51 2002 +++ kernel/fs/procfs/procfs_ctl.c Sat Oct 5 01:20:20 2002 @@ -38,7 +38,7 @@ * * From: * $Id: procfs_ctl.c,v 3.2 1993/12/15 09:40:17 jsp Exp $ - * $FreeBSD: src/sys/fs/procfs/procfs_ctl.c,v 1.47 2002/10/01 17:15:51 jmallett Exp $ + * $FreeBSD: src/sys/fs/procfs/procfs_ctl.c,v 1.46 2002/10/01 00:07:26 jmallett Exp $ */ #include @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -221,7 +222,7 @@ p->p_flag &= ~P_TRACED; /* remove pending SIGTRAP, else the process will die */ - SIGDELSET(p->p_siglist, SIGTRAP); + signal_delete(p, NULL, SIGTRAP); PROC_UNLOCK(p); /* give process back to original parent */ diff -Nrdu -x *CVS* -x *dev* sys/i386/i386/machdep.c kernel/i386/i386/machdep.c --- sys/i386/i386/machdep.c Mon Sep 30 02:02:22 2002 +++ kernel/i386/i386/machdep.c Sat Oct 5 01:20:27 2002 @@ -1,4 +1,6 @@ /*- + * Copyright (c) 2002 Juli Mallett. + * Copyright (c) 2002 New Gold Technology. * Copyright (c) 1992 Terrence R. Lambert. * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. * All rights reserved. @@ -75,6 +77,7 @@ #include #include #include +#include #include #include @@ -408,11 +411,7 @@ #endif /* COMPAT_43 */ void -sendsig(catcher, sig, mask, code) - sig_t catcher; - int sig; - sigset_t *mask; - u_long code; +sendsig(sig_t catcher, struct ksiginfo *ksi, sigset_t *mask) { struct sigframe sf; struct proc *p; @@ -420,15 +419,16 @@ struct sigacts *psp; struct trapframe *regs; struct sigframe *sfp; - int oonstack; + int oonstack, sig; + sig = ksi->ksi_signo; td = curthread; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); psp = p->p_sigacts; #ifdef COMPAT_43 if (SIGISMEMBER(psp->ps_osigset, sig)) { - osendsig(catcher, sig, mask, code); + osendsig(catcher, sig, mask, ksi->ksi_code); return; } #endif @@ -473,15 +473,11 @@ sf.sf_siginfo = (register_t)&sfp->sf_si; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; - /* Fill in POSIX parts */ - sf.sf_si.si_signo = sig; - sf.sf_si.si_code = code; + ksiginfo_to_siginfo_t(ksi, &sf.sf_si); sf.sf_si.si_addr = (void *)regs->tf_err; - sf.sf_si.si_pid = p->p_pid; - sf.sf_si.si_uid = p->p_ucred->cr_uid; } else { /* Old FreeBSD-style arguments. */ - sf.sf_siginfo = code; + sf.sf_siginfo = ksi->ksi_code; sf.sf_addr = regs->tf_err; sf.sf_ahu.sf_handler = catcher; } diff -Nrdu -x *CVS* -x *dev* sys/i386/ibcs2/ibcs2_signal.c kernel/i386/ibcs2/ibcs2_signal.c --- sys/i386/ibcs2/ibcs2_signal.c Tue Oct 1 12:15:51 2002 +++ kernel/i386/ibcs2/ibcs2_signal.c Sat Oct 5 01:20:29 2002 @@ -25,12 +25,13 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/i386/ibcs2/ibcs2_signal.c,v 1.25 2002/10/01 17:15:51 jmallett Exp $ + * $FreeBSD: src/sys/i386/ibcs2/ibcs2_signal.c,v 1.22 2002/08/25 13:17:09 charnier Exp $ */ #include #include #include +#include #include #include #include @@ -452,11 +453,11 @@ struct ibcs2_sigpending_args *uap; { struct proc *p = td->td_proc; - sigset_t bss; + sigset_t curset; ibcs2_sigset_t iss; PROC_LOCK(p); - bss = p->p_siglist; + ksiginfo_to_sigset_t(p, &bss); SIGSETAND(bss, p->p_sigmask); PROC_UNLOCK(p); bsd_to_ibcs2_sigset(&bss, &iss); diff -Nrdu -x *CVS* -x *dev* sys/i386/linux/linux_sysvec.c kernel/i386/linux/linux_sysvec.c --- sys/i386/linux/linux_sysvec.c Sat Sep 7 17:31:44 2002 +++ kernel/i386/linux/linux_sysvec.c Sat Oct 5 01:20:41 2002 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -108,8 +109,8 @@ struct image_params *iparams); static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params); -static void linux_sendsig(sig_t catcher, int sig, sigset_t *mask, - u_long code); +static void linux_sendsig(sig_t catcher, struct ksiginfo *ksi, + sigset_t *mask); /* * Linux syscalls return negative errno's, we do positive and map them @@ -395,15 +396,18 @@ */ static void -linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) +linux_sendsig(sig_t catcher, struct ksiginfo *ksi, sigset_t *mask) { register struct thread *td = curthread; register struct proc *p = td->td_proc; register struct trapframe *regs; struct l_sigframe *fp, frame; l_sigset_t lmask; - int oonstack, i; + int oonstack, i, sig; + u_long code; + sig = ksi->ksi_signo; + code = ksi->ksi_code; PROC_LOCK_ASSERT(p, MA_OWNED); if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { /* Signal handler installed with SA_SIGINFO. */ diff -Nrdu -x *CVS* -x *dev* sys/kern/imgact_elf.c kernel/kern/imgact_elf.c --- sys/kern/imgact_elf.c Sat Sep 21 17:07:16 2002 +++ kernel/kern/imgact_elf.c Sat Oct 5 01:20:56 2002 @@ -1100,7 +1100,6 @@ status->pr_gregsetsz = sizeof(gregset_t); status->pr_fpregsetsz = sizeof(fpregset_t); status->pr_osreldate = osreldate; - status->pr_cursig = p->p_sig; status->pr_pid = p->p_pid; fill_regs(td, &status->pr_reg); diff -Nrdu -x *CVS* -x *dev* sys/kern/init_main.c kernel/kern/init_main.c --- sys/kern/init_main.c Tue Oct 1 12:15:51 2002 +++ kernel/kern/init_main.c Sat Oct 5 01:20:56 2002 @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 - * $FreeBSD: src/sys/kern/init_main.c,v 1.210 2002/10/01 17:15:51 jmallett Exp $ + * $FreeBSD: src/sys/kern/init_main.c,v 1.209 2002/10/01 00:07:26 jmallett Exp $ */ #include "opt_init_path.h" @@ -347,6 +347,8 @@ LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); LIST_INIT(&pgrp0.pg_members); LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist); + + TAILQ_INIT(&p->p_sigq); pgrp0.pg_session = &session0; mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF); diff -Nrdu -x *CVS* -x *dev* sys/kern/kern_exit.c kernel/kern/kern_exit.c --- sys/kern/kern_exit.c Tue Oct 1 12:15:51 2002 +++ kernel/kern/kern_exit.c Sat Oct 5 01:20:57 2002 @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 - * $FreeBSD: src/sys/kern/kern_exit.c,v 1.180 2002/10/01 17:15:51 jmallett Exp $ + * $FreeBSD: src/sys/kern/kern_exit.c,v 1.179 2002/10/01 00:07:27 jmallett Exp $ */ #include "opt_compat.h" @@ -67,6 +67,7 @@ #ifdef KTRACE #include #endif +#include #include #include @@ -209,12 +210,12 @@ PROC_LOCK(p); if (p == p->p_leader) { q = p->p_peers; + PROC_UNLOCK(p); while (q != NULL) { - PROC_LOCK(q); psignal(q, SIGKILL); - PROC_UNLOCK(q); q = q->p_peers; } + PROC_LOCK(p); while (p->p_peers) msleep(p, &p->p_mtx, PWAIT, "exit1", 0); } @@ -244,7 +245,7 @@ */ PROC_LOCK(p); p->p_flag &= ~(P_TRACED | P_PPWAIT); - SIGEMPTYSET(p->p_siglist); + signal_delete(p, NULL, 0); PROC_UNLOCK(p); if (timevalisset(&p->p_realtimer.it_value)) callout_stop(&p->p_itcallout); @@ -473,6 +474,12 @@ */ if (p->p_flag & P_KTHREAD) wakeup(p); + + /* + * And now, kill off its signals... + */ + signal_delete(p, NULL, 0); + PROC_UNLOCK(p); /* diff -Nrdu -x *CVS* -x *dev* sys/kern/kern_fork.c kernel/kern/kern_fork.c --- sys/kern/kern_fork.c Tue Oct 1 12:15:51 2002 +++ kernel/kern/kern_fork.c Sat Oct 5 01:20:57 2002 @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 - * $FreeBSD: src/sys/kern/kern_fork.c,v 1.167 2002/10/01 17:15:51 jmallett Exp $ + * $FreeBSD: src/sys/kern/kern_fork.c,v 1.166 2002/10/01 00:07:27 jmallett Exp $ */ #include "opt_ktrace.h" @@ -605,6 +605,7 @@ LIST_INSERT_AFTER(p1, p2, p_pglist); PGRP_UNLOCK(p1->p_pgrp); LIST_INIT(&p2->p_children); + TAILQ_INIT(&p2->p_sigq); callout_init(&p2->p_itcallout, 0); diff -Nrdu -x *CVS* -x *dev* sys/kern/kern_kthread.c kernel/kern/kern_kthread.c --- sys/kern/kern_kthread.c Tue Oct 1 12:15:51 2002 +++ kernel/kern/kern_kthread.c Sat Oct 5 01:20:57 2002 @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/kern/kern_kthread.c,v 1.27 2002/10/01 17:15:51 jmallett Exp $ + * $FreeBSD: src/sys/kern/kern_kthread.c,v 1.26 2002/10/01 00:07:27 jmallett Exp $ */ #include @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -144,33 +145,29 @@ { /* * Make sure this is indeed a system process and we can safely - * use the p_siglist field. + * use the signal queue. */ PROC_LOCK(p); if ((p->p_flag & P_KTHREAD) == 0) { PROC_UNLOCK(p); return (EINVAL); } - SIGADDSET(p->p_siglist, SIGSTOP); + signal_add(p, NULL, SIGSTOP); wakeup(p); - return msleep(&p->p_siglist, &p->p_mtx, PPAUSE | PDROP, "suspkt", timo); + return msleep(&p->p_sigq, &p->p_mtx, PPAUSE | PDROP, "suspkt", timo); } int kthread_resume(struct proc *p) { - /* - * Make sure this is indeed a system process and we can safely - * use the p_siglist field. - */ PROC_LOCK(p); if ((p->p_flag & P_KTHREAD) == 0) { PROC_UNLOCK(p); return (EINVAL); } - SIGDELSET(p->p_siglist, SIGSTOP); + signal_delete(p, NULL, SIGSTOP); PROC_UNLOCK(p); - wakeup(&p->p_siglist); + wakeup(&p->p_sigq); return (0); } @@ -178,9 +175,9 @@ kthread_suspend_check(struct proc *p) { PROC_LOCK(p); - while (SIGISMEMBER(p->p_siglist, SIGSTOP)) { - wakeup(&p->p_siglist); - msleep(&p->p_siglist, &p->p_mtx, PPAUSE, "ktsusp", 0); + while (signal_queued(p, SIGSTOP)) { + wakeup(&p->p_sigq); + msleep(&p->p_sigq, &p->p_mtx, PPAUSE, "ktsusp", 0); } PROC_UNLOCK(p); } diff -Nrdu -x *CVS* -x *dev* sys/kern/kern_proc.c kernel/kern/kern_proc.c --- sys/kern/kern_proc.c Tue Oct 1 12:15:51 2002 +++ kernel/kern/kern_proc.c Sat Oct 5 01:20:58 2002 @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95 - * $FreeBSD: src/sys/kern/kern_proc.c,v 1.157 2002/10/01 17:15:51 jmallett Exp $ + * $FreeBSD: src/sys/kern/kern_proc.c,v 1.156 2002/10/01 00:07:27 jmallett Exp $ */ #include "opt_ktrace.h" @@ -58,6 +58,7 @@ #include #include #endif +#include #include #include @@ -408,7 +409,7 @@ RANGEOF(struct kse, ke_startcopy, ke_endcopy)); #endif PROC_LOCK(p); - if (SIGPENDING(p)) + if (signal_pending(p)) newke->ke_flags |= KEF_ASTPENDING; PROC_UNLOCK(p); mtx_lock_spin(&sched_lock); @@ -1014,7 +1015,7 @@ strncpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm) - 1); strncpy(kp->ki_ocomm, p->p_comm, sizeof(kp->ki_ocomm) - 1); } - kp->ki_siglist = p->p_siglist; + ksiginfo_to_sigset_t(p, &kp->ki_siglist); kp->ki_sigmask = p->p_sigmask; kp->ki_xstat = p->p_xstat; kp->ki_acflag = p->p_acflag; diff -Nrdu -x *CVS* -x *dev* sys/kern/kern_sig.c kernel/kern/kern_sig.c --- sys/kern/kern_sig.c Tue Oct 1 12:15:51 2002 +++ kernel/kern/kern_sig.c Sat Oct 5 01:20:58 2002 @@ -1,4 +1,6 @@ /* + * Copyright (c) 2002 New Gold Technoloy. All rights reserved. + * Copyright (c) 2002 Juli Mallett. All rights reserved. * Copyright (c) 1982, 1986, 1989, 1991, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. @@ -36,7 +38,7 @@ * SUCH DAMAGE. * * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 - * $FreeBSD: src/sys/kern/kern_sig.c,v 1.195 2002/10/01 17:15:51 jmallett Exp $ + * $FreeBSD: src/sys/kern/kern_sig.c,v 1.194 2002/10/01 00:16:16 jmallett Exp $ */ #include "opt_compat.h" @@ -70,6 +72,7 @@ #include #include #include +#include #include @@ -116,6 +119,9 @@ SYSCTL_INT(_kern, OID_AUTO, coredump, CTLFLAG_RW, &do_coredump, 0, "Enable/Disable coredumps"); +static int stopmask = + sigmask(SIGSTOP) | sigmask(SIGTSTP) | sigmask(SIGTTIN) | sigmask(SIGTTOU); + /* * Signal properties and actions. * The array below categorizes the signals and their default actions @@ -178,12 +184,12 @@ PROC_LOCK_ASSERT(p, MA_OWNED); mtx_assert(&sched_lock, MA_NOTOWNED); - return (SIGPENDING(p) ? issignal(td) : 0); + return (signal_pending(p) ? issignal(td) : 0); } /* * Arrange for ast() to handle unmasked pending signals on return to user - * mode. This must be called whenever a signal is added to p_siglist or + * mode. This must be called whenever a signal is added to p_sigq or * unmasked in p_sigmask. */ void @@ -194,7 +200,7 @@ PROC_LOCK_ASSERT(p, MA_OWNED); mtx_lock_spin(&sched_lock); - if (SIGPENDING(p)) { + if (signal_pending(p)) { p->p_sflag |= PS_NEEDSIGCHK; /* XXXKSE for now punish all KSEs */ FOREACH_KSEGRP_IN_PROC(p, kg) { @@ -341,7 +347,7 @@ (sigprop(sig) & SA_IGNORE && ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL)) { /* never to be seen again */ - SIGDELSET(p->p_siglist, sig); + signal_delete(p, NULL, sig); if (sig != SIGCONT) /* easier in psignal */ SIGADDSET(p->p_sigignore, sig); @@ -494,7 +500,7 @@ if (sigprop(sig) & SA_IGNORE) { if (sig != SIGCONT) SIGADDSET(p->p_sigignore, sig); - SIGDELSET(p->p_siglist, sig); + signal_delete(p, NULL, sig); } ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; } @@ -641,7 +647,7 @@ mtx_lock(&Giant); PROC_LOCK(p); - siglist = p->p_siglist; + ksiginfo_to_sigset_t(p, &siglist); PROC_UNLOCK(p); mtx_unlock(&Giant); error = copyout(&siglist, uap->set, sizeof(sigset_t)); @@ -664,10 +670,12 @@ struct osigpending_args *uap; { struct proc *p = td->td_proc; + sigset_t siglist; mtx_lock(&Giant); PROC_LOCK(p); - SIG2OSIG(p->p_siglist, td->td_retval[0]); + ksiginfo_to_sigset_t(p, &siglist); + SIG2OSIG(siglist, td->td_retval[0]); PROC_UNLOCK(p); mtx_unlock(&Giant); return (0); @@ -1219,7 +1227,10 @@ u_long code; { register struct sigacts *ps = p->p_sigacts; + struct ksiginfo *ksi; + ksiginfo_alloc(&ksi, p, sig); + ksi->ksi_code = code; PROC_LOCK(p); if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(p->p_sigcatch, sig) && !SIGISMEMBER(p->p_sigmask, sig)) { @@ -1229,8 +1240,9 @@ ktrpsig(sig, ps->ps_sigact[_SIG_IDX(sig)], &p->p_sigmask, code); #endif - (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], sig, - &p->p_sigmask, code); + (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], ksi, + &p->p_sigmask); + ksiginfo_destroy(&ksi); SIGSETOR(p->p_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]); if (!SIGISMEMBER(ps->ps_signodefer, sig)) SIGADDSET(p->p_sigmask, sig); @@ -1244,11 +1256,8 @@ SIGADDSET(p->p_sigignore, sig); ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; } - } else { - p->p_code = code; /* XXX for core dump/debugger */ - p->p_sig = sig; /* XXX to verify code */ + } else psignal(p, sig); - } PROC_UNLOCK(p); } @@ -1308,7 +1317,7 @@ } if (prop & SA_CONT) - SIG_STOPSIGMASK(p->p_siglist); + signal_delete_mask(p, stopmask); if (prop & SA_STOP) { /* @@ -1321,10 +1330,10 @@ (p->p_pgrp->pg_jobc == 0) && (action == SIG_DFL)) return; - SIG_CONTSIGMASK(p->p_siglist); + signal_delete_mask(p, sigmask(SIGCONT)); p->p_flag &= ~P_CONTINUED; } - SIGADDSET(p->p_siglist, sig); + signal_add(p, NULL, sig); signotify(p); /* uses schedlock */ /* @@ -1362,10 +1371,10 @@ if (prop & SA_CONT) { /* * If SIGCONT is default (or ignored), we continue the - * process but don't leave the signal in p_siglist as - * it has no further action. If SIGCONT is held, we + * process but don't leave the signal in p_sigq as it + * has no further action. If SIGCONT is held, we * continue the process and leave the signal in - * p_siglist. If the process catches SIGCONT, let it + * p_sigq. If the process catches SIGCONT, let it * handle the signal itself. If it isn't waiting on * an event, it goes back to run state. * Otherwise, process goes back to sleep state. @@ -1373,7 +1382,7 @@ p->p_flag &= ~P_STOPPED_SIG; p->p_flag |= P_CONTINUED; if (action == SIG_DFL) { - SIGDELSET(p->p_siglist, sig); + signal_delete(p, NULL, sig); } else if (action == SIG_CATCH) { /* * The process wants to catch it so it needs @@ -1403,7 +1412,7 @@ * Just make sure the signal STOP bit set. */ p->p_flag |= P_STOPPED_SIG; - SIGDELSET(p->p_siglist, sig); + signal_delete(p, NULL, sig); goto out; } @@ -1437,7 +1446,7 @@ /* * Already active, don't need to start again. */ - SIGDELSET(p->p_siglist, sig); + signal_delete(p, NULL, sig); goto out; } if ((p->p_flag & P_TRACED) || (action != SIG_DFL) || @@ -1461,7 +1470,7 @@ mtx_unlock_spin(&sched_lock); stop(p); p->p_xstat = sig; - SIGDELSET(p->p_siglist, sig); + signal_delete(p, NULL, sig); PROC_LOCK(p->p_pptr); if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0) { @@ -1478,7 +1487,7 @@ /* NOTREACHED */ } else { /* Not in "NORMAL" state. discard the signal. */ - SIGDELSET(p->p_siglist, sig); + signal_delete(p, NULL, sig); goto out; } @@ -1553,7 +1562,7 @@ * be awakened. */ if ((prop & SA_CONT) && action == SIG_DFL) { - SIGDELSET(p->p_siglist, sig); + signal_delete(p, NULL, sig); return; } @@ -1609,13 +1618,13 @@ for (;;) { int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG); - mask = p->p_siglist; + ksiginfo_to_sigset_t(p, &mask); SIGSETNAND(mask, p->p_sigmask); if (p->p_flag & P_PPWAIT) SIG_STOPSIGMASK(mask); if (SIGISEMPTY(mask)) /* no signal to send */ return (0); - sig = sig_ffs(&mask); + sig = signal_queued_mask(p, mask); prop = sigprop(sig); _STOPEVENT(p, S_SIG, sig); @@ -1625,7 +1634,7 @@ * only if P_TRACED was on when they were posted. */ if (SIGISMEMBER(p->p_sigignore, sig) && (traced == 0)) { - SIGDELSET(p->p_siglist, sig); + signal_delete(p, NULL, sig); continue; } if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) { @@ -1660,16 +1669,16 @@ * then it will leave it in p->p_xstat; * otherwise we just look for signals again. */ - SIGDELSET(p->p_siglist, sig); /* clear old signal */ + signal_delete(p, NULL, sig); /* clear old signal */ sig = p->p_xstat; if (sig == 0) continue; /* - * Put the new signal into p_siglist. If the - * signal is being masked, look for other signals. + * Put the new signal into p_sigq. If the signal + * is being masked, look for other signals. */ - SIGADDSET(p->p_siglist, sig); + psignal(p, sig); if (SIGISMEMBER(p->p_sigmask, sig)) continue; signotify(p); @@ -1759,7 +1768,7 @@ */ return (sig); } - SIGDELSET(p->p_siglist, sig); /* take the signal! */ + signal_delete(p, NULL, sig); /* take the signal! */ } /* NOTREACHED */ } @@ -1791,16 +1800,16 @@ { struct thread *td = curthread; register struct proc *p = td->td_proc; + struct ksiginfo *ksi; struct sigacts *ps; sig_t action; sigset_t returnmask; - int code; KASSERT(sig != 0, ("postsig")); PROC_LOCK_ASSERT(p, MA_OWNED); ps = p->p_sigacts; - SIGDELSET(p->p_siglist, sig); + ksiginfo_dequeue(&ksi, p, sig); action = ps->ps_sigact[_SIG_IDX(sig)]; #ifdef KTRACE if (KTRPOINT(td, KTR_PSIG)) @@ -1814,6 +1823,7 @@ * Default action, where the default is to kill * the process. (Other cases were ignored above.) */ + ksiginfo_destroy(&ksi); sigexit(td, sig); /* NOTREACHED */ } else { @@ -1852,17 +1862,13 @@ ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; } p->p_stats->p_ru.ru_nsignals++; - if (p->p_sig != sig) { - code = 0; - } else { - code = p->p_code; - p->p_code = 0; - p->p_sig = 0; - } if (p->p_flag & P_KSES) - if (signal_upcall(p, sig)) + if (signal_upcall(p, sig)) { + ksiginfo_destroy(&ksi); return; - (*p->p_sysent->sv_sendsig)(action, sig, &returnmask, code); + } + (*p->p_sysent->sv_sendsig)(action, ksi, &returnmask); + ksiginfo_destroy(&ksi); } } @@ -1901,7 +1907,6 @@ PROC_LOCK_ASSERT(p, MA_OWNED); p->p_acflag |= AXSIG; if (sigprop(sig) & SA_CORE) { - p->p_sig = sig; /* * Log signals which would cause core dumps * (Log as LOG_INFO to appease those who don't want diff -Nrdu -x *CVS* -x *dev* sys/kern/subr_sigq.c kernel/kern/subr_sigq.c --- sys/kern/subr_sigq.c Wed Dec 31 18:00:00 1969 +++ kernel/kern/subr_sigq.c Sat Oct 5 01:21:00 2002 @@ -0,0 +1,323 @@ +/*- + * Copyright (c) 2002 New Gold Technology. All rights reserved. + * Copyright (c) 2002 Juli Mallett. All rights reserved. + * + * This software was written by Juli Mallett for the + * FreeBSD project. Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/kern/subr_sigq.c,v 1.4 2002/10/01 03:19:49 jmallett Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MALLOC_DECLARE(M_KSIGINFO); +MALLOC_DEFINE(M_KSIGINFO, "ksiginfos", "Kernel signal info structures"); + +int +ksiginfo_alloc(struct ksiginfo **ksip, struct proc *p, int signo) +{ + int error; + struct ksiginfo *ksi; + + error = 0; + + PROC_LOCK_ASSERT(p, MA_NOTOWNED); + ksi = malloc(sizeof *ksi, M_KSIGINFO, M_ZERO | M_NOWAIT); + if (ksi == NULL) { + PROC_LOCK(p); + p->p_suicide = 1; + PROC_UNLOCK(p); + } + ksi->ksi_signo = signo; + if (curproc != NULL) { + ksi->ksi_pid = curproc->p_pid; + ksi->ksi_ruid = curproc->p_ucred->cr_uid; + } + *ksip = ksi; + return (error); +} + +int +ksiginfo_dequeue(struct ksiginfo **ksip, struct proc *p, int signo) +{ + int error; + struct ksiginfo *ksi; + + error = 0; + ksi = NULL; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if (TAILQ_EMPTY(&p->p_sigq)) { + error = EDOOFUS; + goto out; + } + /* + * If we have no signo, get the lowest numbered one that's pending. + * XXX This should probably be duplicated from signal_pending, using + * a pointer to a struct ksiginfo for the 'lowest' value, to avoid + * traversing the list the same amount twice. + */ + if (!signo) + signo = signal_pending(p, 0); + TAILQ_FOREACH(ksi, &p->p_sigq, ksi_queue) { + if (ksi->ksi_signo == signo) + goto out; + } + error = ESRCH; + ksi = NULL; +out: + if (ksi != NULL) + TAILQ_REMOVE(&p->p_sigq, ksi, ksi_queue); + *ksip = ksi; + return (error); +} + +int +ksiginfo_destroy(struct ksiginfo **ksip) +{ + int error; + struct ksiginfo *ksi; + + error = 0; + + ksi = *ksip; + if (ksi == NULL) { + error = EDOOFUS; + goto out; + } + free(ksi, M_KSIGINFO); + ksi = NULL; +out: + *ksip = ksi; + return (error); +} + +int +ksiginfo_to_siginfo_t(struct ksiginfo *ksi, siginfo_t *si) +{ + int error; + + error = 0; + + si->si_addr = ksi->ksi_addr; + si->si_code = ksi->ksi_code; + si->si_errno = ksi->ksi_errno; + si->si_signo = ksi->ksi_signo; + si->si_status = ksi->ksi_status; + si->si_uid = ksi->ksi_ruid; + si->si_pid = ksi->ksi_pid; + + return (error); +} + +int +ksiginfo_to_sigset_t(struct proc *p, sigset_t *setp) +{ + int error; + sigset_t set; + struct ksiginfo *ksi; + + error = 0; + SIGEMPTYSET(set); + + PROC_LOCK_ASSERT(p, MA_OWNED); + /* + * We could set EDOOFUS here, however if there are no queued + * signals, then an empty signal set _is_ valid. + */ + if (TAILQ_EMPTY(&p->p_sigq)) + goto out; + TAILQ_FOREACH(ksi, &p->p_sigq, ksi_queue) + SIGADDSET(set, ksi->ksi_signo); +out: + *setp = set; + return (error); +} + +int +signal_add(struct proc *p, struct ksiginfo *ksi, int signo) +{ + int error; + + error = 0; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if (ksi == NULL) { + PROC_UNLOCK(p); + error = ksiginfo_alloc(&ksi, p, signo); + PROC_LOCK(p); + if (error) + return (error); + } + TAILQ_INSERT_HEAD(&p->p_sigq, ksi, ksi_queue); +out: + return (error); +} + +int +signal_delete(struct proc *p, struct ksiginfo *ksi, int signo) +{ + int error; + + error = 0; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if (ksi == NULL) { + while (signal_queued(p, signo)) { + error = ksiginfo_dequeue(&ksi, p, signo); + if (error) + return (error); + error = ksiginfo_destroy(&ksi); + if (error) + return (error); + } + } +out: + if (ksi != NULL) { + TAILQ_REMOVE(&p->p_sigq, ksi, ksi_queue); + ksiginfo_destroy(&ksi); + } + return (error); +} + +int +signal_delete_mask(struct proc *p, int mask) +{ + int error; + struct ksiginfo *ksi, *prev; + + error = 0; + ksi = prev = NULL; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if (TAILQ_EMPTY(&p->p_sigq)) + goto out; + TAILQ_FOREACH(ksi, &p->p_sigq, ksi_queue) { + if (prev != NULL) { + TAILQ_REMOVE(&p->p_sigq, prev, ksi_queue); + error = ksiginfo_destroy(&prev); + if (error) + return (error); + } + if (sigmask(ksi->ksi_signo) & mask) + prev = ksi; + } + if (prev != NULL) { + TAILQ_REMOVE(&p->p_sigq, prev, ksi_queue); + error = ksiginfo_destroy(&prev); + if (error) + return (error); + } +out: + return (error); +} + +int +signal_pending(struct proc *p) +{ + int error, pending; + sigset_t set; + + error = 0; + pending = 0; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if (TAILQ_EMPTY(&p->p_sigq)) + goto out; + if (p->p_flag & P_TRACED) { + pending = 1; + goto out; + } + error = ksiginfo_to_sigset_t(p, &set); + if (error) + goto out; + pending = !sigsetmasked(&set, &p->p_sigmask); + if (pending) + goto out; +out: + return (pending); +} + +int +signal_queued(struct proc *p, int signo) +{ + int error, lowest, pending; + struct ksiginfo *ksi; + + error = 0; + lowest = 0; + pending = 0; + ksi = NULL; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if (TAILQ_EMPTY(&p->p_sigq)) + goto out; + TAILQ_FOREACH(ksi, &p->p_sigq, ksi_queue) { + pending = ksi->ksi_signo; + + if (signo == pending) + goto out; + else if (signo == 0) { + if (pending < lowest) + lowest = pending; + } + } + if (signo) + pending = 0; + else + pending = lowest; +out: + return (pending); +} + +int +signal_queued_mask(struct proc *p, sigset_t mask) +{ + int pending; + struct ksiginfo *ksi; + + pending = 0; + ksi = NULL; + + PROC_LOCK_ASSERT(p, MA_OWNED); + if (TAILQ_EMPTY(&p->p_sigq)) + goto out; + TAILQ_FOREACH(ksi, &p->p_sigq, ksi_queue) { + if (SIGISMEMBER(mask, ksi->ksi_signo)) { + pending = ksi->ksi_signo; + goto out; + } + } +out: + return (pending); +} diff -Nrdu -x *CVS* -x *dev* sys/kern/tty.c kernel/kern/tty.c --- sys/kern/tty.c Tue Oct 1 12:15:52 2002 +++ kernel/kern/tty.c Sat Oct 5 01:21:00 2002 @@ -44,7 +44,7 @@ * SUCH DAMAGE. * * @(#)tty.c 8.8 (Berkeley) 1/21/94 - * $FreeBSD: src/sys/kern/tty.c,v 1.188 2002/10/01 17:15:52 jmallett Exp $ + * $FreeBSD: src/sys/kern/tty.c,v 1.187 2002/10/01 00:07:27 jmallett Exp $ */ /*- @@ -102,6 +102,7 @@ #include #include #include +#include #include #include @@ -1841,21 +1842,24 @@ ttycheckoutq(struct tty *tp, int wait) { int hiwat, s; - sigset_t oldmask; + sigset_t oldmask, newmask; hiwat = tp->t_ohiwat; SIGEMPTYSET(oldmask); s = spltty(); if (wait) - oldmask = curproc->p_siglist; + ksiginfo_to_sigset_t(curproc, &oldmask); if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) while (tp->t_outq.c_cc > hiwat) { ttstart(tp); if (tp->t_outq.c_cc <= hiwat) break; - if (!(wait && SIGSETEQ(curproc->p_siglist, oldmask))) { - splx(s); - return (0); + if (!wait) { + ksiginfo_to_sigset_t(curproc, &newmask); + if (SIGSETEQ(newmask, oldmask)) { + splx(s); + return (0); + } } SET(tp->t_state, TS_SO_OLOWAT); tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz); diff -Nrdu -x *CVS* -x *dev* sys/netncp/ncp_ncp.c kernel/netncp/ncp_ncp.c --- sys/netncp/ncp_ncp.c Tue Oct 1 12:15:52 2002 +++ kernel/netncp/ncp_ncp.c Sat Oct 5 01:21:30 2002 @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/netncp/ncp_ncp.c,v 1.11 2002/10/01 17:15:52 jmallett Exp $ + * $FreeBSD: src/sys/netncp/ncp_ncp.c,v 1.10 2002/09/30 20:48:28 jmallett Exp $ * * Core of NCP protocol */ @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -80,11 +81,15 @@ if (p == NULL) return 0; - tmpset = p->p_siglist; + PROC_LOCK(p); + ksiginfo_to_sigset_t(p, &tmpset); SIGSETNAND(tmpset, p->p_sigmask); SIGSETNAND(tmpset, p->p_sigignore); - if (SIGNOTEMPTY(p->p_siglist) && NCP_SIGMASK(tmpset)) + if (signal_queued(p, 0) && NCP_SIGMASK(tmpset)) { + PROC_UNLOCK(p); return EINTR; + } + PROC_UNLOCK(p); return 0; } diff -Nrdu -x *CVS* -x *dev* sys/netsmb/smb_subr.c kernel/netsmb/smb_subr.c --- sys/netsmb/smb_subr.c Tue Oct 1 12:15:53 2002 +++ kernel/netsmb/smb_subr.c Sat Oct 5 01:21:32 2002 @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/netsmb/smb_subr.c,v 1.9 2002/10/01 17:15:53 jmallett Exp $ + * $FreeBSD: src/sys/netsmb/smb_subr.c,v 1.8 2002/09/30 20:48:29 jmallett Exp $ */ #include #include @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -75,11 +76,15 @@ if (p == NULL) return 0; - tmpset = p->p_siglist; + PROC_LOCK(p); + ksiginfo_to_sigset_t(p, &tmpset); SIGSETNAND(tmpset, p->p_sigmask); SIGSETNAND(tmpset, p->p_sigignore); - if (SIGNOTEMPTY(p->p_siglist) && SMB_SIGMASK(tmpset)) + if (signal_queued(p, 0) && SMB_SIGMASK(tmpset)) { + PROC_UNLOCK(p); return EINTR; + } + PROC_UNLOCK(p); return 0; } diff -Nrdu -x *CVS* -x *dev* sys/nfsclient/nfs_socket.c kernel/nfsclient/nfs_socket.c --- sys/nfsclient/nfs_socket.c Tue Oct 1 12:15:53 2002 +++ kernel/nfsclient/nfs_socket.c Sat Oct 5 01:21:34 2002 @@ -37,7 +37,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/nfsclient/nfs_socket.c,v 1.90 2002/10/01 17:15:53 jmallett Exp $"); +__FBSDID("$FreeBSD: src/sys/nfsclient/nfs_socket.c,v 1.89 2002/09/30 21:15:33 jmallett Exp $"); /* * Socket operations for use by nfs @@ -61,6 +61,7 @@ #include #include #include +#include #include #include @@ -1239,11 +1240,15 @@ return (0); p = td->td_proc; - tmpset = p->p_siglist; + PROC_LOCK(p); + ksiginfo_to_sigset_t(p, &tmpset); SIGSETNAND(tmpset, p->p_sigmask); SIGSETNAND(tmpset, p->p_sigignore); - if (SIGNOTEMPTY(p->p_siglist) && NFSINT_SIGMASK(tmpset)) + if (signal_queued(p, 0) && NFSINT_SIGMASK(tmpset)) { + PROC_UNLOCK(p); return (EINTR); + } + PROC_UNLOCK(p); return (0); } diff -Nrdu -x *CVS* -x *dev* sys/sys/ksiginfo.h kernel/sys/ksiginfo.h --- sys/sys/ksiginfo.h Wed Dec 31 18:00:00 1969 +++ kernel/sys/ksiginfo.h Sat Oct 5 01:22:02 2002 @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 2002 New Gold Technology. All rights reserved. + * Copyright (c) 2002 Juli Mallett. All rights reserved. + * + * This software was written by Juli Mallett for the + * FreeBSD project. Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/sys/ksiginfo.h,v 1.3 2002/10/01 00:16:17 jmallett Exp $ + */ + +#ifndef _SYS_KSIGINFO_H_ +#define _SYS_KSIGINFO_H_ + +#ifndef _KERNEL +#error "no user-serviceable parts inside" +#endif + +#include +#include + +/* + * Structures and prototypes for working with the in-kernel representation + * of pending signals, and all the information we have about them. + */ + +/* + * This is pushed to userland in the form of a siginfo_t, which is POSIX + * defined. This is for in-kernel representations only, and has no ABI + * consumers. + */ +struct ksiginfo { + TAILQ_ENTRY(ksiginfo) ksi_queue; /* Entry in the signal queue. */ + void *ksi_addr; /* [Fault] address. */ + int ksi_code; /* [Trap] code. */ + int ksi_errno; /* Error number. */ + int ksi_signo; /* Signal number. */ + int ksi_status; /* Exit status (SIGCHLD). */ + uid_t ksi_ruid; /* Real UID of sender. */ + pid_t ksi_pid; /* PID of sender. */ +}; + +struct proc; + +__BEGIN_DECLS; +int ksiginfo_alloc(struct ksiginfo **, struct proc *, int); +int ksiginfo_dequeue(struct ksiginfo **, struct proc *, int); +int ksiginfo_destroy(struct ksiginfo **); +int ksiginfo_to_siginfo_t(struct ksiginfo *, siginfo_t *); +int ksiginfo_to_sigset_t(struct proc *, sigset_t *); +int signal_add(struct proc *, struct ksiginfo *, int); +int signal_delete(struct proc *, struct ksiginfo *, int); +int signal_delete_mask(struct proc *, int); +int signal_pending(struct proc *); +int signal_queued(struct proc *, int); +int signal_queued_mask(struct proc *, sigset_t); +__END_DECLS; + +#endif /* !_SYS_KSIGINFO_H_ */ diff -Nrdu -x *CVS* -x *dev* sys/sys/proc.h kernel/sys/proc.h --- sys/sys/proc.h Tue Oct 1 12:15:53 2002 +++ kernel/sys/proc.h Sat Oct 5 01:22:05 2002 @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)proc.h 8.15 (Berkeley) 5/19/95 - * $FreeBSD: src/sys/sys/proc.h,v 1.264 2002/10/01 17:15:53 jmallett Exp $ + * $FreeBSD: src/sys/sys/proc.h,v 1.263 2002/10/01 00:07:28 jmallett Exp $ */ #ifndef _SYS_PROC_H_ @@ -497,6 +497,7 @@ TAILQ_HEAD(, ksegrp) p_ksegrps; /* (kg_ksegrp) All KSEGs. */ TAILQ_HEAD(, thread) p_threads; /* (td_plist) Threads. (shortcut) */ TAILQ_HEAD(, thread) p_suspended; /* (td_runq) suspended threads */ + TAILQ_HEAD(, ksiginfo) p_sigq; /* (c) Queued signals. */ struct ucred *p_ucred; /* (c) Process owner's identity. */ struct filedesc *p_fd; /* (b) Ptr to open files structure. */ /* Accumulated stats for all KSEs? */ @@ -535,17 +536,15 @@ u_int p_swtime; /* (j) Time swapped in or out. */ struct itimerval p_realtimer; /* (h?/k?) Alarm timer. */ struct bintime p_runtime; /* (j) Real time. */ + int p_suicide; /* (c) Commit signal suicide. */ int p_traceflag; /* (o) Kernel trace points. */ struct vnode *p_tracep; /* (c + o) Trace to vnode. */ - sigset_t p_siglist; /* (c) Sigs arrived, not delivered. */ struct vnode *p_textvp; /* (b) Vnode of executable. */ char p_lock; /* (c) Proclock (prevent swap) count. */ struct klist p_klist; /* (c) Knotes attached to this proc. */ struct sigiolst p_sigiolst; /* (c) List of sigio sources. */ int p_sigparent; /* (c) Signal to parent on exit. */ sigset_t p_oldsigmask; /* (c) Saved mask from pre sigpause. */ - int p_sig; /* (n) For core dump/debugger XXX. */ - u_long p_code; /* (n) For core dump/debugger XXX. */ u_int p_stops; /* (c) Stop event bitmask. */ u_int p_stype; /* (c) Stop event type. */ char p_step; /* (c) Process is stopped. */ diff -Nrdu -x *CVS* -x *dev* sys/sys/signalvar.h kernel/sys/signalvar.h --- sys/sys/signalvar.h Sat Jun 29 12:26:22 2002 +++ kernel/sys/signalvar.h Sat Oct 5 01:22:06 2002 @@ -189,12 +189,6 @@ #ifdef _KERNEL -/* Return nonzero if process p has an unmasked pending signal. */ -#define SIGPENDING(p) \ - (!SIGISEMPTY((p)->p_siglist) && \ - (!sigsetmasked(&(p)->p_siglist, &(p)->p_sigmask) || \ - (p)->p_flag & P_TRACED)) - /* * Return the value of the pseudo-expression ((*set & ~*mask) != 0). This * is an optimized version of SIGISEMPTY() on a temporary variable @@ -212,11 +206,12 @@ return (1); } +struct ksiginfo; +struct mtx; struct pgrp; -struct thread; struct proc; struct sigio; -struct mtx; +struct thread; extern int sugid_coredump; /* Sysctl variable kern.sugid_coredump */ extern struct mtx sigio_lock; @@ -251,7 +246,7 @@ /* * Machine-dependent functions: */ -void sendsig(sig_t action, int sig, sigset_t *retmask, u_long code); +void sendsig(sig_t action, struct ksiginfo *, sigset_t *retmask); #endif /* _KERNEL */ diff -Nrdu -x *CVS* -x *dev* sys/sys/sysent.h kernel/sys/sysent.h --- sys/sys/sysent.h Sun Sep 1 16:41:24 2002 +++ kernel/sys/sysent.h Sat Oct 5 01:22:06 2002 @@ -51,8 +51,9 @@ #define SCARG(p,k) ((p)->k) /* get arg from args pointer */ /* placeholder till we integrate rest of lite2 syscallargs changes XXX */ -struct image_params; struct __sigset; +struct ksiginfo; +struct image_params; struct trapframe; struct vnode; @@ -68,8 +69,8 @@ /* translate trap-to-signal mapping */ int (*sv_fixup)(register_t **, struct image_params *); /* stack fixup function */ - void (*sv_sendsig)(void (*)(int), int, struct __sigset *, - u_long); /* send signal */ + void (*sv_sendsig)(void (*)(int), struct ksiginfo *, + struct __sigset *); /* send signal */ char *sv_sigcode; /* start of sigtramp code */ int *sv_szsigcode; /* size of sigtramp code */ void (*sv_prepsyscall)(struct trapframe *, int *, u_int *, %%% Thanks, juli. -- Juli Mallett | FreeBSD: The Power To Serve Will break world for fulltime employment. | finger jmallett@FreeBSD.org http://people.FreeBSD.org/~jmallett/ | Support my FreeBSD hacking! To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message