Current section
Files
Jump to
Current section
Files
src/ierl_exec.erl
-module(ierl_exec).
-export([exec/2]).
-spec exec( Cmd :: jup_util:string_like(), Args :: [jup_util:string_like()]) ->
{ok, iolist()} | {error, integer(), iolist()}.
exec(Cmd, Args) ->
Ref = make_ref(),
Path =
case os:find_executable(jup_util:ensure_string(Cmd)) of
false ->
error({executable_not_found, Cmd});
P ->
P
end,
Args1 = lists:map(fun jup_util:ensure_string/1, Args),
{Pid, MonitorRef}
= erlang:spawn_monitor(
fun() ->
R = exec_sync(Path, Args1),
exit({Ref, R})
end
),
receive
{'DOWN', MonitorRef, process, Pid, {Ref, Data}} ->
Data;
{'DOWN', MonitorRef, process, Pid, Reason} ->
exit(Reason)
end.
exec_sync(Cmd, Args) ->
P = open_port(
{spawn_executable, Cmd},
[binary, use_stdio, stream, exit_status, hide, {args, Args}]
),
exec_receive(P, []).
exec_receive(Port, Acc) ->
receive
{Port, {data, Data}} ->
exec_receive(Port, [Data|Acc]);
{Port, {exit_status, Status}} ->
Reversed = lists:reverse(Acc),
case Status of
0 ->
{ok, Reversed};
_ ->
{error, Status, Reversed}
end
end.