X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/43866e378188c25dd1e2208016ab3cbeb086ae6c..5eebf7385fedb1517b66b53c28e5aa6bb0a2be50:/bsd/kern/kern_sig.c diff --git a/bsd/kern/kern_sig.c b/bsd/kern/kern_sig.c index 5041944ca..6c593326e 100644 --- a/bsd/kern/kern_sig.c +++ b/bsd/kern/kern_sig.c @@ -1,24 +1,21 @@ /* - * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -85,9 +82,10 @@ #include #include #include - #include +#include + #include #include @@ -113,6 +111,13 @@ void psignal_lock __P((struct proc *, int, int)); void psignal_uthread __P((thread_act_t, int)); kern_return_t do_bsdexception(int, int, int); +static int filt_sigattach(struct knote *kn); +static void filt_sigdetach(struct knote *kn); +static int filt_signal(struct knote *kn, long hint); + +struct filterops sig_filtops = + { 0, filt_sigattach, filt_sigdetach, filt_signal }; + #if SIGNAL_DEBUG void ram_printf __P((int)); int ram_debug=0; @@ -290,6 +295,8 @@ sigaction(p, uap, retval) sa->sa_flags |= SA_SIGINFO; if (ps->ps_signodefer & bit) sa->sa_flags |= SA_NODEFER; + if (ps->ps_64regset & bit) + sa->sa_flags |= SA_64REGSET; if ((signum == SIGCHLD) && (p->p_flag & P_NOCLDSTOP)) sa->sa_flags |= SA_NOCLDSTOP; if ((signum == SIGCHLD) && (p->p_flag & P_NOCLDWAIT)) @@ -427,12 +434,16 @@ setsigvec(p, signum, sa) * Change setting atomically. */ ps->ps_sigact[signum] = sa->sa_handler; - ps->ps_trampact[signum] = sa->sa_tramp; + ps->ps_trampact[signum] = (sig_t) sa->sa_tramp; ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask; if (sa->sa_flags & SA_SIGINFO) ps->ps_siginfo |= bit; else ps->ps_siginfo &= ~bit; + if (sa->sa_flags & SA_64REGSET) + ps->ps_64regset |= bit; + else + ps->ps_64regset &= ~bit; if ((sa->sa_flags & SA_RESTART) == 0) ps->ps_sigintr |= bit; else @@ -655,7 +666,6 @@ osigvec(p, uap, retval) register int signum; int bit, error=0; - panic("osigvec: notsupp"); #if 0 signum = uap->signum; if (signum <= 0 || signum >= NSIG || @@ -684,6 +694,8 @@ osigvec(p, uap, retval) sv->sv_flags ^= SA_RESTART; /* opposite of SV_INTERRUPT */ error = setsigvec(p, signum, (struct sigaction *)sv); } +#else +error = ENOSYS; #endif return (error); } @@ -814,8 +826,7 @@ __pthread_kill(p, uap, retval) } uth = (struct uthread *)get_bsdthread_info(target_act); - { void *tht = getshuttle_thread(target_act); -} + if (uth->uu_flag & UNO_SIGMASK) { error = ESRCH; goto out; @@ -1048,7 +1059,9 @@ sigaltstack(p, uap, retval) psp->ps_sigstk.ss_flags = ss.ss_flags; return (0); } - if (ss.ss_size < MINSIGSTKSZ) +/* The older stacksize was 8K, enforce that one so no compat problems */ +#define OLDMINSIGSTKSZ 8*1024 + if (ss.ss_size < OLDMINSIGSTKSZ) return (ENOMEM); psp->ps_flags |= SAS_ALTSTACK; psp->ps_sigstk= ss; @@ -1069,12 +1082,23 @@ kill(cp, uap, retval) register struct proc *p; register struct pcred *pc = cp->p_cred; + AUDIT_ARG(pid, uap->pid); + AUDIT_ARG(signum, uap->signum); if ((u_int)uap->signum >= NSIG) return (EINVAL); if (uap->pid > 0) { /* kill single process */ - if ((p = pfind(uap->pid)) == NULL) + if ((p = pfind(uap->pid)) == NULL) { + if ((p = pzfind(uap->pid)) != NULL) { + /* + * IEEE Std 1003.1-2001: return success + * when killing a zombie. + */ + return (0); + } return (ESRCH); + } + AUDIT_ARG(process, p); if (!cansignal(cp, pc, p, uap->signum)) return (EPERM); if (uap->signum) @@ -1105,6 +1129,8 @@ okillpg(p, uap, retval) register_t *retval; { + AUDIT_ARG(pid, uap->pgid); + AUDIT_ARG(signum, uap->signum); if ((u_int)uap->signum >= NSIG) return (EINVAL); return (killpg1(p, uap->signum, uap->pgid, 0)); @@ -1376,12 +1402,11 @@ get_signalthread(struct proc *p, int signum) sigset_t mask = sigmask(signum); thread_act_t sig_thread_act; struct task * sig_task = p->task; - thread_t sig_thread; kern_return_t kret; if ((p->p_flag & P_INVFORK) && p->p_vforkact) { sig_thread_act = p->p_vforkact; - kret = check_actforsig(sig_task, sig_thread_act, &sig_thread, 1); + kret = check_actforsig(sig_task, sig_thread_act, 1); if (kret == KERN_SUCCESS) return(sig_thread_act); else @@ -1391,11 +1416,11 @@ get_signalthread(struct proc *p, int signum) TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) { if(((uth->uu_flag & UNO_SIGMASK)== 0) && (((uth->uu_sigmask & mask) == 0) || (uth->uu_sigwait & mask))) { - if (check_actforsig(p->task, uth->uu_act, NULL, 1) == KERN_SUCCESS) + if (check_actforsig(p->task, uth->uu_act, 1) == KERN_SUCCESS) return(uth->uu_act); } } - if (get_signalact(p->task, &thr_act, NULL, 1) == KERN_SUCCESS) { + if (get_signalact(p->task, &thr_act, 1) == KERN_SUCCESS) { return(thr_act); } @@ -1424,10 +1449,7 @@ psignal_lock(p, signum, withlock) register int s, prop; register sig_t action; thread_act_t sig_thread_act; - thread_t sig_thread; register task_t sig_task; - register thread_t cur_thread; - thread_act_t cur_act; int mask; struct uthread *uth; kern_return_t kret; @@ -1459,6 +1481,10 @@ psignal_lock(p, signum, withlock) return; } + s = splhigh(); + KNOTE(&p->p_klist, NOTE_SIGNAL | signum); + splx(s); + /* * do not send signals to the process that has the thread * doing a reboot(). Not doing so will mark that thread aborted @@ -1477,7 +1503,7 @@ psignal_lock(p, signum, withlock) * Deliver the signal to the first thread in the task. This * allows single threaded applications which use signals to * be able to be linked with multithreaded libraries. We have - * an implicit reference to the current_thread, but need + * an implicit reference to the current thread, but need * an explicit one otherwise. The thread reference keeps * the corresponding task data structures around too. This * reference is released by thread_deallocate. @@ -1486,9 +1512,6 @@ psignal_lock(p, signum, withlock) if (((p->p_flag & P_TRACED) == 0) && (p->p_sigignore & mask)) goto psigout; - cur_thread = current_thread(); /* this is a shuttle */ - cur_act = current_act(); - /* If successful return with ast set */ sig_thread_act = get_signalthread(p, signum); @@ -1602,8 +1625,16 @@ psignal_lock(p, signum, withlock) * Wake up the thread, but don't un-suspend it * (except for SIGCONT). */ - if (prop & SA_CONT) - (void) task_resume(sig_task); + if (prop & SA_CONT) { + if (p->p_flag & P_TTYSLEEP) { + p->p_flag &= ~P_TTYSLEEP; + wakeup(&p->p_siglist); + } else { + (void) task_resume(sig_task); + } + p->p_stat = SRUN; + } else if (p->p_stat == SSTOP) + goto psigout; goto run; } else { /* Default action - varies */ @@ -1688,6 +1719,8 @@ psignal_lock(p, signum, withlock) * All other signals wake up the process, but don't * resume it. */ + if (p->p_stat == SSTOP) + goto psigout; goto run; } } @@ -1726,10 +1759,7 @@ psignal_uthread(thr_act, signum) register int s, prop; register sig_t action; thread_act_t sig_thread_act; - thread_t sig_thread; register task_t sig_task; - register thread_t cur_thread; - thread_act_t cur_act; int mask; struct uthread *uth; kern_return_t kret; @@ -1772,7 +1802,7 @@ psignal_uthread(thr_act, signum) * Deliver the signal to the first thread in the task. This * allows single threaded applications which use signals to * be able to be linked with multithreaded libraries. We have - * an implicit reference to the current_thread, but need + * an implicit reference to the current thread, but need * an explicit one otherwise. The thread reference keeps * the corresponding task data structures around too. This * reference is released by thread_deallocate. @@ -1781,10 +1811,7 @@ psignal_uthread(thr_act, signum) if (((p->p_flag & P_TRACED) == 0) && (p->p_sigignore & mask)) goto puthout; - cur_thread = current_thread(); /* this is a shuttle */ - cur_act = current_act(); - - kret = check_actforsig(sig_task, sig_thread_act, &sig_thread, 1); + kret = check_actforsig(sig_task, sig_thread_act, 1); if (kret != KERN_SUCCESS) { error = EINVAL; @@ -2007,7 +2034,7 @@ __inline__ void sig_lock_to_exit( struct proc *p) { - thread_t self = current_thread(); + thread_t self = current_act(); p->exit_thread = self; (void) task_suspend(p->task); @@ -2017,7 +2044,7 @@ __inline__ int sig_try_locked( struct proc *p) { - thread_t self = current_thread(); + thread_t self = current_act(); while (p->sigwait || p->exit_thread) { if (p->exit_thread) { @@ -2025,7 +2052,7 @@ sig_try_locked( /* * Already exiting - no signals. */ - thread_abort(current_act()); + thread_abort(self); } return(0); } @@ -2064,14 +2091,12 @@ issignal(p) { register int signum, mask, prop, sigbits; task_t task = p->task; - thread_t cur_thread; thread_act_t cur_act; int s; struct uthread * ut; kern_return_t kret; struct proc *pp; - cur_thread = current_thread(); cur_act = current_act(); #if SIGNAL_DEBUG @@ -2133,6 +2158,7 @@ issignal(p) do_bsdexception(EXC_SOFTWARE, EXC_SOFT_SIGNAL, signum); signal_lock(p); } else { +// panic("Unsupportef gdb option \n");; pp->si_pid = p->p_pid; pp->si_status = p->p_xstat; pp->si_code = CLD_TRAPPED; @@ -2177,7 +2203,7 @@ issignal(p) * clear it, since sig_lock_to_exit will * wait. */ - clear_wait(current_thread(), THREAD_INTERRUPTED); + clear_wait(current_act(), THREAD_INTERRUPTED); sig_lock_to_exit(p); /* * Since this thread will be resumed @@ -2194,7 +2220,7 @@ issignal(p) /* * We may have to quit */ - if (thread_should_abort(current_thread())) { + if (thread_should_abort(current_act())) { signal_unlock(p); return(0); } @@ -2314,14 +2340,12 @@ CURSIG(p) { register int signum, mask, prop, sigbits; task_t task = p->task; - thread_t cur_thread; thread_act_t cur_act; int s; struct uthread * ut; int retnum = 0; - cur_thread = current_thread(); cur_act = current_act(); ut = get_bsdthread_info(cur_act); @@ -2446,6 +2470,7 @@ stop(p) { p->p_stat = SSTOP; p->p_flag &= ~P_WAITED; + if (p->p_pptr->p_stat != SSTOP) wakeup((caddr_t)p->p_pptr); (void) task_suspend(p->task); /*XXX*/ } @@ -2584,6 +2609,48 @@ sigexit_locked(p, signum) /* NOTREACHED */ } + +static int +filt_sigattach(struct knote *kn) +{ + struct proc *p = current_proc(); + + kn->kn_ptr.p_proc = p; + kn->kn_flags |= EV_CLEAR; /* automatically set */ + + /* XXX lock the proc here while adding to the list? */ + KNOTE_ATTACH(&p->p_klist, kn); + + return (0); +} + +static void +filt_sigdetach(struct knote *kn) +{ + struct proc *p = kn->kn_ptr.p_proc; + + KNOTE_DETACH(&p->p_klist, kn); +} + +/* + * signal knotes are shared with proc knotes, so we apply a mask to + * the hint in order to differentiate them from process hints. This + * could be avoided by using a signal-specific knote list, but probably + * isn't worth the trouble. + */ +static int +filt_signal(struct knote *kn, long hint) +{ + + if (hint & NOTE_SIGNAL) { + hint &= ~NOTE_SIGNAL; + + if (kn->kn_id == hint) + kn->kn_data++; + } + return (kn->kn_data != 0); +} + void bsd_ast(thread_act_t thr_act) { @@ -2605,7 +2672,7 @@ bsd_ast(thread_act_t thr_act) p->p_flag &= ~P_OWEUPC; } - if (CHECK_SIGNALS(p, current_thread(), ut)) { + if (CHECK_SIGNALS(p, current_act(), ut)) { while (signum = issignal(p)) postsig(signum); }