alcove (alcove v0.38.0) View Source

Link to this section Summary

Functions

Allocate memory

Get seccomp system architecture

Convert capsicum constants to integer

Convert capsicum constants to integer

cap_enter(2): place process into capability mode

cap_enter(2): place process into capability mode

cap_fcntls_get(2): get allowed fcntl commands in capability mode

cap_fcntls_get(2): get allowed fcntl commands in capability mode

cap_fcntls_limit(2): manage fcntl commands in capability mode

cap_fcntls_limit(2): manage fcntl commands in capability mode

cap_getmode(2): check if capability mode is enabled

cap_getmode(2): check if capability mode is enabled

cap_ioctls_limit(2): manage allowed ioctl commands

cap_ioctls_limit(2): manage allowed ioctl commands

cap_rights_limit(2): manage process capabilities

cap_rights_limit(2): manage process capabilities

chdir(2): change process current working directory

chdir(2): change process current working directory

chmod(2): change file permissions

chmod(2): change file permissions

chown(2): change file ownership

chown(2): change file ownership

chroot(2): change root directory

chroot(2): change root directory

clearenv(3): zero process environment

clearenv(3): zero process environment

clone(2): create a new process

clone(2): create a new process

Map clone(2) symbols to integer constants

Map clone(2) symbols to integer constants

close(2): close a file descriptor

close(2): close a file descriptor

connect(2): initiate a connection on a socket

connect(2): initiate a connection on a socket

Returns the list of child PIDs for this process

Returns the list of child PIDs for this process

Convert constant to integer

environ(7): return the process environment variables

environ(7): return the process environment variables

Close stdin of the process

Close stdin, stdout or stderr of the process

Convert errno integer to atom

Convert errno integer to atom

Get events generated by alcove port process

Get events generated by alcove port process

execve(2): replace process image with environment

execve(2): replace process image with environment

execvp(2): replace the current process image using the search path

execvp(2): replace the current process image using the search path

exit(3): cause an alcove control process to exit

exit(3): cause an alcove control process to exit

fcntl(2): perform operations on a file descriptor

fcntl(2): perform operations on a file descriptor

Convert fnctl(2) constant to integer

Convert fnctl(2) constant to integer

fexecve(2): replace the process image

fexecve(2): replace the process image

Constants for open(2)

Create a call filter list

Restrict calls available to an alcove control process

Restrict available calls for control and subprocess

Restrict available calls for control and subprocess

fork(2): create a new process

fork(2): create a new process

Get control process attributes

getcwd(3): return the current working directory

getcwd(3): return the current working directory

getenv(3): retrieve an environment variable

getenv(3): retrieve an environment variable

getgid(2): retrieve the process group ID

getgid(2): retrieve the process group ID

getgroups(2): retrieve the list of supplementary groups

getgroups(2): retrieve the list of supplementary groups

gethostname(2): retrieve the system hostname

gethostname(2): retrieve the system hostname

Retrieve port options for event loop

Retrieve port options for event loop

getpgrp(2): retrieve the process group

getpgrp(2): retrieve the process group

getpid(2): retrieve the system PID of the process

getpid(2): retrieve the system PID of the process

getpriority(2): retrieve scheduling priority of process, process group or user

getpriority(2): retrieve scheduling priority of process, process group or user

getresgid(2): get real, effective and saved group ID

getresgid(2): get real, effective and saved group ID

getresuid(2): get real, effective and saved user ID

getresuid(2): get real, effective and saved user ID

getrlimit(2): retrieve the resource limits for a process

getrlimit(2): retrieve the resource limits for a process

getsid(2): retrieve the session ID

getsid(2): retrieve the session ID

getuid(2): returns the process user ID

getuid(2): returns the process user ID

ioctl(2): control device

Convert ioctl constant to integer

Convert ioctl constant to integer

Convert iolist to binary

Convert iolist to binary

jail(2): restrict the current process in a system jail

jail(2): restrict the current process in a system jail

jail_attach(2): join a jailed process

jail_attach(2): join a jailed process

jail_remove(2): destroy a jailed process

jail_remove(2): destroy a jailed process

kill(2): terminate a process

kill(2): terminate a process

link(2) : create a hard link

link(2) : create a hard link

lseek(2): set file offset for read/write

lseek(2): set file offset for read/write

mkdir(2): create a directory

mkdir(2): create a directory

mkfifo(3): make named pipe file

mkfifo(3): make named pipe file

mount(2): mount a filesystem, Linux style

Convert flag names to integers

Convert flag names to integers

open(2): returns a file descriptor associated with a file

open(2): returns a file descriptor associated with a file

pivot_root(2): change the root mount

pivot_root(2): change the root mount

pledge(2): restrict system operations

pledge(2): restrict system operations

prctl(2): operations on a process

Convert prctl option names to integers

Convert prctl option names to integers

procctl(2): control processes

Convert ptrace constant to integer

Convert ptrace constant to integer

read(2): read bytes from a file descriptor

read(2): read bytes from a file descriptor

readdir(3): retrieve list of objects in a directory

readdir(3): retrieve list of objects in a directory

Convert an RLIMIT_* flag to an integer

Convert an RLIMIT_* flag to an integer

rmdir(2): delete a directory

rmdir(2): delete a directory

seccomp(2): restrict system operations

seccomp(2): restrict system operations

Convert seccomp option name to integer

Convert seccomp option name to integer

select(2): poll a list of file descriptor for events

select(2): poll a list of file descriptor for events

Set options for child process of alcove control process

Set options for child process of alcove control process

setenv(3): set an environment variable

setenv(3): set an environment variable

setgid(2): set the GID of the process

setgid(2): set the GID of the process

setgroups(2): set the supplementary groups of the process

setgroups(2): set the supplementary groups of the process

sethostname(2): set the system hostname

sethostname(2): set the system hostname

setns(2): attach to a namespace

setns(2): attach to a namespace

Set port options

setpgid(2): set process group

setpgid(2): set process group

setpriority(2): set scheduling priority of process, process group or user

setpriority(2): set scheduling priority of process, process group or user

setproctitle(3): set the process title

setproctitle(3): set the process title

setresgid(2): set real, effective and saved group ID

setresgid(2): set real, effective and saved group ID

setresuid(2): set real, effective and saved user ID

setresuid(2): set real, effective and saved user ID

setrlimit(2): set a resource limit

setrlimit(2): set a resource limit

setsid(2): create a new session

setsid(2): create a new session

setuid(2): change UID

setuid(2): change UID

sigaction(2): set process behaviour for signals

sigaction(2): set process behaviour for signals

Convert signal names to integers

Convert signal names to integers

socket(2): returns a file descriptor for a communication endpoint

socket(2): returns a file descriptor for a communication endpoint

Read stderr from the process

Send data to stdin of the process

Read stdout from the process

symlink(2): create a symbolic link

symlink(2): create a symbolic link

Convert syscall name to integer

Convert syscall name to integer

umount(2): unmount a filesystem

umount(2): unmount a filesystem

umount2(2): unmount filesystem with flags

umount2(2): unmount filesystem with flags

unlink(2): delete a name from the filesystem

unlink(2): delete a name from the filesystem

unsetenv(3): remove an environment variable

unsetenv(3): remove an environment variable

unshare(2): create a new namespace in the current process

unshare(2): create a new namespace in the current process

unveil(2): restrict filesystem view

unveil(2): restrict filesystem view

Retrieve the alcove version

Retrieve the alcove version

waitpid(2): wait for process to change state

waitpid(2): wait for process to change state

write(2): write to a file descriptor

write(2): write to a file descriptor

Link to this section Types

Specs

alcove_pid() :: #alcove_pid{}.

Specs

alcove_pid_field() :: pid | flowcontrol | signaloneof | fdctl | stdin | stdout | stderr.

Specs

alcove_rlimit() :: #alcove_rlimit{}.

Specs

alcove_timeval() :: #alcove_timeval{}.

Specs

constant() :: atom() | integer().

Specs

cstruct() :: [binary() | {ptr, binary() | non_neg_integer()}, ...].

Specs

fd() :: int32_t().

Specs

fd_set() :: [fd()].

Specs

filter() ::
    alcove_proto:calls() |
    [] |
    {deny, alcove_proto:calls() | []} |
    {allow, alcove_proto:calls() | []}.

Specs

gid_t() :: uint32_t().

Specs

int16_t() :: - 32767..32767.

Specs

int32_t() :: - 2147483647..2147483647.

Specs

int64_t() :: - 9223372036854775807..9223372036854775807.

Specs

int8_t() :: - 127..127.

Specs

mode_t() :: uint32_t().

Specs

off_t() :: uint64_t().

Specs

pid_t() :: int32_t().

Specs

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.

Specs

ptr_arg() :: binary() | constant() | cstruct().

Specs

ptr_val() :: binary() | integer() | cstruct().

Specs

size_t() :: uint64_t().

Specs

ssize_t() :: int64_t().

Specs

uid_t() :: uint32_t().

Specs

uint16_t() :: 0..65535.

Specs

uint32_t() :: 0..4294967295.

Specs

uint64_t() :: 0..18446744073709551615.

Specs

uint8_t() :: 0..255.

Specs

waitstatus() :: {exit_status, int32_t()} | {termsig, atom()} | {stopsig, atom()} | continued.

Link to this section Functions

Specs

alloc(alcove_drv:ref(), [pid_t()], Ptr :: cstruct()) -> {ok, binary(), iodata()}.

Allocate memory

Test memory allocation.

Memory is allocated using a cstruct which is a list containing:

* binary: a value to be allocated and initialized in the memory

* {ptr, integer()}: create a pointer to 0 initialized memory

* {ptr, binary()}: create a pointer to memory initialized to the binary

The return value is an ok tuple:

* the atom ok

* a binary with the raw memory

* an initialized cstruct

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.182.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,4040}
 3> alcove:alloc(Drv, [Pid], [<<"initialized">>, {ptr, 16}, {ptr, <<"initialized">>}]).
 {ok,<<105,110,105,116,105,97,108,105,122,101,100,48,238,
       23,162,165,87,0,0,80,238,23,162,165,87,0,0>>,
     [<<"initialized">>,
      {ptr,<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>},
      {ptr,<<"initialized">>}]}

 % <<"initialized">>: 105,110,105,116,105,97,108,105,122,101,100
 % {ptr,<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>}: 48,238,23,162,165,87,0,0 (pointer)
 % {ptr,<<"initialized">>}: 80,238,23,162,165,87,0,0 (pointer)
Link to this function

alloc(Drv, Pids, Ptr, Timeout)

View Source

Specs

alloc(alcove_drv:ref(), [pid_t()], Ptr :: cstruct(), timeout()) -> {ok, binary(), iodata()}.

Allocate memory

Test memory allocation.

Memory is allocated using a cstruct which is a list containing:

* binary: a value to be allocated and initialized in the memory

* {ptr, integer()}: create a pointer to 0 initialized memory

* {ptr, binary()}: create a pointer to memory initialized to the binary

The return value is an ok tuple:

* the atom ok

* a binary with the raw memory

* an initialized cstruct

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.182.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,4040}
 3> alcove:alloc(Drv, [Pid], [<<"initialized">>, {ptr, 16}, {ptr, <<"initialized">>}]).
 {ok,<<105,110,105,116,105,97,108,105,122,101,100,48,238,
       23,162,165,87,0,0,80,238,23,162,165,87,0,0>>,
     [<<"initialized">>,
      {ptr,<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>},
      {ptr,<<"initialized">>}]}

 % <<"initialized">>: 105,110,105,116,105,97,108,105,122,101,100
 % {ptr,<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>}: 48,238,23,162,165,87,0,0 (pointer)
 % {ptr,<<"initialized">>}: 80,238,23,162,165,87,0,0 (pointer)

Specs

audit_arch() -> atom().

Get seccomp system architecture

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> alcove:audit_arch().
 audit_arch_x86_64
 3> alcove:define(Drv, [], alcove:audit_arch()).
 3221225534
Link to this function

cap_constant(Drv, Pids, Symbol)

View Source

Specs

cap_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> integer() | unknown.

Convert capsicum constants to integer

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.208.0>}
 2> alcove:cap_constant(Drv, [], cap_fcntl_setfl).
 16
Link to this function

cap_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

cap_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) -> integer() | unknown.

Convert capsicum constants to integer

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.208.0>}
 2> alcove:cap_constant(Drv, [], cap_fcntl_setfl).
 16

Specs

cap_enter(alcove_drv:ref(), [pid_t()]) -> ok | {error, posix()}.

cap_enter(2): place process into capability mode

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.208.0>}
 2> {ok, Pid1} = alcove:fork(Drv, []).
 {ok,75331}
 3> {ok, Pid2} = alcove:fork(Drv, []).
 {ok,75332}
 4> ok = alcove:cap_enter(Drv, [Pid1]).
 ok
 5> alcove:kill(Drv, [Pid1], 0, 0).
 {error,ecapmode}
 6> alcove:kill(Drv, [Pid2], 0, 0).
 ok
 7> alcove:kill(Drv, [], 0, 0).
 ok
Link to this function

cap_enter(Drv, Pids, Timeout)

View Source

Specs

cap_enter(alcove_drv:ref(), [pid_t()], timeout()) -> ok | {error, posix()}.

cap_enter(2): place process into capability mode

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.208.0>}
 2> {ok, Pid1} = alcove:fork(Drv, []).
 {ok,75331}
 3> {ok, Pid2} = alcove:fork(Drv, []).
 {ok,75332}
 4> ok = alcove:cap_enter(Drv, [Pid1]).
 ok
 5> alcove:kill(Drv, [Pid1], 0, 0).
 {error,ecapmode}
 6> alcove:kill(Drv, [Pid2], 0, 0).
 ok
 7> alcove:kill(Drv, [], 0, 0).
 ok
Link to this function

cap_fcntls_get(Drv, Pids, FD)

View Source

Specs

cap_fcntls_get(alcove_drv:ref(), [pid_t()], FD :: fd()) -> {ok, integer()} | {error, posix()}.

cap_fcntls_get(2): get allowed fcntl commands in capability mode

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,77853}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> ok = alcove:cap_enter(Drv, [Pid]).
 ok
 5> alcove:cap_fcntls_get(Drv, [Pid], FD).
 {ok,120}
Link to this function

cap_fcntls_get(Drv, Pids, FD, Timeout)

View Source

Specs

cap_fcntls_get(alcove_drv:ref(), [pid_t()], FD :: fd(), timeout()) ->
                  {ok, integer()} | {error, posix()}.

cap_fcntls_get(2): get allowed fcntl commands in capability mode

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,77853}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> ok = alcove:cap_enter(Drv, [Pid]).
 ok
 5> alcove:cap_fcntls_get(Drv, [Pid], FD).
 {ok,120}
Link to this function

cap_fcntls_limit(Drv, Pids, FD, Rights)

View Source

Specs

cap_fcntls_limit(alcove_drv:ref(), [pid_t()], FD :: fd(), Rights :: constant()) ->
                    ok | {error, posix()}.

cap_fcntls_limit(2): manage fcntl commands in capability mode

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,77853}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> ok = alcove:cap_enter(Drv, [Pid]).
 ok
 5> alcove:cap_fcntls_get(Drv, [Pid], FD).
 {ok,120}
 6> ok = alcove:cap_fcntls_limit(Drv, [Pid], FD, [cap_fcntl_setfl]).
 ok
 7> alcove:cap_fcntls_get(Drv, [Pid], FD).
 {ok,16}
Link to this function

cap_fcntls_limit(Drv, Pids, FD, Rights, Timeout)

View Source

Specs

cap_fcntls_limit(alcove_drv:ref(), [pid_t()], FD :: fd(), Rights :: constant(), timeout()) ->
                    ok | {error, posix()}.

cap_fcntls_limit(2): manage fcntl commands in capability mode

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,77853}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> ok = alcove:cap_enter(Drv, [Pid]).
 ok
 5> alcove:cap_fcntls_get(Drv, [Pid], FD).
 {ok,120}
 6> ok = alcove:cap_fcntls_limit(Drv, [Pid], FD, [cap_fcntl_setfl]).
 ok
 7> alcove:cap_fcntls_get(Drv, [Pid], FD).
 {ok,16}

Specs

cap_getmode(alcove_drv:ref(), [pid_t()]) -> {ok, 0 | 1} | {error, posix()}.

cap_getmode(2): check if capability mode is enabled

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,75710}
 3> ok = alcove:cap_enter(Drv, [Pid]).
 ok
 4> alcove:cap_getmode(Drv, [Pid]).
 {ok,1}
 5> alcove:cap_getmode(Drv, []).
 {ok,0}
Link to this function

cap_getmode(Drv, Pids, Timeout)

View Source

Specs

cap_getmode(alcove_drv:ref(), [pid_t()], timeout()) -> {ok, 0 | 1} | {error, posix()}.

cap_getmode(2): check if capability mode is enabled

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,75710}
 3> ok = alcove:cap_enter(Drv, [Pid]).
 ok
 4> alcove:cap_getmode(Drv, [Pid]).
 {ok,1}
 5> alcove:cap_getmode(Drv, []).
 {ok,0}
Link to this function

cap_ioctls_limit(Drv, Pids, FD, Rights)

View Source

Specs

cap_ioctls_limit(alcove_drv:ref(), [pid_t()], FD :: fd(), Rights :: constant()) ->
                    ok | {error, posix()}.

cap_ioctls_limit(2): manage allowed ioctl commands

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,75710}
 3> {ok, Pty} = alcove:open(Drv, [Pid], "/dev/pts/1", [o_rdwr, o_nonblock], 0).
 {ok,6}
 4> alcove:cap_enter(Drv, [Pid]).
 ok
 5> alcove:cap_ioctls_limit(Drv, [Pid], FD, [tiocmget, tiocgwinsz]).
 ok
 6> alcove:ioctl(Drv, [Pid], FD, tiocmset, <<>>).
 {error,enotcapable}
 7> alcove:ioctl(Drv, [Pid], FD, tiocmget, <<>>).
 {ok,0,<<>>}
