Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/libc/pthread_sigmask.c
6162 views
1
/*
2
* Copyright 2021 The Emscripten Authors. All rights reserved.
3
* Emscripten is available under two separate licenses, the MIT license and the
4
* University of Illinois/NCSA Open Source License. Both these licenses can be
5
* found in the LICENSE file.
6
*/
7
8
#define _GNU_SOURCE // for sigorset/sigandset
9
#include <stdbool.h>
10
#include <threads.h>
11
#include <signal.h>
12
#include <errno.h>
13
#include "libc.h"
14
15
#define SST_SIZE (_NSIG/8/sizeof(long))
16
17
static thread_local sigset_t __sig_mask;
18
sigset_t __sig_pending;
19
20
static int siginvertset(sigset_t *dest, const sigset_t *src) {
21
unsigned long i = 0, *d = (void*) dest, *s = (void*) src;
22
for(; i < SST_SIZE; i++) d[i] = ~s[i];
23
return 0;
24
}
25
26
bool __sig_is_blocked(int sig) {
27
return sigismember(&__sig_mask, sig);
28
}
29
30
int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict old) {
31
if (old) {
32
*old = __sig_mask;
33
}
34
35
switch (how) {
36
case SIG_SETMASK:
37
__sig_mask = *set;
38
break;
39
case SIG_BLOCK:
40
sigorset(&__sig_mask, &__sig_mask, set);
41
break;
42
case SIG_UNBLOCK: {
43
sigset_t tmp;
44
siginvertset(&tmp, set);
45
sigandset(&__sig_mask, &__sig_mask, &tmp);
46
break;
47
}
48
default:
49
return EINVAL;
50
}
51
52
// These two signals can never be blocked.
53
sigdelset(&__sig_mask, SIGKILL);
54
sigdelset(&__sig_mask, SIGSTOP);
55
56
// Raise any pending signals that are now unblocked.
57
for (int sig = 0; sig < _NSIG; sig++) {
58
if (sigismember(&__sig_pending, sig) && !sigismember(&__sig_mask, sig)) {
59
sigdelset(&__sig_pending, sig);
60
raise(sig);
61
}
62
}
63
64
return 0;
65
}
66
67
int sigpending(sigset_t *set) {
68
*set = __sig_pending;
69
return 0;
70
}
71
72