Path: blob/main/system/lib/libc/pthread_sigmask.c
6162 views
/*1* Copyright 2021 The Emscripten Authors. All rights reserved.2* Emscripten is available under two separate licenses, the MIT license and the3* University of Illinois/NCSA Open Source License. Both these licenses can be4* found in the LICENSE file.5*/67#define _GNU_SOURCE // for sigorset/sigandset8#include <stdbool.h>9#include <threads.h>10#include <signal.h>11#include <errno.h>12#include "libc.h"1314#define SST_SIZE (_NSIG/8/sizeof(long))1516static thread_local sigset_t __sig_mask;17sigset_t __sig_pending;1819static int siginvertset(sigset_t *dest, const sigset_t *src) {20unsigned long i = 0, *d = (void*) dest, *s = (void*) src;21for(; i < SST_SIZE; i++) d[i] = ~s[i];22return 0;23}2425bool __sig_is_blocked(int sig) {26return sigismember(&__sig_mask, sig);27}2829int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict old) {30if (old) {31*old = __sig_mask;32}3334switch (how) {35case SIG_SETMASK:36__sig_mask = *set;37break;38case SIG_BLOCK:39sigorset(&__sig_mask, &__sig_mask, set);40break;41case SIG_UNBLOCK: {42sigset_t tmp;43siginvertset(&tmp, set);44sigandset(&__sig_mask, &__sig_mask, &tmp);45break;46}47default:48return EINVAL;49}5051// These two signals can never be blocked.52sigdelset(&__sig_mask, SIGKILL);53sigdelset(&__sig_mask, SIGSTOP);5455// Raise any pending signals that are now unblocked.56for (int sig = 0; sig < _NSIG; sig++) {57if (sigismember(&__sig_pending, sig) && !sigismember(&__sig_mask, sig)) {58sigdelset(&__sig_pending, sig);59raise(sig);60}61}6263return 0;64}6566int sigpending(sigset_t *set) {67*set = __sig_pending;68return 0;69}707172