12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061(* [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_listargvin(* run at_exit before changing the working directory *)Stdlib.do_at_exit();Sys.chdir(Path.External.to_stringPath.External.initial_cwd);ifSys.win32thenletpid=Unix.create_process_envprogargvenvUnix.stdinUnix.stdoutUnix.stderrinmatchsnd(Unix.waitpid[]pid)with|WEXITEDn->sys_exitn|WSIGNALED_->sys_exit255|WSTOPPED_->assertfalseelse(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_wait3:Unix.wait_flaglist->int*Unix.process_status*float*Resource_usage.t="dune_wait3"letwaitflags=ifSys.win32thenCode_error.raise"wait3 not available on windows"[]elseletpid,status,end_time,resource_usage=stub_wait3flagsin{Process_info.pid=Pid.of_intpid;status;end_time;resource_usage=Someresource_usage}