View Source prx_task (prx v0.16.4)
Create a subprocess and run a sequence of operations.
Theprx_task
module provides functions for creating a new process from a prx:task/0
, running a series of operations on the subprocess and cleaning up on error. The new task is returned to the caller.
Link to this section Summary
Functions
Fork and configure a subprocess
Fork and configure a subprocess
Run a sequence of operations on a task
Link to this section Types
-type op() :: {atom(), list()} | {module(), atom(), list()} | {module(), atom(), list(), [option()]}.
-type option() :: state | errexit | {state, boolean()} | {errexit, boolean()} | {transform, fun((any()) -> ok | {ok, State :: any()} | {error, prx:posix()})}.
Options to modify the behavior of an operation:
* state
: pass ok
result as the first parameter to the next operation (default: false)
* errexit
: abort operations on error (default: true)
transform
: abort operations on error (default: true)
Link to this section Functions
Fork and configure a subprocess
Returns a new process created using prx:fork/0
after performing the list of operations on the subprocess.
-spec do(prx:task(), [op() | [op()]], any(), [config()]) -> {ok, prx:task()} | {error, prx:posix()}.
Fork and configure a subprocess
Returns a new process created using the init
function provided in the Config
argument list after the process has run the list of operations.
If an operation fails, the subprocess is terminated using the terminate
function.
init
or terminate
functions are not provided, the default functions are used.See also: with/3.
Run a sequence of operations on a task
The with
function runs a sequence of operations on a task. Operations are tuples or list of tuples:
* module name: optional if modifier not used, defaults to prx
* module function
* function arguments
* modifier options (see prx_task:option/0
)
Setuid = true,
[
% equivalent to prx:chdir("/")
{chdir, ["/"]},
% equivalent to prx:setsid(), error is ignored
{prx, setsid, [], [{errexit, false}]},
% the op list can contain op lists
[
case Setuid of
true ->
[
{setresgid, [65534, 65534, 65534]},
{setresuid, [65534, 65534, 65534]}
];
false ->
[]
end
]
]
The called function must return one of:
* ok
* {ok, any()}
* {error, any()}
Any other value will return a badop
exception containing the failing module, function and argument list.
If the op returns an ok
tuple, the second element can optionally be passed as state to the next operation. The initial state can be set using the State
argument to with/3
.
examples
Examples
The example demonstrates limiting the number of file descriptors by passing the highest opened file descriptor to setrlimit/3
.
-module(setlimit).
-export([insn/0]).
-export([close/2, setrlimit/2]).
insn() ->
[
setlimit()
].
setlimit() ->
[
{open, ["/", [o_rdonly]]},
{?MODULE, close, [], [state]},
{?MODULE, setrlimit, [], [state]}
].
close(FD, Task) ->
prx:close(Task, FD).
setrlimit(FD, Task) ->
prx:setrlimit(Task, rlimit_nofile, #{cur => FD, max => FD}).
Calling the module:
1> {ok, Task} = prx:fork().
{ok,<0.186.0>}
2> {ok, Task1} = prx:task(Task, setlimit:insn(), []).
{ok,<0.191.0>}
3> prx:execvp(Task1, ["sh", "-c", "ulimit -n"]).
ok
4> flush().
Shell got {stdout,<0.191.0>,<<"7\n">>}
Shell got {exit_status,<0.191.0>,0}
ok