let input_lines chan =
  
  let rec all lines =
  
    (* intermediate result to be tail rec *)
  
    match try Some (input_line chanwith End_of_file -> None with
  
      Some l -> all (l::lines)
  
    | None -> List.rev lines in
  
  all []
  

  
exception Exec_failure;;
  
let execvp_to_list cmd args =
  
  let desc_readdesc_write = pipe () in
  
  match fork() with
  
    0 ->
  
      let exec () =
  
        close desc_read;
  
        dup2 desc_write stdout;
  
        close desc_write;
  
        execvp cmd (Array.append [| cmd |] argsin
  
      handle_unix_error exec ()
  
  | pid ->
  
      close desc_write;
  
      let chan = in_channel_of_descr desc_read in
  
      let after () =
  
        close_in chan;
  
        match restart_on_EINTR (waitpid []) pid with
  
          _WEXITED 0 -> ()
  
        | __ -> raise Exec_failure in
  
      try_finalize input_lines chan after ();;