+ thread_sigmask(SIG_BLOCK, 0, sigset);
+}
+
+void
+block_signals(sigset_t *what, sigset_t *where, sigset_t *old)
+{
+ if (where) {
+ int i;
+ if (old)
+ sigcopyset(old, where);
+ for(i = 1; i < NSIG; i++) {
+ if (sigismember(what, i))
+ sigaddset(where, i);
+ }
+ } else {
+ thread_sigmask(SIG_BLOCK, what, old);
+ }
+}
+
+void
+unblock_signals(sigset_t *what, sigset_t *where, sigset_t *old)
+{
+ if (where) {
+ int i;
+ if (old)
+ sigcopyset(old, where);
+ for(i = 1; i < NSIG; i++) {
+ if (sigismember(what, i))
+ sigdelset(where, i);
+ }
+ } else {
+ thread_sigmask(SIG_UNBLOCK, what, old);
+ }
+}
+
+static void
+print_sigset(sigset_t *sigset)
+{
+ int i;
+ for(i = 1; i < NSIG; i++) {
+ if (sigismember(sigset, i))
+ fprintf(stderr, "Signal %d masked\n", i);
+ }
+}
+
+/* Return 1 is all signals is sigset2 are masked in sigset, return 0
+ * if all re unmasked else die. Passing NULL for sigset is a shorthand
+ * for the current sigmask. */
+boolean
+all_signals_blocked_p(sigset_t *sigset, sigset_t *sigset2,
+ const char *name)
+{
+#if !defined(LISP_FEATURE_WIN32)
+ int i;
+ boolean has_blocked = 0, has_unblocked = 0;
+ sigset_t current;
+ if (sigset == 0) {
+ get_current_sigmask(¤t);
+ sigset = ¤t;
+ }
+ for(i = 1; i < NSIG; i++) {
+ if (sigismember(sigset2, i)) {
+ if (sigismember(sigset, i))
+ has_blocked = 1;
+ else
+ has_unblocked = 1;
+ }
+ }
+ if (has_blocked && has_unblocked) {
+ print_sigset(sigset);
+ lose("some %s signals blocked, some unblocked\n", name);
+ }
+ if (has_blocked)
+ return 1;
+ else
+ return 0;
+#endif