static void decode_sigset(value vset, sigset_t * set) { sigemptyset(set); while (vset != Val_int(0)) { int sig = caml_convert_signal_number(Int_val(Field(vset, 0))); sigaddset(set, sig); vset = Field(vset, 1); } }
CAMLprim value caml_install_signal_handler(value signal_number, value action) { CAMLparam2 (signal_number, action); CAMLlocal1 (res); int sig, act, oldact; sig = caml_convert_signal_number(Int_val(signal_number)); if (sig < 0 || sig >= NSIG) caml_invalid_argument("Sys.signal: unavailable signal"); switch(action) { case Val_int(0): /* Signal_default */ act = 0; break; case Val_int(1): /* Signal_ignore */ act = 1; break; default: /* Signal_handle */ act = 2; break; } oldact = caml_set_signal_action(sig, act); switch (oldact) { case 0: /* was Signal_default */ res = Val_int(0); break; case 1: /* was Signal_ignore */ res = Val_int(1); break; case 2: /* was Signal_handle */ res = caml_alloc_small (1, 0); Field(res, 0) = Field(caml_signal_handlers, sig); break; default: /* error in caml_set_signal_action */ caml_sys_error(NO_ARG); } if (Is_block(action)) { if (caml_signal_handlers == 0) { caml_signal_handlers = caml_alloc(NSIG, 0); caml_register_global_root(&caml_signal_handlers); } caml_modify(&Field(caml_signal_handlers, sig), Field(action, 0)); } caml_process_pending_signals(); CAMLreturn (res); }
/* Remove a signal handler. */ CAMLprim value lwt_unix_remove_signal(value val_signum) { #if !defined(LWT_ON_WINDOWS) struct sigaction sa; #endif /* The signal number is valid here since it was when we did the set_signal. */ int signum = caml_convert_signal_number(Int_val(val_signum)); signal_notifications[signum] = -1; #if defined(LWT_ON_WINDOWS) if (signum == SIGINT) SetConsoleCtrlHandler(NULL, FALSE); else signal(signum, SIG_DFL); #else sa.sa_handler = SIG_DFL; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(signum, &sa, NULL); #endif return Val_unit; }
/* Install a signal handler. */ CAMLprim value lwt_unix_set_signal(value val_signum, value val_notification) { #if !defined(LWT_ON_WINDOWS) struct sigaction sa; #endif int signum = caml_convert_signal_number(Int_val(val_signum)); int notification = Int_val(val_notification); if (signum < 0 || signum >= NSIG) caml_invalid_argument("Lwt_unix.on_signal: unavailable signal"); signal_notifications[signum] = notification; #if defined(LWT_ON_WINDOWS) if (signum == SIGINT) { if (!SetConsoleCtrlHandler(handle_break, TRUE)) { signal_notifications[signum] = -1; win32_maperr(GetLastError()); uerror("SetConsoleCtrlHandler", Nothing); } } else { if (signal(signum, handle_signal) == SIG_ERR) { signal_notifications[signum] = -1; uerror("signal", Nothing); } } #else sa.sa_handler = handle_signal; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); if (sigaction(signum, &sa, NULL) == -1) { signal_notifications[signum] = -1; uerror("sigaction", Nothing); } #endif return Val_unit; }
CAMLprim value caml_extunix_signalfd(value vfd, value vsigs, value vflags, value v_unit) { CAMLparam4(vfd, vsigs, vflags, v_unit); int fd = ((Val_none == vfd) ? -1 : Int_val(Some_val(vfd))); int flags = 0; int ret = 0; sigset_t ss; sigemptyset (&ss); while (!Is_long (vsigs)) { int sig = caml_convert_signal_number (Int_val (Field (vsigs, 0))); if (sigaddset (&ss, sig) < 0) uerror ("sigaddset", Nothing); vsigs = Field (vsigs, 1); } while (!Is_long (vflags)) { int f = Int_val (Field (vflags, 0)); if (SFD_NONBLOCK == f) flags |= SFD_NONBLOCK; if (SFD_CLOEXEC == f) flags |= SFD_CLOEXEC; vflags = Field (vflags, 1); } ret = signalfd (fd, &ss, flags); if (ret < 0) uerror ("signalfd", Nothing); CAMLreturn (Val_int (ret)); }
CAMLprim value caml_ptrace_cont(value pid, value sig) { CAMLparam2(pid, sig); int sig_no = caml_convert_signal_number(Int_val(sig)); int res = ptrace(PTRACE_CONT, Int_val(pid), NULL, sig_no); CAMLreturn(Val_int(res)); }
CAMLprim value ml_caml_to_nonportable_signal_number(value v_signo) { return Val_int(caml_convert_signal_number(Int_val(v_signo))); }