mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
add CCUnix.async_call for spawning and communicating with subprocess
This commit is contained in:
parent
8195f035fc
commit
4f44308445
3 changed files with 56 additions and 1 deletions
|
|
@ -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:
|
||||||
|
|
||||||
{[
|
{[
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -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 *)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue