Origin: https://git.kernel.org/pub/scm/libs/klibc/klibc.git/commit/?id=
eb10cf8c3128612a089ace8489a81bc4ffd5d07a
Bug-Debian: https://bugs.debian.org/988027
Save and restore the signal mask only if that argument is nonzero,
as required by the standards. (Closes: Debian #988027)
Signed-off-by: mirabilos <tg@debian.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Gbp-Pq: Name sig-set-long-jmp-do-not-ignore-sigsetjmp-s-second-ar.patch
struct __sigjmp_buf {
jmp_buf __jmpbuf;
sigset_t __sigs;
+ unsigned char __sigs_saved;
};
typedef struct __sigjmp_buf sigjmp_buf[1];
#define sigsetjmp(__env, __save) \
({ \
struct __sigjmp_buf *__e = (__env); \
- sigprocmask(0, NULL, &__e->__sigs); \
+ if (__save) { \
+ sigprocmask(0, NULL, &__e->__sigs); \
+ __e->__sigs_saved = 1; \
+ } else \
+ __e->__sigs_saved = 0; \
setjmp(__e->__jmpbuf); \
})
setjmp()/longjmp():
-------------------
setjmp() and longjmp() *do not* save signal state. sigsetjmp() and
-siglongjmp() *do* save the signal mask -- regardless of the value of
-the extra argument.
+siglongjmp() *do* save the signal mask if the extra argument is nonzero.
The standards actually state that if you pass longjmp() a final value
of zero the library should change that to a 1! Presumably the reason
__noreturn siglongjmp(sigjmp_buf buf, int retval)
{
- sigprocmask(SIG_SETMASK, &buf->__sigs, NULL);
+ if (buf->__sigs_saved)
+ sigprocmask(SIG_SETMASK, &buf->__sigs, NULL);
longjmp(buf->__jmpbuf, retval);
}