1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374(* [execve] doesn't exist on Windows, so instead we do a
[Unix.create_process_env] followed by [Unix.waitpid] and finally [sys_exit].
We use [sys_exit] rather than [exit] so that [at_exit] functions are not
invoked. We don't want [at_exit] functions to be invoked to match the
behaviour of [Unix.execve] on Unix. *)externalsys_exit:int->'a="caml_sys_exit"letrestore_cwd_and_execveprogargv~env=letenv=Env.to_unixenv|>Array.of_listinletargv=Array.of_list(prog::argv)in(* run at_exit before changing the working directory *)Stdlib.do_at_exit();Sys.chdir(Path.External.to_stringPath.External.initial_cwd);ifSys.win32||Platform.OS.value=Platform.OS.Haikuthen(letpid=Unix.create_process_envprogargvenvUnix.stdinUnix.stdoutUnix.stderrinmatchsnd(Unix.waitpid[]pid)with|WEXITEDn->sys_exitn|WSIGNALED_->sys_exit255|WSTOPPED_->assertfalse)else(ignore(Unix.sigprocmaskSIG_SETMASK[]:intlist);Unix.execveprogargvenv);;moduleResource_usage=structtypet={user_cpu_time:float;system_cpu_time:float}endmoduleTimes=structtypet={elapsed_time:float;resource_usage:Resource_usage.toption}endmoduleProcess_info=structtypet={pid:Pid.t;status:Unix.process_status;end_time:float;resource_usage:Resource_usage.toption}endexternalstub_wait4:int->Unix.wait_flaglist->int*Unix.process_status*float*Resource_usage.t="dune_wait4"typewait=|Any|PidofPid.tletwaitwaitflags=ifSys.win32thenCode_error.raise"wait4 not available on windows"[]else(letpid=matchwaitwith|Any->-1|Pidpid->Pid.to_intpidinletpid,status,end_time,resource_usage=stub_wait4pidflagsin{Process_info.pid=Pid.of_intpid;status;end_time;resource_usage=Someresource_usage});;