struct
let discriminate_process_status s ret =
begin match ret with
| Lwt_unix.WEXITED 0 -> return ()
| Lwt_unix.WEXITED n -> fail (`Shell (s, `Exited n))
| Lwt_unix.WSIGNALED n -> fail (`Shell (s, `Signaled n))
| Lwt_unix.WSTOPPED n -> fail (`Shell (s, `Stopped n))
end
let status_to_string = function
| `Exited i -> sprintf "Exited with %d" i
| `Exn e -> sprintf "Exception %s" (exn e)
| `Signaled i -> sprintf "Signaled (%d)" i
| `Stopped i -> sprintf "Stopped (%d)" i
let do_or_fail s =
wrap_deferred Lwt_io.(fun () -> Lwt_unix.system s)
~on_exn:(fun e -> `Shell (s, `Exn e))
>>= fun ret ->
discriminate_process_status s ret
let execute s =
wrap_deferred ~on_exn:(fun e -> `Shell (s, `Exn e))
Lwt.(fun () ->
let inprocess = Lwt_process.(open_process_full (shell s)) in
Lwt_list.map_p Lwt_io.read
[inprocess#stdout; inprocess#stderr; ]
>>= fun output ->
inprocess#status >>= fun status ->
return (status, output))
>>= fun (ret, output) ->
let code =
match ret with
| Lwt_unix.WEXITED n -> (`Exited n)
| Lwt_unix.WSIGNALED n -> (`Signaled n)
| Lwt_unix.WSTOPPED n -> (`Stopped n)
in
begin match output with
| [out; err] -> return (out, err, code)
| _ -> assert false
end
end