-/* $OpenBSD: kern_sig.c,v 1.342 2024/10/15 13:49:26 claudio Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.343 2024/10/17 09:11:35 claudio Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
* they aren't returned. This is checked after each entry to the system for
* a syscall or trap. The normal call sequence is
*
- * while (signum = cursig(curproc, &ctx))
+ * while (signum = cursig(curproc, &ctx, 0))
* postsig(signum, &ctx);
*
* Assumes that if the P_SINTR flag is set, we're holding both the
* kernel and scheduler locks.
*/
int
-cursig(struct proc *p, struct sigctx *sctx)
+cursig(struct proc *p, struct sigctx *sctx, int deep)
{
struct process *pr = p->p_p;
int signum, mask, prop;
if (sctx->sig_ignore && (pr->ps_flags & PS_TRACED) == 0)
continue;
+ /*
+ * If cursig is called while going to sleep, abort now
+ * and stop the sleep. When the call unwinded to userret
+ * cursig is called again and there the signal can be
+ * handled cleanly.
+ */
+ if (deep)
+ goto keep;
+
/*
* If traced, always stop, and stay stopped until released
* by the debugger. If our parent process is waiting for
dosigsuspend(p, p->p_sigmask &~ mask);
for (;;) {
- si.si_signo = cursig(p, &ctx);
+ si.si_signo = cursig(p, &ctx, 0);
if (si.si_signo != 0) {
sigset_t smask = sigmask(si.si_signo);
if (smask & mask) {
}
if (SIGPENDING(p) != 0) {
- while ((signum = cursig(p, &ctx)) != 0)
+ while ((signum = cursig(p, &ctx, 0)) != 0)
postsig(p, signum, &ctx);
}
p->p_sigmask = p->p_oldmask;
atomic_clearbits_int(&p->p_flag, P_SIGSUSPEND);
- while ((signum = cursig(p, &ctx)) != 0)
+ while ((signum = cursig(p, &ctx, 0)) != 0)
postsig(p, signum, &ctx);
}
-/* $OpenBSD: kern_synch.c,v 1.206 2024/07/23 08:38:02 claudio Exp $ */
+/* $OpenBSD: kern_synch.c,v 1.207 2024/10/17 09:11:35 claudio Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
if ((err = single_thread_check(p, 1)) != 0)
return err;
- if ((sig = cursig(p, &ctx)) != 0) {
+ if ((sig = cursig(p, &ctx, 1)) != 0) {
if (ctx.sig_intr)
return EINTR;
else
-/* $OpenBSD: signalvar.h,v 1.55 2024/10/09 08:39:49 claudio Exp $ */
+/* $OpenBSD: signalvar.h,v 1.56 2024/10/17 09:11:35 claudio Exp $ */
/* $NetBSD: signalvar.h,v 1.17 1996/04/22 01:23:31 christos Exp $ */
/*
*/
int coredump(struct proc *p);
void execsigs(struct proc *p);
-int cursig(struct proc *p, struct sigctx *);
+int cursig(struct proc *p, struct sigctx *, int);
void pgsigio(struct sigio_ref *sir, int sig, int checkctty);
void pgsignal(struct pgrp *pgrp, int sig, int checkctty);
void psignal(struct proc *p, int sig);
-/* $OpenBSD: mfs_vfsops.c,v 1.62 2022/02/14 11:26:05 claudio Exp $ */
+/* $OpenBSD: mfs_vfsops.c,v 1.63 2024/10/17 09:11:35 claudio Exp $ */
/* $NetBSD: mfs_vfsops.c,v 1.10 1996/02/09 22:31:28 christos Exp $ */
/*
* EINTR/ERESTART.
*/
if (sleepreturn != 0) {
- sig = cursig(p, &ctx);
+ sig = cursig(p, &ctx, 0);
if (vfs_busy(mp, VB_WRITE|VB_NOWAIT) ||
dounmount(mp, (sig == SIGKILL) ? MNT_FORCE : 0, p))
atomic_clearbits_int(&p->p_siglist,