Link to this function

cap_ioctls_limit(Drv, Pids, FD, Rights, Timeout)

View Source

Specs

cap_ioctls_limit(alcove_drv:ref(), [pid_t()], FD :: fd(), Rights :: constant(), timeout()) ->
                    ok | {error, posix()}.

cap_ioctls_limit(2): manage allowed ioctl commands

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,75710}
 3> {ok, Pty} = alcove:open(Drv, [Pid], "/dev/pts/1", [o_rdwr, o_nonblock], 0).
 {ok,6}
 4> alcove:cap_enter(Drv, [Pid]).
 ok
 5> alcove:cap_ioctls_limit(Drv, [Pid], FD, [tiocmget, tiocgwinsz]).
 ok
 6> alcove:ioctl(Drv, [Pid], FD, tiocmset, <<>>).
 {error,enotcapable}
 7> alcove:ioctl(Drv, [Pid], FD, tiocmget, <<>>).
 {ok,0,<<>>}
Link to this function

cap_rights_limit(Drv, Pids, FD, Rights)

View Source

Specs

cap_rights_limit(alcove_drv:ref(), [pid_t()], FD :: fd(), Rights :: constant()) ->
                    ok | {error, posix()}.

cap_rights_limit(2): manage process capabilities

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,75710}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> alcove:cap_enter(Drv, [Pid]).
 ok
 5> alcove:cap_rights_limit(Drv, [Pid], FD, [cap_read]).
 ok
 6> alcove:read(Drv, [Pid], FD, 64).
 {ok,<<"# $FreeBSD$\n#\nroot:*:0:0:Charlie &:/root:/bin/csh\ntoor:*:0:0:Bou">>}
 7> alcove:lseek(Drv, [Pid], FD, 0, 0).
 {error,enotcapable}
 8> alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {error,ecapmode}
Link to this function

cap_rights_limit(Drv, Pids, FD, Rights, Timeout)

View Source

Specs

cap_rights_limit(alcove_drv:ref(), [pid_t()], FD :: fd(), Rights :: constant(), timeout()) ->
                    ok | {error, posix()}.

cap_rights_limit(2): manage process capabilities

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,75710}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> alcove:cap_enter(Drv, [Pid]).
 ok
 5> alcove:cap_rights_limit(Drv, [Pid], FD, [cap_read]).
 ok
 6> alcove:read(Drv, [Pid], FD, 64).
 {ok,<<"# $FreeBSD$\n#\nroot:*:0:0:Charlie &:/root:/bin/csh\ntoor:*:0:0:Bou">>}
 7> alcove:lseek(Drv, [Pid], FD, 0, 0).
 {error,enotcapable}
 8> alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {error,ecapmode}

Specs

chdir(alcove_drv:ref(), [pid_t()], Path :: iodata()) -> ok | {error, posix()}.

chdir(2): change process current working directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18617}
 3> alcove:chdir(Drv, [Pid], "/tmp").
 ok
 4> alcove:chdir(Drv, [], "/").
 ok
 5> alcove:getcwd(Drv, [Pid]).
 {ok,<<"/tmp">>}
 6> alcove:getcwd(Drv, []).
 {ok,<<"/">>}
Link to this function

chdir(Drv, Pids, Path, Timeout)

View Source

Specs

chdir(alcove_drv:ref(), [pid_t()], Path :: iodata(), timeout()) -> ok | {error, posix()}.

chdir(2): change process current working directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18617}
 3> alcove:chdir(Drv, [Pid], "/tmp").
 ok
 4> alcove:chdir(Drv, [], "/").
 ok
 5> alcove:getcwd(Drv, [Pid]).
 {ok,<<"/tmp">>}
 6> alcove:getcwd(Drv, []).
 {ok,<<"/">>}
Link to this function

chmod(Drv, Pids, Path, Mode)

View Source

Specs

chmod(alcove_drv:ref(), [pid_t()], Path :: iodata(), Mode :: mode_t()) -> ok | {error, posix()}.

chmod(2): change file permissions

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/tmp/foo123.txt", [o_wronly, o_creat], 8#644).
 {ok,6}
 4> alcove:chmod(Drv, [Pid], "/tmp/foo123.txt", 8#400).
 ok
Link to this function

chmod(Drv, Pids, Path, Mode, Timeout)

View Source

Specs

chmod(alcove_drv:ref(), [pid_t()], Path :: iodata(), Mode :: mode_t(), timeout()) ->
         ok | {error, posix()}.

chmod(2): change file permissions

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/tmp/foo123.txt", [o_wronly, o_creat], 8#644).
 {ok,6}
 4> alcove:chmod(Drv, [Pid], "/tmp/foo123.txt", 8#400).
 ok
Link to this function

chown(Drv, Pids, Path, Owner, Group)

View Source

Specs

chown(alcove_drv:ref(), [pid_t()], Path :: iodata(), Owner :: uid_t(), Group :: gid_t()) ->
         ok | {error, posix()}.

chown(2): change file ownership

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/tmp/foo123.txt", [o_wronly, o_creat], 8#644).
 {ok,6}
 6> alcove:chown(Drv, [Pid], "/tmp/foo123.txt", 0, 0).
 ok
Link to this function

chown(Drv, Pids, Path, Owner, Group, Timeout)

View Source

Specs

chown(alcove_drv:ref(),
      [pid_t()],
      Path :: iodata(),
      Owner :: uid_t(),
      Group :: gid_t(),
      timeout()) ->
         ok | {error, posix()}.

chown(2): change file ownership

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/tmp/foo123.txt", [o_wronly, o_creat], 8#644).
 {ok,6}
 6> alcove:chown(Drv, [Pid], "/tmp/foo123.txt", 0, 0).
 ok

Specs

chroot(alcove_drv:ref(), [pid_t()], Path :: iodata()) -> ok | {error, posix()}.

chroot(2): change root directory

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:chroot(Drv, [Pid], "/tmp").
 ok
 4> alcove:chdir(Drv, [Pid], "/").
 ok
 5> alcove:getcwd(Drv, [Pid]).
 {ok,<<"/">>}
Link to this function

chroot(Drv, Pids, Path, Timeout)

View Source

Specs

chroot(alcove_drv:ref(), [pid_t()], Path :: iodata(), timeout()) -> ok | {error, posix()}.

chroot(2): change root directory

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:chroot(Drv, [Pid], "/tmp").
 ok
 4> alcove:chdir(Drv, [Pid], "/").
 ok
 5> alcove:getcwd(Drv, [Pid]).
 {ok,<<"/">>}

Specs

clearenv(alcove_drv:ref(), [pid_t()]) -> ok | {error, posix()}.

clearenv(3): zero process environment

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:clearenv(Drv, [Pid]).
 ok
 4> alcove:environ(Drv, [Pid]).
 []
Link to this function

clearenv(Drv, Pids, Timeout)

View Source

Specs

clearenv(alcove_drv:ref(), [pid_t()], timeout()) -> ok | {error, posix()}.

clearenv(3): zero process environment

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:clearenv(Drv, [Pid]).
 ok
 4> alcove:environ(Drv, [Pid]).
 []

Specs

clone(alcove_drv:ref(), [pid_t()], Flags :: int32_t() | [constant()]) ->
         {ok, pid_t()} | {error, posix()}.

clone(2): create a new process

Support

* Linux

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newns, clone_newpid, clone_newipc, clone_newuts, clone_newnet]).
 {ok,19127}
 3> alcove:getpid(Drv, [Pid]).
 1
Link to this function

clone(Drv, Pids, Flags, Timeout)

View Source

Specs

clone(alcove_drv:ref(), [pid_t()], Flags :: int32_t() | [constant()], timeout()) ->
         {ok, pid_t()} | {error, posix()}.

clone(2): create a new process

Support

* Linux

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newns, clone_newpid, clone_newipc, clone_newuts, clone_newnet]).
 {ok,19127}
 3> alcove:getpid(Drv, [Pid]).
 1
Link to this function

clone_constant(Drv, Pids, Symbol)

View Source

Specs

clone_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> unknown | int32_t().

Map clone(2) symbols to integer constants

Support

* Linux

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:clone_constant(Drv, [19127], clone_newuts).
 67108864
Link to this function

clone_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

clone_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) -> unknown | int32_t().

Map clone(2) symbols to integer constants

Support

* Linux

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:clone_constant(Drv, [19127], clone_newuts).
 67108864

Specs

close(alcove_drv:ref(), [pid_t()], FD :: fd()) -> ok | {error, posix()}.

close(2): close a file descriptor

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/tmp/foo123.txt", [o_wronly, o_creat], 8#644).
 {ok,6}
 4> alcove:close(Drv, [Pid], FD).
 ok
Link to this function

close(Drv, Pids, FD, Timeout)

View Source

Specs

close(alcove_drv:ref(), [pid_t()], FD :: fd(), timeout()) -> ok | {error, posix()}.

close(2): close a file descriptor

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/tmp/foo123.txt", [o_wronly, o_creat], 8#644).
 {ok,6}
 4> alcove:close(Drv, [Pid], FD).
 ok
Link to this function

connect(Drv, Pids, FD, Sockaddr)

View Source

Specs

connect(alcove_drv:ref(), [pid_t()], FD :: fd(), Sockaddr :: [] | cstruct()) ->
           ok | {error, posix()}.

connect(2): initiate a connection on a socket

Examples

 -module(unix_socket).

 -export([connect]).

 connect(Data) when is_binary(Data) ->
     {ok, Drv} = alcove:start(),
     {ok, NC} = alcove:fork(Drv, []),
     {ok, Process} = alcove:fork(Drv, []),

     Sockname = <<"/tmp/test.", (integer_to_binary(alcove:getpid(Drv, [])))/binary>>,
     ok = alcove:execvp(Drv, [NC], "nc", ["nc", "-l", "-U", Sockname]),

     ok = waitfor(Sockname),

     {ok, Socket} = alcove:socket(Drv, [Process], af_unix, sock_stream, 0),

     % #define UNIX_PATH_MAX   108
     % struct sockaddr_un {
     % 	__kernel_sa_family_t sun_family; /* AF_UNIX */
     % 	char sun_path[UNIX_PATH_MAX];   /* pathname */
     % };
     AF_UNIX = 1,
     SocknameLen = byte_size(Sockname),
     Len = (unix_path_max() - SocknameLen) * 8,
     ok = alcove:connect(Drv, [Process], Socket, [
         sockaddr_common(AF_UNIX, SocknameLen),
         Sockname,
         <<0:Len>>
     ]),

     % alcove process -> nc
     {ok, N} = alcove:write(Drv, [Process], Socket, Data),
     receive
         {alcove_stdout, Drv, [NC], Stdout} ->
             Stdout
     end.

 % UNIX_PATH_MAX
 unix_path_max() ->
     case erlang:system_info(os_type) of
         {unix, BSD} when BSD == darwin; BSD == openbsd; BSD == netbsd; BSD == freebsd ->
             104;
         {unix, _} ->
             108
     end.

 % struct sockaddr
 sockaddr_common(Family, Length) ->
     case erlang:system_info(os_type) of
         {unix, BSD} when BSD == darwin; BSD == openbsd; BSD == netbsd; BSD == freebsd ->
             <<Length:8, Family:8>>;
         {unix, _} ->
             <<Family:16/native>>
     end.

 waitfor(Sockname) ->
     case file:read_file_info(Sockname) of
         {ok, _} ->
             ok;
         {error, enoent} ->
             timer:sleep(1),
             waitfor(Sockname);
         {error, eperm} ->
             ok;
         Error ->
             Error
     end.
Link to this function

connect(Drv, Pids, FD, Sockaddr, Timeout)

View Source

Specs

connect(alcove_drv:ref(), [pid_t()], FD :: fd(), Sockaddr :: [] | cstruct(), timeout()) ->
           ok | {error, posix()}.

connect(2): initiate a connection on a socket

Examples

 -module(unix_socket).

 -export([connect]).

 connect(Data) when is_binary(Data) ->
     {ok, Drv} = alcove:start(),
     {ok, NC} = alcove:fork(Drv, []),
     {ok, Process} = alcove:fork(Drv, []),

     Sockname = <<"/tmp/test.", (integer_to_binary(alcove:getpid(Drv, [])))/binary>>,
     ok = alcove:execvp(Drv, [NC], "nc", ["nc", "-l", "-U", Sockname]),

     ok = waitfor(Sockname),

     {ok, Socket} = alcove:socket(Drv, [Process], af_unix, sock_stream, 0),

     % #define UNIX_PATH_MAX   108
     % struct sockaddr_un {
     % 	__kernel_sa_family_t sun_family; /* AF_UNIX */
     % 	char sun_path[UNIX_PATH_MAX];   /* pathname */
     % };
     AF_UNIX = 1,
     SocknameLen = byte_size(Sockname),
     Len = (unix_path_max() - SocknameLen) * 8,
     ok = alcove:connect(Drv, [Process], Socket, [
         sockaddr_common(AF_UNIX, SocknameLen),
         Sockname,
         <<0:Len>>
     ]),

     % alcove process -> nc
     {ok, N} = alcove:write(Drv, [Process], Socket, Data),
     receive
         {alcove_stdout, Drv, [NC], Stdout} ->
             Stdout
     end.

 % UNIX_PATH_MAX
 unix_path_max() ->
     case erlang:system_info(os_type) of
         {unix, BSD} when BSD == darwin; BSD == openbsd; BSD == netbsd; BSD == freebsd ->
             104;
         {unix, _} ->
             108
     end.

 % struct sockaddr
 sockaddr_common(Family, Length) ->
     case erlang:system_info(os_type) of
         {unix, BSD} when BSD == darwin; BSD == openbsd; BSD == netbsd; BSD == freebsd ->
             <<Length:8, Family:8>>;
         {unix, _} ->
             <<Family:16/native>>
     end.

 waitfor(Sockname) ->
     case file:read_file_info(Sockname) of
         {ok, _} ->
             ok;
         {error, enoent} ->
             timer:sleep(1),
             waitfor(Sockname);
         {error, eperm} ->
             ok;
         Error ->
             Error
     end.

Specs

cpid(alcove_drv:ref(), [pid_t()]) -> [alcove_pid()].

Returns the list of child PIDs for this process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid1} = alcove:fork(Drv, []).
 {ok,19048}
 3> {ok, Pid2} = alcove:fork(Drv, []).
 {ok,19127}
 4> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 5> alcove:cpid(Drv, [Pid1]).
 []
 6> alcove:cpid(Drv, []).
 [#alcove_pid{pid = 19048,flowcontrol = -1,signaloneof = 15,
              fdctl = 7,stdin = 9,stdout = 10,stderr = 12},
  #alcove_pid{pid = 19127,flowcontrol = -1,signaloneof = 15,
              fdctl = 8,stdin = 13,stdout = 14,stderr = 16}]
Link to this function

cpid(Drv, Pids, Timeout)

View Source

Specs

cpid(alcove_drv:ref(), [pid_t()], timeout()) -> [alcove_pid()].

Returns the list of child PIDs for this process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid1} = alcove:fork(Drv, []).
 {ok,19048}
 3> {ok, Pid2} = alcove:fork(Drv, []).
 {ok,19127}
 4> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 5> alcove:cpid(Drv, [Pid1]).
 []
 6> alcove:cpid(Drv, []).
 [#alcove_pid{pid = 19048,flowcontrol = -1,signaloneof = 15,
              fdctl = 7,stdin = 9,stdout = 10,stderr = 12},
  #alcove_pid{pid = 19127,flowcontrol = -1,signaloneof = 15,
              fdctl = 8,stdin = 13,stdout = 14,stderr = 16}]
Link to this function

define(Drv, Pipeline, Constant)

View Source

Specs

define(alcove_drv:ref(), [pid_t()], atom() | [atom()]) -> integer().

Convert constant to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> alcove:define(Drv, [], clone_newns).
 131072

Specs

environ(alcove_drv:ref(), [pid_t()]) -> [binary()].

environ(7): return the process environment variables

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> alcove:environ(Drv, []).
 [<<"LANG=C.UTF-8">>,
  <<"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin">>,
  <<"TERM=screen">>, <<"SHELL=/bin/bash">>]
Link to this function

environ(Drv, Pids, Timeout)

View Source

Specs

environ(alcove_drv:ref(), [pid_t()], timeout()) -> [binary()].

environ(7): return the process environment variables

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> alcove:environ(Drv, []).
 [<<"LANG=C.UTF-8">>,
  <<"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin">>,
  <<"TERM=screen">>, <<"SHELL=/bin/bash">>]

Specs

eof(alcove_drv:ref(), [pid_t()]) -> ok | {error, posix()}.

Close stdin of the process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:execvp(Drv, [Pid], "cat", ["cat"]).
 ok
 4> alcove:eof(Drv, [Pid]).
 ok
 5> alcove:event(Drv, [Pid]).
 {exit_status,0}

Specs

eof(alcove_drv:ref(), [pid_t()], stdin | stdout | stderr) -> ok | {error, posix()}.

Close stdin, stdout or stderr of the process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:execvp(Drv, [Pid], "cat", ["cat"]).
 ok
 4> alcove:eof(Drv, [Pid], stdin).
 ok
 5> alcove:event(Drv, [Pid]).
 {exit_status,0}
Link to this function

errno_id(Drv, Pids, Errno)

View Source

Specs

errno_id(alcove_drv:ref(), [pid_t()], Errno :: int32_t()) -> posix().

Convert errno integer to atom

Examples

 1> alcove:errno_id(Drv, [], 1).
 eperm
Link to this function

errno_id(Drv, Pids, Errno, Timeout)

View Source

Specs

errno_id(alcove_drv:ref(), [pid_t()], Errno :: int32_t(), timeout()) -> posix().

Convert errno integer to atom

Examples

 1> alcove:errno_id(Drv, [], 1).
 eperm

Specs

event(alcove_drv:ref(), [pid_t()]) -> term().

Get events generated by alcove port process

