mirror of
https://github.com/uselessd/alcove.git
synced 2026-04-15 01:04:41 +00:00
Remove function versions with optional fork path
Enforce the use of the fork path. Having an optional fork path was nice
when working in the shell:
{ok, Child} = alcove:fork(Drv).
Instead of:
{ok, Child} = alcove:fork(Drv, []). % port process forks
However it introduced a few problems:
* made the interface inconsistent and ambiguous
alcove:kill(Drv, Pid, 9)
% vs
alcove:kill(Drv, [], Pid, 9) % the port process is sending the signal
* calls could not have optional arguments
Whether or not calls should have optional arguments is an open question
but the optional fork path would have conflicting arities:
For example, the last argument to mount/8 is used only by Solaris:
% arity 6
-spec mount(alcove_drv:ref(),iodata(),iodata(),iodata(),uint64_t() | [constant()],iodata()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
% arity 7
-spec mount(alcove_drv:ref(),iodata(),iodata(),iodata(),uint64_t() | [constant()],iodata(),iodata()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
% arity 7
-spec mount(alcove_drv:ref(),fork_path(),iodata(),iodata(),iodata(),uint64_t() | [constant()],iodata()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
% arity 8
-spec mount(alcove_drv:ref(),fork_path(),iodata(),iodata(),iodata(),uint64_t() | [constant()],iodata(),iodata()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
* because of the ambiguity in arity, each call can't have an optional
timeout
call/5 sets a timeout of 'infinity'. The timeout isn't accessible from
the "named" functions (e.g., fork, chdir, ...), which means that users
who need the timeout will have to resort to using the call/5
interface. An unfortunate side effect of using call/5 is that dialzyer
won't be able to type check the arguments.
The result of removing the functions without the fork path is that the
code ends up being simpler and more consistent.
This commit is contained in:
107
README.md
107
README.md
@@ -19,7 +19,7 @@ Much like a shell, alcove waits for a command. For example, alcove can
|
||||
be requested to fork(2):
|
||||
|
||||
```erlang
|
||||
{ok, Child1} = alcove:fork(Drv).
|
||||
{ok, Child1} = alcove:fork(Drv, []).
|
||||
```
|
||||
|
||||
Now there are 2 processes in a parent/child relationship, sitting in
|
||||
@@ -33,7 +33,6 @@ Child2 = alcove:getpid(Drv, [Child1,Child2]).
|
||||
An empty fork path refers to the port process:
|
||||
|
||||
```erlang
|
||||
% Same as doing: alcove:fork(Drv).
|
||||
{ok, Child3} = alcove:fork(Drv, []).
|
||||
```
|
||||
|
||||
@@ -157,7 +156,7 @@ sandbox(Drv) ->
|
||||
sandbox(Drv, Argv) ->
|
||||
{Path, Arg0, Args} = argv(Argv),
|
||||
|
||||
{ok, Child} = alcove:fork(Drv),
|
||||
{ok, Child} = alcove:fork(Drv, []),
|
||||
|
||||
setlimits(Drv, Child),
|
||||
chroot(Drv, Child, Path),
|
||||
@@ -218,7 +217,7 @@ true
|
||||
<<"sh: can't fork\n">>
|
||||
|
||||
% If we check the parent for events, we can see the child has exited
|
||||
10> alcove:event(P).
|
||||
10> alcove:event(P, []).
|
||||
{signal,sigchld}
|
||||
```
|
||||
|
||||
@@ -281,7 +280,7 @@ setlimits(Drv, Child) ->
|
||||
sandbox(Drv, Argv) ->
|
||||
{Path, Arg0, Args} = argv(Argv),
|
||||
|
||||
{ok, Child} = alcove:clone(Drv, [
|
||||
{ok, Child} = alcove:clone(Drv, [], [
|
||||
clone_newipc, % IPC
|
||||
clone_newnet, % network
|
||||
clone_newns, % mounts
|
||||
@@ -350,15 +349,6 @@ alcove_drv
|
||||
alcove
|
||||
======
|
||||
|
||||
If any of these functions do not include the fork path, the call is
|
||||
evaluated by the port. The following functions are equivalent:
|
||||
|
||||
alcove:getpid(Drv)
|
||||
alcove:getpid(Drv, [])
|
||||
|
||||
alcove:chown(Drv, "/tmp/test", 8#600)
|
||||
alcove:chown(Drv, [], "/tmp/test", 8#600)
|
||||
|
||||
Functions marked as operating system specific will return
|
||||
{error,unsupported} on other platforms.
|
||||
|
||||
@@ -381,34 +371,28 @@ probably confuse the process.
|
||||
Functions accepting a constant() will return {error, unsupported} if an
|
||||
atom is used as the argument and is not found on the platform.
|
||||
|
||||
chdir(Drv, Path) -> ok | {error, posix()}
|
||||
chdir(Drv, Pids, Path) -> ok | {error, posix()}
|
||||
|
||||
chdir(2) : change process current working directory.
|
||||
|
||||
chmod(Drv, Path, Mode) -> ok | {error, posix()}
|
||||
chmod(Drv, Pids, Path, Mode) -> ok | {error, posix()}
|
||||
|
||||
chmod(2) : change file permissions
|
||||
|
||||
chown(Drv, Path, Owner, Group) -> ok | {error, posix()}
|
||||
chown(Drv, Pids, Path, Owner, Group) -> ok | {error, posix()}
|
||||
|
||||
Types Owner = Group = non_neg_integer()
|
||||
|
||||
chown(2) : change file ownership
|
||||
|
||||
chroot(Drv, Path) -> ok | {error, posix()}
|
||||
chroot(Drv, Pids, Path) -> ok | {error, posix()}
|
||||
|
||||
chroot(2) : change root directory
|
||||
|
||||
clearenv(Drv) -> ok | {error, posix()}
|
||||
clearenv(Drv, Pids) -> ok | {error, posix()}
|
||||
|
||||
clearenv(3) : zero process environment
|
||||
|
||||
clone(Drv, Flags) -> {ok, integer()} | {error, posix() | unsupported}
|
||||
clone(Drv, Pids, Flags) -> {ok, integer()} | {error, posix() | unsupported}
|
||||
|
||||
Types Flags = integer() | [constant()]
|
||||
@@ -417,31 +401,26 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
clone(2) : create a new process
|
||||
|
||||
clone_define(Drv, atom()) -> integer() | unknown
|
||||
clone_define(Drv, Pids, atom()) -> integer() | unknown
|
||||
|
||||
Linux only.
|
||||
|
||||
Map symbols to integer constants.
|
||||
|
||||
close(Drv, FD) -> ok | {error, posix()}
|
||||
close(Drv, Pids, FD) -> ok | {error, posix()}
|
||||
|
||||
close(2) : close a file descriptor.
|
||||
|
||||
environ(Drv) -> [binary()]
|
||||
environ(Drv, Pids) -> [binary()]
|
||||
|
||||
environ(7) : return the process environment variables
|
||||
|
||||
event(Drv) -> term()
|
||||
event(Drv, Pids) -> term()
|
||||
|
||||
event/1,2 is used to retrieve async messages returned from the
|
||||
port, such as caught signals, the exit status or the termination
|
||||
signal.
|
||||
|
||||
execve(Drv, Arg0, [Arg0, Args], Env) -> ok | {error, posix()}
|
||||
execve(Drv, Pids, Arg0, [Arg0, Args], Env) -> ok | {error, posix()}
|
||||
|
||||
Types Arg0 = Args = iodata()
|
||||
@@ -450,7 +429,6 @@ atom is used as the argument and is not found on the platform.
|
||||
execve(2) : replace the process image, specifying the environment
|
||||
for the new process image.
|
||||
|
||||
execvp(Drv, Arg0, [Arg0, Args]) -> ok | {error, posix()}
|
||||
execvp(Drv, Pids, Arg0, [Arg0, Args]) -> ok | {error, posix()}
|
||||
|
||||
Types Arg0 = Args = iodata()
|
||||
@@ -458,44 +436,36 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
execvp(2) : replace the current process image using the search path
|
||||
|
||||
exit(Drv, Value) -> ok
|
||||
exit(Drv, Pids, Value) -> ok
|
||||
|
||||
Types Value = integer()
|
||||
|
||||
exit(3) : cause the child process to exit
|
||||
|
||||
file_define(Drv, atom()) -> integer() | unknown
|
||||
file_define(Drv, Pids, atom()) -> integer() | unknown
|
||||
|
||||
Constants for open(2).
|
||||
|
||||
fork(Drv) -> {ok, integer()} | {error, posix()}
|
||||
fork(Drv, Pids) -> {ok, integer()} | {error, posix()}
|
||||
|
||||
fork(2) : create a new process
|
||||
|
||||
getcwd(Drv) -> {ok, binary()} | {error, posix()}
|
||||
getcwd(Drv, Pids) -> {ok, binary()} | {error, posix()}
|
||||
|
||||
getcwd(3) : return the current working directory
|
||||
|
||||
getenv(Drv, iodata()) -> binary() | false
|
||||
getenv(Drv, Pids, iodata()) -> binary() | false
|
||||
|
||||
getenv(3) : retrieve an environment variable
|
||||
|
||||
getgid(Drv) -> non_neg_integer()
|
||||
getgid(Drv, Pids) -> non_neg_integer()
|
||||
|
||||
getgid(2) : retrieve the processes' group ID
|
||||
|
||||
gethostname(Drv) -> {ok, binary()} | {error, posix()}
|
||||
gethostname(Drv, Pids) -> {ok, binary()} | {error, posix()}
|
||||
|
||||
gethostname(2) : retrieve the system hostname
|
||||
|
||||
getopt(Drv, Options) -> integer() | false
|
||||
getopt(Drv, Pids, Options) -> integer() | false
|
||||
|
||||
Types Options = verbose | childlimit | exit_status | maxchild |
|
||||
@@ -539,17 +509,14 @@ atom is used as the argument and is not found on the platform.
|
||||
If a child process exits because of a signal, notify
|
||||
the controlling Erlang process.
|
||||
|
||||
getpgrp(Drv) -> integer()
|
||||
getpgrp(Drv, Pids) -> integer()
|
||||
|
||||
getpgrp(2) : retrieve the process group.
|
||||
|
||||
getpid(Drv) -> integer()
|
||||
getpid(Drv, Pids) -> integer()
|
||||
|
||||
getpid(2) : retrieve the system PID of the process.
|
||||
|
||||
getpriority(Drv, Which, Who) -> {ok, Prio} | {error, posix() | unsupported}
|
||||
getpriority(Drv, Pids, Which, Who) -> {ok, Prio} | {error, posix() | unsupported}
|
||||
|
||||
Types Which = constant()
|
||||
@@ -558,7 +525,6 @@ atom is used as the argument and is not found on the platform.
|
||||
getpriority(2) : retrieve scheduling priority of process,
|
||||
process group or user
|
||||
|
||||
getresgid(Drv) -> {ok, RGID, EGID, SGID}
|
||||
getresgid(Drv, Pids) -> {ok, RGID, EGID, SGID}
|
||||
|
||||
Types RGID = EGID = SGID = non_neg_integer()
|
||||
@@ -567,7 +533,6 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
Supported on Linux and BSD's.
|
||||
|
||||
getresuid(Drv) -> {ok, RUID, EUID, SUID}
|
||||
getresuid(Drv, Pids) -> {ok, RUID, EUID, SUID}
|
||||
|
||||
Types RUID = EUID = SUID = non_neg_integer()
|
||||
@@ -576,7 +541,6 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
Supported on Linux and BSD's.
|
||||
|
||||
getrlimit(Drv, constant()) -> {ok, #alcove_rlimit{}} | {error, posix() | unsupported}
|
||||
getrlimit(Drv, Pids, constant()) -> {ok, #alcove_rlimit{}} | {error, posix() | unsupported}
|
||||
|
||||
getrlimit(2) : retrive the resource limits for a process. Returns
|
||||
@@ -589,37 +553,30 @@ atom is used as the argument and is not found on the platform.
|
||||
max = integer()
|
||||
}
|
||||
|
||||
getsid(Drv, Pid) -> {ok, integer()} | {error, posix()}
|
||||
getsid(Drv, Pids, Pid) -> {ok, integer()} | {error, posix()}
|
||||
|
||||
getsid(2) : retrieve the session ID
|
||||
|
||||
getuid(Drv) -> integer()
|
||||
getuid(Drv, Pids) -> integer()
|
||||
|
||||
getuid(2) : returns the process user ID
|
||||
|
||||
kill(Drv, Pid, Signal) -> ok | {error, posix() | unsupported}
|
||||
kill(Drv, Pids, Pid, Signal) -> ok | {error, posix() | unsupported}
|
||||
|
||||
Types Signal = constant()
|
||||
|
||||
kill(2) : terminate a process
|
||||
|
||||
lseek(Drv, FD, Offset, Whence) -> ok | {error, posix()}
|
||||
lseek(Drv, Pids, FD, Offset, Whence) -> ok | {error, posix()}
|
||||
|
||||
Types Offset = Whence = integer()
|
||||
|
||||
lseek(2) : set file offset for read/write
|
||||
|
||||
mkdir(Drv, Path, Mode) -> ok | {error, posix()}
|
||||
mkdir(Drv, Pids, Path, Mode) -> ok | {error, posix()}
|
||||
|
||||
mkdir(2) : create a directory
|
||||
|
||||
mount(Drv, Source, Target, FSType, Flags, Data, Options) -> ok
|
||||
| {error, posix() | unsupported}
|
||||
mount(Drv, Pids, Source, Target, FSType, Flags, Data, Options) -> ok
|
||||
| {error, posix() | unsupported}
|
||||
|
||||
@@ -637,7 +594,6 @@ atom is used as the argument and is not found on the platform.
|
||||
as a string of comma separated values terminated by a NULL.
|
||||
Other platforms ignore the Options parameter.
|
||||
|
||||
mount_define(Drv, Flag) -> integer() | unknown
|
||||
mount_define(Drv, Pids, Flag) -> integer() | unknown
|
||||
|
||||
Types Flag = rdonly | nosuid | noexec | noatime | ...
|
||||
@@ -645,12 +601,11 @@ atom is used as the argument and is not found on the platform.
|
||||
Convert flag names to integers. The lower case atoms are used
|
||||
for portability:
|
||||
|
||||
alcove:mount_define(Drv, rdonly)
|
||||
alcove:mount_define(Drv, [], rdonly)
|
||||
|
||||
'rdonly' is mapped to MS_RDONLY on Linux and MNT_RDONLY on
|
||||
FreeBSD.
|
||||
|
||||
open(Drv, Path, Flags, Mode) -> {ok, integer()} | {error, posix() | unsupported}
|
||||
open(Drv, Pids, Path, Flags, Mode) -> {ok, integer()} | {error, posix() | unsupported}
|
||||
|
||||
Types Flags = integer() | [constant()]
|
||||
@@ -660,15 +615,12 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
Lists of values are OR'ed:
|
||||
|
||||
alcove:open(Drv, "/tmp/test", [o_wronly,o_creat], 8#644)
|
||||
alcove:open(Drv, [], "/tmp/test", [o_wronly,o_creat], 8#644)
|
||||
|
||||
pid(Drv) -> [Pid]
|
||||
pid(Drv, Pids) -> [Pid]
|
||||
|
||||
Returns the list of child PIDs for this process.
|
||||
|
||||
prctl(Drv, Option, Arg2, Arg3, Arg4, Arg5) ->
|
||||
{ok, integer(), Val2, Val3, Val4, Val5} | {error, posix() | unsupported}
|
||||
prctl(Drv, Pids, Option, Arg2, Arg3, Arg4, Arg5) ->
|
||||
{ok, integer(), Val2, Val3, Val4, Val5} | {error, posix() | unsupported}
|
||||
|
||||
@@ -714,7 +666,7 @@ atom is used as the argument and is not found on the platform.
|
||||
% See test/alcove_seccomp_tests.erl for all the syscalls
|
||||
% required for the port process to run
|
||||
|
||||
Arch = alcove:define(Drv, alcove:audit_arch()),
|
||||
Arch = alcove:define(Drv, [], alcove:audit_arch()),
|
||||
Filter = [
|
||||
?VALIDATE_ARCHITECTURE(Arch),
|
||||
?EXAMINE_SYSCALL,
|
||||
@@ -722,7 +674,7 @@ atom is used as the argument and is not found on the platform.
|
||||
sys_write
|
||||
],
|
||||
|
||||
{ok,_,_,_,_,_} = alcove:prctl(Drv, pr_set_no_new_privs, 1, 0, 0, 0),
|
||||
{ok,_,_,_,_,_} = alcove:prctl(Drv, [], pr_set_no_new_privs, 1, 0, 0, 0),
|
||||
Pad = (erlang:system_info({wordsize,external}) - 2) * 8,
|
||||
|
||||
Prog = [
|
||||
@@ -730,37 +682,31 @@ atom is used as the argument and is not found on the platform.
|
||||
<<0:Pad>>,
|
||||
{ptr, list_to_binary(Filter)}
|
||||
],
|
||||
alcove:prctl(Drv, pr_set_seccomp, seccomp_mode_filter, Prog, 0, 0).
|
||||
alcove:prctl(Drv, [], pr_set_seccomp, seccomp_mode_filter, Prog, 0, 0).
|
||||
|
||||
|
||||
prctl_define(Drv, atom()) -> integer() | unknown
|
||||
prctl_define(Drv, Pids, atom()) -> integer() | unknown
|
||||
|
||||
Convert prctl option names to integers.
|
||||
|
||||
read(Drv, Fd, Count) -> {ok, binary()} | {error, posix()}
|
||||
read(Drv, Pids, Fd, Count) -> {ok, binary()} | {error, posix()}
|
||||
|
||||
Types Count = non_neg_integer()
|
||||
|
||||
read(2) : read bytes from a file descriptor
|
||||
|
||||
readdir(Drv, Path) -> {ok, [binary()]} | {error, posix()}
|
||||
readdir(Drv, Pids, Path) -> {ok, [binary()]} | {error, posix()}
|
||||
|
||||
readdir(3) : retrieve list of objects in a directory
|
||||
|
||||
rlimit_define(Drv, atom()) -> integer() | unknown
|
||||
rlimit_define(Drv, Pids, atom()) -> integer() | unknown
|
||||
|
||||
Convert an RLIMIT_* flag to an integer().
|
||||
|
||||
rmdir(Drv, Path) -> ok | {error, posix()}
|
||||
rmdir(Drv, Pids, Path) -> ok | {error, posix()}
|
||||
|
||||
rmdir(2) : delete a directory
|
||||
|
||||
select(Drv, Readfds, Writefds, Exceptfds, Timeout) -> {ok, Readfds, Writefds, Exceptfds} | {error, posix()}
|
||||
select(Drv, Pids, Readfds, Writefds, Exceptfds, Timeout) -> {ok, Readfds, Writefds, Exceptfds} | {error, posix()}
|
||||
|
||||
Types Readfds = Writefds = Exceptfds = [] | [integer()]
|
||||
@@ -780,7 +726,6 @@ atom is used as the argument and is not found on the platform.
|
||||
sec : number of seconds to wait
|
||||
usec : number of microseconds to wait
|
||||
|
||||
setenv(Drv, Name, Value, Overwrite) -> ok | {error, posix()}
|
||||
setenv(Drv, Pids, Name, Value, Overwrite) -> ok | {error, posix()}
|
||||
|
||||
Types Name = Value = iodata()
|
||||
@@ -788,26 +733,22 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
setenv(3) : set an environment variable
|
||||
|
||||
setgid(Drv, Gid) -> ok | {error, posix()}
|
||||
setgid(Drv, Pids, Gid) -> ok | {error, posix()}
|
||||
|
||||
Types Gid = non_neg_integer()
|
||||
|
||||
setgid(2) : set the GID of the process
|
||||
|
||||
setpgid(Drv, Pid, Pgid) -> ok | {error, posix()}
|
||||
setpgid(Drv, Pids, Pid, Pgid) -> ok | {error, posix()}
|
||||
|
||||
Types Pgid = integer()
|
||||
|
||||
setpgid(2) : set process group
|
||||
|
||||
setsid(Drv) -> {ok, Pid} | {error, posix()}
|
||||
setsid(Drv, Pids) -> {ok, Pid} | {error, posix()}
|
||||
|
||||
setsid(2) : create a new session
|
||||
|
||||
sethostname(Drv, Hostname) -> ok | {error, posix()}
|
||||
sethostname(Drv, Pids, Hostname) -> ok | {error, posix()}
|
||||
|
||||
Types Hostname = iodata()
|
||||
@@ -816,13 +757,12 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
This function is probably only useful if running in a uts namespace:
|
||||
|
||||
{ok, Child} = alcove:clone(Drv, [clone_newuts]),
|
||||
{ok, Child} = alcove:clone(Drv, [], [clone_newuts]),
|
||||
ok = alcove:sethostname(Drv, [Child], "test"),
|
||||
Hostname1 = alcove:gethostname(Drv),
|
||||
Hostname1 = alcove:gethostname(Drv, []),
|
||||
Hostname2 = alcove:gethostname(Drv, [Child]),
|
||||
Hostname1 =/= Hostname2.
|
||||
|
||||
setns(Drv, Path) -> ok | {error, posix()}
|
||||
setns(Drv, Pids, Path) -> ok | {error, posix()}
|
||||
|
||||
Linux only.
|
||||
@@ -844,19 +784,17 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
For example, to attach to another process' network namespace:
|
||||
|
||||
{ok, Child1} = alcove:clone(Drv, [clone_newnet]),
|
||||
{ok, Child2} = alcove:fork(Drv),
|
||||
{ok, Child1} = alcove:clone(Drv, [], [clone_newnet]),
|
||||
{ok, Child2} = alcove:fork(Drv, []),
|
||||
|
||||
% Move Child2 into the Child1 network namespace
|
||||
ok = alcove:setns(Drv, [Child2],
|
||||
["/proc/", integer_to_list(Child1), "/ns/net"]).
|
||||
|
||||
setopt(Drv, Opt, Val) -> boolean()
|
||||
setopt(Drv, Pids, Opt, Val) -> boolean()
|
||||
|
||||
Set port options. See getopt/2,3 for the list of options.
|
||||
|
||||
setpriority(Drv, Which, Who, Prio) -> ok | {error, posix() | unsupported}
|
||||
setpriority(Drv, Pids, Which, Who, Prio) -> ok | {error, posix() | unsupported}
|
||||
|
||||
Types Which = constant()
|
||||
@@ -865,7 +803,6 @@ atom is used as the argument and is not found on the platform.
|
||||
setpriority(2) : set scheduling priority of process, process
|
||||
group or user
|
||||
|
||||
setproctitle(Drv, Name) -> ok
|
||||
setproctitle(Drv, Pids, Name) -> ok
|
||||
|
||||
Types Name = iodata()
|
||||
@@ -876,10 +813,9 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
On Linux, use prctl/6,7:
|
||||
|
||||
{ok,Fork} = alcove:fork(Drv),
|
||||
{ok,Fork} = alcove:fork(Drv, []),
|
||||
alcove:prctl(Drv, [Fork], pr_set_name, <<"pseudonym">>, 0,0,0).
|
||||
|
||||
setresgid(Drv, RGID, EGID, SGID) -> ok | {error, posix()}
|
||||
setresgid(Drv, Pids, RGID, EGID, SGID) -> ok | {error, posix()}
|
||||
|
||||
Types RGID = EGID = SGID = non_neg_integer()
|
||||
@@ -888,7 +824,6 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
Supported on Linux and BSD's.
|
||||
|
||||
setresuid(Drv, RUID, EUID, SUID) -> ok | {error, posix()}
|
||||
setresuid(Drv, Pids, RUID, EUID, SUID) -> ok | {error, posix()}
|
||||
|
||||
Types RUID = EUID = SUID = non_neg_integer()
|
||||
@@ -897,7 +832,6 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
Supported on Linux and BSD's.
|
||||
|
||||
setrlimit(Drv, Resource, Limit) -> ok | {error, posix() | unsupported}
|
||||
setrlimit(Drv, Pids, Resource, Limit) -> ok | {error, posix() | unsupported}
|
||||
|
||||
Types Resource = constant()
|
||||
@@ -905,14 +839,12 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
setrlimit(2) : set a resource limit
|
||||
|
||||
setuid(Drv, UID) -> ok | {error, posix()}
|
||||
setuid(Drv, Pids, UID) -> ok | {error, posix()}
|
||||
|
||||
Types UID = non_neg_integer()
|
||||
|
||||
setuid(2) : change UID
|
||||
|
||||
sigaction(Drv, Signum, Handler) -> ok | {error, posix() | unsupported}
|
||||
sigaction(Drv, Pids, Signum, Handler) -> ok | {error, posix() | unsupported}
|
||||
|
||||
Types Signum = constant()
|
||||
@@ -929,29 +861,24 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
Multiple caught signals may be reported as one event.
|
||||
|
||||
signal_constant(Drv, integer()) -> atom() | unknown
|
||||
signal_constant(Drv, Pids, integer()) -> atom() | unknown
|
||||
|
||||
Convert integers to signal names.
|
||||
|
||||
signal_define(Drv, atom()) -> integer() | unknown
|
||||
signal_define(Drv, Pids, atom()) -> integer() | unknown
|
||||
|
||||
Convert signal names to integers.
|
||||
|
||||
umount(Drv, Path) -> ok | {error, posix()}
|
||||
umount(Drv, Pids, Path) -> ok | {error, posix()}
|
||||
|
||||
umount(2) : unmount a filesystem
|
||||
|
||||
On BSD systems, calls unmount(2).
|
||||
|
||||
unsetenv(Drv, Name) -> ok | {error, posix()}
|
||||
unsetenv(Drv, Pids, Name) -> ok | {error, posix()}
|
||||
|
||||
unsetenv(3) : remove an environment variable
|
||||
|
||||
unshare(Drv, Flags) -> ok | {error, posix() | unsupported}
|
||||
unshare(Drv, Pids, Flags) -> ok | {error, posix() | unsupported}
|
||||
|
||||
Types Flags = constant()
|
||||
@@ -962,16 +889,14 @@ atom is used as the argument and is not found on the platform.
|
||||
|
||||
unshare(2) lets you make a new namespace without calling clone(2):
|
||||
|
||||
ok = alcove:unshare(Drv, [clone_newnet]).
|
||||
ok = alcove:unshare(Drv, [], [clone_newnet]).
|
||||
|
||||
% The port is now running in a namespace without network access.
|
||||
|
||||
version(Drv) -> binary()
|
||||
version(Drv, Pids) -> binary()
|
||||
|
||||
Retrieves the alcove version.
|
||||
|
||||
write(Drv, FD, Buf) -> {ok, Count} | {error, posix()}
|
||||
write(Drv, Pids, FD, Buf) -> {ok, Count} | {error, posix()}
|
||||
|
||||
Types Buf = iodata()
|
||||
@@ -983,8 +908,6 @@ atom is used as the argument and is not found on the platform.
|
||||
The alcove module functions can be rewritten to use call/2,3,4,5 which
|
||||
allows setting timeouts.
|
||||
|
||||
call(Drv, Call) -> term()
|
||||
call(Drv, Call, Argv) -> term()
|
||||
call(Drv, Pids, Call, Argv) -> term()
|
||||
call(Drv, Pids, Call, Argv, Timeout) -> term()
|
||||
|
||||
|
||||
@@ -56,11 +56,6 @@ mkerl(File, Proto) ->
|
||||
]),
|
||||
|
||||
Comment_gen = erl_syntax:comment([" Generated functions"]),
|
||||
Exports_gen0 = erl_syntax:attribute(erl_syntax:atom(export), [
|
||||
erl_syntax:list([
|
||||
erl_syntax:arity_qualifier(erl_syntax:atom(Fun), erl_syntax:integer(Arity+1))
|
||||
|| {Fun, Arity} <- Calls ])
|
||||
]),
|
||||
|
||||
Exports_gen1 = erl_syntax:attribute(erl_syntax:atom(export), [
|
||||
erl_syntax:list([
|
||||
@@ -73,14 +68,6 @@ mkerl(File, Proto) ->
|
||||
% name(Drv, ...) -> alcove:call(Drv, [], Fun, [...])
|
||||
Arg = arg("Arg", Arity),
|
||||
|
||||
Pattern0 = [erl_syntax:variable("Drv")|Arg],
|
||||
Body0 = erl_syntax:application(
|
||||
erl_syntax:atom(call),
|
||||
[erl_syntax:variable("Drv"), erl_syntax:nil(),
|
||||
erl_syntax:atom(Fun), erl_syntax:list(Arg)]
|
||||
),
|
||||
Clause0 = erl_syntax:clause(Pattern0, [], [Body0]),
|
||||
|
||||
% name(Drv, Pids, ...) -> alcove:call(Drv, Pids, Fun, [...])
|
||||
Pattern1 = [erl_syntax:variable("Drv"), erl_syntax:variable("Pids")|Arg],
|
||||
Body1 = erl_syntax:application(
|
||||
@@ -90,8 +77,7 @@ mkerl(File, Proto) ->
|
||||
),
|
||||
Clause1 = erl_syntax:clause(Pattern1, [], [Body1]),
|
||||
|
||||
[erl_syntax:function(erl_syntax:atom(Fun), [Clause0]),
|
||||
erl_syntax:function(erl_syntax:atom(Fun), [Clause1])]
|
||||
[erl_syntax:function(erl_syntax:atom(Fun), [Clause1])]
|
||||
|
||||
end || {Fun, Arity} <- Calls ],
|
||||
|
||||
@@ -106,7 +92,6 @@ mkerl(File, Proto) ->
|
||||
Exports_static,
|
||||
|
||||
Comment_gen,
|
||||
Exports_gen0,
|
||||
Exports_gen1,
|
||||
|
||||
Static,
|
||||
@@ -146,13 +131,13 @@ b2i(N) when is_binary(N) ->
|
||||
static_exports() ->
|
||||
[{audit_arch,0},
|
||||
|
||||
{define,2},{define,3},
|
||||
{stdin,2}, {stdin,3},
|
||||
{stdout,1}, {stdout,2}, {stdout,3},
|
||||
{stderr,1}, {stderr,2}, {stderr,3},
|
||||
{define,3},
|
||||
{stdin,3},
|
||||
{stdout,2}, {stdout,3},
|
||||
{stderr,2}, {stderr,3},
|
||||
{eof,2}, {eof,3},
|
||||
{event,1}, {event,2}, {event,3},
|
||||
{call,2}, {call,3}, {call,4}, {call,5}].
|
||||
{event,2}, {event,3},
|
||||
{call,4}, {call,5}].
|
||||
|
||||
static() ->
|
||||
[ static({Fun, Arity}) || {Fun, Arity} <- static_exports() ].
|
||||
@@ -173,11 +158,6 @@ static({audit_arch,0}) ->
|
||||
proplists:get_value({Arch,OS,Wordsize}, Arches, unsupported).
|
||||
";
|
||||
|
||||
static({define,2}) ->
|
||||
"
|
||||
define(Drv, Const) ->
|
||||
define(Drv, [], Const).
|
||||
";
|
||||
static({define,3}) ->
|
||||
"
|
||||
define(Drv, Pids, Const) when is_atom(Const) ->
|
||||
@@ -215,22 +195,12 @@ const(\"noexec\") -> mount_define;
|
||||
const(\"noatime\") -> mount_define.
|
||||
";
|
||||
|
||||
static({stdin,2}) ->
|
||||
"
|
||||
stdin(Drv, Data) ->
|
||||
stdin(Drv, [], Data).
|
||||
";
|
||||
static({stdin,3}) ->
|
||||
"
|
||||
stdin(Drv, Pids, Data) ->
|
||||
alcove_drv:stdin(Drv, Pids, Data).
|
||||
";
|
||||
|
||||
static({stdout,1}) ->
|
||||
"
|
||||
stdout(Drv) ->
|
||||
stdout(Drv, [], 0).
|
||||
";
|
||||
static({stdout,2}) ->
|
||||
"
|
||||
stdout(Drv, Pids) ->
|
||||
@@ -242,11 +212,6 @@ stdout(Drv, Pids, Timeout) ->
|
||||
alcove_drv:stdout(Drv, Pids, Timeout).
|
||||
";
|
||||
|
||||
static({stderr,1}) ->
|
||||
"
|
||||
stderr(Drv) ->
|
||||
stderr(Drv, [], 0).
|
||||
";
|
||||
static({stderr,2}) ->
|
||||
"
|
||||
stderr(Drv, Pids) ->
|
||||
@@ -286,11 +251,6 @@ eof_1(Drv, Pids, #alcove_pid{stderr = FD}, stderr) ->
|
||||
close(Drv, Pids, FD).
|
||||
";
|
||||
|
||||
static({event,1}) ->
|
||||
"
|
||||
event(Drv) ->
|
||||
event(Drv, [], 0).
|
||||
";
|
||||
static({event,2}) ->
|
||||
"
|
||||
event(Drv, Pids) ->
|
||||
@@ -302,16 +262,6 @@ event(Drv, Pids, Timeout) ->
|
||||
alcove_drv:event(Drv, Pids, Timeout).
|
||||
";
|
||||
|
||||
static({call,2}) ->
|
||||
"
|
||||
call(Drv, Command) ->
|
||||
call(Drv, [], Command, [], infinity).
|
||||
";
|
||||
static({call,3}) ->
|
||||
"
|
||||
call(Drv, Command, Argv) ->
|
||||
call(Drv, [], Command, Argv, infinity).
|
||||
";
|
||||
static({call,4}) ->
|
||||
"
|
||||
call(Drv, Pids, Command, Argv) ->
|
||||
@@ -379,229 +329,155 @@ specs() ->
|
||||
|
||||
-spec audit_arch() -> atom().
|
||||
|
||||
-spec call(alcove_drv:ref(),atom()) -> term().
|
||||
-spec call(alcove_drv:ref(),atom(),list()) -> term().
|
||||
-spec call(alcove_drv:ref(),fork_path(),atom(),list()) -> term().
|
||||
-spec call(alcove_drv:ref(),fork_path(),atom(),list(),timeout()) -> term().
|
||||
|
||||
-spec chdir(alcove_drv:ref(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec chdir(alcove_drv:ref(),fork_path(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec chmod(alcove_drv:ref(),iodata(),mode_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec chmod(alcove_drv:ref(),fork_path(),iodata(),mode_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec chown(alcove_drv:ref(),iodata(),uid_t(),gid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec chown(alcove_drv:ref(),fork_path(),iodata(),uid_t(),gid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec chroot(alcove_drv:ref(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec chroot(alcove_drv:ref(),fork_path(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec clearenv(alcove_drv:ref()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec clearenv(alcove_drv:ref(),fork_path()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec clone(alcove_drv:ref(),int32_t() | [constant()]) -> {'ok', pid_t()} | {'error', file:posix() | 'unsupported'}.
|
||||
-spec clone(alcove_drv:ref(),fork_path(),int32_t() | [constant()]) -> {'ok', pid_t()} | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec clone_define(alcove_drv:ref(),atom()) -> 'unknown' | int32_t().
|
||||
-spec clone_define(alcove_drv:ref(),fork_path(),atom()) -> 'unknown' | int32_t().
|
||||
|
||||
-spec close(alcove_drv:ref(),fd()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec close(alcove_drv:ref(),fork_path(),fd()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec define(alcove_drv:ref(),atom() | [atom()]) -> 'unknown' | integer().
|
||||
-spec define(alcove_drv:ref(),fork_path(),atom() | [atom()]) -> 'unknown' | integer().
|
||||
|
||||
-spec environ(alcove_drv:ref()) -> [binary()].
|
||||
-spec environ(alcove_drv:ref(),fork_path()) -> [binary()].
|
||||
|
||||
-spec eof(alcove_drv:ref(),fork_path()) -> 'ok' | {'error',file:posix()}.
|
||||
-spec eof(alcove_drv:ref(),fork_path(),'stdin' | 'stdout' | 'stderr') -> 'ok' | {'error',file:posix()}.
|
||||
|
||||
-spec errno_id(alcove_drv:ref(),int32_t()) -> file:posix().
|
||||
-spec errno_id(alcove_drv:ref(),fork_path(),int32_t()) -> file:posix().
|
||||
|
||||
-spec event(alcove_drv:ref()) -> term().
|
||||
-spec event(alcove_drv:ref(),fork_path()) -> term().
|
||||
-spec event(alcove_drv:ref(),fork_path(),timeout()) -> term().
|
||||
|
||||
-spec execve(alcove_drv:ref(),iodata(),[iodata()],[iodata()]) -> 'ok'.
|
||||
-spec execve(alcove_drv:ref(),fork_path(),iodata(),[iodata()],[iodata()]) -> 'ok'.
|
||||
|
||||
-spec execvp(alcove_drv:ref(),iodata(),[iodata()]) -> 'ok'.
|
||||
-spec execvp(alcove_drv:ref(),fork_path(),iodata(),[iodata()]) -> 'ok'.
|
||||
|
||||
-spec exit(alcove_drv:ref(),int32_t()) -> 'ok'.
|
||||
-spec exit(alcove_drv:ref(),fork_path(),int32_t()) -> 'ok'.
|
||||
|
||||
-spec file_define(alcove_drv:ref(),atom()) -> non_neg_integer() | 'unknown'.
|
||||
-spec file_define(alcove_drv:ref(),fork_path(),atom()) -> non_neg_integer() | 'unknown'.
|
||||
|
||||
-spec fork(alcove_drv:ref()) -> {'ok', pid_t()} | {'error', file:posix()}.
|
||||
-spec fork(alcove_drv:ref(),fork_path()) -> {'ok', pid_t()} | {'error', file:posix()}.
|
||||
|
||||
-spec getcwd(alcove_drv:ref()) -> {'ok', binary()} | {'error', file:posix()}.
|
||||
-spec getcwd(alcove_drv:ref(),fork_path()) -> {'ok', binary()} | {'error', file:posix()}.
|
||||
|
||||
-spec getenv(alcove_drv:ref(),iodata()) -> binary() | 'false'.
|
||||
-spec getenv(alcove_drv:ref(),fork_path(),iodata()) -> binary() | 'false'.
|
||||
|
||||
-spec getgid(alcove_drv:ref()) -> gid_t().
|
||||
-spec getgid(alcove_drv:ref(),fork_path()) -> gid_t().
|
||||
|
||||
-spec gethostname(alcove_drv:ref()) -> {'ok', binary()} | {'error', file:posix()}.
|
||||
-spec gethostname(alcove_drv:ref(),fork_path()) -> {'ok', binary()} | {'error', file:posix()}.
|
||||
|
||||
-spec getopt(alcove_drv:ref(),atom()) -> 'false' | non_neg_integer().
|
||||
-spec getopt(alcove_drv:ref(),fork_path(),atom()) -> 'false' | non_neg_integer().
|
||||
|
||||
-spec getpgrp(alcove_drv:ref()) -> pid_t().
|
||||
-spec getpgrp(alcove_drv:ref(),fork_path()) -> pid_t().
|
||||
|
||||
-spec getpid(alcove_drv:ref()) -> pid_t().
|
||||
-spec getpid(alcove_drv:ref(),fork_path()) -> pid_t().
|
||||
|
||||
-spec getpriority(alcove_drv:ref(),constant(),int32_t()) -> {'ok',int32_t()} | {'error', file:posix() | 'unsupported'}.
|
||||
-spec getpriority(alcove_drv:ref(),fork_path(),constant(),int32_t()) -> {'ok',int32_t()} | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec getresgid(alcove_drv:ref()) -> {'ok', gid_t(), gid_t(), gid_t()} | {'error', file:posix()}.
|
||||
-spec getresgid(alcove_drv:ref(), fork_path()) -> {'ok', gid_t(), gid_t(), gid_t()} | {'error', file:posix()}.
|
||||
|
||||
-spec getresuid(alcove_drv:ref()) -> {'ok', uid_t(), uid_t(), uid_t()} | {'error', file:posix()}.
|
||||
-spec getresuid(alcove_drv:ref(), fork_path()) -> {'ok', uid_t(), uid_t(), uid_t()} | {'error', file:posix()}.
|
||||
|
||||
-spec getrlimit(alcove_drv:ref(),constant()) -> {'ok', #alcove_rlimit{}} | {'error', file:posix() | 'unsupported'}.
|
||||
-spec getrlimit(alcove_drv:ref(),fork_path(),constant()) -> {'ok', #alcove_rlimit{}} | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec getsid(alcove_drv:ref(), pid_t()) -> {'ok', pid_t()} | {'error', file:posix()}.
|
||||
-spec getsid(alcove_drv:ref(), fork_path(), pid_t()) -> {'ok', pid_t()} | {'error', file:posix()}.
|
||||
|
||||
-spec getuid(alcove_drv:ref()) -> uid_t().
|
||||
-spec getuid(alcove_drv:ref(),fork_path()) -> uid_t().
|
||||
|
||||
-spec kill(alcove_drv:ref(), pid_t(), constant()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
-spec kill(alcove_drv:ref(), fork_path(), pid_t(), constant()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec lseek(alcove_drv:ref(),fd(),off_t(),int32_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec lseek(alcove_drv:ref(),fork_path(),fd(),off_t(),int32_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec mkdir(alcove_drv:ref(),iodata(),mode_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec mkdir(alcove_drv:ref(),fork_path(),iodata(),mode_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec mount(alcove_drv:ref(),iodata(),iodata(),iodata(),uint64_t() | [constant()],iodata(),iodata()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
-spec mount(alcove_drv:ref(),fork_path(),iodata(),iodata(),iodata(),uint64_t() | [constant()],iodata(),iodata()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec mount_define(alcove_drv:ref(),atom()) -> 'unknown' | uint64_t().
|
||||
-spec mount_define(alcove_drv:ref(),fork_path(),atom()) -> 'unknown' | uint64_t().
|
||||
|
||||
-spec open(alcove_drv:ref(),iodata(),int32_t() | [constant()],integer()) -> {'ok',fd()} | {'error', file:posix() | 'unsupported'}.
|
||||
-spec open(alcove_drv:ref(),fork_path(),iodata(),int32_t() | [constant()],mode_t()) -> {'ok',fd()} | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec pid(alcove_drv:ref()) -> [#alcove_pid{}].
|
||||
-spec pid(alcove_drv:ref(),fork_path()) -> [#alcove_pid{}].
|
||||
|
||||
-spec pivot_root(alcove_drv:ref(),iodata(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec pivot_root(alcove_drv:ref(),fork_path(),iodata(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-type prctl_arg() :: [binary() | {ptr, binary() | non_neg_integer()} ] | binary() | integer() | atom().
|
||||
-type prctl_val() :: binary() | integer().
|
||||
|
||||
-spec prctl(alcove_drv:ref(),constant(),prctl_arg(),prctl_arg(),prctl_arg(),prctl_arg()) -> {'ok',integer(),prctl_val(),prctl_val(),prctl_val(),prctl_val()} | {'error', file:posix() | 'unsupported'}.
|
||||
-spec prctl(alcove_drv:ref(),fork_path(),constant(),prctl_arg(),prctl_arg(),prctl_arg(),prctl_arg()) -> {'ok',integer(),prctl_val(),prctl_val(),prctl_val(),prctl_val()} | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec prctl_define(alcove_drv:ref(),atom()) -> 'unknown' | non_neg_integer().
|
||||
-spec prctl_define(alcove_drv:ref(),fork_path(),atom()) -> 'unknown' | non_neg_integer().
|
||||
|
||||
-spec read(alcove_drv:ref(),fd(),size_t()) -> {'ok', binary()} | {'error', file:posix()}.
|
||||
-spec read(alcove_drv:ref(),fork_path(),fd(),size_t()) -> {'ok', binary()} | {'error', file:posix()}.
|
||||
|
||||
-spec readdir(alcove_drv:ref(),iodata()) -> {'ok', [binary()]} | {'error', file:posix()}.
|
||||
-spec readdir(alcove_drv:ref(),fork_path(),iodata()) -> {'ok', [binary()]} | {'error', file:posix()}.
|
||||
|
||||
-spec rmdir(alcove_drv:ref(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec rmdir(alcove_drv:ref(),fork_path(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec rlimit_define(alcove_drv:ref(),atom()) -> 'unknown' | non_neg_integer().
|
||||
-spec rlimit_define(alcove_drv:ref(),fork_path(),atom()) -> 'unknown' | non_neg_integer().
|
||||
|
||||
-spec select(alcove_drv:ref(),[fd_set()],[fd_set()],[fd_set()],
|
||||
<<>> | #alcove_timeval{}) -> {ok, [fd_set()], [fd_set()], [fd_set()]} | {'error', file:posix()}.
|
||||
-spec select(alcove_drv:ref(),fork_path(),[fd_set()],[fd_set()],[fd_set()],
|
||||
<<>> | #alcove_timeval{}) -> {ok, [fd_set()], [fd_set()], [fd_set()]} | {'error', file:posix()}.
|
||||
|
||||
-spec setenv(alcove_drv:ref(),iodata(),iodata(),int32_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec setenv(alcove_drv:ref(),fork_path(),iodata(),iodata(),int32_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec setgid(alcove_drv:ref(),gid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec setgid(alcove_drv:ref(),fork_path(),gid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec sethostname(alcove_drv:ref(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec sethostname(alcove_drv:ref(),fork_path(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec setns(alcove_drv:ref(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec setns(alcove_drv:ref(),fork_path(),iodata()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec setopt(alcove_drv:ref(),atom(), non_neg_integer()) -> boolean().
|
||||
-spec setopt(alcove_drv:ref(),fork_path(),atom(),non_neg_integer()) -> boolean().
|
||||
|
||||
-spec setpgid(alcove_drv:ref(),pid_t(),pid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec setpgid(alcove_drv:ref(),fork_path(),pid_t(),pid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec setpriority(alcove_drv:ref(),constant(),int32_t(),int32_t()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
-spec setpriority(alcove_drv:ref(),fork_path(),constant(),int32_t(),int32_t()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec setproctitle(alcove_drv:ref(),iodata()) -> 'ok'.
|
||||
-spec setproctitle(alcove_drv:ref(),fork_path(),iodata()) -> 'ok'.
|
||||
|
||||
-spec setresgid(alcove_drv:ref(),gid_t(),gid_t(),gid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec setresgid(alcove_drv:ref(),fork_path(),gid_t(),gid_t(),gid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec setresuid(alcove_drv:ref(),uid_t(),uid_t(),uid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec setresuid(alcove_drv:ref(),fork_path(),uid_t(),uid_t(),uid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec setrlimit(alcove_drv:ref(),constant(),#alcove_rlimit{}) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
-spec setrlimit(alcove_drv:ref(),fork_path(),constant(),#alcove_rlimit{}) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec setsid(alcove_drv:ref()) -> {ok,pid_t()} | {error, file:posix()}.
|
||||
-spec setsid(alcove_drv:ref(),fork_path()) -> {ok,pid_t()} | {error, file:posix()}.
|
||||
|
||||
-spec setuid(alcove_drv:ref(),uid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
-spec setuid(alcove_drv:ref(),fork_path(),uid_t()) -> 'ok' | {'error', file:posix()}.
|
||||
|
||||
-spec sigaction(alcove_drv:ref(),constant(),atom()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
-spec sigaction(alcove_drv:ref(),fork_path(),constant(),atom()) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec signal_constant(alcove_drv:ref(),non_neg_integer()) -> 'unknown' | atom().
|
||||
-spec signal_constant(alcove_drv:ref(),fork_path(),non_neg_integer()) -> 'unknown' | atom().
|
||||
|
||||
-spec signal_define(alcove_drv:ref(),atom()) -> 'unknown' | non_neg_integer().
|
||||
-spec signal_define(alcove_drv:ref(),fork_path(),atom()) -> 'unknown' | non_neg_integer().
|
||||
|
||||
-spec syscall_define(alcove_drv:ref(),atom()) -> 'unknown' | non_neg_integer().
|
||||
-spec syscall_define(alcove_drv:ref(),fork_path(),atom()) -> 'unknown' | non_neg_integer().
|
||||
|
||||
-spec stderr(alcove_drv:ref()) -> 'false' | binary().
|
||||
-spec stderr(alcove_drv:ref(),fork_path()) -> 'false' | binary().
|
||||
-spec stderr(alcove_drv:ref(),fork_path(),timeout()) -> 'false' | binary().
|
||||
|
||||
-spec stdin(alcove_drv:ref(),iodata()) -> 'true'.
|
||||
-spec stdin(alcove_drv:ref(),fork_path(),iodata()) -> 'true'.
|
||||
|
||||
-spec stdout(alcove_drv:ref()) -> 'false' | binary().
|
||||
-spec stdout(alcove_drv:ref(),fork_path()) -> 'false' | binary().
|
||||
-spec stdout(alcove_drv:ref(),fork_path(),timeout()) -> 'false' | binary().
|
||||
|
||||
-spec umount(alcove_drv:ref(),iodata()) -> 'ok' | {error, file:posix()}.
|
||||
-spec umount(alcove_drv:ref(),fork_path(),iodata()) -> 'ok' | {error, file:posix()}.
|
||||
|
||||
-spec unsetenv(alcove_drv:ref(),iodata()) -> 'ok' | {error, file:posix()}.
|
||||
-spec unsetenv(alcove_drv:ref(),fork_path(),iodata()) -> 'ok' | {error, file:posix()}.
|
||||
|
||||
-spec unshare(alcove_drv:ref(),int32_t() | [constant()]) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
-spec unshare(alcove_drv:ref(),fork_path(),int32_t() | [constant()]) -> 'ok' | {'error', file:posix() | 'unsupported'}.
|
||||
|
||||
-spec write(alcove_drv:ref(),fd(),iodata()) -> {'ok', ssize_t()} | {'error', file:posix()}.
|
||||
-spec write(alcove_drv:ref(),fork_path(),fd(),iodata()) -> {'ok', ssize_t()} | {'error', file:posix()}.
|
||||
|
||||
-spec version(alcove_drv:ref()) -> binary().
|
||||
-spec version(alcove_drv:ref(),fork_path()) -> binary().
|
||||
".
|
||||
|
||||
@@ -27,7 +27,7 @@ sandbox(Drv) ->
|
||||
sandbox(Drv, Argv) ->
|
||||
{Path, Arg0, Args} = argv(Argv),
|
||||
|
||||
{ok, Child} = alcove:fork(Drv),
|
||||
{ok, Child} = alcove:fork(Drv, []),
|
||||
|
||||
setlimits(Drv, Child),
|
||||
chroot(Drv, Child, Path),
|
||||
|
||||
@@ -60,7 +60,7 @@ start(GPIO, N) ->
|
||||
clone_newpid,
|
||||
clone_newuts
|
||||
],
|
||||
{ok, Child} = alcove:clone(Drv, Flags),
|
||||
{ok, Child} = alcove:clone(Drv, [], Flags),
|
||||
|
||||
ok = alcove:chroot(Drv, [Child],
|
||||
["/sys/class/gpio/gpio", integer_to_list(GPIO)]),
|
||||
@@ -72,16 +72,16 @@ start(GPIO, N) ->
|
||||
ok = alcove:setuid(Drv, [Child], Id),
|
||||
|
||||
% Drop privs in the port
|
||||
{ok, UFD} = alcove:open(Drv, "/sys/class/gpio/unexport",
|
||||
{ok, UFD} = alcove:open(Drv, [], "/sys/class/gpio/unexport",
|
||||
[o_wronly,o_cloexec], 0),
|
||||
|
||||
ok = alcove:unshare(Drv, Flags),
|
||||
ok = alcove:chroot(Drv, "priv"),
|
||||
ok = alcove:chdir(Drv, "/"),
|
||||
ok = alcove:unshare(Drv, [], Flags),
|
||||
ok = alcove:chroot(Drv, [], "priv"),
|
||||
ok = alcove:chdir(Drv, [], "/"),
|
||||
|
||||
Id1 = id(),
|
||||
ok = alcove:setgid(Drv, Id1),
|
||||
ok = alcove:setuid(Drv, Id1),
|
||||
ok = alcove:setgid(Drv, [], Id1),
|
||||
ok = alcove:setuid(Drv, [], Id1),
|
||||
|
||||
strobe(#state{
|
||||
drv = Drv,
|
||||
@@ -96,8 +96,8 @@ strobe(#state{drv = Drv, pid = Child, direction = FD,
|
||||
unexport = UFD, gpio = GPIO}, 0) ->
|
||||
alcove:write(Drv, [Child], FD, <<"low">>),
|
||||
alcove:close(Drv, [Child], FD),
|
||||
{ok, _} = alcove:write(Drv, UFD, integer_to_list(GPIO)),
|
||||
alcove:close(Drv, UFD),
|
||||
{ok, _} = alcove:write(Drv, [], UFD, integer_to_list(GPIO)),
|
||||
alcove:close(Drv, [], UFD),
|
||||
alcove_drv:stop(Drv);
|
||||
strobe(#state{drv = Drv, pid = Child, direction = FD} = State, N) ->
|
||||
timer:sleep(100),
|
||||
@@ -110,10 +110,10 @@ id() ->
|
||||
crypto:rand_uniform(16#f0000000, 16#f000ffff).
|
||||
|
||||
export(Drv, Pin) ->
|
||||
{ok, FD} = alcove:open(Drv, "/sys/class/gpio/export",
|
||||
{ok, FD} = alcove:open(Drv, [], "/sys/class/gpio/export",
|
||||
[o_wronly,o_cloexec], 0),
|
||||
case alcove:write(Drv, FD, integer_to_list(Pin)) of
|
||||
case alcove:write(Drv, [], FD, integer_to_list(Pin)) of
|
||||
{ok, _} -> ok;
|
||||
{error,ebusy} -> ok
|
||||
end,
|
||||
alcove:close(Drv, FD).
|
||||
alcove:close(Drv, [], FD).
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
start() ->
|
||||
{ok, Drv} = alcove_drv:start_link([{exec, "sudo"}]),
|
||||
case alcove_cgroup:supported(Drv) of
|
||||
case alcove_cgroup:supported(Drv, []) of
|
||||
true ->
|
||||
ok = alcove_cgroup:create(Drv, [], [<<"alcove">>]),
|
||||
{ok,1} = alcove_cgroup:set(Drv, [], <<"cpuset">>, [<<"alcove">>],
|
||||
@@ -43,7 +43,7 @@ sandbox(Drv) ->
|
||||
sandbox(Drv, Argv) ->
|
||||
{Path, Arg0, Args} = argv(Argv),
|
||||
|
||||
{ok, Child} = alcove:clone(Drv, [
|
||||
{ok, Child} = alcove:clone(Drv, [], [
|
||||
clone_newipc,
|
||||
clone_newnet,
|
||||
clone_newns,
|
||||
|
||||
@@ -22,7 +22,7 @@ start() ->
|
||||
start(Options) ->
|
||||
{ok, Drv} = alcove_drv:start_link(Options ++ [{exec, "sudo"}]),
|
||||
|
||||
ok = alcove:chdir(Drv, "/"),
|
||||
ok = alcove:chdir(Drv, [], "/"),
|
||||
chroot_init(),
|
||||
cgroup_init(Drv,
|
||||
[<<"alcove">>],
|
||||
@@ -130,7 +130,7 @@ network_drain(Drv, Socket, Child) ->
|
||||
end.
|
||||
|
||||
clone(Drv, _Options) ->
|
||||
alcove:clone(Drv, [
|
||||
alcove:clone(Drv, [], [
|
||||
clone_newipc,
|
||||
clone_newnet,
|
||||
clone_newns,
|
||||
@@ -142,7 +142,7 @@ clone_init(Drv, Child, Options) ->
|
||||
Id = id(),
|
||||
Hostname = lists:concat(["alcove", Child]),
|
||||
|
||||
case alcove_cgroup:supported(Drv) of
|
||||
case alcove_cgroup:supported(Drv, []) of
|
||||
true ->
|
||||
cgroup_init(Drv, [<<"alcove">>, Hostname], Options),
|
||||
{ok,_} = alcove_cgroup:set(Drv, [], <<>>, [<<"alcove">>, Hostname],
|
||||
@@ -309,7 +309,7 @@ cgroup_init(Drv, Namespace, Options) ->
|
||||
Bytes = proplists:get_value(<<"memory.limit_in_bytes">>,
|
||||
Options, <<"16m">>),
|
||||
|
||||
case alcove_cgroup:supported(Drv) of
|
||||
case alcove_cgroup:supported(Drv, []) of
|
||||
true ->
|
||||
alcove_cgroup:create(Drv, [], Namespace),
|
||||
alcove_cgroup:set(Drv, [], <<"cpuset">>, Namespace,
|
||||
|
||||
@@ -43,9 +43,9 @@ accept(LSock, Options) ->
|
||||
create(Socket, _Options) ->
|
||||
{ok, Drv} = alcove_drv:start_link([{exec,"sudo"}]),
|
||||
|
||||
ok = alcove:chdir(Drv, "/"),
|
||||
ok = alcove:chdir(Drv, [], "/"),
|
||||
|
||||
{ok, PID} = alcove:clone(Drv, [
|
||||
{ok, PID} = alcove:clone(Drv, [], [
|
||||
clone_newipc,
|
||||
clone_newnet,
|
||||
clone_newns,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
{xref_checks, [undefined_function_calls]}.
|
||||
{eunit_opts, [verbose, {report, {eunit_surefire, [{dir, "."}]}}]}.
|
||||
%{dialyzer, [{plt_extra_apps, ["examples","test"]}]}.
|
||||
|
||||
% rebar2 compatibility: disable port compiler
|
||||
{port_specs, [{"", []}]}.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{application, alcove,
|
||||
[
|
||||
{description, "Erlang application container/sandbox"},
|
||||
{vsn, "0.20.0"},
|
||||
{vsn, "0.21.0"},
|
||||
{registered, []},
|
||||
{applications, [
|
||||
kernel,
|
||||
|
||||
@@ -14,18 +14,14 @@
|
||||
-module(alcove_cgroup).
|
||||
-include_lib("alcove/include/alcove.hrl").
|
||||
|
||||
-export([supported/1, supported/2]).
|
||||
-export([create/1, create/2, create/3, destroy/1, destroy/2, destroy/3]).
|
||||
-export([supported/2]).
|
||||
-export([create/2, create/3, destroy/2, destroy/3]).
|
||||
-export([cgroup/1, cgroup/2, fold/5, fold/6, fold_files/6, fold_files/7]).
|
||||
-export([get/5, set/6]).
|
||||
-export([is_file/3, is_dir/3]).
|
||||
-export([mounts/1, mounts/2]).
|
||||
-export([join/2,relpath/1,expand/1]).
|
||||
|
||||
-spec supported(alcove_drv:ref()) -> boolean().
|
||||
supported(Drv) ->
|
||||
supported(Drv, []).
|
||||
|
||||
-spec supported(alcove_drv:ref(),alcove:fork_path()) -> boolean().
|
||||
supported(Drv, Pids) ->
|
||||
foreach([
|
||||
@@ -50,10 +46,6 @@ supported(Drv, Pids) ->
|
||||
%% * the process may be running in a chroot or a different mount namespace
|
||||
%%
|
||||
|
||||
-spec create(alcove_drv:ref()) -> 'ok'.
|
||||
create(Drv) ->
|
||||
create(Drv, []).
|
||||
|
||||
-spec create(alcove_drv:ref(),alcove:fork_path()) -> 'ok'.
|
||||
create(Drv, Pids) ->
|
||||
create(Drv, Pids, [<<"alcove">>]).
|
||||
@@ -74,10 +66,6 @@ create_1(Drv, Pids, Namespace) ->
|
||||
end,
|
||||
fold(Drv, <<>>, [], Fun, []).
|
||||
|
||||
-spec destroy(alcove_drv:ref()) -> [ok | {error, file:posix()}].
|
||||
destroy(Drv) ->
|
||||
destroy(Drv, []).
|
||||
|
||||
-spec destroy(alcove_drv:ref(),alcove:fork_path()) -> [ok | {error, file:posix()}].
|
||||
destroy(Drv, Pids) ->
|
||||
destroy(Drv, Pids, [<<"alcove">>]).
|
||||
@@ -228,7 +216,7 @@ is_dir(Drv, Pids, Path) ->
|
||||
is_file(Drv, Pids, File) ->
|
||||
case alcove:open(Drv, Pids, File, [o_rdonly], 0) of
|
||||
{ok, FH} ->
|
||||
alcove:close(Drv, FH),
|
||||
alcove:close(Drv, Pids, FH),
|
||||
true;
|
||||
_ ->
|
||||
false
|
||||
|
||||
@@ -55,21 +55,21 @@ start() ->
|
||||
|
||||
#state{
|
||||
pid = Drv,
|
||||
seccomp = alcove:define(Drv, seccomp_mode_filter) =/= unknown
|
||||
seccomp = alcove:define(Drv, [], seccomp_mode_filter) =/= unknown
|
||||
}.
|
||||
|
||||
stop(#state{pid = Drv}) ->
|
||||
alcove_drv:stop(Drv).
|
||||
|
||||
kill(#state{pid = Drv}) ->
|
||||
{ok, Pid} = alcove:fork(Drv),
|
||||
{ok, Pid} = alcove:fork(Drv, []),
|
||||
enforce(Drv, [Pid], ?BPF_STMT(?BPF_RET+?BPF_K, ?SECCOMP_RET_KILL)),
|
||||
% Allowed: cached by process
|
||||
Reply0 = alcove:getpid(Drv, [Pid]),
|
||||
% Not allowed: SIGSYS
|
||||
Reply1 = (catch alcove:getcwd(Drv, [Pid])),
|
||||
|
||||
Reply2 = alcove:kill(Drv, Pid, 0),
|
||||
Reply2 = alcove:kill(Drv, [], Pid, 0),
|
||||
|
||||
[
|
||||
?_assertEqual(Pid, Reply0),
|
||||
@@ -78,11 +78,11 @@ kill(#state{pid = Drv}) ->
|
||||
].
|
||||
|
||||
allow(#state{pid = Drv}) ->
|
||||
{ok, Pid} = alcove:fork(Drv),
|
||||
{ok, Pid} = alcove:fork(Drv, []),
|
||||
enforce(Drv, [Pid], ?BPF_STMT(?BPF_RET+?BPF_K, ?SECCOMP_RET_ALLOW)),
|
||||
Reply0 = alcove:getpid(Drv, [Pid]),
|
||||
Reply1 = alcove:getcwd(Drv, [Pid]),
|
||||
Reply2 = alcove:kill(Drv, Pid, 0),
|
||||
Reply2 = alcove:kill(Drv, [], Pid, 0),
|
||||
alcove:exit(Drv, [Pid], 0),
|
||||
|
||||
[
|
||||
@@ -92,7 +92,7 @@ allow(#state{pid = Drv}) ->
|
||||
].
|
||||
|
||||
trap(#state{pid = Drv}) ->
|
||||
{ok, Pid} = alcove:fork(Drv),
|
||||
{ok, Pid} = alcove:fork(Drv, []),
|
||||
ok = alcove:sigaction(Drv, [Pid], sigsys, sig_catch),
|
||||
|
||||
enforce(Drv, [Pid], ?BPF_STMT(?BPF_RET+?BPF_K, ?SECCOMP_RET_TRAP)),
|
||||
@@ -111,7 +111,7 @@ trap(#state{pid = Drv}) ->
|
||||
ok
|
||||
end,
|
||||
|
||||
Reply3 = alcove:kill(Drv, Pid, 0),
|
||||
Reply3 = alcove:kill(Drv, [], Pid, 0),
|
||||
alcove:exit(Drv, [Pid], 0),
|
||||
|
||||
[
|
||||
@@ -122,13 +122,13 @@ trap(#state{pid = Drv}) ->
|
||||
].
|
||||
|
||||
allow_syscall(Drv, Syscall) ->
|
||||
case alcove:define(Drv, Syscall) of
|
||||
case alcove:define(Drv, [], Syscall) of
|
||||
unknown -> [];
|
||||
NR -> ?ALLOW_SYSCALL(NR)
|
||||
end.
|
||||
|
||||
filter(Drv) ->
|
||||
Arch = alcove:define(Drv, alcove:audit_arch()),
|
||||
Arch = alcove:define(Drv, [], alcove:audit_arch()),
|
||||
[
|
||||
?VALIDATE_ARCHITECTURE(Arch),
|
||||
?EXAMINE_SYSCALL,
|
||||
|
||||
@@ -83,12 +83,12 @@ start() ->
|
||||
|
||||
{ok, Drv} = alcove_drv:start_link([{exec, Exec}, {maxchild, 8}]),
|
||||
|
||||
ok = alcove:sigaction(Drv, sigchld, sig_catch),
|
||||
ok = alcove:sigaction(Drv, sigpipe, sig_ign),
|
||||
ok = alcove:sigaction(Drv, [], sigchld, sig_catch),
|
||||
ok = alcove:sigaction(Drv, [], sigpipe, sig_ign),
|
||||
|
||||
case {Use_fork, os:type()} of
|
||||
{false, {unix,linux} = OS} ->
|
||||
{ok, Child} = alcove:clone(Drv, [
|
||||
{ok, Child} = alcove:clone(Drv, [], [
|
||||
clone_newipc,
|
||||
clone_newnet,
|
||||
clone_newns,
|
||||
@@ -102,7 +102,7 @@ start() ->
|
||||
os = OS
|
||||
};
|
||||
{_, {unix,_} = OS} ->
|
||||
{ok, Child} = alcove:fork(Drv),
|
||||
{ok, Child} = alcove:fork(Drv, []),
|
||||
#state{
|
||||
pid = Drv,
|
||||
child = Child,
|
||||
@@ -130,7 +130,7 @@ msg(_) ->
|
||||
).
|
||||
|
||||
version(#state{pid = Drv}) ->
|
||||
Version = alcove:version(Drv),
|
||||
Version = alcove:version(Drv, []),
|
||||
?_assertEqual(true, is_binary(Version)).
|
||||
|
||||
iodata(#state{pid = Drv}) ->
|
||||
@@ -141,18 +141,18 @@ iodata(#state{pid = Drv}) ->
|
||||
21,
|
||||
<<22>>],
|
||||
|
||||
Reply0 = alcove:iolist_to_bin(Drv, Iolist),
|
||||
Reply0 = alcove:iolist_to_bin(Drv, [], Iolist),
|
||||
|
||||
% Valid iolists: binary, string, lists, bytes must be within a list
|
||||
Reply1 = (catch alcove:iolist_to_bin(Drv, 10)),
|
||||
Reply2 = (catch alcove:iolist_to_bin(Drv, [123456])),
|
||||
Reply3 = alcove:iolist_to_bin(Drv, <<1,2,3,4,5,6>>),
|
||||
Reply4 = alcove:iolist_to_bin(Drv, "ok"),
|
||||
Reply1 = (catch alcove:iolist_to_bin(Drv, [], 10)),
|
||||
Reply2 = (catch alcove:iolist_to_bin(Drv, [], [123456])),
|
||||
Reply3 = alcove:iolist_to_bin(Drv, [], <<1,2,3,4,5,6>>),
|
||||
Reply4 = alcove:iolist_to_bin(Drv, [], "ok"),
|
||||
|
||||
% Arbitrary implementation limit of 16 nested
|
||||
% lists. iolist_to_binary/1 does not have this limitation.
|
||||
Reply5 = alcove:iolist_to_bin(Drv, [[[[[[[[[[[[[[[["ok"]]]]]]]]]]]]]]]]),
|
||||
Reply6 = (catch alcove:iolist_to_bin(Drv, [[[[[[[[[[[[[[[[["fail"]]]]]]]]]]]]]]]]])),
|
||||
Reply5 = alcove:iolist_to_bin(Drv, [], [[[[[[[[[[[[[[[["ok"]]]]]]]]]]]]]]]]),
|
||||
Reply6 = (catch alcove:iolist_to_bin(Drv, [], [[[[[[[[[[[[[[[[["fail"]]]]]]]]]]]]]]]]])),
|
||||
|
||||
[
|
||||
?_assertEqual(Reply0, iolist_to_binary(Iolist)),
|
||||
@@ -165,7 +165,7 @@ iodata(#state{pid = Drv}) ->
|
||||
].
|
||||
|
||||
pid(#state{pid = Drv}) ->
|
||||
Pids = alcove:pid(Drv),
|
||||
Pids = alcove:pid(Drv, []),
|
||||
?_assertEqual(1, length(Pids)).
|
||||
|
||||
getpid(#state{clone = true, pid = Drv, child = Child}) ->
|
||||
@@ -177,7 +177,7 @@ getpid(#state{pid = Drv, child = Child}) ->
|
||||
?_assertEqual(true, PID > 0).
|
||||
|
||||
setopt(#state{pid = Drv}) ->
|
||||
{ok, Fork} = alcove:fork(Drv),
|
||||
{ok, Fork} = alcove:fork(Drv, []),
|
||||
|
||||
true = alcove:setopt(Drv, [Fork], maxchild, 128),
|
||||
|
||||
@@ -208,7 +208,7 @@ setopt(#state{pid = Drv}) ->
|
||||
].
|
||||
|
||||
event(#state{pid = Drv}) ->
|
||||
{ok, Fork} = alcove:fork(Drv),
|
||||
{ok, Fork} = alcove:fork(Drv, []),
|
||||
Reply0 = alcove:exit(Drv, [Fork], 0),
|
||||
Reply1 = alcove:event(Drv, [Fork], 5000),
|
||||
Reply2 = alcove:event(Drv, [], 5000),
|
||||
@@ -262,7 +262,7 @@ clone_define(_) ->
|
||||
[].
|
||||
|
||||
setns(#state{clone = true, pid = Drv, child = Child}) ->
|
||||
{ok, Child1} = alcove:fork(Drv),
|
||||
{ok, Child1} = alcove:fork(Drv, []),
|
||||
ok = alcove:setns(Drv, [Child1], [
|
||||
"/proc/",
|
||||
integer_to_list(Child),
|
||||
@@ -275,25 +275,25 @@ setns(_) ->
|
||||
[].
|
||||
|
||||
unshare(#state{clone = true, pid = Drv}) ->
|
||||
Host = alcove:gethostname(Drv),
|
||||
{ok, Child1} = alcove:fork(Drv),
|
||||
Host = alcove:gethostname(Drv, []),
|
||||
{ok, Child1} = alcove:fork(Drv, []),
|
||||
ok = alcove:unshare(Drv, [Child1], [clone_newuts]),
|
||||
Reply = alcove:sethostname(Drv, [Child1], "unshare"),
|
||||
Hostname = alcove:gethostname(Drv, [Child1]),
|
||||
Host = alcove:gethostname(Drv),
|
||||
Host = alcove:gethostname(Drv, []),
|
||||
[?_assertEqual(ok, Reply),
|
||||
?_assertEqual({ok, <<"unshare">>}, Hostname)];
|
||||
unshare(_) ->
|
||||
[].
|
||||
|
||||
mount_define(#state{os = {unix,sunos}, pid = Drv}) ->
|
||||
Flags = alcove:define(Drv, [
|
||||
Flags = alcove:define(Drv, [], [
|
||||
rdonly,
|
||||
nosuid
|
||||
]),
|
||||
?_assertEqual(true, is_integer(Flags));
|
||||
mount_define(#state{pid = Drv}) ->
|
||||
Flags = alcove:define(Drv, [
|
||||
Flags = alcove:define(Drv, [], [
|
||||
rdonly,
|
||||
nosuid,
|
||||
noexec,
|
||||
@@ -414,7 +414,7 @@ fork(#state{pid = Drv, child = Child}) ->
|
||||
].
|
||||
|
||||
badpid(#state{pid = Drv}) ->
|
||||
{ok, Child} = alcove:fork(Drv),
|
||||
{ok, Child} = alcove:fork(Drv, []),
|
||||
|
||||
% EPIPE or PID not found
|
||||
ok = alcove:execvp(Drv, [Child], "/bin/sh",
|
||||
@@ -439,17 +439,17 @@ badpid(#state{pid = Drv}) ->
|
||||
].
|
||||
|
||||
signal(#state{pid = Drv}) ->
|
||||
{ok, Child1} = alcove:fork(Drv),
|
||||
{ok, Child1} = alcove:fork(Drv, []),
|
||||
|
||||
SA0 = alcove:sigaction(Drv, [Child1], sigterm, sig_ign),
|
||||
Kill0 = alcove:kill(Drv, Child1, sigterm),
|
||||
Kill0 = alcove:kill(Drv, [], Child1, sigterm),
|
||||
Pid0 = alcove:getpid(Drv, [Child1]),
|
||||
|
||||
SA1 = alcove:sigaction(Drv, [Child1], sigterm, sig_dfl),
|
||||
Kill1 = alcove:kill(Drv, Child1, sigterm),
|
||||
Kill1 = alcove:kill(Drv, [], Child1, sigterm),
|
||||
waitpid(Drv, [], Child1),
|
||||
alcove:kill(Drv, Child1, 0),
|
||||
Search = alcove:kill(Drv, Child1, 0),
|
||||
alcove:kill(Drv, [], Child1, 0),
|
||||
Search = alcove:kill(Drv, [], Child1, 0),
|
||||
|
||||
[
|
||||
?_assertEqual(ok, SA0),
|
||||
@@ -470,12 +470,12 @@ portstress(#state{pid = Drv, child = Child}) ->
|
||||
?_assertEqual(Ok, Reply).
|
||||
|
||||
forkstress(#state{pid = Drv}) ->
|
||||
{ok, Fork} = alcove:fork(Drv),
|
||||
{ok, Fork} = alcove:fork(Drv, []),
|
||||
Reply = forkstress_1(Drv, Fork, 100),
|
||||
?_assertEqual(ok, Reply).
|
||||
|
||||
forkchain(#state{pid = Drv}) ->
|
||||
{ok, Child0} = alcove:fork(Drv),
|
||||
{ok, Child0} = alcove:fork(Drv, []),
|
||||
{ok, Child1} = alcove:fork(Drv, [Child0]),
|
||||
{ok, Child2} = alcove:fork(Drv, [Child0, Child1]),
|
||||
{ok, Child3} = alcove:fork(Drv, [Child0, Child1, Child2]),
|
||||
@@ -488,7 +488,7 @@ forkchain(#state{pid = Drv}) ->
|
||||
?_assertEqual(Pid, Child4).
|
||||
|
||||
eof(#state{pid = Drv}) ->
|
||||
{ok, Child} = alcove:fork(Drv),
|
||||
{ok, Child} = alcove:fork(Drv, []),
|
||||
{ok, Child0} = alcove:fork(Drv, [Child]),
|
||||
|
||||
ok = alcove:eof(Drv, [Child,Child0], stderr),
|
||||
@@ -513,7 +513,7 @@ eof(#state{pid = Drv}) ->
|
||||
].
|
||||
|
||||
alloc(#state{os = {unix,_}, pid = Drv}) ->
|
||||
{ok, Buf, Cstruct} = alcove:alloc(Drv,
|
||||
{ok, Buf, Cstruct} = alcove:alloc(Drv, [],
|
||||
[<<1,2,3,4,5,6,7,8,9,10>>,
|
||||
{ptr, 11},
|
||||
<<11,12,13,14,15>>,
|
||||
@@ -532,7 +532,7 @@ alloc(#state{os = {unix,_}, pid = Drv}) ->
|
||||
].
|
||||
|
||||
prctl(#state{os = {unix,linux}, pid = Drv}) ->
|
||||
{ok, Fork} = alcove:fork(Drv),
|
||||
{ok, Fork} = alcove:fork(Drv, []),
|
||||
|
||||
% capability is set:
|
||||
% returns 0 | 1 in function result, arg2 = int
|
||||
@@ -565,7 +565,7 @@ prctl(_) ->
|
||||
[].
|
||||
|
||||
priority(#state{os = {unix,_}, pid = Drv}) ->
|
||||
{ok, Fork0} = alcove:fork(Drv),
|
||||
{ok, Fork0} = alcove:fork(Drv, []),
|
||||
{ok, Fork1} = alcove:fork(Drv, [Fork0]),
|
||||
{ok, Fork2} = alcove:fork(Drv, [Fork0]),
|
||||
|
||||
@@ -614,7 +614,7 @@ execvp(_) ->
|
||||
[].
|
||||
|
||||
execvp_with_signal(#state{pid = Drv}) ->
|
||||
{ok, Fork} = alcove:fork(Drv),
|
||||
{ok, Fork} = alcove:fork(Drv, []),
|
||||
Reply0 = (catch alcove:execvp(Drv, [Fork], "/bin/sh",
|
||||
["/bin/sh", "-c", "kill -9 $$"])),
|
||||
Reply1 = alcove:event(Drv, [Fork], 5000),
|
||||
@@ -657,8 +657,8 @@ stderr(_) ->
|
||||
[].
|
||||
|
||||
execve(#state{pid = Drv}) ->
|
||||
{ok, Child0} = alcove:fork(Drv),
|
||||
{ok, Child1} = alcove:fork(Drv),
|
||||
{ok, Child0} = alcove:fork(Drv, []),
|
||||
{ok, Child1} = alcove:fork(Drv, []),
|
||||
|
||||
Reply0 = (catch alcove:execve(Drv, [Child0], "/usr/bin/env",
|
||||
["/usr/bin/env"], ["A=1", "B=2", "C=3", false])),
|
||||
@@ -694,13 +694,13 @@ stream(#state{pid = Drv}) ->
|
||||
?_assertEqual(ok, Reply).
|
||||
|
||||
open(#state{pid = Drv}) ->
|
||||
O_RDONLY = alcove:define(Drv, o_rdonly),
|
||||
O_RDONLY = alcove:define(Drv, [], o_rdonly),
|
||||
|
||||
File = "/nonexistent",
|
||||
|
||||
Reply0 = alcove:open(Drv, File, O_RDONLY, 0),
|
||||
Reply1 = alcove:open(Drv, File, [O_RDONLY,O_RDONLY,O_RDONLY,O_RDONLY], 0),
|
||||
Reply2 = alcove:open(Drv, File, [o_rdonly, o_rdonly, o_rdonly], 0),
|
||||
Reply0 = alcove:open(Drv, [], File, O_RDONLY, 0),
|
||||
Reply1 = alcove:open(Drv, [], File, [O_RDONLY,O_RDONLY,O_RDONLY,O_RDONLY], 0),
|
||||
Reply2 = alcove:open(Drv, [], File, [o_rdonly, o_rdonly, o_rdonly], 0),
|
||||
|
||||
[
|
||||
?_assertEqual({error,enoent}, Reply0),
|
||||
@@ -716,7 +716,7 @@ execvp_mid_chain(#state{os = {unix,OS}, pid = Drv}) ->
|
||||
alcove:stdin(Drv, Pids, "test\n"),
|
||||
Reply0 = alcove:stdout(Drv, Pids, 5000),
|
||||
waitpid_exit(Drv, [], lists:last(Rest)),
|
||||
Reply1 = [ alcove:kill(Drv, Pid, 0) || Pid <- Rest ],
|
||||
Reply1 = [ alcove:kill(Drv, [], Pid, 0) || Pid <- Rest ],
|
||||
|
||||
ChildState = case OS of
|
||||
openbsd -> {error,esrch};
|
||||
@@ -772,7 +772,7 @@ flush(stdout, Drv, Pids) ->
|
||||
|
||||
get_unused_pid(Drv) ->
|
||||
PID = crypto:rand_uniform(16#0affffff, 16#0fffffff),
|
||||
case alcove:kill(Drv, PID, 0) of
|
||||
case alcove:kill(Drv, [], PID, 0) of
|
||||
{error,esrch} -> PID;
|
||||
_ -> get_unused_pid(Drv)
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user