seq_runtime/signal/
ops.rs1use crate::stack::{Stack, pop, push};
8use crate::value::Value;
9
10#[cfg(unix)]
11use std::sync::atomic::Ordering;
12
13#[cfg(unix)]
14use super::{MAX_SIGNAL, SIGNAL_FLAGS};
15
16#[cfg(unix)]
27#[unsafe(no_mangle)]
28pub unsafe extern "C" fn patch_seq_signal_trap(stack: Stack) -> Stack {
29 unsafe {
30 let (stack, sig_val) = pop(stack);
31 let sig_num = match sig_val {
32 Value::Int(n) => {
33 if n < 0 || n as usize >= MAX_SIGNAL {
34 panic!("signal.trap: invalid signal number {}", n);
35 }
36 n as libc::c_int
37 }
38 _ => panic!(
39 "signal.trap: expected Int (signal number), got {:?}",
40 sig_val
41 ),
42 };
43
44 if let Err(e) = super::handlers::install_signal_handler(sig_num) {
46 panic!(
47 "signal.trap: failed to install handler for signal {}: {}",
48 sig_num, e
49 );
50 }
51 stack
52 }
53}
54
55#[cfg(unix)]
65#[unsafe(no_mangle)]
66pub unsafe extern "C" fn patch_seq_signal_received(stack: Stack) -> Stack {
67 unsafe {
68 let (stack, sig_val) = pop(stack);
69 let sig_num = match sig_val {
70 Value::Int(n) => {
71 if n < 0 || n as usize >= MAX_SIGNAL {
72 panic!("signal.received?: invalid signal number {}", n);
73 }
74 n as usize
75 }
76 _ => panic!(
77 "signal.received?: expected Int (signal number), got {:?}",
78 sig_val
79 ),
80 };
81
82 let was_set = SIGNAL_FLAGS[sig_num].swap(false, Ordering::Acquire);
84 push(stack, Value::Bool(was_set))
85 }
86}
87
88#[cfg(unix)]
98#[unsafe(no_mangle)]
99pub unsafe extern "C" fn patch_seq_signal_pending(stack: Stack) -> Stack {
100 unsafe {
101 let (stack, sig_val) = pop(stack);
102 let sig_num = match sig_val {
103 Value::Int(n) => {
104 if n < 0 || n as usize >= MAX_SIGNAL {
105 panic!("signal.pending?: invalid signal number {}", n);
106 }
107 n as usize
108 }
109 _ => panic!(
110 "signal.pending?: expected Int (signal number), got {:?}",
111 sig_val
112 ),
113 };
114
115 let is_set = SIGNAL_FLAGS[sig_num].load(Ordering::Acquire);
116 push(stack, Value::Bool(is_set))
117 }
118}
119
120#[cfg(unix)]
129#[unsafe(no_mangle)]
130pub unsafe extern "C" fn patch_seq_signal_default(stack: Stack) -> Stack {
131 unsafe {
132 let (stack, sig_val) = pop(stack);
133 let sig_num = match sig_val {
134 Value::Int(n) => {
135 if n < 0 || n as usize >= MAX_SIGNAL {
136 panic!("signal.default: invalid signal number {}", n);
137 }
138 n as libc::c_int
139 }
140 _ => panic!(
141 "signal.default: expected Int (signal number), got {:?}",
142 sig_val
143 ),
144 };
145
146 if let Err(e) = super::handlers::restore_default_handler(sig_num) {
147 panic!(
148 "signal.default: failed to restore default handler for signal {}: {}",
149 sig_num, e
150 );
151 }
152 stack
153 }
154}
155
156#[cfg(unix)]
166#[unsafe(no_mangle)]
167pub unsafe extern "C" fn patch_seq_signal_ignore(stack: Stack) -> Stack {
168 unsafe {
169 let (stack, sig_val) = pop(stack);
170 let sig_num = match sig_val {
171 Value::Int(n) => {
172 if n < 0 || n as usize >= MAX_SIGNAL {
173 panic!("signal.ignore: invalid signal number {}", n);
174 }
175 n as libc::c_int
176 }
177 _ => panic!(
178 "signal.ignore: expected Int (signal number), got {:?}",
179 sig_val
180 ),
181 };
182
183 if let Err(e) = super::handlers::ignore_signal(sig_num) {
184 panic!("signal.ignore: failed to ignore signal {}: {}", sig_num, e);
185 }
186 stack
187 }
188}
189
190#[cfg(unix)]
199#[unsafe(no_mangle)]
200pub unsafe extern "C" fn patch_seq_signal_clear(stack: Stack) -> Stack {
201 unsafe {
202 let (stack, sig_val) = pop(stack);
203 let sig_num = match sig_val {
204 Value::Int(n) => {
205 if n < 0 || n as usize >= MAX_SIGNAL {
206 panic!("signal.clear: invalid signal number {}", n);
207 }
208 n as usize
209 }
210 _ => panic!(
211 "signal.clear: expected Int (signal number), got {:?}",
212 sig_val
213 ),
214 };
215
216 SIGNAL_FLAGS[sig_num].store(false, Ordering::Release);
217 stack
218 }
219}
220
221#[cfg(not(unix))]
227#[unsafe(no_mangle)]
228pub unsafe extern "C" fn patch_seq_signal_trap(stack: Stack) -> Stack {
229 let (stack, _) = unsafe { pop(stack) };
230 stack
232}
233
234#[cfg(not(unix))]
237#[unsafe(no_mangle)]
238pub unsafe extern "C" fn patch_seq_signal_default(stack: Stack) -> Stack {
239 let (stack, _) = unsafe { pop(stack) };
240 stack
241}
242
243#[cfg(not(unix))]
246#[unsafe(no_mangle)]
247pub unsafe extern "C" fn patch_seq_signal_ignore(stack: Stack) -> Stack {
248 let (stack, _) = unsafe { pop(stack) };
249 stack
250}
251
252#[cfg(not(unix))]
255#[unsafe(no_mangle)]
256pub unsafe extern "C" fn patch_seq_signal_received(stack: Stack) -> Stack {
257 let (stack, _) = unsafe { pop(stack) };
258 unsafe { push(stack, Value::Bool(false)) }
260}
261
262#[cfg(not(unix))]
265#[unsafe(no_mangle)]
266pub unsafe extern "C" fn patch_seq_signal_pending(stack: Stack) -> Stack {
267 let (stack, _) = unsafe { pop(stack) };
268 unsafe { push(stack, Value::Bool(false)) }
270}
271
272#[cfg(not(unix))]
275#[unsafe(no_mangle)]
276pub unsafe extern "C" fn patch_seq_signal_clear(stack: Stack) -> Stack {
277 let (stack, _) = unsafe { pop(stack) };
278 stack
280}