v2 / vlib / os / signal.c.v
45 lines · 38 sloc · 1.68 KB · 3d60410b605d001e54f280070d5f952da9de1112
Raw
1module os
2
3#include <signal.h>
4
5// v_signal_with_handler_cast wraps signal() with a cast to avoid
6// clang -Werror=incompatible-function-pointer-types between
7// void (*)(os__Signal) and void (*)(int).
8#define v_signal_with_handler_cast(sig, handler) signal((sig), (void (*)(int))(handler))
9
10fn C.v_signal_with_handler_cast(signal i32, handlercb SignalHandler) voidptr
11
12// signal will assign `handler` callback to be called when `signum` signal is received.
13pub fn signal_opt(signum Signal, handler SignalHandler) !SignalHandler {
14 C.errno = 0
15 prev_handler := C.v_signal_with_handler_cast(int(signum), handler)
16 if prev_handler == C.SIG_ERR {
17 // errno isn't correctly set on Windows, but EINVAL is this only possible value it can take anyway
18 return error_with_code(posix_get_error_msg(C.EINVAL), C.EINVAL)
19 }
20 return SignalHandler(prev_handler)
21}
22
23// A convenient way to ignore certain system signals when there is no need to process certain system signals,
24// Masking of system signals under posix systems requires a distinction between main and background threads.
25// Since there is no good way to easily tell whether the current thread is the main or background thread,
26// So a global variable is introduced to make the distinction.
27
28// An empty system signal handler (callback function) used to mask the specified system signal.
29fn ignore_signal_handler(_signal Signal) {
30}
31
32// signal_ignore to mask system signals, e.g.: signal_ignore(.pipe, .urg, ...).
33pub fn signal_ignore(args ...Signal) {
34 if is_main_thread() {
35 // for main thread.
36 $if !windows {
37 for arg in args {
38 signal_opt(arg, ignore_signal_handler) or {}
39 }
40 }
41 } else {
42 // for background threads.
43 signal_ignore_internal(...args)
44 }
45}
46