I'm looking at the following OCaml code, which attempts to open a subprocess, feed it some input, and then collect all of the output it produces on either stdout or stderr. But the fact that it first reads everything from stdout and then reads everything from stderr seems fishy -- if the subprocess happens to write a lot of stuff to stderr, it seems like the result will be a deadlock.
let rec output_lines (output : string list) (chan : out_channel) : unit =
ignore (List.map (output_string chan) output); flush chan
let async_command
(name : string)
(arguments : string list)
: (in_channel * out_channel * in_channel) =
Unix.open_process_full
(name ^ " " ^ (String.concat " " arguments))
(Unix.environment ())
let sync_command
(name : string)
(arguments : string list)
(input : string list) : (string list * string list) =
let (o, i, e) = async_command name arguments in
output_lines input i;
let out, err = (input_lines o, input_lines e) in
let status = Unix.close_process_full (o, i, e) in
begin match status with
| Unix.WEXITED x -> if x != 0 then raise (Shell_error (unlines err))
| Unix.WSIGNALED x -> if x = Sys.sigint then raise Sys.Break
| Unix.WSTOPPED x -> if x = Sys.sigint then raise Sys.Break
end;
(out, err)
How should this be fixed? (Better yet, what library should I use where this functionality is already implemented?)
output_linesfor similar reasons. - Jeffrey Scofieldstderras OCaml evaluates from right to left (though it is not specified, this is what usually happens). This is not to say that this will solve the deadlock problem, just for your information. - ivg