···142142 ~finally:(fun () -> Unix.tcsetattr Unix.stdin TCSADRAIN saved_tio)
143143 fn
144144145145+let resolve_program ?(update = true) ?path hash name =
146146+ let v =
147147+ if not (String.contains name '/') then begin
148148+ path
149149+ |> Option.value ~default:"/bin:/usr/bin"
150150+ |> String.split_on_char ':'
151151+ |> List.find_map (fun dir ->
152152+ let p = Filename.concat dir name in
153153+ if Sys.file_exists p then Some p else None)
154154+ end
155155+ else if Sys.file_exists name then Some name
156156+ else None
157157+ in
158158+ match (update, v) with
159159+ | true, Some loc ->
160160+ let hash = Hash.add ~utility:name ~loc hash in
161161+ (hash, Some loc)
162162+ | false, Some loc -> (hash, Some loc)
163163+ | _, None -> (hash, None)
164164+145165module Signals = struct
146166 type t =
147167 | Interrupt
+47-43
src/lib/eval.ml
···159159 let file_creation_mode ctx = 0o666 - ctx.umask
160160 let cwd_of_ctx ctx = S.cwd ctx.state |> Fpath.to_string |> ( / ) ctx.fs
161161162162- let resolve_program ?(update = true) ctx name =
163163- let v =
164164- if not (String.contains name '/') then begin
165165- S.lookup ctx.state ~param:"PATH"
166166- |> Option.value ~default:"/bin:/usr/bin"
167167- |> String.split_on_char ':'
168168- |> List.find_map (fun dir ->
169169- let p = Filename.concat dir name in
170170- if Sys.file_exists p then Some p else None)
171171- end
172172- else if Sys.file_exists name then Some name
173173- else None
174174- in
175175- match (update, v) with
176176- | true, Some loc ->
177177- let hash = Hash.add ~utility:name ~loc ctx.hash in
178178- ({ ctx with hash }, Some loc)
179179- | false, Some loc -> (ctx, Some loc)
180180- | _, None -> (ctx, None)
181181-182162 let get_env ?(extra = []) ctx =
183163 let extra =
184164 extra @ List.map (fun (k, v) -> (k, v)) @@ S.exports ctx.state
···237217 let mode = if async then Types.Async else Types.Switched sw in
238218 let fds = ctx.rdrs @ Option.value ~default:[] fds in
239219 let ctx, process =
240240- match (executable, resolve_program ctx executable) with
241241- | _, (ctx, None) | "", (ctx, _) ->
220220+ let hash, prog =
221221+ Eunix.resolve_program
222222+ ?path:(S.lookup ctx.state ~param:"PATH")
223223+ ctx.hash executable
224224+ in
225225+ let ctx = { ctx with hash } in
226226+ match (executable, prog) with
227227+ | _, None | "", _ ->
242228 Eio.Flow.copy_string
243229 (Fmt.str "msh: command not found: %s\n" executable)
244230 stdout;
245231 (ctx, Error (127, `Not_found))
246246- | _, (ctx, Some full_path) ->
232232+ | _, Some full_path ->
247233 Debug.Log.debug (fun f ->
248234 f "executing %a\n%a"
249235 Fmt.(list ~sep:(Fmt.any " ") (quote string))
···397383 @@ fun () ->
398384 if args <> [] then
399385 let name = List.hd args in
400400- let prog =
401401- match
402402- resolve_program ~update:false ctx name
403403- with
404404- | _, None -> Fmt.failwith "%s not found" name
405405- | _, Some p -> p
386386+ let ctx, prog =
387387+ let hash, prog =
388388+ Eunix.resolve_program ~update:false
389389+ ?path:(S.lookup ctx.state ~param:"PATH")
390390+ ctx.hash name
391391+ in
392392+ let ctx = { ctx with hash } in
393393+ match prog with
394394+ | None -> Fmt.failwith "%s not found" name
395395+ | Some p -> (ctx, p)
406396 in
407397 Unix.execve prog (Array.of_list args)
408398 (Array.of_list
···473463 in
474464 loop (Exit.value ctx) job rest
475465 | _ -> (
476476- let exec_and_args =
466466+ let ctx, exec_and_args =
477467 if is_command then begin
478468 match command_args with
479469 | [] -> assert false
480470 | x :: xs -> (
481481- match
482482- resolve_program ~update:false
483483- ctx x
484484- with
485485- | _, None ->
486486- Exit.nonzero ("", []) 1
487487- | _, Some prog ->
471471+ let hash, prog =
472472+ Eunix.resolve_program
473473+ ~update:false
474474+ ?path:
475475+ (S.lookup ctx.state
476476+ ~param:"PATH")
477477+ ctx.hash x
478478+ in
479479+ let ctx = { ctx with hash } in
480480+ match prog with
481481+ | None ->
482482+ (ctx, Exit.nonzero ("", []) 1)
483483+ | Some prog ->
488484 if print_command then
489489- Exit.zero ("echo", [ prog ])
490490- else Exit.zero (x, xs))
485485+ ( ctx,
486486+ Exit.zero
487487+ ("echo", [ prog ]) )
488488+ else (ctx, Exit.zero (x, xs)))
491489 end
492492- else Exit.zero (executable, args)
490490+ else (ctx, Exit.zero (executable, args))
493491 in
494492 match exec_and_args with
495493 | Exit.Nonzero _ as v ->
···14821480 | _, WEXITED 0 -> Exit.zero ctx
14831481 | _, (WEXITED n | WSIGNALED n | WSTOPPED n) -> Exit.nonzero ctx n)
14841482 | Dot file -> (
14851485- match resolve_program ctx file with
14861486- | ctx, None -> Exit.nonzero ctx 127
14871487- | ctx, Some fname ->
14831483+ let hash, prog =
14841484+ Eunix.resolve_program
14851485+ ?path:(S.lookup ctx.state ~param:"PATH")
14861486+ ctx.hash file
14871487+ in
14881488+ let ctx = { ctx with hash } in
14891489+ match prog with
14901490+ | None -> Exit.nonzero ctx 127
14911491+ | Some fname ->
14881492 Debug.Log.debug (fun f -> f "sourcing...");
14891493 let program = Ast.of_file (ctx.fs / fname) in
14901494 let ctx, _ =
+1-1
src/lib/posix/exec.ml
···204204 with_fds m @@ fun m ->
205205 (* TODO: investigate -- the plan from Eio seems to also invert the list of redirections.
206206 This is problematic for redirections, so we have copied the entire action here. *)
207207- let plan = Eio_unix__.Inherit_fds.plan m |> List.rev in
207207+ let plan = Eio_unix__.Inherit_fds.plan m in
208208 Eio_unix.Private.Fork_action.
209209 { run = (fun k -> k (Obj.repr (action_dups, plan, blocking))) }
210210