+ }
+ /*
+ * SIGKILL priority twiddling moved here from above because
+ * it needs sig_thread. Could merge it into large switch
+ * below if we didn't care about priority for tracing
+ * as SIGKILL's action is always SIG_DFL.
+ */
+ if ((signum == SIGKILL) && (p->p_nice > NZERO)) {
+ p->p_nice = NZERO;
+ }
+
+ /*
+ * Process is traced - wake it up (if not already
+ * stopped) so that it can discover the signal in
+ * issig() and stop for the parent.
+ */
+ if (p->p_flag & P_TRACED) {
+ if (p->p_stat != SSTOP)
+ goto run;
+ else
+ goto psigout;
+ }
+
+ if (action == SIG_WAIT) {
+ uth->uu_sigwait = mask;
+ uth->uu_siglist &= ~mask;
+ p->p_siglist &= ~mask;
+ wakeup(&uth->uu_sigwait);
+ /* if it is SIGCONT resume whole process */
+ if (prop & SA_CONT)
+ (void) task_resume(sig_task);
+ goto psigout;
+ }
+
+ if (action != SIG_DFL) {
+ /*
+ * User wants to catch the signal.
+ * Wake up the thread, but don't un-suspend it
+ * (except for SIGCONT).
+ */
+ if (prop & SA_CONT)
+ (void) task_resume(sig_task);
+ goto run;
+ } else {
+ /* Default action - varies */
+ if (mask & stopsigmask) {
+ /*
+ * These are the signals which by default
+ * stop a process.
+ *
+ * Don't clog system with children of init
+ * stopped from the keyboard.
+ */
+ if (!(prop & SA_STOP) && p->p_pptr == initproc) {
+ psignal_lock(p, SIGKILL, 0);
+ uth->uu_siglist &= ~mask;
+ p->p_siglist &= ~mask;
+ goto psigout;
+ }
+
+ /*
+ * Stop the task
+ * if task hasn't already been stopped by
+ * a signal.
+ */
+ uth->uu_siglist &= ~mask;
+ p->p_siglist &= ~mask;
+ if (p->p_stat != SSTOP) {
+ p->p_xstat = signum;
+ stop(p);
+ if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0) {
+ struct proc *pp = p->p_pptr;
+
+ pp->si_pid = p->p_pid;
+ pp->si_status = p->p_xstat;
+ pp->si_code = CLD_STOPPED;
+ pp->si_uid = p->p_cred->p_ruid;
+ psignal(pp, SIGCHLD);
+ }
+ }
+ goto psigout;
+ }
+
+ switch (signum) {
+ /*
+ * Signals ignored by default have been dealt
+ * with already, since their bits are on in
+ * p_sigignore.
+ */
+
+ case SIGKILL:
+ /*
+ * Kill signal always sets process running and
+ * unsuspends it.
+ */
+ /*
+ * Process will be running after 'run'
+ */
+ p->p_stat = SRUN;
+
+ thread_abort(sig_thread_act);
+
+ goto psigout;
+
+ case SIGCONT:
+ /*
+ * Let the process run. If it's sleeping on an
+ * event, it remains so.
+ */
+ if (p->p_flag & P_TTYSLEEP) {
+ p->p_flag &= ~P_TTYSLEEP;
+ wakeup(&p->p_siglist);
+ } else {
+ (void) task_resume(sig_task);
+ }
+ uth->uu_siglist &= ~mask;
+ p->p_siglist &= ~mask;
+ p->p_stat = SRUN;
+
+ goto psigout;
+
+ default:
+ /*
+ * All other signals wake up the process, but don't
+ * resume it.
+ */
+ goto run;
+ }
+ }
+ /*NOTREACHED*/
+run:
+ /*
+ * If we're being traced (possibly because someone attached us
+ * while we were stopped), check for a signal from the debugger.
+ */
+ if (p->p_stat == SSTOP) {
+ if ((p->p_flag & P_TRACED) != 0 && p->p_xstat != 0)
+ uth->uu_siglist |= sigmask(p->p_xstat);
+ } else {
+ /*
+ * setrunnable(p) in BSD and
+ * Wake up the thread if it is interruptible.
+ */
+ p->p_stat = SRUN;
+ thread_abort_safely(sig_thread_act);
+ }
+psigout:
+ if (withlock)
+ signal_unlock(p);
+ if (sw_funnel)
+ thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
+}
+
+
+/* psignal_lock(p, signum, withlock ) */
+void
+psignal_uthread(thr_act, signum)
+ thread_act_t thr_act;
+ int signum;
+{
+ struct proc *p;
+ 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;
+ int error = 0;
+
+ p = (struct proc *)get_bsdtask_info(get_threadtask(thr_act));
+ if ((u_int)signum >= NSIG || signum == 0)
+ panic("Invalid signal number in psignal_uthread");
+ mask = sigmask(signum);
+ prop = sigprop[signum];
+
+#if SIGNAL_DEBUG
+ if(rdebug_proc && (p == rdebug_proc)) {
+ ram_printf(3);
+ }
+#endif /* SIGNAL_DEBUG */
+
+ /*
+ * We will need the task pointer later. Grab it now to
+ * check for a zombie process. Also don't send signals
+ * to kernel internal tasks.
+ */
+ if (((sig_task = p->task) == TASK_NULL) || is_kerneltask(sig_task)) {
+ return;
+ }
+
+ sig_thread_act = thr_act;
+ /*
+ * do not send signals to the process that has the thread
+ * doing a reboot(). Not doing so will mark that thread aborted
+ * and can cause IO failures wich will cause data loss.
+ */
+ if (ISSET(p->p_flag, P_REBOOT)) {
+ return;
+ }
+
+ signal_lock(p);
+