123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247open!Importinclude(Int:sigtypet=int[@@derivingbin_io]includeComparable.Swithtypet:=tincludeHashable.Swithtypet:=tend)externalml_caml_to_nonportable_signal_number:int->int="ml_caml_to_nonportable_signal_number"externalml_nonportable_to_caml_signal_number:int->int="ml_nonportable_to_caml_signal_number"letof_system_intt=ml_nonportable_to_caml_signal_numbertletto_system_intt=ml_caml_to_nonportable_signal_numbertletof_caml_intt=tletto_caml_intt=ttypesys_behavior=[|`Continue(** Continue the process if it is currently stopped *)|`Dump_core(** Terminate the process and dump core *)|`Ignore(** Ignore the signal *)|`Stop(** Stop the process *)|`Terminate(** Terminate the process *)][@@derivingsexp]letequal(t:t)t'=(t=t')includestruct(* Please keep in sync with the list for to_string/sys_behavior *)openSysletabrt=sigabrtletalrm=sigalrmletbus=sigbusletchld=sigchldletcont=sigcontletfpe=sigfpelethup=sighupletill=sigillletint=sigintletkill=sigkillletpipe=sigpipeletpoll=sigpollletprof=sigprofletquit=sigquitletsegv=sigsegvletstop=sigstopletsys=sigsysletterm=sigtermlettrap=sigtraplettstp=sigtstpletttin=sigttinletttou=sigttouleturg=sigurgletusr1=sigusr1letusr2=sigusr2letvtalrm=sigvtalrmletxcpu=sigxcpuletxfsz=sigxfszletzero=0endexceptionInvalid_signal_mnemonic_or_numberofstring[@@derivingsexp]letto_string_with_version,of_string,default_sys_behavior=letknown=[("sigabrt",abrt,`Dump_core,1);("sigalrm",alrm,`Terminate,1);("sigbus",bus,`Dump_core,2);("sigchld",chld,`Ignore,1);("sigcont",cont,`Continue,1);("sigfpe",fpe,`Dump_core,1);("sighup",hup,`Terminate,1);("sigill",ill,`Dump_core,1);("sigint",int,`Terminate,1);("sigkill",kill,`Terminate,1);("sigpipe",pipe,`Terminate,1);("sigpoll",poll,`Terminate,2);("sigprof",prof,`Terminate,1);("sigquit",quit,`Dump_core,1);("sigsegv",segv,`Dump_core,1);("sigstop",stop,`Stop,1);("sigsys",sys,`Dump_core,2);("sigterm",term,`Terminate,1);("sigtrap",trap,`Dump_core,2);("sigtstp",tstp,`Stop,1);("sigttin",ttin,`Stop,1);("sigttou",ttou,`Stop,1);("sigurg",urg,`Ignore,2);("sigusr1",usr1,`Terminate,1);("sigusr2",usr2,`Terminate,1);("sigvtalrm",vtalrm,`Terminate,1);("sigxcpu",xcpu,`Dump_core,2);("sigxfsz",xfsz,`Dump_core,2);("sigzero",zero,`Ignore,1);]inletname_and_version_by_t=Int.Table.create~size:1()inlett_by_name=String.Table.create~size:1()inletbehavior_by_t=Int.Table.create~size:1()inList.iterknown~f:(fun(name,t,behavior,stable_version)->Hashtbl.setname_and_version_by_t~key:t~data:(name,stable_version);Hashtbl.sett_by_name~key:name~data:t;Hashtbl.setbehavior_by_t~key:t~data:behavior);(* For unknown signal numbers, [to_string] returns a meaningful
string, while [default_sys_behavior] has to raise an exception
because we don't know what the right answer is. *)letto_string_with_versiont~version:requested_version=matchHashtbl.findname_and_version_by_ttwith|Some(string,needed_version)whenrequested_version>=needed_version->string|_->"<unknown signal "^Int.to_stringt^">"inletof_strings=lets=String.lowercase(String.strips)inmatchHashtbl.findt_by_nameswith|Somesn->sn|None->ifString.is_prefixs~prefix:"<unknown signal "thentryInt.of_string(String.slices16~-1)with_->raise(Invalid_signal_mnemonic_or_numbers)elseraise(Invalid_signal_mnemonic_or_numbers)inletdefault_sys_behaviort=matchHashtbl.findbehavior_by_ttwith|None->raise(Invalid_argument("Signal.default_sys_behavior: unknown signal "^Int.to_stringt))|Somebehavior->behaviorinto_string_with_version,of_string,default_sys_behavior;;exceptionExpected_atomofSexp.t[@@derivingsexp]letsexp_of_t_with_versiont~version=Sexp.Atom(to_string_with_versiont~version)letto_strings=to_string_with_versions~version:2letsexp_of_tt=sexp_of_t_with_versiont~version:1lett_of_sexps=matchswith|Sexp.Atoms->of_strings|_->raise(Expected_atoms);;typepid_spec=[`PidofPid.t|`My_group|`GroupofPid.t][@@derivingsexp_of]letpid_spec_to_int=function|`Pidpid->Pid.to_intpid|`My_group->0|`Grouppid->~-(Pid.to_intpid);;letpid_spec_to_stringp=Int.to_string(pid_spec_to_intp)letsendsignalpid_spec=tryUnixLabels.kill~pid:(pid_spec_to_intpid_spec)~signal;`OkwithUnix.Unix_error(Unix.ESRCH,_,_)->`No_such_process;;letsend_itpid_spec=matchsendtpid_specwith|`Ok|`No_such_process->();;letsend_exntpid_spec=matchsendtpid_specwith|`Ok->()|`No_such_process->failwithf"Signal.send_exn %s pid:%s"(to_stringt)(pid_spec_to_stringpid_spec)();;moduleExpert=structtypebehavior=[`Default|`Ignore|`Handleoft->unit]moduleBehavior=structletof_caml=function|Sys.Signal_default->`Default|Sys.Signal_ignore->`Ignore|Sys.Signal_handlef->`Handlefletto_caml=function|`Default->Sys.Signal_default|`Ignore->Sys.Signal_ignore|`Handlef->Sys.Signal_handle(funt->Exn.handle_uncaught_and_exit(fun()->ft));;endletsignaltbehavior=Behavior.of_caml(Sys.signalt(Behavior.to_camlbehavior));;letsettbehavior=ignore(signaltbehavior)lethandletf=sett(`Handlef)endopenExpertlethandle_defaultt=sett`Defaultletignoret=sett`Ignoretypesigprocmask_command=[`Set|`Block|`Unblock]letsigprocmaskmodesigs=letmode=matchmodewith|`Block->Unix.SIG_BLOCK|`Unblock->Unix.SIG_UNBLOCK|`Set->Unix.SIG_SETMASKinUnix.sigprocmaskmodesigs;;letsigpending=Unix.sigpendingletsigsuspend=Unix.sigsuspendletcan_send_topid=trysend_exnzero(`Pidpid);truewith|_->false;;moduleStable=structmoduleV2=structtypenonrect=t[@@derivingbin_io,compare]lett_of_sexp=t_of_sexpletsexp_of_tt=sexp_of_t_with_versiont~version:2endmoduleV1=structtypenonrect=t[@@derivingbin_io,compare]lett_of_sexp=t_of_sexpletsexp_of_tt=sexp_of_t_with_versiont~version:1endend