add CCUnix.async_call for spawning and communicating with subprocess

This commit is contained in:
Simon Cruanes 2015-04-24 16:04:09 +02:00
parent 8195f035fc
commit 4f44308445
3 changed files with 56 additions and 1 deletions

View file

@ -25,7 +25,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Hash Table with Heterogeneous Keys} (** {1 Hash Table with Heterogeneous Keys}
From https://github.com/mjambon/mixtbl , thanks to him. From https://github.com/mjambon/mixtbl (thanks to him).
Example: Example:
{[ {[

View file

@ -113,3 +113,36 @@ let call ?(bufsize=2048) ?(stdin=`Str "") ?(env=[||]) cmd =
end end
) )
type line = string
type async_call_result =
< stdout:line gen;
stderr:line gen;
stdin:line -> unit; (* send a line *)
close_in:unit; (* close stdin *)
close_err:unit;
close_out:unit;
wait:Unix.process_status; (* block until the process ends *)
>
let async_call ?(env=[||]) cmd =
(* render the command *)
let buf = Buffer.create 256 in
kbprintf' buf cmd
(fun buf ->
let cmd = Buffer.contents buf in
let oc, ic, errc = Unix.open_process_full cmd env in
object
method stdout () =
try Some (input_line oc)
with End_of_file -> None
method stderr () =
try Some (input_line errc)
with End_of_file -> None
method stdin l = output_string ic l; output_char ic '\n'
method close_in = close_out ic
method close_out = close_in oc
method close_err = close_in errc
method wait = Unix.close_process_full (oc, ic, errc)
end
)

View file

@ -73,5 +73,27 @@ val call : ?bufsize:int ->
(call "echo %s" "a'b'c")#stdout = "abc\n" (call "echo %s" "a'b'c")#stdout = "abc\n"
*) *)
type line = string
type async_call_result =
< stdout:line gen;
stderr:line gen;
stdin:line -> unit; (* send a line *)
close_in:unit; (* close stdin *)
close_err:unit;
close_out:unit;
wait:Unix.process_status; (* block until the process ends *)
>
(** A subprocess for interactive usage (read/write channels line by line)
@since NEXT_RELEASE *)
val async_call : ?env:string array ->
('a, Buffer.t, unit, async_call_result) format4 ->
'a
(** Spawns a subprocess, like {!call}, but the subprocess's channels are
line generators and line sinks (for stdin).
if [p] is [async_call "cmd"], then [p#wait] waits for the subprocess
to die. Channels can be closed independently.
@since NEXT_RELEASE *)