diff --git a/src/lib/eval.ml b/src/lib/eval.ml index dbb4a8f..278c2f8 100644 --- a/src/lib/eval.ml +++ b/src/lib/eval.ml @@ -374,44 +374,59 @@ module Make (S : Types.State) (E : Types.Exec) = struct in loop saved_ctx job (pgid, some_read) rest | None -> ( - let exec_and_args = - if is_command then begin - match command_args with - | [] -> assert false - | x :: xs -> ( - Eunix.with_redirections rdrs @@ fun () -> - match resolve_program ~update:false ctx x with - | _, None -> Exit.nonzero ("", []) 1 - | _, Some prog -> - if print_command then - Exit.zero ("echo", [ prog ]) - else Exit.zero (x, xs)) - end - else Exit.zero (executable, args_as_strings) - in - match exec_and_args with - | Exit.Nonzero _ as v -> - let job = - handle_job ~pgid job (`Built_in (v >|= fun _ -> ())) + match Built_ins.of_args command_args with + | Some (Error _) -> + ( ctx, + handle_job ~pgid job (`Built_in (Exit.nonzero () 1)) + ) + | Some (Ok bi) -> + let ctx = + handle_built_in ~rdrs ~stdout:some_write ctx bi in - loop ctx job (pgid, some_read) rest - | Exit.Zero (executable, args) -> ( - match stdout_of_previous with - | None -> - let ctx, job = - exec_process ctx job ~fds:rdrs - ~stdout:some_write ~pgid executable args + close_stdout ~is_global some_write; + let built_in = ctx >|= fun _ -> () in + let job = handle_job ~pgid job (`Built_in built_in) in + loop (Exit.value ctx) job (pgid, some_read) rest + | _ -> ( + let exec_and_args = + if is_command then begin + match command_args with + | [] -> assert false + | x :: xs -> ( + Eunix.with_redirections rdrs @@ fun () -> + match resolve_program ~update:false ctx x with + | _, None -> Exit.nonzero ("", []) 1 + | _, Some prog -> + if print_command then + Exit.zero ("echo", [ prog ]) + else Exit.zero (x, xs)) + end + else Exit.zero (executable, args_as_strings) + in + match exec_and_args with + | Exit.Nonzero _ as v -> + let job = + handle_job ~pgid job + (`Built_in (v >|= fun _ -> ())) in - close_stdout ~is_global some_write; loop ctx job (pgid, some_read) rest - | Some stdout -> - let ctx, job = - exec_process ctx job ~fds:rdrs ~stdin:stdout - ~stdout:some_write ~pgid executable - args_as_strings - in - close_stdout ~is_global some_write; - loop ctx job (pgid, some_read) rest)))) + | Exit.Zero (executable, args) -> ( + match stdout_of_previous with + | None -> + let ctx, job = + exec_process ctx job ~fds:rdrs + ~stdout:some_write ~pgid executable args + in + close_stdout ~is_global some_write; + loop ctx job (pgid, some_read) rest + | Some stdout -> + let ctx, job = + exec_process ctx job ~fds:rdrs ~stdin:stdout + ~stdout:some_write ~pgid executable + args_as_strings + in + close_stdout ~is_global some_write; + loop ctx job (pgid, some_read) rest))))) | Some (Ok bi) -> let ctx = handle_built_in ~rdrs ~stdout:some_write ctx bi in close_stdout ~is_global some_write; diff --git a/test/built_ins.t b/test/built_ins.t index 04c8b78..688795e 100644 --- a/test/built_ins.t +++ b/test/built_ins.t @@ -184,6 +184,10 @@ First clean up the directory a bit $ msh -c "command -v skjdlksjdlkwjdlkw" [1] +Command should also still allow shell built-ins to run. + + $ msh -c "command pwd | xargs -- basename" + 8. Alias This is mostly handled by Morbig, but we have had to do some fixes...