From f48068addb8865f9338d23ffbe1043e369df37a1 Mon Sep 17 00:00:00 2001 From: raf Date: Mon, 6 Aug 2007 13:50:45 -0700 Subject: 6586967 Signal is sometimes not delivered on the alternate stack (although it should) --- usr/src/uts/common/syscall/signotify.c | 65 +++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) (limited to 'usr/src/uts/common/syscall/signotify.c') diff --git a/usr/src/uts/common/syscall/signotify.c b/usr/src/uts/common/syscall/signotify.c index 0c32a0cd5e..860e22bd24 100644 --- a/usr/src/uts/common/syscall/signotify.c +++ b/usr/src/uts/common/syscall/signotify.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -224,3 +225,59 @@ signotify(int cmd, siginfo_t *siginfo, signotify_id_t *sn_id) return (0); } + +int +sigresend(int sig, siginfo_t *siginfo, sigset_t *mask) +{ + kthread_t *t = curthread; + proc_t *p = ttoproc(t); + klwp_t *lwp = ttolwp(t); + sigqueue_t *sqp = kmem_zalloc(sizeof (*sqp), KM_SLEEP); + sigset_t set; + k_sigset_t kset; + int error; + + if (sig <= 0 || sig >= NSIG || sigismember(&cantmask, sig)) { + error = EINVAL; + goto bad; + } + + if (siginfo == NULL) { + sqp->sq_info.si_signo = sig; + sqp->sq_info.si_code = SI_NOINFO; + } else { + if (copyin_siginfo(get_udatamodel(), siginfo, &sqp->sq_info)) { + error = EFAULT; + goto bad; + } + if (sqp->sq_info.si_signo != sig) { + error = EINVAL; + goto bad; + } + } + + if (copyin(mask, &set, sizeof (set))) { + error = EFAULT; + goto bad; + } + sigutok(&set, &kset); + + mutex_enter(&p->p_lock); + if (lwp->lwp_cursig || lwp->lwp_curinfo) { + mutex_exit(&p->p_lock); + t->t_sig_check = 1; + error = EAGAIN; + goto bad; + } + lwp->lwp_cursig = sig; + lwp->lwp_curinfo = sqp; + schedctl_finish_sigblock(t); + t->t_hold = kset; + mutex_exit(&p->p_lock); + + t->t_sig_check = 1; + return (0); +bad: + kmem_free(sqp, sizeof (*sqp)); + return (set_errno(error)); +} -- cgit v1.2.3