event/1,2 is used to retrieve async messages returned from the port, such as caught signals, the exit status or the termination signal.

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:kill(Drv, [], Pid, 15).
 ok
 4> alcove:event(Drv, [Pid]).
 {signal,sigterm,
         <<15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,74,0,0,0,0,0,0,0,
                   0,...>>}
Link to this function

event(Drv, Pids, Timeout)

View Source

Specs

event(alcove_drv:ref(), [pid_t()], timeout()) -> term().

Get events generated by alcove port process

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,19048}
 3> alcove:kill(Drv, [], Pid, 15).
 ok
 4> alcove:event(Drv, [Pid], 5000).
 {signal,sigterm,
         <<15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,74,0,0,0,0,0,0,0,
                   0,...>>}
 5> alcove:event(Drv, [Pid], 5000).
 false
Link to this function

execve(Drv, Pids, Arg0, Argv, Env)

View Source

Specs

execve(alcove_drv:ref(), [pid_t()], Arg0 :: iodata(), Argv :: [iodata()], Env :: [iodata()]) ->
          ok | {error, posix()}.

execve(2): replace process image with environment

Replace the process image, specifying the environment for the new process image.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,29037}
 3> alcove:execve(Drv, [Pid], "/usr/bin/env", ["env"], ["FOO=123"]).
 ok

 % Shell got {alcove_stdout,<0.176.0>,[29037],<<"FOO=123\n">>}
 % Shell got {alcove_event,<0.176.0>,[29037],{exit_status,0}}

 4> alcove:stdout(Drv, [Pid]).
 [<<"FOO=123\n">>]
 5> alcove:event(Drv, [Pid], 5000).
 {exit_status,0}
 ok
Link to this function

execve(Drv, Pids, Arg0, Argv, Env, Timeout)

View Source

Specs

execve(alcove_drv:ref(),
       [pid_t()],
       Arg0 :: iodata(),
       Argv :: [iodata()],
       Env :: [iodata()],
       timeout()) ->
          ok | {error, posix()}.

execve(2): replace process image with environment

Replace the process image, specifying the environment for the new process image.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,29037}
 3> alcove:execve(Drv, [Pid], "/usr/bin/env", ["env"], ["FOO=123"]).
 ok

 % Shell got {alcove_stdout,<0.176.0>,[29037],<<"FOO=123\n">>}
 % Shell got {alcove_event,<0.176.0>,[29037],{exit_status,0}}

 4> alcove:stdout(Drv, [Pid]).
 [<<"FOO=123\n">>]
 5> alcove:event(Drv, [Pid], 5000).
 {exit_status,0}
 ok
Link to this function

execvp(Drv, Pids, Arg0, Argv)

View Source

Specs

execvp(alcove_drv:ref(), [pid_t()], Arg0 :: iodata(), Argv :: [iodata()]) -> ok | {error, posix()}.

execvp(2): replace the current process image using the search path

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,29087}
 3> alcove:execvp(Drv, [Pid], "cat", ["cat"]).
 ok
 4> alcove:stdin(Drv, [Pid], "test\n").
 ok
 5> alcove:stdout(Drv, [Pid]).
 [<<"test\n">>]
 6> alcove:stdin(Drv, [Pid], "123\n").
 ok
 7> flush().
 Shell got {alcove_stdout,<0.176.0>,[29087],<<"123\n">>}
 ok
Link to this function

execvp(Drv, Pids, Arg0, Argv, Timeout)

View Source

Specs

execvp(alcove_drv:ref(), [pid_t()], Arg0 :: iodata(), Argv :: [iodata()], timeout()) ->
          ok | {error, posix()}.

execvp(2): replace the current process image using the search path

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,29087}
 3> alcove:execvp(Drv, [Pid], "cat", ["cat"]).
 ok
 4> alcove:stdin(Drv, [Pid], "test\n").
 ok
 5> alcove:stdout(Drv, [Pid]).
 [<<"test\n">>]
 6> alcove:stdin(Drv, [Pid], "123\n").
 ok
 7> flush().
 Shell got {alcove_stdout,<0.176.0>,[29087],<<"123\n">>}
 ok

Specs

exit(alcove_drv:ref(), [pid_t()], Status :: int32_t()) -> ok.

exit(3): cause an alcove control process to exit

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,30973}
 3> alcove:exit(Drv, [Pid], 111).
 ok
 4> flush().
 Shell got {alcove_event,<0.176.0>,[30973],{exit_status,111}}
 ok
Link to this function

exit(Drv, Pids, Status, Timeout)

View Source

Specs

exit(alcove_drv:ref(), [pid_t()], Status :: int32_t(), timeout()) -> ok.

exit(3): cause an alcove control process to exit

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,30973}
 3> alcove:exit(Drv, [Pid], 111).
 ok
 4> flush().
 Shell got {alcove_event,<0.176.0>,[30973],{exit_status,111}}
 ok
Link to this function

fcntl(Drv, Pids, FD, Cmd, Arg)

View Source

Specs

fcntl(alcove_drv:ref(), [pid_t()], FD :: fd(), Cmd :: constant(), Arg :: int64_t()) ->
         {ok, int64_t()} | {error, posix()}.

fcntl(2): perform operations on a file descriptor

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,31012}

 % stdin = 0
 3> alcove:fcntl(Drv, [Pid], 0, f_getfd, 0).
 {ok,0}
Link to this function

fcntl(Drv, Pids, FD, Cmd, Arg, Timeout)

View Source

Specs

fcntl(alcove_drv:ref(), [pid_t()], FD :: fd(), Cmd :: constant(), Arg :: int64_t(), timeout()) ->
         {ok, int64_t()} | {error, posix()}.

fcntl(2): perform operations on a file descriptor

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.176.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,31012}

 % stdin = 0
 3> alcove:fcntl(Drv, [Pid], 0, f_getfd, 0).
 {ok,0}
Link to this function

fcntl_constant(Drv, Pids, Symbol)

View Source

Specs

fcntl_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> integer() | unknown.

Convert fnctl(2) constant to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> alcove:fcntl_constant(Drv, [], fd_cloexec).
 1
Link to this function

fcntl_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

fcntl_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) -> integer() | unknown.

Convert fnctl(2) constant to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.176.0>}
 2> alcove:fcntl_constant(Drv, [], fd_cloexec).
 1
Link to this function

fexecve(Drv, Pids, FD, Argv, Env)

View Source

Specs

fexecve(alcove_drv:ref(), [pid_t()], FD :: fd(), Argv :: [iodata()], Env :: [iodata()]) ->
           ok | {error, posix()}.

fexecve(2): replace the process image

Replace the process image, specifying the environment for the new process image, using a previously opened file descriptor. The file descriptor can be set to close after exec() by passing the O_CLOEXEC flag to open:

 {ok, Pid} = alcove:fork(Drv, []),
 {ok, FD} = alcove:open(Drv, [Pid], "/bin/ls", [o_rdonly,o_cloexec], 0),
 ok = alcove:fexecve(Drv, [Pid], FD, ["ls", "-al"], ["FOO=123"]).

Linux requires an environment to be set unlike with execve(2). The environment can be empty:

 % Environment required on Linux
 ok = alcove:fexecve(Drv, [Pid], FD, ["ls", "-al"], [""]).

Support

* Linux

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,31491}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/usr/bin/env", [o_rdonly,o_cloexec], 0).
 {ok,6}
 4> alcove:fexecve(Drv, [Pid], FD, ["env", "-0"], ["FOO=123"]).
 ok
 5> flush().
 Shell got {alcove_stdout,<0.177.0>,[31491],<<70,79,79,61,49,50,51,0>>}
 Shell got {alcove_event,<0.177.0>,[31491],{exit_status,0}}
 ok
Link to this function

fexecve(Drv, Pids, FD, Argv, Env, Timeout)

View Source

Specs

fexecve(alcove_drv:ref(), [pid_t()], FD :: fd(), Argv :: [iodata()], Env :: [iodata()], timeout()) ->
           ok | {error, posix()}.

fexecve(2): replace the process image

Replace the process image, specifying the environment for the new process image, using a previously opened file descriptor. The file descriptor can be set to close after exec() by passing the O_CLOEXEC flag to open:

 {ok, Pid} = alcove:fork(Drv, []),
 {ok, FD} = alcove:open(Drv, [Pid], "/bin/ls", [o_rdonly,o_cloexec], 0),
 ok = alcove:fexecve(Drv, [Pid], FD, ["ls", "-al"], ["FOO=123"]).

Linux requires an environment to be set unlike with execve(2). The environment can be empty:

 % Environment required on Linux
 ok = alcove:fexecve(Drv, [Pid], FD, ["ls", "-al"], [""]).

Support

* Linux

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,31491}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/usr/bin/env", [o_rdonly,o_cloexec], 0).
 {ok,6}
 4> alcove:fexecve(Drv, [Pid], FD, ["env", "-0"], ["FOO=123"]).
 ok
 5> flush().
 Shell got {alcove_stdout,<0.177.0>,[31491],<<70,79,79,61,49,50,51,0>>}
 Shell got {alcove_event,<0.177.0>,[31491],{exit_status,0}}
 ok
Link to this function

file_constant(Drv, Pids, Symbol)

View Source

Specs

file_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> non_neg_integer() | unknown.

Constants for open(2)

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:file_constant(Drv, [], o_rdonly).
 0
Link to this function

file_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

file_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) ->
                 non_neg_integer() | unknown.

Constants for open(2)

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:file_constant(Drv, [], o_rdonly).
 0

Specs

filter(filter()) -> binary().

Create a call filter list

Generate a list of calls to filter for filter/3,4. By default, calls are blocked. To restrict the alcove control process to a subset of calls, use the allow tuple:

 # alcove process restricted to fork, clone, getpid
 alcove:filter({allow, [fork, clone, getpid]})

Examples

 1> alcove:filter({allow, [fork, clone, getpid]}).
 <<255,223,255,239,239,255,255,255,255,255,255,255,15>>
 2> alcove:filter([fork, clone, getpid]).
 <<0,32,0,16,16>>
 3> alcove:filter({deny, [fork, clone, getpid]}).
 <<0,32,0,16,16>>
Link to this function

filter(Drv, Pids, Calls)

View Source

Specs

filter(alcove_drv:ref(), [pid_t()], [] | binary()) -> ok | {error, einval}.

Restrict calls available to an alcove control process

filter/3 restrict calls available to an alcove control process. Restricted control processes continue to proxy data and monitor and reap subprocesses.

Invoking a filtered call will crash the process with 'undef'.

If the filter call is filtered, subsequent calls to filter/3,4 will fail.

Once added, the call cannot be removed from the filter set. Passing an empty list ([]) specifies the current filter set should not be modified.

Filters are inherited by the child process from the parent. filter/3 specifies the subprocess should use the same filter as the parent:

 1> catch_exception(true).
 false
 2> {ok, Drv} = alcove_drv:start().
 {ok,<0.179.0>}
 3> {ok, Pid} = alcove:fork(Drv, []).
 {ok,16464}
 4> Filter = alcove:filter([fork]).
 <<0,0,0,16>>
 % equivalent to: alcove:filter(Drv, [], Filter, Filter)
 5> alcove:filter(Drv, [], Filter).
 ok
 6> alcove:fork(Drv, [Pid]).
 * exception error: undefined function alcove:fork/2
Link to this function

filter(Drv, Pids, Calls, Calls)

View Source

Specs

filter(alcove_drv:ref(), [pid_t()], Calls :: [] | binary(), Calls :: [] | binary()) ->
          ok | {error, einval}.

Restrict available calls for control and subprocess

filter/4 allows setting different filters for the control and subprocesses:

Examples

 1> catch_exception(true).
 false
 2> {ok, Drv} = alcove_drv:start().
 {ok,<0.189.0>}
 3> F1 = alcove:filter({allow, [fork,filter,getcwd]}).
 <<255,255,255,231,239,255,255,255,255,255,255,255,15>>
 4> F2 = alcove:filter({allow, [getpid,gethostname]}).
 <<255,255,255,223,237,255,255,255,255,255,255,255,15>>
 % Control process: restricted to: fork, filter
 % Any forked control subprocess: restricted to: getpid, gethostname
 5> alcove:filter(Drv, [], F1, F2).
 ok
 6> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18721}
 7> alcove:getpid(Drv, [Pid]).
 18721
 8> alcove:getpid(Drv, []).
 * exception error: undefined function alcove:getpid/2
 9> alcove:getcwd(Drv, [Pid]).
 * exception error: undefined function alcove:getcwd/2
 10> alcove:getcwd(Drv, []).
 {ok, <<"/">>}
Link to this function

filter(Drv, Pids, Calls, Calls, Timeout)

View Source

Specs

filter(alcove_drv:ref(), [pid_t()], Calls :: [] | binary(), Calls :: [] | binary(), timeout()) ->
          ok | {error, einval}.

Restrict available calls for control and subprocess

filter/4 allows setting different filters for the control and subprocesses:

Examples

 1> catch_exception(true).
 false
 2> {ok, Drv} = alcove_drv:start().
 {ok,<0.189.0>}
 3> F1 = alcove:filter({allow, [fork,filter,getcwd]}).
 <<255,255,255,231,239,255,255,255,255,255,255,255,15>>
 4> F2 = alcove:filter({allow, [getpid,gethostname]}).
 <<255,255,255,223,237,255,255,255,255,255,255,255,15>>
 % Control process: restricted to: fork, filter
 % Any forked control subprocess: restricted to: getpid, gethostname
 5> alcove:filter(Drv, [], F1, F2).
 ok
 6> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18721}
 7> alcove:getpid(Drv, [Pid]).
 18721
 8> alcove:getpid(Drv, []).
 * exception error: undefined function alcove:getpid/2
 9> alcove:getcwd(Drv, [Pid]).
 * exception error: undefined function alcove:getcwd/2
 10> alcove:getcwd(Drv, []).
 {ok, <<"/">>}

Specs

fork(alcove_drv:ref(), [pid_t()]) -> {ok, pid_t()} | {error, posix()}.

fork(2): create a new process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.189.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18721}
 3> alcove:getpid(Drv, [Pid]).
 18721
Link to this function

fork(Drv, Pids, Timeout)

View Source

Specs

fork(alcove_drv:ref(), [pid_t()], timeout()) -> {ok, pid_t()} | {error, posix()}.

fork(2): create a new process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.189.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18721}
 3> alcove:getpid(Drv, [Pid]).
 18721
Link to this function

getcpid(Drv, Pids, Pid, Key)

View Source

Specs

getcpid(alcove_drv:ref(), [pid_t()], pid_t(), alcove_pid_field()) -> false | int32_t().

Get control process attributes

Retrieves attributes set by the alcove control process for a child process.

* flowcontrol

Number of messages allowed from process:

-1 : flowcontrol disabled

0 : stdout/stderr for process is not read

1+ : read this many messages from the process

* signaloneof

Signal sent to child process on shutdown.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,3925}
 3> alcove:getcpid(Drv, [], Pid, flowcontrol).
 -1

Specs

getcwd(alcove_drv:ref(), [pid_t()]) -> {ok, binary()} | {error, posix()}.

getcwd(3): return the current working directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,3925}
 3> alcove:chdir(Drv, [Pid], "/").
 ok
 4> alcove:getcwd(Drv, [Pid]).
 {ok,<<"/">>}
Link to this function

getcwd(Drv, Pids, Timeout)

View Source

Specs

getcwd(alcove_drv:ref(), [pid_t()], timeout()) -> {ok, binary()} | {error, posix()}.

getcwd(3): return the current working directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,3925}
 3> alcove:chdir(Drv, [Pid], "/").
 ok
 4> alcove:getcwd(Drv, [Pid]).
 {ok,<<"/">>}

Specs

getenv(alcove_drv:ref(), [pid_t()], Name :: iodata()) -> binary() | false.

getenv(3): retrieve an environment variable

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getenv(Drv, [], "TERM").
 <<"screen">>
Link to this function

getenv(Drv, Pids, Name, Timeout)

View Source

Specs

getenv(alcove_drv:ref(), [pid_t()], Name :: iodata(), timeout()) -> binary() | false.

getenv(3): retrieve an environment variable

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getenv(Drv, [], "TERM").
 <<"screen">>

Specs

getgid(alcove_drv:ref(), [pid_t()]) -> gid_t().

getgid(2): retrieve the process group ID

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getgid(Drv, []).
 1000
Link to this function

getgid(Drv, Pids, Timeout)

View Source

Specs

getgid(alcove_drv:ref(), [pid_t()], timeout()) -> gid_t().

getgid(2): retrieve the process group ID

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getgid(Drv, []).
 1000

Specs

getgroups(alcove_drv:ref(), [pid_t()]) -> {ok, [gid_t()]} | {error, posix()}.

getgroups(2): retrieve the list of supplementary groups

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getgroups(Drv, []).
 {ok,[24,20,1000]}
Link to this function

getgroups(Drv, Pids, Timeout)

View Source

Specs

getgroups(alcove_drv:ref(), [pid_t()], timeout()) -> {ok, [gid_t()]} | {error, posix()}.

getgroups(2): retrieve the list of supplementary groups

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getgroups(Drv, []).
 {ok,[24,20,1000]}

Specs

gethostname(alcove_drv:ref(), [pid_t()]) -> {ok, binary()} | {error, posix()}.

gethostname(2): retrieve the system hostname

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:gethostname(Drv, []).
 {ok,<<"host1">>}
Link to this function

gethostname(Drv, Pids, Timeout)

View Source

Specs

gethostname(alcove_drv:ref(), [pid_t()], timeout()) -> {ok, binary()} | {error, posix()}.

gethostname(2): retrieve the system hostname

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:gethostname(Drv, []).
 {ok,<<"host1">>}

Specs

getopt(alcove_drv:ref(), [pid_t()], Opt :: atom()) -> false | int32_t().

Retrieve port options for event loop

Options are configurable per process, with the default settings inherited from the parent.

The initial values for these options are set for the port by alcove_drv:start/1.

* maxchild : non_neg_integer() : (ulimit -n) / 4 - 4

Number of child processes allowed for this process. This value can be modified by adjusting RLIMIT_NOFILE for the process.

