Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / basis / Posix / Signal.c
1 #include "platform.h"
2
3 extern struct GC_state gcState;
4
5 static void handler (int signum) {
6 GC_handler (&gcState, signum);
7 }
8
9 C_Errno_t(C_Int_t) Posix_Signal_default (C_Signal_t signum) {
10 struct sigaction sa;
11
12 sigdelset (GC_getSignalsHandledAddr (&gcState), signum);
13 memset (&sa, 0, sizeof(sa));
14 sa.sa_handler = SIG_DFL;
15 return sigaction (signum, &sa, NULL);
16 }
17
18 C_Errno_t(C_Int_t) Posix_Signal_isDefault (C_Int_t signum, Ref(C_Int_t) isDef) {
19 int res;
20 struct sigaction sa;
21
22 memset (&sa, 0, sizeof(sa));
23 res = sigaction (signum, NULL, &sa);
24 *((C_Int_t*)isDef) = sa.sa_handler == SIG_DFL;
25 return res;
26 }
27
28 C_Errno_t(C_Int_t) Posix_Signal_ignore (C_Signal_t signum) {
29 struct sigaction sa;
30
31 sigdelset (GC_getSignalsHandledAddr (&gcState), signum);
32 memset (&sa, 0, sizeof(sa));
33 sa.sa_handler = SIG_IGN;
34 return sigaction (signum, &sa, NULL);
35 }
36
37 C_Errno_t(C_Int_t) Posix_Signal_isIgnore (C_Int_t signum, Ref(C_Int_t) isIgn) {
38 int res;
39 struct sigaction sa;
40
41 memset (&sa, 0, sizeof(sa));
42 res = sigaction (signum, NULL, &sa);
43 *((C_Int_t*)isIgn) = sa.sa_handler == SIG_IGN;
44 return res;
45 }
46
47 C_Errno_t(C_Int_t) Posix_Signal_handlee (C_Int_t signum) {
48 struct sigaction sa;
49
50 sigaddset (GC_getSignalsHandledAddr (&gcState), signum);
51 memset (&sa, 0, sizeof(sa));
52 /* The mask must be full because GC_handler reads and writes
53 * s->signalsPending (else there is a race condition).
54 */
55 sigfillset (&sa.sa_mask);
56 #if HAS_SIGALTSTACK
57 sa.sa_flags = SA_ONSTACK;
58 #endif
59 sa.sa_handler = handler;
60 return sigaction (signum, &sa, NULL);
61 }
62
63 void Posix_Signal_handleGC (void) {
64 GC_setGCSignalHandled (&gcState, TRUE);
65 }
66
67 C_Int_t Posix_Signal_isPending (C_Int_t signum) {
68 return sigismember (GC_getSignalsPendingAddr (&gcState), signum);
69 }
70
71 C_Int_t Posix_Signal_isPendingGC (void) {
72 return GC_getGCSignalPending (&gcState);
73 }
74
75 void Posix_Signal_resetPending (void) {
76 sigemptyset (GC_getSignalsPendingAddr (&gcState));
77 GC_setGCSignalPending (&gcState, FALSE);
78 }
79
80 C_Errno_t(C_Int_t) Posix_Signal_sigaddset (Array(Word8_t) sigset, C_Signal_t signum) {
81 return sigaddset ((sigset_t*)sigset, signum);
82 }
83
84 C_Errno_t(C_Int_t) Posix_Signal_sigdelset (Array(Word8_t) sigset, C_Signal_t signum) {
85 return sigdelset ((sigset_t*)sigset, signum);
86 }
87
88 C_Errno_t(C_Int_t) Posix_Signal_sigemptyset (Array(Word8_t) sigset) {
89 return sigemptyset ((sigset_t*)sigset);
90 }
91
92 C_Errno_t(C_Int_t) Posix_Signal_sigfillset (Array(Word8_t) sigset) {
93 return sigfillset ((sigset_t*)sigset);
94 }
95
96 C_Errno_t(C_Int_t) Posix_Signal_sigismember (Vector(Word8_t) sigset, C_Signal_t signum) {
97 return sigismember ((sigset_t*)sigset, signum);
98 }
99
100 C_Errno_t(C_Int_t) Posix_Signal_sigprocmask (C_Int_t how, Vector(Word8_t) sigset, Array(Word8_t) oldsigset) {
101 return sigprocmask (how, (sigset_t*)sigset, (sigset_t*)oldsigset);
102 }
103
104 #if ASSERT
105 #define LOCAL_USED_FOR_ASSERT
106 #else
107 #define LOCAL_USED_FOR_ASSERT __attribute__ ((unused))
108 #endif
109
110 void Posix_Signal_sigsuspend (Vector(Word8_t) sigset) {
111 LOCAL_USED_FOR_ASSERT int res;
112
113 res = sigsuspend ((sigset_t*)sigset);
114 assert (-1 == res);
115 }