(* TEST readonly_files = "myecho.ml"; { program = "${test_build_directory}/quotecommand.byte"; setup-ocamlc.byte-build-env; program = "${test_build_directory}/myecho.exe"; all_modules = "myecho.ml"; ocamlc.byte; program = "${test_build_directory}/quotecommand.byte"; all_modules = "quotecommand.ml"; ocamlc.byte; check-ocamlc.byte-output; run; check-program-output; }{ program = "${test_build_directory}/quotecommand.opt"; setup-ocamlopt.byte-build-env; program = "${test_build_directory}/myecho.exe"; all_modules = "myecho.ml"; ocamlopt.byte; program = "${test_build_directory}/quotecommand.opt"; all_modules = "quotecommand.ml"; ocamlopt.byte; check-ocamlopt.byte-output; run; check-program-output; } *) open Printf let copy_channels ic oc = let sz = 1024 in let buf = Bytes.create sz in let rec copy () = let n = input ic buf 0 sz in if n > 0 then (output oc buf 0 n; copy()) in copy() let copy_file src dst = let ic = open_in_bin src in let oc = open_out_gen [Open_wronly; Open_creat; Open_trunc; Open_binary] 0o777 dst in copy_channels ic oc; close_in ic; close_out oc let cat_file f = let ic = open_in f in copy_channels ic stdout; close_in ic let myecho = Filename.concat Filename.current_dir_name "my echo.exe" let run prog ?stdin ?stdout ?stderr args = flush Stdlib.stdout; let rc = Sys.command (Filename.quote_command prog ?stdin ?stdout ?stderr args) in if rc > 0 then begin printf "!!! %s failed\n" prog; exit 2 end let _ = let run = run myecho in copy_file "myecho.exe" "my echo.exe"; printf "-------- Spaces\n"; run ["Lorem ipsum dolor"; "sit amet,"; "consectetur adipiscing elit,"]; printf "-------- All ASCII characters\n"; run ["!\"#$%&'()*+,-./"; "0123456789"; ":;<=>?@"; "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; "[\\]^_`"; "abcdefghijklmnopqrstuvwxyz"; "{~|~}" ]; printf "-------- Output redirection\n"; run ~stdout:"my 'file'.tmp" ["sed do eiusmod tempor incididunt"; "ut labore et dolore magna aliqua."]; printf "-------- Input redirection\n"; run ~stdin:"my 'file'.tmp" []; Sys.remove "my 'file'.tmp"; printf "-------- Error redirection\n"; run ~stderr:"my 'file'.tmp" ["Exceptur sint"; "-err"; "occaecat"; "cupidatat"; "-out"; "non proident"; "-err"; "sunt in culpa"]; printf "-- stderr:\n"; cat_file "my 'file'.tmp"; Sys.remove "my 'file'.tmp"; printf "-------- Output and error redirections (different files)\n"; run ~stdout:"my stdout.tmp" ~stderr:"my stderr.tmp" ["qui officia"; "-err"; "deserunt"; "mollit"; "-out"; "anim id est"; "-err"; "laborum."]; printf "-- stdout:\n"; cat_file "my stdout.tmp"; Sys.remove "my stdout.tmp"; printf "-- stderr:\n"; cat_file "my stderr.tmp"; Sys.remove "my stderr.tmp"; printf "-------- Output and error redirections (same file)\n"; run ~stdout:"my file.tmp" ~stderr:"my file.tmp" ["Duis aute"; "irure dolor"; "-err"; "in reprehenderit"; "in voluptate"; "-out"; "velit esse cillum"; "-err"; "dolore"]; cat_file "my file.tmp"; Sys.remove "my file.tmp"; Sys.remove "my echo.exe" let _ = printf "-------- Forward slashes in program position\n"; run "./myecho.exe" ["alea iacta est"]