* exit_status : 1 | 0 : 1

Controls whether the controlling Erlang process is informed of a process exit value.

* maxforkdepth : non_neg_integer() : 16

Sets the maximum length of the alcove process pipeline.

* termsig : 1 | 0 : 1

If a child process exits because of a signal, notify the controlling Erlang process.

* flowcontrol : int32_t() : -1 (disabled)

Sets the default flow control behaviour for a newly forked process. Flow control is applied after the child process calls exec().

See setcpid/5.

* signaloneof : 0-255 : 15

Send a signal to a child process on shutdown (stdin of the alcove control process is closed).

See setcpid/5.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getopt(Drv, [], maxforkdepth).
 16
Link to this function

getopt(Drv, Pids, Opt, Timeout)

View Source

Specs

getopt(alcove_drv:ref(), [pid_t()], Opt :: atom(), timeout()) -> false | int32_t().

Retrieve port options for event loop

Options are configurable per process, with the default settings inherited from the parent.

The initial values for these options are set for the port by alcove_drv:start/1.

* maxchild : non_neg_integer() : (ulimit -n) / 4 - 4

Number of child processes allowed for this process. This value can be modified by adjusting RLIMIT_NOFILE for the process.

* exit_status : 1 | 0 : 1

Controls whether the controlling Erlang process is informed of a process exit value.

* maxforkdepth : non_neg_integer() : 16

Sets the maximum length of the alcove process pipeline.

* termsig : 1 | 0 : 1

If a child process exits because of a signal, notify the controlling Erlang process.

* flowcontrol : int32_t() : -1 (disabled)

Sets the default flow control behaviour for a newly forked process. Flow control is applied after the child process calls exec().

See setcpid/5.

* signaloneof : 0-255 : 15

Send a signal to a child process on shutdown (stdin of the alcove control process is closed).

See setcpid/5.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getopt(Drv, [], maxforkdepth).
 16

Specs

getpgrp(alcove_drv:ref(), [pid_t()]) -> pid_t().

getpgrp(2): retrieve the process group

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getpgrp(Drv, []).
 3924
Link to this function

getpgrp(Drv, Pids, Timeout)

View Source

Specs

getpgrp(alcove_drv:ref(), [pid_t()], timeout()) -> pid_t().

getpgrp(2): retrieve the process group

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getpgrp(Drv, []).
 3924

Specs

getpid(alcove_drv:ref(), [pid_t()]) -> pid_t().

getpid(2): retrieve the system PID of the process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getpid(Drv, []).
 3924
Link to this function

getpid(Drv, Pids, Timeout)

View Source

Specs

getpid(alcove_drv:ref(), [pid_t()], timeout()) -> pid_t().

getpid(2): retrieve the system PID of the process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getpid(Drv, []).
 3924
Link to this function

getpriority(Drv, Pids, Which, Who)

View Source

Specs

getpriority(alcove_drv:ref(), [pid_t()], Which :: constant(), Who :: int32_t()) ->
               {ok, int32_t()} | {error, posix()}.

getpriority(2): retrieve scheduling priority of process, process group or user

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getpriority(Drv, [], prio_process, 0).
 {ok,0}
Link to this function

getpriority(Drv, Pids, Which, Who, Timeout)

View Source

Specs

getpriority(alcove_drv:ref(), [pid_t()], Which :: constant(), Who :: int32_t(), timeout()) ->
               {ok, int32_t()} | {error, posix()}.

getpriority(2): retrieve scheduling priority of process, process group or user

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getpriority(Drv, [], prio_process, 0).
 {ok,0}

Specs

getresgid(alcove_drv:ref(), [pid_t()]) ->
             {ok, Real :: gid_t(), Effective :: gid_t(), Saved :: gid_t()} | {error, posix()}.

getresgid(2): get real, effective and saved group ID

Support

* Linux

* OpenBSD

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getresgid(Drv, []).
 {ok,1000,1000,1000}
Link to this function

getresgid(Drv, Pids, Timeout)

View Source

Specs

getresgid(alcove_drv:ref(), [pid_t()], timeout()) ->
             {ok, Real :: gid_t(), Effective :: gid_t(), Saved :: gid_t()} | {error, posix()}.

getresgid(2): get real, effective and saved group ID

Support

* Linux

* OpenBSD

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getresgid(Drv, []).
 {ok,1000,1000,1000}

Specs

getresuid(alcove_drv:ref(), [pid_t()]) ->
             {ok, Real :: uid_t(), Effective :: uid_t(), Saved :: uid_t()} | {error, posix()}.

getresuid(2): get real, effective and saved user ID

Support

* Linux

* OpenBSD

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getresuid(Drv, []).
 {ok,1000,1000,1000}
Link to this function

getresuid(Drv, Pids, Timeout)

View Source

Specs

getresuid(alcove_drv:ref(), [pid_t()], timeout()) ->
             {ok, Real :: uid_t(), Effective :: uid_t(), Saved :: uid_t()} | {error, posix()}.

getresuid(2): get real, effective and saved user ID

Support

* Linux

* OpenBSD

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getresuid(Drv, []).
 {ok,1000,1000,1000}
Link to this function

getrlimit(Drv, Pids, Resource)

View Source

Specs

getrlimit(alcove_drv:ref(), [pid_t()], Resource :: constant()) ->
             {ok, alcove_rlimit()} | {error, posix()}.

getrlimit(2): retrieve the resource limits for a process

Returns a record:

 -include_lib("alcove/include/alcove.hrl").

 #alcove_rlimit{
     cur = integer(),
     max = integer()
     }

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 3> alcove:getrlimit(Drv, [], rlimit_nofile).
 {ok,#alcove_rlimit{cur = 1024,max = 1048576}}
Link to this function

getrlimit(Drv, Pids, Resource, Timeout)

View Source

Specs

getrlimit(alcove_drv:ref(), [pid_t()], Resource :: constant(), timeout()) ->
             {ok, alcove_rlimit()} | {error, posix()}.

getrlimit(2): retrieve the resource limits for a process

Returns a record:

 -include_lib("alcove/include/alcove.hrl").

 #alcove_rlimit{
     cur = integer(),
     max = integer()
     }

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 3> alcove:getrlimit(Drv, [], rlimit_nofile).
 {ok,#alcove_rlimit{cur = 1024,max = 1048576}}
Link to this function

getsid(Drv, Pids, OSPid)

View Source

Specs

getsid(alcove_drv:ref(), [pid_t()], OSPid :: pid_t()) -> {ok, pid_t()} | {error, posix()}.

getsid(2): retrieve the session ID

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getsid(Drv, [], 0).
 {ok,3924}
Link to this function

getsid(Drv, Pids, OSPid, Timeout)

View Source

Specs

getsid(alcove_drv:ref(), [pid_t()], OSPid :: pid_t(), timeout()) ->
          {ok, pid_t()} | {error, posix()}.

getsid(2): retrieve the session ID

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getsid(Drv, [], 0).
 {ok,3924}

Specs

getuid(alcove_drv:ref(), [pid_t()]) -> uid_t().

getuid(2): returns the process user ID

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getuid(Drv, []).
 1000
Link to this function

getuid(Drv, Pids, Timeout)

View Source

Specs

getuid(alcove_drv:ref(), [pid_t()], timeout()) -> uid_t().

getuid(2): returns the process user ID

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:getuid(Drv, []).
 1000
Link to this function

ioctl(Drv, Pids, FD, Request, Argp)

View Source

Specs

ioctl(alcove_drv:ref(), [pid_t()], FD :: fd(), Request :: constant(), Argp :: cstruct()) ->
         {ok, integer(), iodata()} | {error, posix()}.

ioctl(2): control device

Controls a device using a file descriptor previously obtained using open/5.

Argp can be either a binary or a list representation of a C struct. See prctl/7 below for a description of the list elements.

On success, ioctl/5 returns a 3-tuple:

* Result: an integer equal to the return value of the ioctl

Usually 0 but some ioctls may use the return value as the output parameter.

* Bin: the value depends on the type of the input parameter Argp

* cstruct: contains the contents of the memory pointed to by Argp

* integer/binary: an empty binary

Examples

An example of creating a tap device in a net namespace on Linux:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newnet]).
 {ok,8288}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/dev/net/tun", [o_rdwr], 0).
 {ok,6}
 4> {ok, 0, <<"tap", _/binary>>} = alcove:ioctl(Drv, [Pid], FD, tunsetiff, <<
 4>                 % generate a tuntap device name
 4>                 0:(16 * 8),
 4>                 % IFF_TAP, IFF_NO_PI
 4>                 (16#0002 bor 16#1000):2/native-unsigned-integer-unit:8,
 4>                 0:(14 * 8)
 4>             >>).
 {ok,0,
     <<116,97,112,48,0,0,0,0,0,0,0,0,0,0,0,0,2,16,0,0,0,0,0,0,
       0,0,...>>}
Link to this function

ioctl(Drv, Pids, FD, Request, Argp, Timeout)

View Source

Specs

ioctl(alcove_drv:ref(),
      [pid_t()],
      FD :: fd(),
      Request :: constant(),
      Argp :: cstruct(),
      timeout()) ->
         {ok, integer(), iodata()} | {error, posix()}.

ioctl(2): control device

Controls a device using a file descriptor previously obtained using open/5.

Argp can be either a binary or a list representation of a C struct. See prctl/7 below for a description of the list elements.

On success, ioctl/5 returns a 3-tuple:

* Result: an integer equal to the return value of the ioctl

Usually 0 but some ioctls may use the return value as the output parameter.

* Bin: the value depends on the type of the input parameter Argp

* cstruct: contains the contents of the memory pointed to by Argp

* integer/binary: an empty binary

Examples

An example of creating a tap device in a net namespace on Linux:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newnet]).
 {ok,8288}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/dev/net/tun", [o_rdwr], 0).
 {ok,6}
 4> {ok, 0, <<"tap", _/binary>>} = alcove:ioctl(Drv, [Pid], FD, tunsetiff, <<
 4>                 % generate a tuntap device name
 4>                 0:(16 * 8),
 4>                 % IFF_TAP, IFF_NO_PI
 4>                 (16#0002 bor 16#1000):2/native-unsigned-integer-unit:8,
 4>                 0:(14 * 8)
 4>             >>).
 {ok,0,
     <<116,97,112,48,0,0,0,0,0,0,0,0,0,0,0,0,2,16,0,0,0,0,0,0,
       0,0,...>>}
Link to this function

ioctl_constant(Drv, Pids, Symbol)

View Source

Specs

ioctl_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> integer() | unknown.

Convert ioctl constant to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:ioctl_constant(Drv, [], siocgifaddr).
 35093
 3> alcove:ioctl_constant(Drv, [], 'SIOCGIFADDR').
 35093
Link to this function

ioctl_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

ioctl_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) -> integer() | unknown.

Convert ioctl constant to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:ioctl_constant(Drv, [], siocgifaddr).
 35093
 3> alcove:ioctl_constant(Drv, [], 'SIOCGIFADDR').
 35093
Link to this function

iolist_to_bin(Drv, Pids, Arg1)

View Source

Specs

iolist_to_bin(alcove_drv:ref(), [pid_t()], iodata()) -> binary().

Convert iolist to binary

Test conversion of iolists to binary in a control process.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:iolist_to_bin(Drv, [], ["foo", [<<"1">>, <<"2">>, [<<"3">>], ["bar"]]]).
 <<"foo123bar">>
Link to this function

iolist_to_bin(Drv, Pids, Arg1, Timeout)

View Source

Specs

iolist_to_bin(alcove_drv:ref(), [pid_t()], iodata(), timeout()) -> binary().

Convert iolist to binary

Test conversion of iolists to binary in a control process.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:iolist_to_bin(Drv, [], ["foo", [<<"1">>, <<"2">>, [<<"3">>], ["bar"]]]).
 <<"foo123bar">>

Specs

jail(alcove_drv:ref(), [pid_t()], cstruct()) -> {ok, int32_t()} | {error, posix()}.

jail(2): restrict the current process in a system jail

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 3> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 4> Jail0 = alcove_cstruct:jail(#alcove_jail{
 4>         path = "/rescue",
 4>         hostname = "test0",
 4>         jailname = "jail0"
 4>     }).
 [<<2,0,0,0>>,
  <<0,0,0,0>>,
  {ptr,<<47,114,101,115,99,117,101,0>>},
  {ptr,<<116,101,115,116,48,0>>},
  {ptr,<<106,97,105,108,48,0>>},
  <<0,0,0,0,0,0,0,0>>,
  {ptr,<<>>},
  {ptr,<<>>}]
 5> {ok, JID0} = alcove:jail(Drv, [Pid], Jail0).
 {ok,21}
 6> alcove:gethostname(Drv, [Pid]).
 {ok,<<"test0">>}
Link to this function

jail(Drv, Pids, Arg1, Timeout)

View Source

Specs

jail(alcove_drv:ref(), [pid_t()], cstruct(), timeout()) -> {ok, int32_t()} | {error, posix()}.

jail(2): restrict the current process in a system jail

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 3> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 4> Jail0 = alcove_cstruct:jail(#alcove_jail{
 4>         path = "/rescue",
 4>         hostname = "test0",
 4>         jailname = "jail0"
 4>     }).
 [<<2,0,0,0>>,
  <<0,0,0,0>>,
  {ptr,<<47,114,101,115,99,117,101,0>>},
  {ptr,<<116,101,115,116,48,0>>},
  {ptr,<<106,97,105,108,48,0>>},
  <<0,0,0,0,0,0,0,0>>,
  {ptr,<<>>},
  {ptr,<<>>}]
 5> {ok, JID0} = alcove:jail(Drv, [Pid], Jail0).
 {ok,21}
 6> alcove:gethostname(Drv, [Pid]).
 {ok,<<"test0">>}
Link to this function

jail_attach(Drv, Pids, Arg1)

View Source

Specs

jail_attach(alcove_drv:ref(), [pid_t()], int32_t()) -> ok | {error, posix()}.

jail_attach(2): join a jailed process

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 3> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 4> Jail0 = alcove_cstruct:jail(#alcove_jail{
 4>         path = "/rescue",
 4>         hostname = "test0",
 4>         jailname = "jail0"
 4>     }).
 [<<2,0,0,0>>,
  <<0,0,0,0>>,
  {ptr,<<47,114,101,115,99,117,101,0>>},
  {ptr,<<116,101,115,116,48,0>>},
  {ptr,<<106,97,105,108,48,0>>},
  <<0,0,0,0,0,0,0,0>>,
  {ptr,<<>>},
  {ptr,<<>>}]
 5> {ok, JID0} = alcove:jail(Drv, [Pid], Jail0).
 {ok,21}
 6> {ok, Pid0} = alcove:fork(Drv, []).
 {ok,44379}
 7> ok = alcove:jail_attach(Drv, [Pid0], JID0).
 ok
 8> alcove:gethostname(Drv, [Pid0]).
 {ok,<<"test0">>}
 9> ok = alcove:jail_remove(Drv, [], JID0).
 ok
Link to this function

jail_attach(Drv, Pids, Arg1, Timeout)

View Source

Specs

jail_attach(alcove_drv:ref(), [pid_t()], int32_t(), timeout()) -> ok | {error, posix()}.

jail_attach(2): join a jailed process

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 3> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 4> Jail0 = alcove_cstruct:jail(#alcove_jail{
 4>         path = "/rescue",
 4>         hostname = "test0",
 4>         jailname = "jail0"
 4>     }).
 [<<2,0,0,0>>,
  <<0,0,0,0>>,
  {ptr,<<47,114,101,115,99,117,101,0>>},
  {ptr,<<116,101,115,116,48,0>>},
  {ptr,<<106,97,105,108,48,0>>},
  <<0,0,0,0,0,0,0,0>>,
  {ptr,<<>>},
  {ptr,<<>>}]
 5> {ok, JID0} = alcove:jail(Drv, [Pid], Jail0).
 {ok,21}
 6> {ok, Pid0} = alcove:fork(Drv, []).
 {ok,44379}
 7> ok = alcove:jail_attach(Drv, [Pid0], JID0).
 ok
 8> alcove:gethostname(Drv, [Pid0]).
 {ok,<<"test0">>}
 9> ok = alcove:jail_remove(Drv, [], JID0).
 ok
Link to this function

jail_remove(Drv, Pids, Arg1)

View Source

Specs

jail_remove(alcove_drv:ref(), [pid_t()], int32_t()) -> ok | {error, posix()}.

jail_remove(2): destroy a jailed process

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 3> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 4> Jail0 = alcove_cstruct:jail(#alcove_jail{
 4>         path = "/rescue",
 4>         hostname = "test0",
 4>         jailname = "jail0"
 4>     }).
 [<<2,0,0,0>>,
  <<0,0,0,0>>,
  {ptr,<<47,114,101,115,99,117,101,0>>},
  {ptr,<<116,101,115,116,48,0>>},
  {ptr,<<106,97,105,108,48,0>>},
  <<0,0,0,0,0,0,0,0>>,
  {ptr,<<>>},
  {ptr,<<>>}]
 5> {ok, JID0} = alcove:jail(Drv, [Pid], Jail0).
 {ok,21}
 6> {ok, Pid0} = alcove:fork(Drv, []).
 {ok,44379}
 7> ok = alcove:jail_attach(Drv, [Pid0], JID0).
 ok
 8> alcove:gethostname(Drv, [Pid0]).
 {ok,<<"test0">>}
 9> ok = alcove:jail_remove(Drv, [], JID0).
 ok
Link to this function

jail_remove(Drv, Pids, Arg1, Timeout)

View Source

Specs

jail_remove(alcove_drv:ref(), [pid_t()], int32_t(), timeout()) -> ok | {error, posix()}.

