Current section

Files

Jump to
alcove bin alcove.escript
Raw

bin/alcove.escript

#!/usr/bin/env escript
%%%
%%% Generate the alcove.erl file
%%%
main([]) ->
ModuleName = "alcove",
Proto = "c_src/alcove_call.proto",
main([ModuleName, Proto]);
main([ModuleName, Proto]) ->
Module = erl_syntax:attribute(
erl_syntax:atom(module),
[erl_syntax:atom(ModuleName)]
),
Includes = includes(["alcove.hrl"]),
% Type specs
Specs = erl_syntax:comment(["%__SPECS__%%"]),
% Any hardcoded functions will be included here
Static = erl_syntax:comment(["%__STATIC__%%"]),
Calls = calls(Proto),
% Generate the list of exports
Comment_static = erl_syntax:comment([" Static functions"]),
Exports_static = erl_syntax:attribute(erl_syntax:atom(export), [
erl_syntax:list([
erl_syntax:arity_qualifier(erl_syntax:atom(Fun), erl_syntax:integer(Arity))
|| {Fun, Arity} <- static_exports() ])
]),
Comment_gen = erl_syntax:comment([" Generated functions"]),
Exports_gen1 = erl_syntax:attribute(erl_syntax:atom(export), [
erl_syntax:list([
erl_syntax:arity_qualifier(erl_syntax:atom(Fun), erl_syntax:integer(Arity+2))
|| {Fun, Arity} <- Calls ])
]),
Exports_gen2 = erl_syntax:attribute(erl_syntax:atom(export), [
erl_syntax:list([
erl_syntax:arity_qualifier(erl_syntax:atom(Fun), erl_syntax:integer(Arity+3))
|| {Fun, Arity} <- Calls ])
]),
% Generate the functions
Functions = [ begin
% name(Drv, ...) -> alcove:call(Drv, [], Fun, [...])
Arg = arg("Arg", Arity),
% name(Drv, Pids, ...) -> name(Drv, Pids, ..., infinity)
Pattern1 = [erl_syntax:variable("Drv"), erl_syntax:variable("Pids")|Arg],
Body1 = call(Fun, Arg, "infinity"),
Clause1 = erl_syntax:clause(Pattern1, [], [Body1]),
% name(Drv, Pids, ..., Timeout) -> alcove:call(Drv, Pids, Fun, [...], Timeout)
Pattern2 = lists:flatten([erl_syntax:variable("Drv"), erl_syntax:variable("Pids"), Arg, erl_syntax:variable("Timeout")]),
Body2 = call(Fun, Arg, "Timeout"),
Clause2 = erl_syntax:clause(Pattern2, [], [Body2]),
[erl_syntax:function(erl_syntax:atom(Fun), [Clause1]),
erl_syntax:function(erl_syntax:atom(Fun), [Clause2])]
end || {Fun, Arity} <- Calls ],
Code0 = erl_prettypr:format(erl_syntax:form_list(lists:flatten([
license(),
Module,
Includes,
Specs,
Comment_static,
Exports_static,
Comment_gen,
Exports_gen1,
Exports_gen2,
Static,
Functions
]))),
Code = lists:foldl(fun({Marker, Generated}, Text) ->
re:replace(Text, Marker, Generated)
end,
Code0,
[
{"%%__STATIC__%%", static()},
{"%%__SPECS__%%", specs()}
]),
io:format("~s~n", [Code]).
arg(Prefix, Arity) ->
[ erl_syntax:variable(lists:flatten([Prefix, integer_to_list(N)]))
|| N <- lists:seq(1,Arity) ].
call(Fun, Arg, Timeout) ->
erl_syntax:case_expr(
erl_syntax:application(
erl_syntax:atom("alcove_drv"),
erl_syntax:atom("call"),
[
erl_syntax:variable("Drv"),
erl_syntax:variable("Pids"),
erl_syntax:atom(Fun),
erl_syntax:list(Arg),
case Timeout of
"infinity" -> erl_syntax:atom("infinity");
_ -> erl_syntax:variable(Timeout)
end
]
),
[
erl_syntax:clause(
[erl_syntax:tuple([
erl_syntax:atom("alcove_error"),
erl_syntax:variable("Error")
])],
none,
[
erl_syntax:application(
erl_syntax:atom("erlang"),
erl_syntax:atom("error"),
[
erl_syntax:variable("Error"),
erl_syntax:list(
lists:flatten([
erl_syntax:variable("Drv"),
erl_syntax:variable("Pids"),
Arg,
case Timeout of
"infinity" -> [];
_ -> erl_syntax:variable("Timeout")
end
])
)
]
)
]
),
erl_syntax:clause(
[erl_syntax:variable("Reply")],
none,
[erl_syntax:variable("Reply")]
)
]
).
% List the supported alcove API functions
calls(Proto) ->
{ok, Bin} = file:read_file(Proto),
Fun = binary:split(Bin, <<"\n">>, [trim,global]),
call_to_fun(Fun, []).
call_to_fun([], Acc) ->
lists:reverse(Acc);
call_to_fun([H|T], Acc) ->
[Fun, Arity] = binary:split(H, <<"/">>),
call_to_fun(T, [{binary_to_list(Fun), b2i(Arity)}|Acc]).
b2i(N) when is_binary(N) ->
list_to_integer(binary_to_list(N)).
static_exports() ->
[{audit_arch,0},
{wordalign,1}, {wordalign,2},
{define,3},
{stdin,3},
{stdout,2}, {stdout,3},
{stderr,2}, {stderr,3},
{eof,2}, {eof,3},
{event,2}, {event,3},
{getcpid,4}].
static() ->
[ static({Fun, Arity}) || {Fun, Arity} <- static_exports() ].
static({audit_arch,0}) ->
"audit_arch() ->
Arches = [
{{\"armv6l\",\"linux\",4}, audit_arch_arm},
{{\"armv7l\",\"linux\",4}, audit_arch_arm},
{{\"i386\",\"linux\",4}, audit_arch_i386},
{{\"aarch64\",\"linux\",8}, audit_arch_aarch64},
{{\"x86_64\",\"linux\",8}, audit_arch_x86_64}
],
[Arch,_,OS|_] = string:tokens(
erlang:system_info(system_architecture),
\"-\"
),
Wordsize = erlang:system_info({wordsize,external}),
proplists:get_value({Arch,OS,Wordsize}, Arches, enotsup).
";
static({wordalign,1}) ->
"wordalign(Offset) ->
wordalign(Offset, erlang:system_info({wordsize, external})).
";
static({wordalign,2}) ->
"wordalign(Offset, Align) ->
(Align - (Offset rem Align)) rem Align.
";
static({define,3}) ->
"
define(Drv, ForkChain, Constant) when is_atom(Constant) ->
define(Drv, ForkChain, [Constant]);
define(Drv, ForkChain, Constants) when is_list(Constants) ->
lists:foldl(fun
(Constant,Result) when is_atom(Constant) ->
Val = define_constant(Drv, ForkChain, Constant),
Result bxor Val;
(Val,Result) when is_integer(Val) ->
Result bxor Val
end,
0,
Constants).
define_constant(Drv, ForkChain, Constant) ->
Fun = [
fun clone_constant/3,
fun fcntl_constant/3,
fun file_constant/3,
fun ioctl_constant/3,
fun mount_constant/3,
fun prctl_constant/3,
fun rlimit_constant/3,
fun signal_constant/3,
fun syscall_constant/3
],
define_foreach(Drv, ForkChain, Constant, Fun).
define_foreach(_Drv, _ForkChain, Constant, []) ->
erlang:error({unknown, Constant});
define_foreach(Drv, ForkChain, Constant, [Fun|Rest]) ->
try Fun(Drv, ForkChain, Constant) of
unknown ->
define_foreach(Drv, ForkChain, Constant, Rest);
Val when is_integer(Val) ->
Val
catch
% Function call not supported on this platform
error:undef ->
define_foreach(Drv, ForkChain, Constant, Rest)
end.
";
static({stdin,3}) ->
"
stdin(Drv, Pids, Data) ->
case alcove_drv:stdin(Drv, Pids, Data) of
ok ->
ok;
{alcove_error, Error} ->
erlang:error(Error, [Drv, Pids, Data])
end.
";
static({stdout,2}) ->
"
stdout(Drv, Pids) ->
stdout(Drv, Pids, 0).
";
static({stdout,3}) ->
"
stdout(Drv, Pids, Timeout) ->
stdout_1(Drv, Pids, Timeout, []).
stdout_1(Drv, Pids, Timeout, Acc) ->
case alcove_drv:stdout(Drv, Pids, Timeout) of
false ->
lists:reverse(Acc);
{alcove_error, Error} ->
erlang:error(Error, [Drv, Pids, Timeout]);
{alcove_pipe, Error} ->
erlang:error(Error, [Drv, Pids, Timeout]);
Reply ->
stdout_1(Drv, Pids, Timeout, [Reply|Acc])
end.
";
static({stderr,2}) ->
"
stderr(Drv, Pids) ->
stderr(Drv, Pids, 0).
";
static({stderr,3}) ->
"
stderr(Drv, Pids, Timeout) ->
stderr_1(Drv, Pids, Timeout, []).
stderr_1(Drv, Pids, Timeout, Acc) ->
case alcove_drv:stderr(Drv, Pids, Timeout) of
false ->
lists:reverse(Acc);
{alcove_error, Error} ->
erlang:error(Error, [Drv, Pids, Timeout]);
{alcove_pipe, Error} ->
erlang:error(Error, [Drv, Pids, Timeout]);
Reply ->
stderr_1(Drv, Pids, Timeout, [Reply|Acc])
end.
";
static({eof,2}) ->
"
-spec eof(alcove_drv:ref(),[pid_t()]) -> 'ok' | {'error',posix()}.
eof(Drv, Pids) ->
eof(Drv, Pids, stdin).
";
static({eof,3}) ->
"
-spec eof(alcove_drv:ref(),[pid_t()],'stdin' | 'stdout' | 'stderr')
-> 'ok' | {'error',posix()}.
eof(_Drv, [], _Stdio) ->
{error,esrch};
eof(Drv, Pids0, Stdio) ->
[Pid|Rest] = lists:reverse(Pids0),
Pids = lists:reverse(Rest),
Proc = cpid(Drv, Pids),
case lists:keyfind(Pid, 2, Proc) of
false ->
{error,esrch};
N ->
eof_1(Drv, Pids, N, Stdio)
end.
eof_1(Drv, Pids, #alcove_pid{stdin = FD}, stdin) ->
close(Drv, Pids, FD);
eof_1(Drv, Pids, #alcove_pid{stdout = FD}, stdout) ->
close(Drv, Pids, FD);
eof_1(Drv, Pids, #alcove_pid{stderr = FD}, stderr) ->
close(Drv, Pids, FD).
";
static({event,2}) ->
"
event(Drv, Pids) ->
event(Drv, Pids, 0).
";
static({event,3}) ->
"
event(Drv, Pids, Timeout) ->
alcove_drv:event(Drv, Pids, Timeout).
";
static({getcpid,4}) ->
"
getcpid(Drv, Pids, Pid, Key) ->
N = indexof(Key, record_info(fields, alcove_pid)),
case lists:keyfind(Pid, #alcove_pid.pid, alcove:cpid(Drv, Pids)) of
false ->
false;
Child when is_integer(N) ->
element(N, Child)
end.
indexof(El, List) ->
indexof(El, List, 2).
indexof(_El, [], _N) ->
false;
indexof(El, [El|_], N) ->
N;
indexof(El, [_|Tail], N) ->
indexof(El, Tail, N+1).
".
includes(Header) ->
[ erl_syntax:attribute(erl_syntax:atom(include), [erl_syntax:string(N)]) || N <- Header ].
% FIXME hack for hard coding typespecs
specs() ->
"
-type uint8_t() :: 0 .. 16#ff.
-type uint16_t() :: 0 .. 16#ffff.
-type uint32_t() :: 0 .. 16#ffffffff.
-type uint64_t() :: 0 .. 16#ffffffffffffffff.
-type int8_t() :: -16#7f .. 16#7f.
-type int16_t() :: -16#7fff .. 16#7fff.
-type int32_t() :: -16#7fffffff .. 16#7fffffff.
-type int64_t() :: -16#7fffffffffffffff .. 16#7fffffffffffffff.
-type mode_t() :: uint32_t().
-type uid_t() :: uint32_t().
-type gid_t() :: uint32_t().
-type off_t() :: uint64_t().
-type size_t() :: uint64_t().
-type ssize_t() :: int64_t().
-type pid_t() :: int32_t().
-type fd() :: int32_t().
-type fd_set() :: [fd()].
-type constant() :: atom() | integer().
-type cstruct() :: nonempty_list(binary() | {ptr, binary() | non_neg_integer()}).
-type posix() :: 'e2big'
| 'eacces' | 'eaddrinuse' | 'eaddrnotavail' | 'eadv' | 'eafnosupport'
| 'eagain' | 'ealign' | 'ealready'
| 'ebade' | 'ebadf' | 'ebadfd' | 'ebadmsg' | 'ebadr' | 'ebadrpc'
| 'ebadrqc' | 'ebadslt' | 'ebfont' | 'ebusy'
| 'ecapmode' | 'echild' | 'echrng' | 'ecomm' | 'econnaborted'
| 'econnrefused' | 'econnreset'
| 'edeadlk' | 'edeadlock' | 'edestaddrreq' | 'edirty' | 'edom' | 'edotdot'
| 'edquot' | 'eduppkg'
| 'eexist'
| 'efault' | 'efbig'
| 'ehostdown' | 'ehostunreach'
| 'eidrm' | 'einit' | 'einprogress' | 'eintr' | 'einval' | 'eio'
| 'eisconn' | 'eisdir' | 'eisnam'
| 'el2hlt' | 'el2nsync' | 'el3hlt' | 'el3rst' | 'elbin' | 'elibacc'
| 'elibbad' | 'elibexec' | 'elibmax' | 'elibscn' | 'elnrng' | 'eloop'
| 'emfile' | 'emlink' | 'emsgsize' | 'emultihop'
| 'enametoolong' | 'enavail' | 'enet' | 'enetdown' | 'enetreset'
| 'enetunreach' | 'enfile' | 'enoano' | 'enobufs' | 'enocsi' | 'enodata'
| 'enodev' | 'enoent' | 'enoexec' | 'enolck' | 'enolink' | 'enomem'
| 'enomsg' | 'enonet' | 'enopkg' | 'enoprotoopt' | 'enospc' | 'enosr'
| 'enostr' | 'enosym' | 'enosys' | 'enotblk' | 'enotcapable' | 'enotconn'
| 'enotdir' | 'enotempty' | 'enotnam' | 'enotrecoverable' | 'enotsock'
| 'enotsup' | 'enotty' | 'enotuniq' | 'enxio' | 'eopnotsupp'
| 'eoverflow' | 'eownerdead'
| 'eperm' | 'epfnosupport' | 'epipe' | 'eproclim' | 'eprocunavail'
| 'eprogmismatch' | 'eprogunavail' | 'eproto' | 'eprotonosupport'
| 'eprototype'
| 'erange' | 'erefused' | 'eremchg' | 'eremdev' | 'eremote' | 'eremoteio'
| 'eremoterelease' | 'erofs' | 'erpcmismatch' | 'erremote'
| 'eshutdown' | 'esocktnosupport' | 'espipe' | 'esrch' | 'esrmnt'
| 'estale' | 'esuccess'
| 'etime' | 'etimedout' | 'etoomanyrefs' | 'etxtbsy'
| 'euclean' | 'eunatch' | 'eusers'
| 'eversion'
| 'ewouldblock'
| 'exdev' | 'exfull'.
-type alcove_pid_field() :: pid
| flowcontrol
| signaloneof
| fdctl
| stdin
| stdout
| stderr.
-type alcove_pid() :: #alcove_pid{}.
-type alcove_rlimit() :: #alcove_rlimit{}.
-type alcove_timeval() :: #alcove_timeval{}.
-export_type([
uint8_t/0, uint16_t/0, uint32_t/0, uint64_t/0,
int8_t/0, int16_t/0, int32_t/0, int64_t/0,
mode_t/0,
uid_t/0,
gid_t/0,
off_t/0,
size_t/0,
ssize_t/0,
fd/0,
fd_set/0,
pid_t/0,
constant/0,
posix/0,
alcove_pid_field/0,
alcove_pid/0,
alcove_rlimit/0,
alcove_timeval/0
]).
-spec audit_arch() -> atom().
-spec cap_constant(alcove_drv:ref(),[pid_t()],atom()) -> integer() | 'unknown'.
-spec cap_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> integer() | 'unknown'.
-spec cap_enter(alcove_drv:ref(),[pid_t()]) -> 'ok' | {'error', posix()}.
-spec cap_enter(alcove_drv:ref(),[pid_t()],timeout()) -> 'ok' | {'error', posix()}.
-spec cap_fcntls_get(alcove_drv:ref(),[pid_t()],fd()) -> {'ok', integer()} | {'error', posix()}.
-spec cap_fcntls_get(alcove_drv:ref(),[pid_t()],fd(),timeout()) -> {'ok', integer()} | {'error', posix()}.
-spec cap_fcntls_limit(alcove_drv:ref(),[pid_t()],fd(),constant()) -> 'ok' | {'error', posix()}.
-spec cap_fcntls_limit(alcove_drv:ref(),[pid_t()],fd(),constant(),timeout()) -> 'ok' | {'error', posix()}.
-spec cap_getmode(alcove_drv:ref(),[pid_t()]) -> {'ok', 0 | 1} | {'error', posix()}.
-spec cap_getmode(alcove_drv:ref(),[pid_t()],timeout()) -> {'ok', 0 | 1} | {'error', posix()}.
-spec cap_ioctls_limit(alcove_drv:ref(),[pid_t()],fd(),constant()) -> 'ok' | {'error', posix()}.
-spec cap_ioctls_limit(alcove_drv:ref(),[pid_t()],fd(),constant(),timeout()) -> 'ok' | {'error', posix()}.
-spec cap_rights_limit(alcove_drv:ref(),[pid_t()],fd(),constant()) -> 'ok' | {'error', posix()}.
-spec cap_rights_limit(alcove_drv:ref(),[pid_t()],fd(),constant(),timeout()) -> 'ok' | {'error', posix()}.
-spec chdir(alcove_drv:ref(),[pid_t()],iodata()) -> 'ok' | {'error', posix()}.
-spec chdir(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> 'ok' | {'error', posix()}.
-spec cpid(alcove_drv:ref(),[pid_t()]) -> [alcove_pid()].
-spec cpid(alcove_drv:ref(),[pid_t()],timeout()) -> [alcove_pid()].
-spec chmod(alcove_drv:ref(),[pid_t()],iodata(),mode_t()) -> 'ok' | {'error', posix()}.
-spec chmod(alcove_drv:ref(),[pid_t()],iodata(),mode_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec chown(alcove_drv:ref(),[pid_t()],iodata(),uid_t(),gid_t()) -> 'ok' | {'error', posix()}.
-spec chown(alcove_drv:ref(),[pid_t()],iodata(),uid_t(),gid_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec chroot(alcove_drv:ref(),[pid_t()],iodata()) -> 'ok' | {'error', posix()}.
-spec chroot(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> 'ok' | {'error', posix()}.
-spec clearenv(alcove_drv:ref(),[pid_t()]) -> 'ok' | {'error', posix()}.
-spec clearenv(alcove_drv:ref(),[pid_t()],timeout()) -> 'ok' | {'error', posix()}.
-spec clone(alcove_drv:ref(),[pid_t()],int32_t() | [constant()]) -> {'ok', pid_t()} | {'error', posix()}.
-spec clone(alcove_drv:ref(),[pid_t()],int32_t() | [constant()],timeout()) -> {'ok', pid_t()} | {'error', posix()}.
-spec clone_constant(alcove_drv:ref(),[pid_t()],atom()) -> 'unknown' | int32_t().
-spec clone_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> 'unknown' | int32_t().
-spec close(alcove_drv:ref(),[pid_t()],fd()) -> 'ok' | {'error', posix()}.
-spec close(alcove_drv:ref(),[pid_t()],fd(),timeout()) -> 'ok' | {'error', posix()}.
-spec connect(alcove_drv:ref(),[pid_t()],fd(), [] | cstruct()) -> 'ok' | {'error', posix()}.
-spec connect(alcove_drv:ref(),[pid_t()],fd(), [] | cstruct(),timeout()) -> 'ok' | {'error', posix()}.
-spec define(alcove_drv:ref(),[pid_t()],atom() | [atom()]) -> integer().
-spec environ(alcove_drv:ref(),[pid_t()]) -> [binary()].
-spec environ(alcove_drv:ref(),[pid_t()],timeout()) -> [binary()].
-spec errno_id(alcove_drv:ref(),[pid_t()],int32_t()) -> posix().
-spec errno_id(alcove_drv:ref(),[pid_t()],int32_t(),timeout()) -> posix().
-spec event(alcove_drv:ref(),[pid_t()]) -> term().
-spec event(alcove_drv:ref(),[pid_t()],timeout()) -> term().
-spec execve(alcove_drv:ref(),[pid_t()],iodata(),[iodata()],[iodata()]) -> 'ok' | {'error',posix()}.
-spec execve(alcove_drv:ref(),[pid_t()],iodata(),[iodata()],[iodata()],timeout()) -> 'ok' | {'error',posix()}.
-spec execvp(alcove_drv:ref(),[pid_t()],iodata(),[iodata()]) -> 'ok' | {'error',posix()}.
-spec execvp(alcove_drv:ref(),[pid_t()],iodata(),[iodata()],timeout()) -> 'ok' | {'error',posix()}.
-spec exit(alcove_drv:ref(),[pid_t()],int32_t()) -> 'ok'.
-spec exit(alcove_drv:ref(),[pid_t()],int32_t(),timeout()) -> 'ok'.
-spec fcntl(alcove_drv:ref(), [pid_t()], fd(), constant(), int64_t()) -> {'ok',int64_t()} | {'error', posix()}.
-spec fcntl(alcove_drv:ref(), [pid_t()], fd(), constant(), int64_t(), timeout()) -> {'ok',int64_t()} | {'error', posix()}.
-spec fcntl_constant(alcove_drv:ref(),[pid_t()],atom()) -> integer() | 'unknown'.
-spec fcntl_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> integer() | 'unknown'.
-spec fexecve(alcove_drv:ref(),[pid_t()],fd(),[iodata()],[iodata()]) -> 'ok' | {'error',posix()}.
-spec fexecve(alcove_drv:ref(),[pid_t()],fd(),[iodata()],[iodata()],timeout()) -> 'ok' | {'error',posix()}.
-spec file_constant(alcove_drv:ref(),[pid_t()],atom()) -> non_neg_integer() | 'unknown'.
-spec file_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> non_neg_integer() | 'unknown'.
-spec filter(alcove_drv:ref(),[pid_t()],alcove_proto:call()) -> ok | {'error', 'einval'}.
-spec filter(alcove_drv:ref(),[pid_t()],alcove_proto:call(),timeout()) -> ok | {'error', 'einval'}.
-spec fork(alcove_drv:ref(),[pid_t()]) -> {'ok', pid_t()} | {'error', posix()}.
-spec fork(alcove_drv:ref(),[pid_t()],timeout()) -> {'ok', pid_t()} | {'error', posix()}.
-spec getcpid(alcove_drv:ref(),[pid_t()],pid_t(),alcove_pid_field()) -> 'false' | int32_t().
-spec getcwd(alcove_drv:ref(),[pid_t()]) -> {'ok', binary()} | {'error', posix()}.
-spec getcwd(alcove_drv:ref(),[pid_t()],timeout()) -> {'ok', binary()} | {'error', posix()}.
-spec getenv(alcove_drv:ref(),[pid_t()],iodata()) -> binary() | 'false'.
-spec getenv(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> binary() | 'false'.
-spec getgid(alcove_drv:ref(),[pid_t()]) -> gid_t().
-spec getgid(alcove_drv:ref(),[pid_t()],timeout()) -> gid_t().
-spec getgroups(alcove_drv:ref(),[pid_t()]) -> {ok, [gid_t()]} | {error, posix()}.
-spec getgroups(alcove_drv:ref(),[pid_t()],timeout()) -> {ok, [gid_t()]} | {error, posix()}.
-spec gethostname(alcove_drv:ref(),[pid_t()]) -> {'ok', binary()} | {'error', posix()}.
-spec gethostname(alcove_drv:ref(),[pid_t()],timeout()) -> {'ok', binary()} | {'error', posix()}.
-spec getopt(alcove_drv:ref(),[pid_t()],atom()) -> 'false' | int32_t().
-spec getopt(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> 'false' | int32_t().
-spec getpgrp(alcove_drv:ref(),[pid_t()]) -> pid_t().
-spec getpgrp(alcove_drv:ref(),[pid_t()],timeout()) -> pid_t().
-spec getpid(alcove_drv:ref(),[pid_t()]) -> pid_t().
-spec getpid(alcove_drv:ref(),[pid_t()],timeout()) -> pid_t().
-spec getpriority(alcove_drv:ref(),[pid_t()],constant(),int32_t()) -> {'ok',int32_t()} | {'error', posix()}.
-spec getpriority(alcove_drv:ref(),[pid_t()],constant(),int32_t(),timeout()) -> {'ok',int32_t()} | {'error', posix()}.
-spec getresgid(alcove_drv:ref(),[pid_t()]) -> {'ok', gid_t(), gid_t(), gid_t()} | {'error', posix()}.
-spec getresgid(alcove_drv:ref(),[pid_t()],timeout()) -> {'ok', gid_t(), gid_t(), gid_t()} | {'error', posix()}.
-spec getresuid(alcove_drv:ref(),[pid_t()]) -> {'ok', uid_t(), uid_t(), uid_t()} | {'error', posix()}.
-spec getresuid(alcove_drv:ref(),[pid_t()],timeout()) -> {'ok', uid_t(), uid_t(), uid_t()} | {'error', posix()}.
-spec getrlimit(alcove_drv:ref(),[pid_t()],constant()) -> {'ok', alcove_rlimit()} | {'error', posix()}.
-spec getrlimit(alcove_drv:ref(),[pid_t()],constant(),timeout()) -> {'ok', alcove_rlimit()} | {'error', posix()}.
-spec getsid(alcove_drv:ref(),[pid_t()],pid_t()) -> {'ok', pid_t()} | {'error', posix()}.
-spec getsid(alcove_drv:ref(),[pid_t()],pid_t(),timeout()) -> {'ok', pid_t()} | {'error', posix()}.
-spec getuid(alcove_drv:ref(),[pid_t()]) -> uid_t().
-spec getuid(alcove_drv:ref(),[pid_t()],timeout()) -> uid_t().
-spec ioctl(alcove_drv:ref(), [pid_t()], fd(), constant(), cstruct()) -> {'ok',integer(),iodata()} | {'error', posix()}.
-spec ioctl(alcove_drv:ref(), [pid_t()], fd(), constant(), cstruct(), timeout()) -> {'ok',integer(),iodata()} | {'error', posix()}.
-spec ioctl_constant(alcove_drv:ref(),[pid_t()],atom()) -> integer() | 'unknown'.
-spec ioctl_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> integer() | 'unknown'.
-spec iolist_to_bin(alcove_drv:ref(),[pid_t()],iodata()) -> binary().
-spec iolist_to_bin(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> binary().
-spec jail(alcove_drv:ref(),[pid_t()],cstruct()) -> {'ok', int32_t()} | {'error', posix()}.
-spec jail(alcove_drv:ref(),[pid_t()],cstruct(),timeout()) -> {'ok', int32_t()} | {'error', posix()}.
-spec jail_attach(alcove_drv:ref(),[pid_t()],int32_t()) -> 'ok' | {'error', posix()}.
-spec jail_attach(alcove_drv:ref(),[pid_t()],int32_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec jail_remove(alcove_drv:ref(),[pid_t()],int32_t()) -> 'ok' | {'error', posix()}.
-spec jail_remove(alcove_drv:ref(),[pid_t()],int32_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec kill(alcove_drv:ref(),[pid_t()],pid_t(),constant()) -> 'ok' | {'error', posix()}.
-spec kill(alcove_drv:ref(),[pid_t()],pid_t(),constant(),timeout()) -> 'ok' | {'error', posix()}.
-spec link(alcove_drv:ref(),[pid_t()],iodata(),iodata()) -> 'ok' | {error, posix()}.
-spec link(alcove_drv:ref(),[pid_t()],iodata(),iodata(),timeout()) -> 'ok' | {error, posix()}.
-spec lseek(alcove_drv:ref(),[pid_t()],fd(),off_t(),int32_t()) -> 'ok' | {'error', posix()}.
-spec lseek(alcove_drv:ref(),[pid_t()],fd(),off_t(),int32_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec mkdir(alcove_drv:ref(),[pid_t()],iodata(),mode_t()) -> 'ok' | {'error', posix()}.
-spec mkdir(alcove_drv:ref(),[pid_t()],iodata(),mode_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec mkfifo(alcove_drv:ref(),[pid_t()],iodata(),mode_t()) -> 'ok' | {'error', posix()}.
-spec mkfifo(alcove_drv:ref(),[pid_t()],iodata(),mode_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec mount(alcove_drv:ref(),[pid_t()],iodata(),iodata(),iodata(),uint64_t() | [constant()],iodata(),iodata()) -> 'ok' | {'error', posix()}.
-spec mount(alcove_drv:ref(),[pid_t()],iodata(),iodata(),iodata(),uint64_t() | [constant()],iodata(),iodata(),timeout()) -> 'ok' | {'error', posix()}.
-spec mount_constant(alcove_drv:ref(),[pid_t()],atom()) -> 'unknown' | uint64_t().
-spec mount_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> 'unknown' | uint64_t().
-spec open(alcove_drv:ref(),[pid_t()],iodata(),int32_t() | [constant()],mode_t()) -> {'ok',fd()} | {'error', posix()}.
-spec open(alcove_drv:ref(),[pid_t()],iodata(),int32_t() | [constant()],mode_t(),timeout()) -> {'ok',fd()} | {'error', posix()}.
-spec pledge(alcove_drv:ref(),[pid_t()],iodata() | null,iodata() | null) -> 'ok' | {'error', posix()}.
-spec pledge(alcove_drv:ref(),[pid_t()],iodata() | null,iodata() | null,timeout()) -> 'ok' | {'error', posix()}.
-spec pivot_root(alcove_drv:ref(),[pid_t()],iodata(),iodata()) -> 'ok' | {'error', posix()}.
-spec pivot_root(alcove_drv:ref(),[pid_t()],iodata(),iodata(),timeout()) -> 'ok' | {'error', posix()}.
-type ptr_arg() :: binary() | constant() | cstruct().
-type ptr_val() :: binary() | integer() | cstruct().
-spec prctl(alcove_drv:ref(),[pid_t()],constant(),ptr_arg(),ptr_arg(),ptr_arg(),ptr_arg())
-> {'ok',integer(),ptr_val(),ptr_val(),ptr_val(),ptr_val()} | {'error', posix()}.
-spec prctl(alcove_drv:ref(),[pid_t()],constant(),ptr_arg(),ptr_arg(),ptr_arg(),ptr_arg(),timeout())
-> {'ok',integer(),ptr_val(),ptr_val(),ptr_val(),ptr_val()} | {'error', posix()}.
-spec prctl_constant(alcove_drv:ref(),[pid_t()],atom()) -> 'unknown' | non_neg_integer().
-spec prctl_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> 'unknown' | non_neg_integer().
-spec procctl(alcove_drv:ref(),[pid_t()],constant(),pid_t(),constant(),[] | cstruct())
-> {'ok',binary(),cstruct()} | {'error', posix()}.
-spec procctl(alcove_drv:ref(),[pid_t()],constant(),pid_t(),constant(),[] | cstruct(),timeout())
-> {'ok',binary(),cstruct()} | {'error', posix()}.
-spec ptrace(alcove_drv:ref(),[pid_t()],constant(),pid_t(),ptr_arg(),ptr_arg())
-> {'ok', integer(), ptr_val(), ptr_val()} | {'error', posix()}.
-spec ptrace(alcove_drv:ref(),[pid_t()],constant(),pid_t(),ptr_arg(),ptr_arg(),timeout())
-> {'ok', integer(), ptr_val(), ptr_val()} | {'error', posix()}.
-spec ptrace_constant(alcove_drv:ref(),[pid_t()],atom())
-> 'unknown' | integer().
-spec ptrace_constant(alcove_drv:ref(),[pid_t()],atom(),timeout())
-> 'unknown' | integer().
-spec read(alcove_drv:ref(),[pid_t()],fd(),size_t()) -> {'ok', binary()} | {'error', posix()}.
-spec read(alcove_drv:ref(),[pid_t()],fd(),size_t(),timeout()) -> {'ok', binary()} | {'error', posix()}.
-spec readdir(alcove_drv:ref(),[pid_t()],iodata()) -> {'ok', [binary()]} | {'error', posix()}.
-spec readdir(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> {'ok', [binary()]} | {'error', posix()}.
-spec rmdir(alcove_drv:ref(),[pid_t()],iodata()) -> 'ok' | {'error', posix()}.
-spec rmdir(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> 'ok' | {'error', posix()}.
-spec rlimit_constant(alcove_drv:ref(),[pid_t()],atom()) -> 'unknown' | non_neg_integer().
-spec rlimit_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> 'unknown' | non_neg_integer().
-spec seccomp(alcove_drv:ref(),[pid_t()],constant(),constant(),cstruct()) -> 'ok' | {'error', posix()}.
-spec seccomp(alcove_drv:ref(),[pid_t()],constant(),constant(),cstruct(),timeout()) -> 'ok' | {'error', posix()}.
-spec seccomp_constant(alcove_drv:ref(),[pid_t()],atom()) -> 'unknown' | non_neg_integer().
-spec seccomp_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> 'unknown' | non_neg_integer().
-spec select(alcove_drv:ref(),[pid_t()],fd_set(),fd_set(),fd_set(),
[] | 'null' | alcove_timeval()) -> {ok, fd_set(), fd_set(), fd_set()} | {'error', posix()}.
-spec select(alcove_drv:ref(),[pid_t()],fd_set(),fd_set(),fd_set(),
[] | 'null' | alcove_timeval(),timeout()) -> {ok, fd_set(), fd_set(), fd_set()} | {'error', posix()}.
-spec setenv(alcove_drv:ref(),[pid_t()],iodata(),iodata(),int32_t()) -> 'ok' | {'error', posix()}.
-spec setenv(alcove_drv:ref(),[pid_t()],iodata(),iodata(),int32_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec setcpid(alcove_drv:ref(),[pid_t()],pid_t(),alcove_pid_field(),int32_t()) -> boolean().
-spec setcpid(alcove_drv:ref(),[pid_t()],pid_t(),alcove_pid_field(),int32_t(),timeout()) -> boolean().
-spec setgid(alcove_drv:ref(),[pid_t()],gid_t()) -> 'ok' | {'error', posix()}.
-spec setgid(alcove_drv:ref(),[pid_t()],gid_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec setgroups(alcove_drv:ref(),[pid_t()],[gid_t()]) -> 'ok' | {'error', posix()}.
-spec setgroups(alcove_drv:ref(),[pid_t()],[gid_t()],timeout()) -> 'ok' | {'error', posix()}.
-spec sethostname(alcove_drv:ref(),[pid_t()],iodata()) -> 'ok' | {'error', posix()}.
-spec sethostname(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> 'ok' | {'error', posix()}.
-spec setns(alcove_drv:ref(),[pid_t()],iodata(),constant()) -> 'ok' | {'error', posix()}.
-spec setns(alcove_drv:ref(),[pid_t()],iodata(),constant(),timeout()) -> 'ok' | {'error', posix()}.
-spec setopt(alcove_drv:ref(),[pid_t()],atom(),int32_t()) -> boolean().
-spec setopt(alcove_drv:ref(),[pid_t()],atom(),int32_t(),timeout()) -> boolean().
-spec setpgid(alcove_drv:ref(),[pid_t()],pid_t(),pid_t()) -> 'ok' | {'error', posix()}.
-spec setpgid(alcove_drv:ref(),[pid_t()],pid_t(),pid_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec setpriority(alcove_drv:ref(),[pid_t()],constant(),int32_t(),int32_t()) -> 'ok' | {'error', posix()}.
-spec setpriority(alcove_drv:ref(),[pid_t()],constant(),int32_t(),int32_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec setproctitle(alcove_drv:ref(),[pid_t()],iodata()) -> 'ok'.
-spec setproctitle(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> 'ok'.
-spec setresgid(alcove_drv:ref(),[pid_t()],gid_t(),gid_t(),gid_t()) -> 'ok' | {'error', posix()}.
-spec setresgid(alcove_drv:ref(),[pid_t()],gid_t(),gid_t(),gid_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec setresuid(alcove_drv:ref(),[pid_t()],uid_t(),uid_t(),uid_t()) -> 'ok' | {'error', posix()}.
-spec setresuid(alcove_drv:ref(),[pid_t()],uid_t(),uid_t(),uid_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec setrlimit(alcove_drv:ref(),[pid_t()],constant(),alcove_rlimit()) -> 'ok' | {'error', posix()}.
-spec setrlimit(alcove_drv:ref(),[pid_t()],constant(),alcove_rlimit(),timeout()) -> 'ok' | {'error', posix()}.
-spec setsid(alcove_drv:ref(),[pid_t()]) -> {ok,pid_t()} | {error, posix()}.
-spec setsid(alcove_drv:ref(),[pid_t()],timeout()) -> {ok,pid_t()} | {error, posix()}.
-spec setuid(alcove_drv:ref(),[pid_t()],uid_t()) -> 'ok' | {'error', posix()}.
-spec setuid(alcove_drv:ref(),[pid_t()],uid_t(),timeout()) -> 'ok' | {'error', posix()}.
-spec sigaction(alcove_drv:ref(),[pid_t()],constant() | [] | <<>>,atom()) -> {'ok',atom()} | {'error', posix()}.
-spec sigaction(alcove_drv:ref(),[pid_t()],constant() | [] | <<>>,atom(),timeout()) -> {'ok',atom()} | {'error', posix()}.
-spec signal_constant(alcove_drv:ref(),[pid_t()],atom()) -> 'unknown' | non_neg_integer().
-spec signal_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> 'unknown' | non_neg_integer().
-spec socket(alcove_drv:ref(),[pid_t()],constant(),constant(),int32_t()) -> {'ok',fd()} | {'error', posix()}.
-spec socket(alcove_drv:ref(),[pid_t()],constant(),constant(),int32_t(),timeout()) -> {'ok',fd()} | {'error', posix()}.
-spec syscall_constant(alcove_drv:ref(),[pid_t()],atom()) -> 'unknown' | non_neg_integer().
-spec syscall_constant(alcove_drv:ref(),[pid_t()],atom(),timeout()) -> 'unknown' | non_neg_integer().
-spec stderr(alcove_drv:ref(),[pid_t()]) -> [binary()].
-spec stderr(alcove_drv:ref(),[pid_t()],timeout()) -> [binary()].
-spec stdin(alcove_drv:ref(),[pid_t()],iodata()) -> 'ok'.
-spec stdout(alcove_drv:ref(),[pid_t()]) -> [binary()].
-spec stdout(alcove_drv:ref(),[pid_t()],timeout()) -> [binary()].
-spec symlink(alcove_drv:ref(),[pid_t()],iodata(),iodata()) -> 'ok' | {error, posix()}.
-spec symlink(alcove_drv:ref(),[pid_t()],iodata(),iodata(),timeout()) -> 'ok' | {error, posix()}.
-spec unlink(alcove_drv:ref(),[pid_t()],iodata()) -> 'ok' | {error, posix()}.
-spec unlink(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> 'ok' | {error, posix()}.
-spec umount(alcove_drv:ref(),[pid_t()],iodata()) -> 'ok' | {error, posix()}.
-spec umount(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> 'ok' | {error, posix()}.
-spec umount2(alcove_drv:ref(),[pid_t()],iodata(),int32_t() | [constant()]) -> 'ok' | {error, posix()}.
-spec umount2(alcove_drv:ref(),[pid_t()],iodata(),int32_t() | [constant()],timeout()) -> 'ok' | {error, posix()}.
-spec unsetenv(alcove_drv:ref(),[pid_t()],iodata()) -> 'ok' | {error, posix()}.
-spec unsetenv(alcove_drv:ref(),[pid_t()],iodata(),timeout()) -> 'ok' | {error, posix()}.
-spec unshare(alcove_drv:ref(),[pid_t()],int32_t() | [constant()]) -> 'ok' | {'error', posix()}.
-spec unshare(alcove_drv:ref(),[pid_t()],int32_t() | [constant()],timeout()) -> 'ok' | {'error', posix()}.
-spec unveil(alcove_drv:ref(),[pid_t()],iodata() | null,iodata() | null) -> 'ok' | {'error', posix()}.
-spec unveil(alcove_drv:ref(),[pid_t()],iodata() | null,iodata() | null,timeout()) -> 'ok' | {'error', posix()}.
-type waitpid_value() :: {exit_status, int32_t()}
| {termsig, atom()}
| {stopsig, atom()}
| continued.
-spec waitpid(alcove_drv:ref(),[pid_t()],pid_t(),int32_t() | [constant()]) -> {'ok', pid_t(), [waitpid_value()]} | {'error', posix()}.
-spec waitpid(alcove_drv:ref(),[pid_t()],pid_t(),int32_t() | [constant()],timeout()) -> {'ok', pid_t(), [waitpid_value()]} | {'error', posix()}.
-spec write(alcove_drv:ref(),[pid_t()],fd(),iodata()) -> {'ok', ssize_t()} | {'error', posix()}.
-spec write(alcove_drv:ref(),[pid_t()],fd(),iodata(),timeout()) -> {'ok', ssize_t()} | {'error', posix()}.
-spec version(alcove_drv:ref(),[pid_t()]) -> binary().
-spec version(alcove_drv:ref(),[pid_t()],timeout()) -> binary().
".
license() ->
{{Year,_,_},{_,_,_}} = calendar:universal_time(),
Date = integer_to_list(Year),
License = [
" Copyright (c) " ++ Date ++ ", Michael Santos <michael.santos@gmail.com>",
" Permission to use, copy, modify, and/or distribute this software for any",
" purpose with or without fee is hereby granted, provided that the above",
" copyright notice and this permission notice appear in all copies.",
"",
" THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES",
" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF",
" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR",
" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES",
" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN",
" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF",
" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE."],
erl_syntax:comment(License).