View Source prx_task (prx v0.16.4)

Create a subprocess and run a sequence of operations.

The prx_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

Types

Options to modify the behavior of an operation

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 config() ::
    {init, fun((prx:task()) -> {ok, prx:task()} | {error, prx:posix()})} |
    {terminate, fun((prx:task(), prx:task()) -> any())}.
-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

-spec do(prx:task(), [op() | [op()]], any()) -> {ok, prx:task()} | {error, prx:posix()}.

Fork and configure a subprocess

Returns a new process created using prx:fork/0 after performing the list of operations on the subprocess.

If an operation returns an error, the process is terminated using SIGKILL.
Link to this function

do(Parent, Ops, State, Config)

View Source
-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.

If init or terminate functions are not provided, the default functions are used.

See also: with/3.

-spec with(prx:task(), Ops :: [op() | [op()]], State :: any()) -> ok | {error, any()}.

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