jail_remove(2): destroy a jailed process

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 3> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 4> Jail0 = alcove_cstruct:jail(#alcove_jail{
 4>         path = "/rescue",
 4>         hostname = "test0",
 4>         jailname = "jail0"
 4>     }).
 [<<2,0,0,0>>,
  <<0,0,0,0>>,
  {ptr,<<47,114,101,115,99,117,101,0>>},
  {ptr,<<116,101,115,116,48,0>>},
  {ptr,<<106,97,105,108,48,0>>},
  <<0,0,0,0,0,0,0,0>>,
  {ptr,<<>>},
  {ptr,<<>>}]
 5> {ok, JID0} = alcove:jail(Drv, [Pid], Jail0).
 {ok,21}
 6> {ok, Pid0} = alcove:fork(Drv, []).
 {ok,44379}
 7> ok = alcove:jail_attach(Drv, [Pid0], JID0).
 ok
 8> alcove:gethostname(Drv, [Pid0]).
 {ok,<<"test0">>}
 9> ok = alcove:jail_remove(Drv, [], JID0).
 ok
Link to this function

kill(Drv, Pids, OSPid, Signal)

View Source

Specs

kill(alcove_drv:ref(), [pid_t()], OSPid :: pid_t(), Signal :: constant()) -> ok | {error, posix()}.

kill(2): terminate a process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:kill(Drv, [], 0, 0).
 ok
 3> alcove:kill(Drv, [], 12345, 0).
 {error,esrch}
 4> {ok, Pid} = alcove:fork(Drv, []).
 {ok,8288}
 5> alcove:kill(Drv, [], Pid, 0).
 ok
 6> alcove:kill(Drv, [], Pid, sigkill).
 ok
 7> alcove:kill(Drv, [], Pid, 0).
 {error,esrch}
 8> flush().
 Shell got {alcove_ctl,<0.177.0>,[8288],fdctl_closed}
 Shell got {alcove_event,<0.177.0>,[8288],{termsig,sigkill}}
Link to this function

kill(Drv, Pids, OSPID, Signal, Timeout)

View Source

Specs

kill(alcove_drv:ref(), [pid_t()], OSPID :: pid_t(), Signal :: constant(), timeout()) ->
        ok | {error, posix()}.

kill(2): terminate a process

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:kill(Drv, [], 0, 0).
 ok
 3> alcove:kill(Drv, [], 12345, 0).
 {error,esrch}
 4> {ok, Pid} = alcove:fork(Drv, []).
 {ok,8288}
 5> alcove:kill(Drv, [], Pid, 0).
 ok
 6> alcove:kill(Drv, [], Pid, sigkill).
 ok
 7> alcove:kill(Drv, [], Pid, 0).
 {error,esrch}
 8> flush().
 Shell got {alcove_ctl,<0.177.0>,[8288],fdctl_closed}
 Shell got {alcove_event,<0.177.0>,[8288],{termsig,sigkill}}
Link to this function

link(Drv, Pids, OldPath, NewPath)

View Source

Specs

link(alcove_drv:ref(), [pid_t()], OldPath :: iodata(), NewPath :: iodata()) ->
        ok | {error, posix()}.

link(2) : create a hard link

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/tmp/alcove-link-test.txt", [o_wronly, o_creat], 8#644).
 {ok,6}
 4> alcove:link(Drv, [Pid], "/tmp/alcove-link-test.txt", "/tmp/alcove-link-test.link").
 ok
Link to this function

link(Drv, Pids, OldPath, NewPath, Timeout)

View Source

Specs

link(alcove_drv:ref(), [pid_t()], OldPath :: iodata(), NewPath :: iodata(), timeout()) ->
        ok | {error, posix()}.

link(2) : create a hard link

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/tmp/alcove-link-test.txt", [o_wronly, o_creat], 8#644).
 {ok,6}
 4> alcove:link(Drv, [Pid], "/tmp/alcove-link-test.txt", "/tmp/alcove-link-test.link").
 ok
Link to this function

lseek(Drv, Pids, FD, Offset, Whence)

View Source

Specs

lseek(alcove_drv:ref(), [pid_t()], FD :: fd(), Offset :: off_t(), Whence :: int32_t()) ->
         ok | {error, posix()}.

lseek(2): set file offset for read/write

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> alcove:lseek(Drv, [Pid], FD, 0, 0).
 ok
Link to this function

lseek(Drv, Pids, FD, Offset, Whence, Timeout)

View Source

Specs

lseek(alcove_drv:ref(), [pid_t()], FD :: fd(), Offset :: off_t(), Whence :: int32_t(), timeout()) ->
         ok | {error, posix()}.

lseek(2): set file offset for read/write

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,18820}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> alcove:lseek(Drv, [Pid], FD, 0, 0).
 ok
Link to this function

mkdir(Drv, Pids, Path, Mode)

View Source

Specs

mkdir(alcove_drv:ref(), [pid_t()], Path :: iodata(), Mode :: mode_t()) -> ok | {error, posix()}.

mkdir(2): create a directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:mkdir(Drv, [], "/tmp/alcove-mkdir-test", 8#755).
 ok
Link to this function

mkdir(Drv, Pids, Path, Mode, Timeout)

View Source

Specs

mkdir(alcove_drv:ref(), [pid_t()], Path :: iodata(), Mode :: mode_t(), timeout()) ->
         ok | {error, posix()}.

mkdir(2): create a directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:mkdir(Drv, [], "/tmp/alcove-mkdir-test", 8#755).
 ok
Link to this function

mkfifo(Drv, Pids, Path, Mode)

View Source

Specs

mkfifo(alcove_drv:ref(), [pid_t()], Path :: iodata(), Mode :: mode_t()) -> ok | {error, posix()}.

mkfifo(3): make named pipe file

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:mkfifo(Drv, [], "/tmp/alcove-fifo-test", 8#700).
 ok
Link to this function

mkfifo(Drv, Pids, Path, Mode, Timeout)

View Source

Specs

mkfifo(alcove_drv:ref(), [pid_t()], Path :: iodata(), Mode :: mode_t(), timeout()) ->
          ok | {error, posix()}.

mkfifo(3): make named pipe file

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:mkfifo(Drv, [], "/tmp/alcove-fifo-test", 8#700).
 ok
Link to this function

mount(Drv, Pids, Source, Target, FSType, Flags, Data, Options)

View Source

Specs

mount(alcove_drv:ref(),
      [pid_t()],
      Source :: iodata(),
      Target :: iodata(),
      FSType :: iodata(),
      Flags :: uint64_t() | [constant()],
      Data :: iodata(),
      Options :: iodata()) ->
         ok | {error, posix()}.

mount(2): mount a filesystem, Linux style

The arguments are:

* source

* target

* filesystem type

* flags

* data

An empty list may be used to specify NULL.

For example, filesystems mounted in a Linux mount namespace may be visible in the global mount namespace. To avoid this, first remount the root filesystem within a mount namespace using the MS_REC|MS_PRIVATE flags:

 {ok, Task} = alcove:clone(Drv, [], [clone_newns]),
 ok = alcove:mount(Drv, [Task], "none", "/", [], [ms_rec, ms_private], []).

On BSD systems, the Source argument is ignored and passed to the system mount call as:

 mount(FSType, Target, Flags, Data);

On Solaris, some mount options are passed in the Options argument as a string of comma separated values terminated by a NULL. Other platforms ignore the Options parameter.

Examples

An example of bind mounting a directory within a linux mount namespace:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newns]).
 {ok,10059}
 3> alcove:mount(Drv, [Pid], "/tmp", "/mnt", "", [ms_bind, ms_rdonly, ms_noexec], "", "").
 ok
 4> alcove:umount(Drv, [Pid], "/mnt").
 ok
Link to this function

mount(Drv, Pids, Source, Target, FSType, Flags, Data, Options, Timeout)

View Source

Specs

mount(alcove_drv:ref(),
      [pid_t()],
      Source :: iodata(),
      Target :: iodata(),
      FSType :: iodata(),
      Flags :: uint64_t() | [constant()],
      Data :: iodata(),
      Options :: iodata(),
      timeout()) ->
         ok | {error, posix()}.

mount(2): mount a filesystem, Linux style

The arguments are:

* source

* target

* filesystem type

* flags

* data

An empty list may be used to specify NULL.

For example, filesystems mounted in a Linux mount namespace may be visible in the global mount namespace. To avoid this, first remount the root filesystem within a mount namespace using the MS_REC|MS_PRIVATE flags:

 {ok, Task} = alcove:clone(Drv, [], [clone_newns]),
 ok = alcove:mount(Drv, [Task], "none", "/", [], [ms_rec, ms_private], []).

On BSD systems, the Source argument is ignored and passed to the system mount call as:

 mount(FSType, Target, Flags, Data);

On Solaris, some mount options are passed in the Options argument as a string of comma separated values terminated by a NULL. Other platforms ignore the Options parameter.

Examples

An example of bind mounting a directory within a linux mount namespace:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newns]).
 {ok,10059}
 3> alcove:mount(Drv, [Pid], "/tmp", "/mnt", "", [ms_bind, ms_rdonly, ms_noexec], "", "").
 ok
 4> alcove:umount(Drv, [Pid], "/mnt").
 ok
Link to this function

mount_constant(Drv, Pids, Symbol)

View Source

Specs

mount_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> unknown | uint64_t().

Convert flag names to integers

Names are derived from the C macro name with the underscore prefix removed. For example, rdonly is mapped to MS_RDONLY on Linux and MNT_RDONLY on FreeBSD.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:mount_constant(Drv, [], rdonly).
 1
 3> alcove:mount_constant(Drv, [], 'RDONLY').
 1
Link to this function

mount_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

mount_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) -> unknown | uint64_t().

Convert flag names to integers

Names are derived from the C macro name with the underscore prefix removed. For example, rdonly is mapped to MS_RDONLY on Linux and MNT_RDONLY on FreeBSD.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:mount_constant(Drv, [], rdonly).
 1
 3> alcove:mount_constant(Drv, [], 'RDONLY').
 1
Link to this function

open(Drv, Pids, Path, Flags, Mode)

View Source

Specs

open(alcove_drv:ref(),
     [pid_t()],
     Path :: iodata(),
     Flags :: int32_t() | [constant()],
     Mode :: mode_t()) ->
        {ok, fd()} | {error, posix()}.

open(2): returns a file descriptor associated with a file

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:open(Drv, [], "/tmp/alcove-open-test", [o_wronly,o_creat], 8#644).
 {ok,6}
Link to this function

open(Drv, Pids, Path, Flags, Mode, Timeout)

View Source

Specs

open(alcove_drv:ref(),
     [pid_t()],
     Path :: iodata(),
     Flags :: int32_t() | [constant()],
     Mode :: mode_t(),
     timeout()) ->
        {ok, fd()} | {error, posix()}.

open(2): returns a file descriptor associated with a file

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:open(Drv, [], "/tmp/alcove-open-test", [o_wronly,o_creat], 8#644).
 {ok,6}
Link to this function

pivot_root(Drv, Pids, NewRoot, PutOld)

View Source

Specs

pivot_root(alcove_drv:ref(), [pid_t()], NewRoot :: iodata(), PutOld :: iodata()) ->
              ok | {error, posix()}.

pivot_root(2): change the root mount

Use pivot_root(2) in a Linux mount namespace to change the root filesystem.

Warning: using pivot_root(2) in the global namespace may have unexpected effects.

Support

* Linux

Examples

The new root must be a mount point. /tmp or /run are usually mounted as tmpfs.

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> alcove:mkdir(Drv, [], "/run/alcove-old-root", 8#755).
 ok
 3> {ok, Pid} = alcove:clone(Drv, [], [clone_newns]).
 {ok,1371}
 4> alcove:pivot_root(Drv, [Pid], "/run", "/run/alcove-old-root").
 ok
Link to this function

pivot_root(Drv, Pids, NewRoot, PutOld, Timeout)

View Source

Specs

pivot_root(alcove_drv:ref(), [pid_t()], NewRoot :: iodata(), PutOld :: iodata(), timeout()) ->
              ok | {error, posix()}.

pivot_root(2): change the root mount

Use pivot_root(2) in a Linux mount namespace to change the root filesystem.

Warning: using pivot_root(2) in the global namespace may have unexpected effects.

Support

* Linux

Examples

The new root must be a mount point. /tmp or /run are usually mounted as tmpfs.

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> alcove:mkdir(Drv, [], "/run/alcove-old-root", 8#755).
 ok
 3> {ok, Pid} = alcove:clone(Drv, [], [clone_newns]).
 {ok,1371}
 4> alcove:pivot_root(Drv, [Pid], "/run", "/run/alcove-old-root").
 ok
Link to this function

pledge(Drv, Pids, Promises, ExecPromises)

View Source

Specs

pledge(alcove_drv:ref(), [pid_t()], Promises :: iodata(), ExecPromises :: iodata()) ->
          ok | {error, posix()}.

pledge(2): restrict system operations

An empty list ([]) specifies promises should not be changed. Warning: an empty string ("") is equivalent to an empty list.

To specify no capabilities, use an empty binary: <<>>> or <<"">>

Support

* OpenBSD

Examples

Fork a control process:

* restricted to stdio, proc and exec capabilities * unrestricted after calling exec

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,10059}
 3> alcove:pledge(Drv, [Pid], <<"stdio proc exec">>, []).
 ok
Link to this function

pledge(Drv, Pids, Promises, ExecPromises, Timeout)

View Source

Specs

pledge(alcove_drv:ref(), [pid_t()], Promises :: iodata(), ExecPromises :: iodata(), timeout()) ->
          ok | {error, posix()}.

pledge(2): restrict system operations

An empty list ([]) specifies promises should not be changed. Warning: an empty string ("") is equivalent to an empty list.

To specify no capabilities, use an empty binary: <<>>> or <<"">>

Support

* OpenBSD

Examples

Fork a control process:

* restricted to stdio, proc and exec capabilities * unrestricted after calling exec

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,10059}
 3> alcove:pledge(Drv, [Pid], <<"stdio proc exec">>, []).
 ok
Link to this function

prctl(Drv, Pids, Arg1, Arg2, Arg3, Arg4, Arg5)

View Source

Specs

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()}.

prctl(2): operations on a process

This function can be used to set BPF syscall filters on processes (seccomp mode).

A list can be used for prctl operations requiring a C structure as an argument. List elements are used to contiguously populate a buffer (it is up to the caller to add padding):

* binary(): the element is copied directly into the buffer

On return, the contents of the binary is returned to the caller.

* {ptr, N}: N bytes of memory is allocated and zeroed. The pointer is placed in the buffer.

On return, the contents of the memory is returned to the caller.

* {ptr, binary()}

Memory equal to the size of the binary is allocated and initialized with the contents of the binary.

On return, the contents of the memory is returned to the caller.

Support

* Linux

Examples

To enforce a seccomp filter:

 % NOTE: this filter will cause the port to receive a SIGSYS
 % See test/alcove_seccomp_tests.erl for all the syscalls
 % required for the port process to run

 Arch = alcove:define(Drv, [], alcove:audit_arch()),
 Filter = [
     ?VALIDATE_ARCHITECTURE(Arch),
     ?EXAMINE_SYSCALL,
     sys_read,
     sys_write
 ],

 {ok,_,_,_,_,_} = alcove:prctl(Drv, [], pr_set_no_new_privs, 1, 0, 0, 0),
 Pad = (erlang:system_info({wordsize,external}) - 2) * 8,

 Prog = [
     <<(iolist_size(Filter) div 8):2/native-unsigned-integer-unit:8>>,
     <<0:Pad>>,
     {ptr, list_to_binary(Filter)}
 ],
 alcove:prctl(Drv, [], pr_set_seccomp, seccomp_mode_filter, Prog, 0, 0).
Link to this function

prctl(Drv, Pids, Arg1, Arg2, Arg3, Arg4, Arg5, Timeout)

View Source

Specs

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()}.

prctl(2): operations on a process

This function can be used to set BPF syscall filters on processes (seccomp mode).

A list can be used for prctl operations requiring a C structure as an argument. List elements are used to contiguously populate a buffer (it is up to the caller to add padding):

* binary(): the element is copied directly into the buffer

On return, the contents of the binary is returned to the caller.

* {ptr, N}: N bytes of memory is allocated and zeroed. The pointer is placed in the buffer.

On return, the contents of the memory is returned to the caller.

* {ptr, binary()}

Memory equal to the size of the binary is allocated and initialized with the contents of the binary.

On return, the contents of the memory is returned to the caller.

Support

* Linux

Examples

To enforce a seccomp filter:

 % NOTE: this filter will cause the port to receive a SIGSYS
 % See test/alcove_seccomp_tests.erl for all the syscalls
 % required for the port process to run

 Arch = alcove:define(Drv, [], alcove:audit_arch()),
 Filter = [
     ?VALIDATE_ARCHITECTURE(Arch),
     ?EXAMINE_SYSCALL,
     sys_read,
     sys_write
 ],

 {ok,_,_,_,_,_} = alcove:prctl(Drv, [], pr_set_no_new_privs, 1, 0, 0, 0),
 Pad = (erlang:system_info({wordsize,external}) - 2) * 8,

 Prog = [
     <<(iolist_size(Filter) div 8):2/native-unsigned-integer-unit:8>>,
     <<0:Pad>>,
     {ptr, list_to_binary(Filter)}
 ],
 alcove:prctl(Drv, [], pr_set_seccomp, seccomp_mode_filter, Prog, 0, 0).
Link to this function

prctl_constant(Drv, Pids, Symbol)

View Source

Specs

prctl_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> unknown | non_neg_integer().

Convert prctl option names to integers

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:prctl_constant(Drv, [], pr_set_name).
 15
Link to this function

prctl_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

prctl_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) ->
                  unknown | non_neg_integer().

Convert prctl option names to integers

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:prctl_constant(Drv, [], pr_set_name).
 15
Link to this function

procctl(Drv, Pids, IDType, ID, Cmd, Data)

View Source

Specs

procctl(alcove_drv:ref(),
        [pid_t()],
        IDType :: constant(),
        ID :: pid_t(),
        Cmd :: constant(),
        Data :: [] | cstruct()) ->
           {ok, binary(), cstruct()} | {error, posix()}.

