1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768typec_action=Obj.ttypet={run:'a.((c_action->'a)->'a)}[@@unboxed](* A [fork_fn] is a C function that can be executed after forking. It cannot call OCaml code or
run the OCaml GC. It is passed a [Unix.file_descr] for errors and a pointer
to a [c_action]. On success it should write nothing to the error stream and
return 0. On error, it should write a message to the error FD and return a
non-zero value for the exit status (e.g. 1). *)typefork_fnletrecwith_actionsactionsfn=matchactionswith|[]->fn[]|{run}::xs->run@@func_action->with_actionsxs@@func_actions->fn(c_action::c_actions)leterr_closedop()=Fmt.failwith"%s: FD is closed!"opexternalaction_execve:unit->fork_fn="eio_unix_fork_execve"letaction_execve=action_execve()letexecvepath~argv~env={run=funk->k(Obj.repr(action_execve,path,argv,env))}externalaction_chdir:unit->fork_fn="eio_unix_fork_chdir"letaction_chdir=action_chdir()letchdirpath={run=funk->k(Obj.repr(action_chdir,path))}externalaction_fchdir:unit->fork_fn="eio_unix_fork_fchdir"letaction_fchdir=action_fchdir()letfchdirfd={run=funk->Rcfd.use~if_closed:(err_closed"fchdir")fd@@funfd->k(Obj.repr(action_fchdir,fd))}letint_of_fd:Unix.file_descr->int=Obj.magictypeaction=Inherit_fds.action={src:int;dst:int}letrecwith_fdsmappingk=matchmappingwith|[]->k[]|(dst,src,_)::xs->Rcfd.use~if_closed:(err_closed"inherit_fds")src@@funsrc->with_fdsxs@@funxs->k((dst,int_of_fdsrc)::xs)typeblocking=[|`Blocking|`Nonblocking|`Preserve_blocking]externalaction_dups:unit->fork_fn="eio_unix_fork_dups"letaction_dups=action_dups()letinherit_fdsm=letblocking=m|>List.filter_map(fun(dst,_,flags)->matchflagswith|`Blocking->Some(dst,true)|`Nonblocking->Some(dst,false)|`Preserve_blocking->None)inwith_fdsm@@funm->letplan:actionlist=Inherit_fds.planmin{run=funk->k(Obj.repr(action_dups,plan,blocking))}