Guest User

Untitled

a guest
Feb 20th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.46 KB | None | 0 0
  1. open Prelude
  2.  
  3. (* adapted from unix.ml *)
  4.  
  5. let try_set_close_on_exec fd =
  6. try Unix.set_close_on_exec fd; true with Invalid_argument _ -> false
  7.  
  8. let open_proc cmd input output toclose =
  9. let cloexec = List.for_all try_set_close_on_exec toclose in
  10. match Unix.fork () with
  11. 0 -> if input <> Unix.stdin then begin Unix.dup2 input Unix.stdin; Unix.close input end;
  12. if output <> Unix.stdout then begin Unix.dup2 output Unix.stdout; Unix.close output end;
  13. if not cloexec then List.iter Unix.close toclose;
  14. begin try Unix.execvp (head cmd) (Array.of_list cmd)
  15. with _ -> exit 127
  16. end
  17. | id -> id
  18.  
  19. let popenWithStdin ?(toclose=[]) stdin cmd =
  20. let (in_read, in_write) = Unix.pipe () in
  21. ignore (open_proc cmd stdin in_write ([in_read] @ toclose));
  22. Unix.close in_write;
  23. Unix.close stdin;
  24. in_read
  25.  
  26.  
  27. let rec buildPipeline ?toclose = foldl (popenWithStdin ?toclose)
  28.  
  29. let withPipeline cmds f =
  30. let ifd, ofd = Unix.pipe () in
  31. let ifd = buildPipeline ~toclose:[ofd] ifd cmds in (* if we don't close ofd, all will hang *)
  32. let ic = Unix.in_channel_of_descr ifd
  33. and oc = Unix.out_channel_of_descr ofd in
  34. finally (fun _ -> close_out_noerr oc; close_in_noerr ic)
  35. (f ic) oc
  36.  
  37. let pipeline = [
  38. ["tr"; "[:upper:]"; "[:lower:]"];
  39. ["grep"; "-o"; "ello"];
  40. ]
  41.  
  42. let () =
  43. withPipeline pipeline
  44. (fun ic oc ->
  45. output_string oc "hElLo JeLlo";
  46. close_out oc;
  47. puts (readAll ic)
  48. )
Add Comment
Please, Sign In to add comment