procctl(2): control processes

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Pid, []).
 {ok,44378}
 3> alcove:procctl(Drv, [Pid], 0, Pid, 'PROC_REAP_ACQUIRE', []).
 {ok,<<>>,[]}
 4> alcove:procctl(Drv, [Pid], p_pid, Pid, 'PROC_REAP_STATUS', [
 4>      <<0,0,0,0>>, % rs_flags
 4>      <<0,0,0,0>>, % rs_children
 4>      <<0,0,0,0>>, % rs_descendants
 4>      <<0,0,0,0>>, % rs_reaper
 4>      <<0,0,0,0>>  % rs_pid
 4>    ]).
 {ok,<<1,0,0,0,0,0,0,0,0,0,0,0,118,173,0,0,255,255,255,255>>,
     [<<1,0,0,0>>,
      <<0,0,0,0>>,
      <<0,0,0,0>>,
      <<118,173,0,0>>,
      <<"\377\377\377\377">>]}
Link to this function

procctl(Drv, Pids, IDType, ID, Cmd, Data, Timeout)

View Source

Specs

procctl(alcove_drv:ref(),
        [pid_t()],
        IDType :: constant(),
        ID :: pid_t(),
        Cmd :: constant(),
        Data :: [] | cstruct(),
        timeout()) ->
           {ok, binary(), cstruct()} | {error, posix()}.

procctl(2): control processes

Support

* FreeBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Pid, []).
 {ok,44378}
 3> alcove:procctl(Drv, [Pid], 0, Pid, 'PROC_REAP_ACQUIRE', []).
 {ok,<<>>,[]}
 4> alcove:procctl(Drv, [Pid], p_pid, Pid, 'PROC_REAP_STATUS', [
 4>      <<0,0,0,0>>, % rs_flags
 4>      <<0,0,0,0>>, % rs_children
 4>      <<0,0,0,0>>, % rs_descendants
 4>      <<0,0,0,0>>, % rs_reaper
 4>      <<0,0,0,0>>  % rs_pid
 4>    ]).
 {ok,<<1,0,0,0,0,0,0,0,0,0,0,0,118,173,0,0,255,255,255,255>>,
     [<<1,0,0,0>>,
      <<0,0,0,0>>,
      <<0,0,0,0>>,
      <<118,173,0,0>>,
      <<"\377\377\377\377">>]}
Link to this function

ptrace(Drv, Pids, Request, OSPid, Addr, Data)

View Source

Specs

ptrace(alcove_drv:ref(),
       [pid_t()],
       Request :: constant(),
       OSPid :: pid_t(),
       Addr :: ptr_arg(),
       Data :: ptr_arg()) ->
          {ok, integer(), ptr_val(), ptr_val()} | {error, posix()}.

ptrace(2): process trace

Examples

 -module(ptrace).

 -export([run/0]).

 run() ->
     {ok, Drv} = alcove_drv:start_link(),
     {ok, Pid1} = alcove:fork(Drv, []),

     {ok, Pid2} = alcove:fork(Drv, [Pid1]),

     % disable the alcove event loop: child process must be managed by
     % the caller
     {ok, sig_dfl} = alcove:sigaction(Drv, [Pid1], sigchld, sig_info),

     % enable ptracing in the child process and exec() a command
     {ok, 0, <<>>, <<>>} = alcove:ptrace(
         Drv,
         [Pid1, Pid2],
         ptrace_traceme,
         0,
         0,
         0
     ),
     ok = alcove:execvp(Drv, [Pid1, Pid2], "cat", ["cat"]),

     % the parent is notified
     {signal, sigchld, _} = alcove:event(Drv, [Pid1], 5000),
     {ok, Pid2, _, [{stopsig, sigtrap}]} = alcove:waitpid(
         Drv,
         [Pid1],
         -1,
         [wnohang]
     ),

     % should be no other events
     {ok, 0, 0, []} = alcove:waitpid(Drv, [Pid1], -1, [wnohang]),

     % allow the process to continue
     {ok, 0, <<>>, <<>>} = alcove:ptrace(Drv, [Pid1], ptrace_cont, Pid2, 0, 0),

     ok = alcove:stdin(Drv, [Pid1, Pid2], "test\n"),

     ok =
         receive
             {alcove_stdout, Drv, [Pid1, Pid2], <<"test\n">>} ->
                 ok
         after 5000 -> timeout
         end,

     % Send a SIGTERM and re-write it to a harmless SIGWINCH
     ok = alcove:kill(Drv, [Pid1], Pid2, sigterm),
     {signal, sigchld, _} = alcove:event(Drv, [Pid1], 5000),
     {ok, Pid2, _, [{stopsig, sigterm}]} = alcove:waitpid(
         Drv,
         [Pid1],
         -1,
         [wnohang]
     ),

     {ok, 0, <<>>, <<>>} = alcove:ptrace(
         Drv,
         [Pid1],
         ptrace_cont,
         Pid2,
         0,
         28
     ),

     % Convert a SIGWINCH to SIGTERM
     ok = alcove:kill(Drv, [Pid1], Pid2, sigwinch),
     {signal, sigchld, _} = alcove:event(Drv, [Pid1], 5000),
     {ok, 0, <<>>, <<>>} = alcove:ptrace(
         Drv,
         [Pid1],
         ptrace_cont,
         Pid2,
         0,
         15
     ),
     {ok, Pid2, _, [{termsig, sigterm}]} = alcove:waitpid(
         Drv,
         [Pid1],
         -1,
         []
     ).
Link to this function

ptrace(Drv, Pids, Request, OSPid, Addr, Data, Timeout)

View Source

Specs

ptrace(alcove_drv:ref(),
       [pid_t()],
       Request :: constant(),
       OSPid :: pid_t(),
       Addr :: ptr_arg(),
       Data :: ptr_arg(),
       timeout()) ->
          {ok, integer(), ptr_val(), ptr_val()} | {error, posix()}.

ptrace(2): process trace

Examples

 -module(ptrace).

 -export([run/0]).

 run() ->
     {ok, Drv} = alcove_drv:start_link(),
     {ok, Pid1} = alcove:fork(Drv, []),

     {ok, Pid2} = alcove:fork(Drv, [Pid1]),

     % disable the alcove event loop: child process must be managed by
     % the caller
     {ok, sig_dfl} = alcove:sigaction(Drv, [Pid1], sigchld, sig_info),

     % enable ptracing in the child process and exec() a command
     {ok, 0, <<>>, <<>>} = alcove:ptrace(
         Drv,
         [Pid1, Pid2],
         ptrace_traceme,
         0,
         0,
         0
     ),
     ok = alcove:execvp(Drv, [Pid1, Pid2], "cat", ["cat"]),

     % the parent is notified
     {signal, sigchld, _} = alcove:event(Drv, [Pid1], 5000),
     {ok, Pid2, _, [{stopsig, sigtrap}]} = alcove:waitpid(
         Drv,
         [Pid1],
         -1,
         [wnohang]
     ),

     % should be no other events
     {ok, 0, 0, []} = alcove:waitpid(Drv, [Pid1], -1, [wnohang]),

     % allow the process to continue
     {ok, 0, <<>>, <<>>} = alcove:ptrace(Drv, [Pid1], ptrace_cont, Pid2, 0, 0),

     ok = alcove:stdin(Drv, [Pid1, Pid2], "test\n"),

     ok =
         receive
             {alcove_stdout, Drv, [Pid1, Pid2], <<"test\n">>} ->
                 ok
         after 5000 -> timeout
         end,

     % Send a SIGTERM and re-write it to a harmless SIGWINCH
     ok = alcove:kill(Drv, [Pid1], Pid2, sigterm),
     {signal, sigchld, _} = alcove:event(Drv, [Pid1], 5000),
     {ok, Pid2, _, [{stopsig, sigterm}]} = alcove:waitpid(
         Drv,
         [Pid1],
         -1,
         [wnohang]
     ),

     {ok, 0, <<>>, <<>>} = alcove:ptrace(
         Drv,
         [Pid1],
         ptrace_cont,
         Pid2,
         0,
         28
     ),

     % Convert a SIGWINCH to SIGTERM
     ok = alcove:kill(Drv, [Pid1], Pid2, sigwinch),
     {signal, sigchld, _} = alcove:event(Drv, [Pid1], 5000),
     {ok, 0, <<>>, <<>>} = alcove:ptrace(
         Drv,
         [Pid1],
         ptrace_cont,
         Pid2,
         0,
         15
     ),
     {ok, Pid2, _, [{termsig, sigterm}]} = alcove:waitpid(
         Drv,
         [Pid1],
         -1,
         []
     ).
Link to this function

ptrace_constant(Drv, Pids, Symbol)

View Source

Specs

ptrace_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> unknown | integer().

Convert ptrace constant to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:ptrace_constant(Drv, [], ptrace_traceme).
 0
Link to this function

ptrace_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

ptrace_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) -> unknown | integer().

Convert ptrace constant to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:ptrace_constant(Drv, [], ptrace_traceme).
 0
Link to this function

read(Drv, Pids, FD, Count)

View Source

Specs

read(alcove_drv:ref(), [pid_t()], FD :: fd(), Count :: size_t()) ->
        {ok, binary()} | {error, posix()}.

read(2): read bytes from a file descriptor

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,75710}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> alcove:read(Drv, [Pid], FD, 64).
 {ok,<<"# $FreeBSD$\n#\nroot:*:0:0:Charlie &:/root:/bin/csh\ntoor:*:0:0:Bou">>}
Link to this function

read(Drv, Pids, FD, Count, Timeout)

View Source

Specs

read(alcove_drv:ref(), [pid_t()], FD :: fd(), Count :: size_t(), timeout()) ->
        {ok, binary()} | {error, posix()}.

read(2): read bytes from a file descriptor

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,75710}
 3> {ok, FD} = alcove:open(Drv, [Pid], "/etc/passwd", [o_rdonly], 0).
 {ok,6}
 4> alcove:read(Drv, [Pid], FD, 64).
 {ok,<<"# $FreeBSD$\n#\nroot:*:0:0:Charlie &:/root:/bin/csh\ntoor:*:0:0:Bou">>}
Link to this function

readdir(Drv, Pids, Path)

View Source

Specs

readdir(alcove_drv:ref(), [pid_t()], Path :: iodata()) -> {ok, [binary()]} | {error, posix()}.

readdir(3): retrieve list of objects in a directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> alcove:readdir(Drv, [], "/dev/pts").
 {ok,[<<".">>,<<"..">>,<<"50">>,<<"49">>,<<"45">>,<<"48">>,
      <<"47">>,<<"46">>,<<"44">>,<<"43">>,<<"42">>,<<"41">>,
      <<"40">>,<<"39">>,<<"38">>,<<"37">>,<<"36">>,<<"35">>,
      <<"34">>,<<"33">>,<<"32">>,<<"31">>,<<"30">>,<<"29">>,
      <<"28">>,<<"27">>,<<...>>|...]}
Link to this function

readdir(Drv, Pids, Path, Timeout)

View Source

Specs

readdir(alcove_drv:ref(), [pid_t()], Path :: iodata(), timeout()) ->
           {ok, [binary()]} | {error, posix()}.

readdir(3): retrieve list of objects in a directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.209.0>}
 2> alcove:readdir(Drv, [], "/dev/pts").
 {ok,[<<".">>,<<"..">>,<<"50">>,<<"49">>,<<"45">>,<<"48">>,
      <<"47">>,<<"46">>,<<"44">>,<<"43">>,<<"42">>,<<"41">>,
      <<"40">>,<<"39">>,<<"38">>,<<"37">>,<<"36">>,<<"35">>,
      <<"34">>,<<"33">>,<<"32">>,<<"31">>,<<"30">>,<<"29">>,
      <<"28">>,<<"27">>,<<...>>|...]}
Link to this function

rlimit_constant(Drv, Pids, Symbol)

View Source

Specs

rlimit_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> unknown | non_neg_integer().

Convert an RLIMIT_* flag to an integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:rlimit_constant(Drv, [], rlimit_nofile).
 7
Link to this function

rlimit_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

rlimit_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) ->
                   unknown | non_neg_integer().

Convert an RLIMIT_* flag to an integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:rlimit_constant(Drv, [], rlimit_nofile).
 7

Specs

rmdir(alcove_drv:ref(), [pid_t()], Path :: iodata()) -> ok | {error, posix()}.

rmdir(2): delete a directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:mkdir(Drv, [], "/tmp/alcove-rmdir-test", 8#755).
 ok
 3> alcove:rmdir(Drv, [], "/tmp/alcove-rmdir-test").
 ok
Link to this function

rmdir(Drv, Pids, Path, Timeout)

View Source

Specs

rmdir(alcove_drv:ref(), [pid_t()], Path :: iodata(), timeout()) -> ok | {error, posix()}.

rmdir(2): delete a directory

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:mkdir(Drv, [], "/tmp/alcove-rmdir-test", 8#755).
 ok
 3> alcove:rmdir(Drv, [], "/tmp/alcove-rmdir-test").
 ok
Link to this function

seccomp(Drv, Pids, Operation, Flags, Prog)

View Source

Specs

seccomp(alcove_drv:ref(),
        [pid_t()],
        Operation :: constant(),
        Flags :: constant(),
        Prog :: cstruct()) ->
           ok | {error, posix()}.

seccomp(2): restrict system operations

Also see prctl/7.

Support

* Linux

Examples

To enforce a seccomp filter:

 % NOTE: this filter will cause the port to receive a SIGSYS
 % See test/alcove_seccomp_tests.erl for all the syscalls
 % required for the port process to run

 Arch = alcove:define(Drv, [], alcove:audit_arch()),
 Filter = [
     ?VALIDATE_ARCHITECTURE(Arch),
     ?EXAMINE_SYSCALL,
     sys_read,
     sys_write
 ],

 {ok,_,_,_,_,_} = alcove:prctl(Drv, [], pr_set_no_new_privs, 1, 0, 0, 0),
 Pad = (erlang:system_info({wordsize,external}) - 2) * 8,

 Prog = [
     <<(iolist_size(Filter) div 8):2/native-unsigned-integer-unit:8>>,
     <<0:Pad>>,
     {ptr, list_to_binary(Filter)}
 ],
 alcove:seccomp(Drv, [], seccomp_set_mode_filter, 0, Prog).
Link to this function

seccomp(Drv, Pids, Operation, Flags, Prog, Timeout)

View Source

Specs

seccomp(alcove_drv:ref(),
        [pid_t()],
        Operation :: constant(),
        Flags :: constant(),
        Prog :: cstruct(),
        timeout()) ->
           ok | {error, posix()}.

seccomp(2): restrict system operations

Also see prctl/7.

Support

* Linux

Examples

To enforce a seccomp filter:

 % NOTE: this filter will cause the port to receive a SIGSYS
 % See test/alcove_seccomp_tests.erl for all the syscalls
 % required for the port process to run

 Arch = alcove:define(Drv, [], alcove:audit_arch()),
 Filter = [
     ?VALIDATE_ARCHITECTURE(Arch),
     ?EXAMINE_SYSCALL,
     sys_read,
     sys_write
 ],

 {ok,_,_,_,_,_} = alcove:prctl(Drv, [], pr_set_no_new_privs, 1, 0, 0, 0),
 Pad = (erlang:system_info({wordsize,external}) - 2) * 8,

 Prog = [
     <<(iolist_size(Filter) div 8):2/native-unsigned-integer-unit:8>>,
     <<0:Pad>>,
     {ptr, list_to_binary(Filter)}
 ],
 alcove:seccomp(Drv, [], seccomp_set_mode_filter, 0, Prog).
Link to this function

seccomp_constant(Drv, Pids, Symbol)

View Source

Specs

seccomp_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> unknown | non_neg_integer().

Convert seccomp option name to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:seccomp_constant(Drv, [], 'SECCOMP_SET_MODE_STRICT').
 0
Link to this function

seccomp_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

seccomp_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) ->
                    unknown | non_neg_integer().

Convert seccomp option name to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:seccomp_constant(Drv, [], 'SECCOMP_SET_MODE_STRICT').
 0
Link to this function

select(Drv, Pids, Readfds, Writefds, Exceptfds, Timeval)

View Source

Specs

select(alcove_drv:ref(),
       [pid_t()],
       Readfds :: fd_set(),
       Writefds :: fd_set(),
       Exceptfds :: fd_set(),
       Timeval :: [] | null | alcove_timeval()) ->
          {ok, Readset :: fd_set(), Writeset :: fd_set(), Exceptset :: fd_set()} |
          {error, posix()}.

select(2): poll a list of file descriptor for events

select/6 will block until an event occurs on a file descriptor, a timeout is reached or interrupted by a signal.

The Timeout value may be:

* passing an empty list ([]) causes select to block indefinitely (no timeout)

* an alcove_timeval record with these fields:

* sec : number of seconds to wait

* usec : number of microseconds to wait

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, FD} = alcove:open(Drv, [], "/dev/null", [o_rdwr], 0).
 {ok,6}
 3> alcove:select(Drv, [], [FD], [FD], [FD], []).
 {ok,[6],[6],[]}
 4> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 5> alcove:select(Drv, [], [FD], [FD], [FD], #alcove_timeval{sec = 1, usec = 1}).
 {ok,[6],[6],[]}
Link to this function

select(Drv, Pids, Readfds, Writefds, Exceptfds, Timeval, Timeout)

View Source

Specs

select(alcove_drv:ref(),
       [pid_t()],
       Readfds :: fd_set(),
       Writefds :: fd_set(),
       Exceptfds :: fd_set(),
       Timeval :: [] | null | alcove_timeval(),
       timeout()) ->
          {ok, Readset :: fd_set(), Writeset :: fd_set(), Exceptset :: fd_set()} |
          {error, posix()}.

select(2): poll a list of file descriptor for events

select/6 will block until an event occurs on a file descriptor, a timeout is reached or interrupted by a signal.

The Timeout value may be:

* passing an empty list ([]) causes select to block indefinitely (no timeout)

* an alcove_timeval record with these fields:

* sec : number of seconds to wait

* usec : number of microseconds to wait

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, FD} = alcove:open(Drv, [], "/dev/null", [o_rdwr], 0).
 {ok,6}
 3> alcove:select(Drv, [], [FD], [FD], [FD], []).
 {ok,[6],[6],[]}
 4> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 5> alcove:select(Drv, [], [FD], [FD], [FD], #alcove_timeval{sec = 1, usec = 1}).
 {ok,[6],[6],[]}
Link to this function

setcpid(Drv, Pids, Child, Opt, Val)

View Source

Specs

setcpid(alcove_drv:ref(),
        [pid_t()],
        Child :: pid_t(),
        Opt :: alcove_pid_field(),
        Val :: int32_t()) ->
           boolean().

Set options for child process of alcove control process

* flowcontrol

Enable rate limiting of the stdout and stderr of a child process. stdin is not rate limited (default: -1 (disabled))

* 0 : stdout/stderr for process is not read * 1-2147483646 : read this many messages from the process * -1 : disable flow control

NOTE: the limit applies to stdout and stderr. If the limit is set to 1, it is possible to get:

* 1 message from stdout * 1 message from stderr * 1 message from stdout and stderr

* signaloneof

The alcove control process sends this signal to the child process on shutdown (default: 15 (SIGTERM))

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,24440}
 3> alcove:setcpid(Drv, [], Pid, flowcontrol, 0).
 true
 4> alcove:getcpid(Drv, [], Pid, flowcontrol).
 0
