summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_sig.c155
1 files changed, 77 insertions, 78 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 6aad5bcb69a..8d2537ec55e 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.330 2024/06/03 12:48:25 claudio Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.331 2024/07/09 09:22:50 claudio Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -1065,6 +1065,73 @@ ptsignal(struct proc *p, int signum, enum signal_type type)
switch (p->p_stat) {
+ case SSTOP:
+ /*
+ * If traced process is already stopped,
+ * then no further action is necessary.
+ */
+ if (pr->ps_flags & PS_TRACED)
+ goto out;
+
+ /*
+ * Kill signal always sets processes running.
+ */
+ if (signum == SIGKILL) {
+ atomic_clearbits_int(&p->p_flag, P_SUSPSIG);
+ goto runfast;
+ }
+
+ if (prop & SA_CONT) {
+ /*
+ * If SIGCONT is default (or ignored), we continue the
+ * process but don't leave the signal in p_siglist, as
+ * it has no further action. If SIGCONT is held, we
+ * continue the process and leave the signal in
+ * p_siglist. If the process catches SIGCONT, let it
+ * handle the signal itself. If it isn't waiting on
+ * an event, then it goes back to run state.
+ * Otherwise, process goes back to sleep state.
+ */
+ atomic_setbits_int(&p->p_flag, P_CONTINUED);
+ atomic_clearbits_int(&p->p_flag, P_SUSPSIG);
+ wakeparent = 1;
+ if (action == SIG_DFL)
+ mask = 0;
+ if (action == SIG_CATCH)
+ goto runfast;
+ if (p->p_wchan == NULL)
+ goto run;
+ atomic_clearbits_int(&p->p_flag, P_WSLEEP);
+ p->p_stat = SSLEEP;
+ goto out;
+ }
+
+ /*
+ * Defer further processing for signals which are held,
+ * except that stopped processes must be continued by SIGCONT.
+ */
+ if (action == SIG_HOLD)
+ goto out;
+
+ if (prop & SA_STOP) {
+ /*
+ * Already stopped, don't need to stop again.
+ * (If we did the shell could get confused.)
+ */
+ mask = 0;
+ goto out;
+ }
+
+ /*
+ * If process is sleeping interruptibly, then simulate a
+ * wakeup so that when it is continued, it will be made
+ * runnable and can look at the signal. But don't make
+ * the process runnable, leave it stopped.
+ */
+ if (p->p_flag & P_SINTR)
+ unsleep(p);
+ goto out;
+
case SSLEEP:
/*
* If process is sleeping uninterruptibly
@@ -1143,73 +1210,6 @@ ptsignal(struct proc *p, int signum, enum signal_type type)
goto runfast;
/* NOTREACHED */
- case SSTOP:
- /*
- * If traced process is already stopped,
- * then no further action is necessary.
- */
- if (pr->ps_flags & PS_TRACED)
- goto out;
-
- /*
- * Kill signal always sets processes running.
- */
- if (signum == SIGKILL) {
- atomic_clearbits_int(&p->p_flag, P_SUSPSIG);
- goto runfast;
- }
-
- if (prop & SA_CONT) {
- /*
- * If SIGCONT is default (or ignored), we continue the
- * process but don't leave the signal in p_siglist, as
- * it has no further action. If SIGCONT is held, we
- * continue the process and leave the signal in
- * p_siglist. If the process catches SIGCONT, let it
- * handle the signal itself. If it isn't waiting on
- * an event, then it goes back to run state.
- * Otherwise, process goes back to sleep state.
- */
- atomic_setbits_int(&p->p_flag, P_CONTINUED);
- atomic_clearbits_int(&p->p_flag, P_SUSPSIG);
- wakeparent = 1;
- if (action == SIG_DFL)
- mask = 0;
- if (action == SIG_CATCH)
- goto runfast;
- if (p->p_wchan == NULL)
- goto run;
- atomic_clearbits_int(&p->p_flag, P_WSLEEP);
- p->p_stat = SSLEEP;
- goto out;
- }
-
- /*
- * Defer further processing for signals which are held,
- * except that stopped processes must be continued by SIGCONT.
- */
- if (action == SIG_HOLD)
- goto out;
-
- if (prop & SA_STOP) {
- /*
- * Already stopped, don't need to stop again.
- * (If we did the shell could get confused.)
- */
- mask = 0;
- goto out;
- }
-
- /*
- * If process is sleeping interruptibly, then simulate a
- * wakeup so that when it is continued, it will be made
- * runnable and can look at the signal. But don't make
- * the process runnable, leave it stopped.
- */
- if (p->p_flag & P_SINTR)
- unsleep(p);
- goto out;
-
case SONPROC:
if (action == SIG_HOLD)
goto out;
@@ -2160,8 +2160,12 @@ single_thread_set(struct proc *p, int flags)
SCHED_LOCK();
atomic_setbits_int(&q->p_flag, P_SUSPSINGLE);
switch (q->p_stat) {
- case SIDL:
- case SDEAD:
+ case SSTOP:
+ if (mode == SINGLE_EXIT) {
+ unsleep(q);
+ setrunnable(q);
+ } else
+ --pr->ps_singlecnt;
break;
case SSLEEP:
/* if it's not interruptible, then just have to wait */
@@ -2177,17 +2181,12 @@ single_thread_set(struct proc *p, int flags)
setrunnable(q);
}
break;
- case SSTOP:
- if (mode == SINGLE_EXIT) {
- unsleep(q);
- setrunnable(q);
- } else
- --pr->ps_singlecnt;
- break;
case SONPROC:
signotify(q);
- /* FALLTHROUGH */
+ break;
case SRUN:
+ case SIDL:
+ case SDEAD:
break;
}
SCHED_UNLOCK();