| 1 | module 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 | |
| 10 | fn 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. |
| 13 | pub 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. |
| 29 | fn ignore_signal_handler(_signal Signal) { |
| 30 | } |
| 31 | |
| 32 | // signal_ignore to mask system signals, e.g.: signal_ignore(.pipe, .urg, ...). |
| 33 | pub 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 | |