Link to this function

setcpid(Drv, Pids, Child, Opt, Val, Timeout)

View Source

Specs

setcpid(alcove_drv:ref(),
        [pid_t()],
        Child :: pid_t(),
        Opt :: alcove_pid_field(),
        Val :: int32_t(),
        timeout()) ->
           boolean().

Set options for child process of alcove control process

* flowcontrol

Enable rate limiting of the stdout and stderr of a child process. stdin is not rate limited (default: -1 (disabled))

* 0 : stdout/stderr for process is not read * 1-2147483646 : read this many messages from the process * -1 : disable flow control

NOTE: the limit applies to stdout and stderr. If the limit is set to 1, it is possible to get:

* 1 message from stdout * 1 message from stderr * 1 message from stdout and stderr

* signaloneof

The alcove control process sends this signal to the child process on shutdown (default: 15 (SIGTERM))

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,24440}
 3> alcove:setcpid(Drv, [], Pid, flowcontrol, 0).
 true
 4> alcove:getcpid(Drv, [], Pid, flowcontrol).
 0
Link to this function

setenv(Drv, Pids, Name, Value, Overwrite)

View Source

Specs

setenv(alcove_drv:ref(), [pid_t()], Name :: iodata(), Value :: iodata(), Overwrite :: int32_t()) ->
          ok | {error, posix()}.

setenv(3): set an environment variable

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:setenv(Drv, [], "ALCOVE_TEST", "foo", 0).
 ok
 3> alcove:getenv(Drv, [], "ALCOVE_TEST").
 <<"foo">>
 4> alcove:setenv(Drv, [], "ALCOVE_TEST", "bar", 0).
 ok
 5> alcove:getenv(Drv, [], "ALCOVE_TEST").
 <<"foo">>
 6> alcove:setenv(Drv, [], "ALCOVE_TEST", "bar", 1).
 ok
 7> alcove:getenv(Drv, [], "ALCOVE_TEST").
 <<"bar">>
Link to this function

setenv(Drv, Pids, Name, Value, Overwrite, Timeout)

View Source

Specs

setenv(alcove_drv:ref(),
       [pid_t()],
       Name :: iodata(),
       Value :: iodata(),
       Overwrite :: int32_t(),
       timeout()) ->
          ok | {error, posix()}.

setenv(3): set an environment variable

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:setenv(Drv, [], "ALCOVE_TEST", "foo", 0).
 ok
 3> alcove:getenv(Drv, [], "ALCOVE_TEST").
 <<"foo">>
 4> alcove:setenv(Drv, [], "ALCOVE_TEST", "bar", 0).
 ok
 5> alcove:getenv(Drv, [], "ALCOVE_TEST").
 <<"foo">>
 6> alcove:setenv(Drv, [], "ALCOVE_TEST", "bar", 1).
 ok
 7> alcove:getenv(Drv, [], "ALCOVE_TEST").
 <<"bar">>

Specs

setgid(alcove_drv:ref(), [pid_t()], Gid :: gid_t()) -> ok | {error, posix()}.

setgid(2): set the GID of the process

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 72> alcove:setgid(Drv, [Pid], 123).
 ok
 73> alcove:getgid(Drv, [Pid]).
 123
Link to this function

setgid(Drv, Pids, Gid, Timeout)

View Source

Specs

setgid(alcove_drv:ref(), [pid_t()], Gid :: gid_t(), timeout()) -> ok | {error, posix()}.

setgid(2): set the GID of the process

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 72> alcove:setgid(Drv, [Pid], 123).
 ok
 73> alcove:getgid(Drv, [Pid]).
 123
Link to this function

setgroups(Drv, Pids, Groups)

View Source

Specs

setgroups(alcove_drv:ref(), [pid_t()], Groups :: [gid_t()]) -> ok | {error, posix()}.

setgroups(2): set the supplementary groups of the process

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 75> alcove:setgroups(Drv, [Pid], []).
 ok
 76> alcove:getgroups(Drv, [Pid]).
 {ok,[]}
Link to this function

setgroups(Drv, Pids, Groups, Timeout)

View Source

Specs

setgroups(alcove_drv:ref(), [pid_t()], Groups :: [gid_t()], timeout()) -> ok | {error, posix()}.

setgroups(2): set the supplementary groups of the process

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 75> alcove:setgroups(Drv, [Pid], []).
 ok
 76> alcove:getgroups(Drv, [Pid]).
 {ok,[]}
Link to this function

sethostname(Drv, Pids, Hostname)

View Source

Specs

sethostname(alcove_drv:ref(), [pid_t()], Hostname :: iodata()) -> ok | {error, posix()}.

sethostname(2): set the system hostname

This function is probably only useful if running in a uts namespace or a jail.

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newuts]).
 {ok,44378}
 3> alcove:sethostname(Drv, [Pid], "test").
 ok
 4> alcove:gethostname(Drv, []).
 {ok,<<"host1">>}
 5> alcove:gethostname(Drv, [Pid]).
 {ok,<<"test">>}
Link to this function

sethostname(Drv, Pids, Hostname, Timeout)

View Source

Specs

sethostname(alcove_drv:ref(), [pid_t()], Hostname :: iodata(), timeout()) -> ok | {error, posix()}.

sethostname(2): set the system hostname

This function is probably only useful if running in a uts namespace or a jail.

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newuts]).
 {ok,44378}
 3> alcove:sethostname(Drv, [Pid], "test").
 ok
 4> alcove:gethostname(Drv, []).
 {ok,<<"host1">>}
 5> alcove:gethostname(Drv, [Pid]).
 {ok,<<"test">>}
Link to this function

setns(Drv, Pids, FD, NSType)

View Source

Specs

setns(alcove_drv:ref(), [pid_t()], FD :: fd(), NSType :: constant()) -> ok | {error, posix()}.

setns(2): attach to a namespace

A process namespace is represented as a path in the /proc filesystem. The path is /proc/<pid>/ns/<ns>, where:

* pid: the system PID

* ns: a file representing the namespace

The available namespaces is dependent on the kernel version. You can see which are supported by running:

 ls -al /proc/$$/ns

Support

* Linux

Examples

Attach a process to an existing network namespace:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid1} = alcove:clone(Drv, [], [clone_newnet]).
 {ok,27125}
 3> {ok, Pid2} = alcove:fork(Drv, []).
 {ok,27126}
 % Move Pid2 into the Pid1 network namespace
 4> {ok, FD} = alcove:open(Drv, [Pid2], ["/proc/", integer_to_list(Pid1), "/ns/net"], [o_rdonly], 0).
 {ok,8}
 5> alcove:setns(Drv, [Pid2], FD, 0).
 ok
 6> alcove:close(Drv, [Pid2], FD).
Link to this function

setns(Drv, Pids, FD, NSType, Timeout)

View Source

Specs

setns(alcove_drv:ref(), [pid_t()], FD :: fd(), NSType :: constant(), timeout()) ->
         ok | {error, posix()}.

setns(2): attach to a namespace

A process namespace is represented as a path in the /proc filesystem. The path is /proc/<pid>/ns/<ns>, where:

* pid: the system PID

* ns: a file representing the namespace

The available namespaces is dependent on the kernel version. You can see which are supported by running:

 ls -al /proc/$$/ns

Support

* Linux

Examples

Attach a process to an existing network namespace:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid1} = alcove:clone(Drv, [], [clone_newnet]).
 {ok,27125}
 3> {ok, Pid2} = alcove:fork(Drv, []).
 {ok,27126}
 % Move Pid2 into the Pid1 network namespace
 4> {ok, FD} = alcove:open(Drv, [Pid2], ["/proc/", integer_to_list(Pid1), "/ns/net"], [o_rdonly], 0).
 {ok,8}
 5> alcove:setns(Drv, [Pid2], FD, 0).
 ok
 6> alcove:close(Drv, [Pid2], FD).
Link to this function

setopt(Drv, Pids, Opt, Val)

View Source

Specs

setopt(alcove_drv:ref(), [pid_t()], Opt :: atom(), Val :: int32_t()) -> boolean().

Set port options

See getopt/2,3 for the list of options.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:setopt(Drv, [], maxforkdepth, 128).
 true
Link to this function

setopt(Drv, Pids, Opt, Val, Timeout)

View Source

Specs

setopt(alcove_drv:ref(), [pid_t()], Opt :: atom(), Val :: int32_t(), timeout()) -> boolean().

Set port options

See getopt/2,3 for the list of options.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:setopt(Drv, [], maxforkdepth, 128).
 true
Link to this function

setpgid(Drv, Pids, OSPid, Pgid)

View Source

Specs

setpgid(alcove_drv:ref(), [pid_t()], OSPid :: pid_t(), Pgid :: pid_t()) -> ok | {error, posix()}.

setpgid(2): set process group

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28210}
 3> alcove:setpgid(Drv, [Pid], 0, 0).
 ok
Link to this function

setpgid(Drv, Pids, OSPid, Pgid, Timeout)

View Source

Specs

setpgid(alcove_drv:ref(), [pid_t()], OSPid :: pid_t(), Pgid :: pid_t(), timeout()) ->
           ok | {error, posix()}.

setpgid(2): set process group

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28210}
 3> alcove:setpgid(Drv, [Pid], 0, 0).
 ok
Link to this function

setpriority(Drv, Pids, Which, Who, Prio)

View Source

Specs

setpriority(alcove_drv:ref(), [pid_t()], Which :: constant(), Who :: int32_t(), Prio :: int32_t()) ->
               ok | {error, posix()}.

setpriority(2): set scheduling priority of process, process group or user

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28210}
 3> alcove:setpriority(Drv, [Pid], prio_process, 0, 10).
 ok
 4> alcove:getpriority(Drv, [Pid], prio_process, 0).
 {ok,10}
Link to this function

setpriority(Drv, Pids, Which, Who, Prio, Timeout)

View Source

Specs

setpriority(alcove_drv:ref(),
            [pid_t()],
            Which :: constant(),
            Who :: int32_t(),
            Prio :: int32_t(),
            timeout()) ->
               ok | {error, posix()}.

setpriority(2): set scheduling priority of process, process group or user

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28210}
 3> alcove:setpriority(Drv, [Pid], prio_process, 0, 10).
 ok
 4> alcove:getpriority(Drv, [Pid], prio_process, 0).
 {ok,10}
Link to this function

setproctitle(Drv, Pids, Title)

View Source

Specs

setproctitle(alcove_drv:ref(), [pid_t()], Title :: iodata()) -> ok.

setproctitle(3): set the process title

Overwrites arg0.

On Linux, prctl/6,7 can be used to set the command name:

 {ok,Fork} = alcove:fork(Drv, []),
 alcove:prctl(Drv, [Fork], pr_set_name, <<"pseudonym">>, 0,0,0).

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28210}
 3> alcove:setproctitle(Drv, [Pid], "new process name").
 ok
Link to this function

setproctitle(Drv, Pids, Title, Timeout)

View Source

Specs

setproctitle(alcove_drv:ref(), [pid_t()], Title :: iodata(), timeout()) -> ok.

setproctitle(3): set the process title

Overwrites arg0.

On Linux, prctl/6,7 can be used to set the command name:

 {ok,Fork} = alcove:fork(Drv, []),
 alcove:prctl(Drv, [Fork], pr_set_name, <<"pseudonym">>, 0,0,0).

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28210}
 3> alcove:setproctitle(Drv, [Pid], "new process name").
 ok
Link to this function

setresgid(Drv, Pids, Real, Effective, Saved)

View Source

Specs

setresgid(alcove_drv:ref(), [pid_t()], Real :: gid_t(), Effective :: gid_t(), Saved :: gid_t()) ->
             ok | {error, posix()}.

setresgid(2): set real, effective and saved group ID

Support

* Linux

* FreeBSD

* OpenBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:setresgid(Drv, [Pid], 123, 123, 123).
 ok
Link to this function

setresgid(Drv, Pids, Real, Effective, Saved, Timeout)

View Source

Specs

setresgid(alcove_drv:ref(),
          [pid_t()],
          Real :: gid_t(),
          Effective :: gid_t(),
          Saved :: gid_t(),
          timeout()) ->
             ok | {error, posix()}.

setresgid(2): set real, effective and saved group ID

Support

* Linux

* FreeBSD

* OpenBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:setresgid(Drv, [Pid], 123, 123, 123).
 ok
Link to this function

setresuid(Drv, Pids, Real, Effective, Saved)

View Source

Specs

setresuid(alcove_drv:ref(), [pid_t()], Real :: uid_t(), Effective :: uid_t(), Saved :: uid_t()) ->
             ok | {error, posix()}.

setresuid(2): set real, effective and saved user ID

Support

* Linux

* FreeBSD

* OpenBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:setresuid(Drv, [Pid], 123, 123, 123).
 ok
Link to this function

setresuid(Drv, Pids, Real, Effective, Saved, Timeout)

View Source

Specs

setresuid(alcove_drv:ref(),
          [pid_t()],
          Real :: uid_t(),
          Effective :: uid_t(),
          Saved :: uid_t(),
          timeout()) ->
             ok | {error, posix()}.

setresuid(2): set real, effective and saved user ID

Support

* Linux

* FreeBSD

* OpenBSD

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:setresuid(Drv, [Pid], 123, 123, 123).
 ok
Link to this function

setrlimit(Drv, Pids, Resource, Limit)

View Source

Specs

setrlimit(alcove_drv:ref(), [pid_t()], Resource :: constant(), Limit :: alcove_rlimit()) ->
             ok | {error, posix()}.

