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;
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))
* 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
register int signum;
int bit, error=0;
- panic("osigvec: notsupp");
#if 0
signum = uap->signum;
if (signum <= 0 || signum >= NSIG ||
sv->sv_flags ^= SA_RESTART; /* opposite of SV_INTERRUPT */
error = setsigvec(p, signum, (struct sigaction *)sv);
}
+#else
+error = ENOSYS;
#endif
return (error);
}
}
uth = (struct uthread *)get_bsdthread_info(target_act);
- { void *tht = getshuttle_thread(target_act);
-}
+
if (uth->uu_flag & UNO_SIGMASK) {
error = ESRCH;
goto out;
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;
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);
+ }
if (!cansignal(cp, pc, p, uap->signum))
return (EPERM);
if (uap->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
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);
}
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;
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
* 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.
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);
* 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;
+ }
goto run;
} else {
/* Default action - varies */
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;
* 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.
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;
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);
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) {
/*
* Already exiting - no signals.
*/
- thread_abort(current_act());
+ thread_abort(self);
}
return(0);
}
{
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
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;
* 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
/*
* We may have to quit
*/
- if (thread_should_abort(current_thread())) {
+ if (thread_should_abort(current_act())) {
signal_unlock(p);
return(0);
}
{
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);
/* 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)
{
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);
}