diff options
author | raf <none@none> | 2007-08-06 13:50:45 -0700 |
---|---|---|
committer | raf <none@none> | 2007-08-06 13:50:45 -0700 |
commit | f48068addb8865f9338d23ffbe1043e369df37a1 (patch) | |
tree | 4491fa42ed4f6bc8843d62a840b682b769407e96 /usr/src/uts/common/syscall/signotify.c | |
parent | ee834aa8ed0c4cc43a04342fe22402b3db18a906 (diff) | |
download | illumos-gate-f48068addb8865f9338d23ffbe1043e369df37a1.tar.gz |
6586967 Signal is sometimes not delivered on the alternate stack (although it should)
Diffstat (limited to 'usr/src/uts/common/syscall/signotify.c')
-rw-r--r-- | usr/src/uts/common/syscall/signotify.c | 65 |
1 files changed, 61 insertions, 4 deletions
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 <sys/fault.h> #include <sys/signal.h> #include <sys/siginfo.h> +#include <sys/schedctl.h> #include <vm/as.h> #include <sys/debug.h> #include <sys/contract/process_impl.h> @@ -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)); +} |