setrlimit(2): set a resource limit

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 3> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 4> alcove:getrlimit(Drv, [Pid], rlimit_nofile).
 {ok,#alcove_rlimit{cur = 1024,max = 1048576}}
 5> alcove:setrlimit(Drv, [Pid], rlimit_nofile, #alcove_rlimit{cur = 64, max = 64}).
 ok
 6> alcove:getrlimit(Drv, [Pid], rlimit_nofile).
 {ok,#alcove_rlimit{cur = 64,max = 64}}
Link to this function

setrlimit(Drv, Pids, Resource, Limit, Timeout)

View Source

Specs

setrlimit(alcove_drv:ref(),
          [pid_t()],
          Resource :: constant(),
          Limit :: alcove_rlimit(),
          timeout()) ->
             ok | {error, posix()}.

setrlimit(2): set a resource limit

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 3> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 4> alcove:getrlimit(Drv, [Pid], rlimit_nofile).
 {ok,#alcove_rlimit{cur = 1024,max = 1048576}}
 5> alcove:setrlimit(Drv, [Pid], rlimit_nofile, #alcove_rlimit{cur = 64, max = 64}).
 ok
 6> alcove:getrlimit(Drv, [Pid], rlimit_nofile).
 {ok,#alcove_rlimit{cur = 64,max = 64}}

Specs

setsid(alcove_drv:ref(), [pid_t()]) -> {ok, OSPid :: pid_t()} | {error, posix()}.

setsid(2): create a new session

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:setsid(Drv, [Pid]).
 {ok,28493}
Link to this function

setsid(Drv, Pids, Timeout)

View Source

Specs

setsid(alcove_drv:ref(), [pid_t()], timeout()) -> {ok, OSPid :: pid_t()} | {error, posix()}.

setsid(2): create a new session

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:setsid(Drv, [Pid]).
 {ok,28493}

Specs

setuid(alcove_drv:ref(), [pid_t()], User :: uid_t()) -> ok | {error, posix()}.

setuid(2): change UID

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 72> alcove:setuid(Drv, [Pid], 123).
 ok
 73> alcove:getuid(Drv, [Pid]).
 123
Link to this function

setuid(Drv, Pids, User, Timeout)

View Source

Specs

setuid(alcove_drv:ref(), [pid_t()], User :: uid_t(), timeout()) -> ok | {error, posix()}.

setuid(2): change UID

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.208.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,44378}
 72> alcove:setuid(Drv, [Pid], 123).
 ok
 73> alcove:getuid(Drv, [Pid]).
 123
Link to this function

sigaction(Drv, Pids, Signum, Handler)

View Source

Specs

sigaction(alcove_drv:ref(), [pid_t()], Signum :: constant(), Handler :: [] | atom()) ->
             {ok, OldHandler :: atom()} | {error, posix()}.

sigaction(2): set process behaviour for signals

* sig_dfl

Uses the default behaviour for the signal

* sig_ign

Ignores the signal

* sig_info

Catches the signal and sends the controlling Erlang process an event:

 {signal, atom(), Info}

Info is a binary containing the siginfo_t structure. See sigaction(2) for details.

* []

Returns the current handler for the signal.

Multiple caught signals of the same type may be reported as one event.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 3> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 4> alcove:kill(Drv, [], Pid, sigterm).
 ok
 5> flush().
 Shell got {alcove_event,<0.177.0>,
                         [28493],
                         {signal,sigterm,
                                 <<15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,111,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0>>}}
 ok
 6> alcove:sigaction(Drv, [Pid], sigterm, sig_ign).
 {ok,sig_info}
 7> alcove:kill(Drv, [], Pid, sigterm).
 ok
 8> flush().
 ok
 9> alcove:sigaction(Drv, [Pid], sigterm, sig_info).
 {ok,sig_ign}
 10> alcove:kill(Drv, [], Pid, sigterm).
 ok
 11> flush().
 Shell got {alcove_event,<0.177.0>,
                         [28493],
                         {signal,sigterm,
                                 <<15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,111,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0>>}}
 ok
Link to this function

sigaction(Drv, Pids, Signum, Handler, Timeout)

View Source

Specs

sigaction(alcove_drv:ref(), [pid_t()], Signum :: constant(), Handler :: [] | atom(), timeout()) ->
             {ok, OldHandler :: atom()} | {error, posix()}.

sigaction(2): set process behaviour for signals

* sig_dfl

Uses the default behaviour for the signal

* sig_ign

Ignores the signal

* sig_info

Catches the signal and sends the controlling Erlang process an event:

 {signal, atom(), Info}

Info is a binary containing the siginfo_t structure. See sigaction(2) for details.

* []

Returns the current handler for the signal.

Multiple caught signals of the same type may be reported as one event.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> rr(alcove).
 [alcove_jail,alcove_pid,alcove_rlimit,alcove_timeval]
 3> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 4> alcove:kill(Drv, [], Pid, sigterm).
 ok
 5> flush().
 Shell got {alcove_event,<0.177.0>,
                         [28493],
                         {signal,sigterm,
                                 <<15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,111,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0>>}}
 ok
 6> alcove:sigaction(Drv, [Pid], sigterm, sig_ign).
 {ok,sig_info}
 7> alcove:kill(Drv, [], Pid, sigterm).
 ok
 8> flush().
 ok
 9> alcove:sigaction(Drv, [Pid], sigterm, sig_info).
 {ok,sig_ign}
 10> alcove:kill(Drv, [], Pid, sigterm).
 ok
 11> flush().
 Shell got {alcove_event,<0.177.0>,
                         [28493],
                         {signal,sigterm,
                                 <<15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,111,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                   0,0,0,0>>}}
 ok
Link to this function

signal_constant(Drv, Pids, Symbol)

View Source

Specs

signal_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> unknown | non_neg_integer().

Convert signal names to integers

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:signal_constant(Drv, [], 'SIGHUP').
 1
 3> alcove:signal_constant(Drv, [], sighup).
 1
Link to this function

signal_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

signal_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) ->
                   unknown | non_neg_integer().

Convert signal names to integers

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:signal_constant(Drv, [], 'SIGHUP').
 1
 3> alcove:signal_constant(Drv, [], sighup).
 1
Link to this function

socket(Drv, Pids, Domain, Type, Protocol)

View Source

Specs

socket(alcove_drv:ref(),
       [pid_t()],
       Domain :: constant(),
       Type :: constant(),
       Protocol :: int32_t()) ->
          {ok, fd()} | {error, posix()}.

socket(2): returns a file descriptor for a communication endpoint

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Socket} = alcove:socket(Drv, [], af_inet, sock_stream, 0).
 {ok,6}
 3> alcove:close(Drv, [], Socket).
 ok
Link to this function

socket(Drv, Pids, Domain, Type, Protocol, Timeout)

View Source

Specs

socket(alcove_drv:ref(),
       [pid_t()],
       Domain :: constant(),
       Type :: constant(),
       Protocol :: int32_t(),
       timeout()) ->
          {ok, fd()} | {error, posix()}.

socket(2): returns a file descriptor for a communication endpoint

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Socket} = alcove:socket(Drv, [], af_inet, sock_stream, 0).
 {ok,6}
 3> alcove:close(Drv, [], Socket).
 ok

Specs

stderr(alcove_drv:ref(), [pid_t()]) -> [binary()].

Read stderr from the process

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:execvp(Drv, [Pid], "cat", ["cat", "/nonexistent"]).
 ok
 4> alcove:stderr(Drv, [Pid]).
 [<<"cat: /nonexistent: No such file or directoryn">>]
Link to this function

stderr(Drv, Pids, Timeout)

View Source

Specs

stderr(alcove_drv:ref(), [pid_t()], timeout()) -> [binary()].

Specs

stdin(alcove_drv:ref(), [pid_t()], iodata()) -> ok.

Send data to stdin of the process

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:execvp(Drv, [Pid], "cat", ["cat"]).
 ok
 4> alcove:stdin(Drv, [Pid], "testn").
 ok
 5> alcove:stdout(Drv, [Pid]).
 [<<"testn">>]

Specs

stdout(alcove_drv:ref(), [pid_t()]) -> [binary()].

Read stdout from the process

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:execvp(Drv, [Pid], "cat", ["cat"]).
 ok
 4> alcove:stdin(Drv, [Pid], "testn").
 ok
 5> alcove:stdout(Drv, [Pid]).
 [<<"testn">>]
Link to this function

stdout(Drv, Pids, Timeout)

View Source

Specs

stdout(alcove_drv:ref(), [pid_t()], timeout()) -> [binary()].
Link to this function

symlink(Drv, Pids, OldPath, NewPath)

View Source

Specs

symlink(alcove_drv:ref(), [pid_t()], OldPath :: iodata(), NewPath :: iodata()) ->
           ok | {error, posix()}.

symlink(2): create a symbolic link

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:symlink(Drv, [], "/etc/hosts", "/tmp/hosts.tmp").
 ok
Link to this function

symlink(Drv, Pids, OldPath, NewPath, Timeout)

View Source

Specs

symlink(alcove_drv:ref(), [pid_t()], OldPath :: iodata(), NewPath :: iodata(), timeout()) ->
           ok | {error, posix()}.

symlink(2): create a symbolic link

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:symlink(Drv, [], "/etc/hosts", "/tmp/hosts.tmp").
 ok
Link to this function

syscall_constant(Drv, Pids, Symbol)

View Source

Specs

syscall_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom()) -> unknown | non_neg_integer().

Convert syscall name to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:syscall_constant(Drv, [], 'SYS_exit').
 60
 3> alcove:syscall_constant(Drv, [], sys_exit).
 60
Link to this function

syscall_constant(Drv, Pids, Symbol, Timeout)

View Source

Specs

syscall_constant(alcove_drv:ref(), [pid_t()], Symbol :: atom(), timeout()) ->
                    unknown | non_neg_integer().

Convert syscall name to integer

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:syscall_constant(Drv, [], 'SYS_exit').
 60
 3> alcove:syscall_constant(Drv, [], sys_exit).
 60

Specs

umount(alcove_drv:ref(), [pid_t()], Path :: iodata()) -> ok | {error, posix()}.

umount(2): unmount a filesystem

On BSD systems, calls unmount(2).

Examples

An example of bind mounting a directory within a linux mount namespace:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newns]).
 {ok,10059}
 3> alcove:mount(Drv, [Pid], "/tmp", "/mnt", "", [ms_bind, ms_rdonly, ms_noexec], "", "").
 ok
 4> alcove:umount(Drv, [Pid], "/mnt").
 ok
Link to this function

umount(Drv, Pids, Path, Timeout)

View Source

Specs

umount(alcove_drv:ref(), [pid_t()], Path :: iodata(), timeout()) -> ok | {error, posix()}.

umount(2): unmount a filesystem

On BSD systems, calls unmount(2).

Examples

An example of bind mounting a directory within a linux mount namespace:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newns]).
 {ok,10059}
 3> alcove:mount(Drv, [Pid], "/tmp", "/mnt", "", [ms_bind, ms_rdonly, ms_noexec], "", "").
 ok
 4> alcove:umount(Drv, [Pid], "/mnt").
 ok
Link to this function

umount2(Drv, Pids, Path, Flags)

View Source

Specs

umount2(alcove_drv:ref(), [pid_t()], Path :: iodata(), Flags :: int32_t() | [constant()]) ->
           ok | {error, posix()}.

umount2(2): unmount filesystem with flags

Support

* Linux

Examples

An example of bind mounting a directory within a linux mount namespace:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newns]).
 {ok,10059}
 3> alcove:mount(Drv, [Pid], "/tmp", "/mnt", "", [ms_bind, ms_rdonly, ms_noexec], "", "").
 ok
 4> alcove:umount2(Drv, [Pid], "/mnt", [mnt_detach]).
 ok
Link to this function

umount2(Drv, Pids, Path, Flags, Timeout)

View Source

Specs

umount2(alcove_drv:ref(),
        [pid_t()],
        Path :: iodata(),
        Flags :: int32_t() | [constant()],
        timeout()) ->
           ok | {error, posix()}.

umount2(2): unmount filesystem with flags

Support

* Linux

Examples

An example of bind mounting a directory within a linux mount namespace:

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:clone(Drv, [], [clone_newns]).
 {ok,10059}
 3> alcove:mount(Drv, [Pid], "/tmp", "/mnt", "", [ms_bind, ms_rdonly, ms_noexec], "", "").
 ok
 4> alcove:umount2(Drv, [Pid], "/mnt", [mnt_detach]).
 ok

Specs

unlink(alcove_drv:ref(), [pid_t()], Path :: iodata()) -> ok | {error, posix()}.

unlink(2): delete a name from the filesystem

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:open(Drv, [], "/tmp/alcove-open-test", [o_wronly,o_creat], 8#644).
 {ok,6}
 3> alcove:unlink(Drv, [], "/tmp/alcove-open-test").
 ok
Link to this function

unlink(Drv, Pids, Path, Timeout)

View Source

Specs

unlink(alcove_drv:ref(), [pid_t()], Path :: iodata(), timeout()) -> ok | {error, posix()}.

unlink(2): delete a name from the filesystem

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:open(Drv, [], "/tmp/alcove-open-test", [o_wronly,o_creat], 8#644).
 {ok,6}
 3> alcove:unlink(Drv, [], "/tmp/alcove-open-test").
 ok
Link to this function

unsetenv(Drv, Pids, Name)

View Source

Specs

unsetenv(alcove_drv:ref(), [pid_t()], Name :: iodata()) -> ok | {error, posix()}.

unsetenv(3): remove an environment variable

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:setenv(Drv, [], "ALCOVE_TEST", "foo", 0).
 ok
 3> alcove:getenv(Drv, [], "ALCOVE_TEST").
 <<"foo">>
 4> alcove:unsetenv(Drv, [], "ALCOVE_TEST").
 ok
 5> alcove:getenv(Drv, [], "ALCOVE_TEST").
 false
Link to this function

unsetenv(Drv, Pids, Name, Timeout)

View Source

Specs

unsetenv(alcove_drv:ref(), [pid_t()], Name :: iodata(), timeout()) -> ok | {error, posix()}.

unsetenv(3): remove an environment variable

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:setenv(Drv, [], "ALCOVE_TEST", "foo", 0).
 ok
 3> alcove:getenv(Drv, [], "ALCOVE_TEST").
 <<"foo">>
 4> alcove:unsetenv(Drv, [], "ALCOVE_TEST").
 ok
 5> alcove:getenv(Drv, [], "ALCOVE_TEST").
 false
Link to this function

unshare(Drv, Pids, Flags)

View Source

Specs

unshare(alcove_drv:ref(), [pid_t()], Flags :: int32_t() | [constant()]) -> ok | {error, posix()}.

unshare(2): create a new namespace in the current process

Make a new namespace without calling clone(2):

 ok = alcove:unshare(Drv, [], [clone_newnet]).
 % The port is now running in a namespace without network access.

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:unshare(Drv, [Pid], [clone_newuts]).
 ok
 4> alcove:sethostname(Drv, [Pid], "unshare").
 ok
 5> alcove:gethostname(Drv, [Pid]).
 {ok,<<"unshare">>}
 6> alcove:gethostname(Drv, []).
 {ok,<<"host1">>}
Link to this function

unshare(Drv, Pids, Flags, Timeout)

View Source

Specs

unshare(alcove_drv:ref(), [pid_t()], Flags :: int32_t() | [constant()], timeout()) ->
           ok | {error, posix()}.

unshare(2): create a new namespace in the current process

Make a new namespace without calling clone(2):

 ok = alcove:unshare(Drv, [], [clone_newnet]).
 % The port is now running in a namespace without network access.

Examples

 1> {ok, Drv} = alcove_drv:start([{exec, "sudo -n"}]).
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28493}
 3> alcove:unshare(Drv, [Pid], [clone_newuts]).
 ok
 4> alcove:sethostname(Drv, [Pid], "unshare").
 ok
 5> alcove:gethostname(Drv, [Pid]).
 {ok,<<"unshare">>}
 6> alcove:gethostname(Drv, []).
 {ok,<<"host1">>}
Link to this function

unveil(Drv, Pids, Path, Permissions)

View Source

Specs

unveil(alcove_drv:ref(), [pid_t()], Path :: iodata(), Permissions :: iodata()) ->
          ok | {error, posix()}.

unveil(2): restrict filesystem view

To disable unveil calls, use an empty list ([]) or, equivalently, an empty string ("").

 alcove:unveil(Drv, [Task], <<"/etc">>, <<"r">>),
 alcove:unveil(Drv, [Task], [], []).

Support

* OpenBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28978}
 3> alcove:unveil(Drv, [Pid], <<"/etc">>, <<"r">>).
 ok
 4> alcove:unveil(Drv, [Task], [], []).
 ok
Link to this function

unveil(Drv, Pids, Path, Permissions, Timeout)

View Source

Specs

unveil(alcove_drv:ref(), [pid_t()], Path :: iodata(), Permissions :: iodata(), timeout()) ->
          ok | {error, posix()}.

unveil(2): restrict filesystem view

To disable unveil calls, use an empty list ([]) or, equivalently, an empty string ("").

 alcove:unveil(Drv, [Task], <<"/etc">>, <<"r">>),
 alcove:unveil(Drv, [Task], [], []).

Support

* OpenBSD

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28978}
 3> alcove:unveil(Drv, [Pid], <<"/etc">>, <<"r">>).
 ok
 4> alcove:unveil(Drv, [Task], [], []).
 ok

Specs

version(alcove_drv:ref(), [pid_t()]) -> binary().

Retrieve the alcove version

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:version(Drv, []).
 <<"0.37.0">>
Link to this function

version(Drv, Pids, Timeout)

View Source

Specs

version(alcove_drv:ref(), [pid_t()], timeout()) -> binary().

Retrieve the alcove version

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> alcove:version(Drv, []).
 <<"0.37.0">>
Link to this function

waitpid(Drv, Pids, OSPid, Options)

View Source

Specs

waitpid(alcove_drv:ref(), [pid_t()], OSPid :: pid_t(), Options :: int32_t() | [constant()]) ->
           {ok, pid_t(), WaitStatus :: [waitstatus()]} | {error, posix()}.

waitpid(2): wait for process to change state

Process state changes are handled by the alcove SIGCHLD event handler by default. To use waitpid/4,5, disable the signal handler:

 alcove:sigaction(Drv, [Pid], sigchld, sig_info)

Note: if the default SIGCHLD handler is disabled, waitpid/4,5 should be called to reap zombie processes:

 alcove:waitpid(Drv, [], -1, [wnohang])

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28978}
 3> alcove:sigaction(Drv, [Pid], sigchld, sig_info).
 {ok,sig_dfl}
 4> alcove:execvp(Drv, [Pid], "sleep", ["sleep", "20"]).
 ok
 5> alcove:waitpid(Drv, [], -1, []).
 {ok,28978,0,[{exit_status,0}]}
Link to this function

waitpid(Drv, Pids, OSPid, Options, Timeout)

View Source

Specs

waitpid(alcove_drv:ref(),
        [pid_t()],
        OSPid :: pid_t(),
        Options :: int32_t() | [constant()],
        timeout()) ->
           {ok, pid_t(), WaitStatus :: [waitstatus()]} | {error, posix()}.

waitpid(2): wait for process to change state

Process state changes are handled by the alcove SIGCHLD event handler by default. To use waitpid/4,5, disable the signal handler:

 alcove:sigaction(Drv, [Pid], sigchld, sig_info)

Note: if the default SIGCHLD handler is disabled, waitpid/4,5 should be called to reap zombie processes:

 alcove:waitpid(Drv, [], -1, [wnohang])

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, Pid} = alcove:fork(Drv, []).
 {ok,28978}
 3> alcove:sigaction(Drv, [Pid], sigchld, sig_info).
 {ok,sig_dfl}
 4> alcove:execvp(Drv, [Pid], "sleep", ["sleep", "20"]).
 ok
 5> alcove:waitpid(Drv, [], -1, []).
 {ok,28978,0,[{exit_status,0}]}
Link to this function

write(Drv, Pids, FD, Buf)

View Source

Specs

write(alcove_drv:ref(), [pid_t()], FD :: fd(), Buf :: iodata()) ->
         {ok, Count :: ssize_t()} | {error, posix()}.

write(2): write to a file descriptor

Writes a buffer to a file descriptor and returns the number of bytes written.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, FD} = alcove:open(Drv, [], "/tmp/alcove-write-test", [o_wronly,o_creat], 8#644).
 {ok,6}
 3> alcove:write(Drv, [], FD, <<"test">>).
 {ok,4}
Link to this function

write(Drv, Pids, FD, Buf, Timeout)

View Source

Specs

write(alcove_drv:ref(), [pid_t()], FD :: fd(), Buf :: iodata(), timeout()) ->
         {ok, Count :: ssize_t()} | {error, posix()}.

write(2): write to a file descriptor

Writes a buffer to a file descriptor and returns the number of bytes written.

Examples

 1> {ok, Drv} = alcove_drv:start().
 {ok,<0.177.0>}
 2> {ok, FD} = alcove:open(Drv, [], "/tmp/alcove-write-test", [o_wronly,o_creat], 8#644).
 {ok,6}
 3> alcove:write(Drv, [], FD, <<"test">>).
 {ok,4}