perc is an Erlang interface for controlling Unix processes.
rebar3 do compile, eunit
kill(Pid, Signal) -> ok | {error, posix()}
Types Pid = integer()
Signal = integer() | atom()
Send a signal to a Unix process.
Process IDs and signals are signed 32-bit integers. A signal
can also be the lower cased signal name as an atom.
Sending a signal to PID 0 will send the signal to the Erlang VM.
getuid() -> uint32_t()
See getuid(2).
Get user identity.
getgid() -> uint32_t()
See getgid(2).
Get group identity.
geteuid() -> uint32_t()
See geteuid(2).
Get effective user id.
getegid() -> uint32_t()
See getegid(2).
Get effective group id.
getgroups() -> [uint32_t()]
See getgroups(2).
Retrieve the list of supplementary groups.
setgroups([uint32_t()]) -> ok | {error, posix()}
See setgroups(2).
Set the list of supplementary groups.
setresuid(Ruid, Euid, Suid) -> ok | {error, posix()}
Types Ruid = uint32_t()
Euid = uint32_t()
Suid = uint32_t()
See setresuid(2).
Set real, effective and saved user id.
setresgid(Rgid, Egid, Sgid) -> ok | {error, posix()}
Types Rgid = uint32_t()
Egid = uint32_t()
Sgid = uint32_t()
See setresgid(2).
Set real, effective and saved group id.
getpriority(Which, Who) -> {ok, integer()} | {error, posix()}
Types Which = integer()
Who = integer()
See getpriority(2).
Get the priority (the "nice" value) of processes by pid, process
group or user.
setpriority(Which, Who, Prio) -> ok | {error, posix()}
Types Which = integer()
Who = integer()
Prio = integer()
See setpriority(2).
Set the priority (the "nice" value) of processes by pid, process
group or user.
renice(Type, Prio) -> ok | {error, posix()}
Types Type = {Which, Who}
Which = pid | pgrp | user
Who = integer()
Prio = integer() | string()
Convenience wrapper around getpriority/2 and setpriority/3,
similar to renice(1).
WARNING: renice/2 makes successive calls to getpriority/2 and
setpriority/3. Since this sequence is not atomic, the priority
may change between calls or the process may have been terminated.
Sets the priority of a process or processes by pid, pgroup or
user. The new priority may be an integer or a list containing a
relative priority, indicated by using a "+" or "-". For example,
using "+10" will increase the niceness of the process by 10.
prlimit(Pid, Resource, NewLimit, OldLimit) -> {ok, NewLimit1, OldLimit1} | {error, Error}
Types Pid = integer()
Resource = integer()
| rlimit_cpu
| rlimit_fsize
| rlimit_data
| rlimit_stack
| rlimit_core
| rlimit_rss
| rlimit_nproc
| rlimit_nofile
| rlimit_ofile
| rlimit_memlock
| rlimit_as
| rlimit_locks
| rlimit_sigpending
| rlimit_msgqueue
| rlimit_nice
| rlimit_rtprio
| rlimit_rttime
| rlimit_nlimits
| rlim_infinity
NewLimit = NewLimit1 = <<>> | binary()
OldLimit = OldLimit1 = <<>> | binary()
Error = unsupported | posix()
Linux only: on other platforms, {error, unsupported} will be
returned to the caller.
Set or retrieve process limits for a process. Passing in an
empty binary for NewLimit or OldLimit indicates the caller is
not interested in these values.
The binary size of NewLimit/OldLimit must otherwise match the size
of a struct rlimit for the platform. struct rlimit is usually
composed of two 8 byte values in native format. To retrieve the
current settings, pass in a zeroed 16 byte value.
getrlimit(Resource) -> {ok, Limit} | {error, Error}
Types Resource = integer() | rlimit()
Error = posix()
Get process limits for beam. See prlimit/4 for a list of the
resource atoms.
The value returned is a struct rlimit:
1> {ok, <<Soft:8/native-unsigned-integer-unit:8, Hard:8/native-unsigned-integer-unit:8>>} = perc:getrlimit(rlimit_nofile).
2> Soft.
1024
3> Hard.
4096
setrlimit(Resource, Limit) -> {ok, Limit} | {error, Error}
Types Resource = integer() | rlimit()
Error = posix()
Limit = binary()
Set process limits for beam. See prlimit/4 for a list of the
resource atoms.
umask() -> CurMask
umask(Mask) -> OldMask
Types Mask = integer() | list()
CurMask = OldMask = integer()
Sets the file creation mask for beam. The mask may be either
an integer or a list representing an octal number, e.g., either
8#022 or "022".
The old mask value is returned. To retrieve the current umask,
use umask/0 or getumask/0.
WARNING: umask/0 is destructive: the umask is retrieved by setting
the process mask to 0, then re-setting it back to the original
mask. Between the successive calls to umask(2), the process
mask is 0. An erlang process calling umask/0 concurrently with
a process creating a file may have unexpected results.
getumask() -> CurMask
Types CurMask = OldMask = integer()
Obtain the current process mask by parsing /proc/self/status,
avoiding the race condition in umask/0.
If /proc/self/status does not exist or is not parsable, getumask/0
fails back to umask/0.
WARNING: support for signalfd(2) is experimental only and is disabled by default.
To enable, add -DHAVE_SIGNALFD
to the rebar.config tuple for your
architecture. Some of the signals may be caught by beam. signalfd is
likely to work only with a single threaded beam. The interaction between
signals and POSIX threads is mysterious.
start(Signals) -> {ok, pid()} | {error, enomem}
Types Signals = [ Signal ]
Signal = integer() | Names
Names = sighup
| sigint
| sigquit
| sigill
| sigtrap
| sigabrt
| sigbus
| sigfpe
| sigkill
| sigusr1
| sigsegv
| sigusr2
| sigpipe
| sigalrm
| sigterm
| sigstkflt
| sigchld
| sigcont
| sigstop
| sigtstp
| sigttin
| sigttou
| sigurg
| sigxcpu
| sigxfsz
| sigvtalrm
| sigprof
| sigwinch
| sigio
| sigpwr
| sigsys
| sigrtmin
| sigrtmax
Linux only: on other platforms, {error, unsupported} will be
returned to the caller.
Receive notification when the beam process receives a signal:
{signal, pid(), #signalfd_siginfo{}}
The tuple contains the PID of the gen_server and information
about the signal. See signalfd(2) for details about the returned
data. For example, to match the signal number:
-include_lib("perc/include/perc_signal.hrl").
start() ->
{ok, Ref} = perc_signal:start([sighup]),
receive
{signal, Ref, #signalfd_siginfo{
ssi_signo = 1,
ssi_pid = Pid,
ssi_uid = UID,
}} ->
error_logger:info_report([
{sending_pid, Pid},
{sending_uid, UID}
])
end.
stop(Ref) -> ok
Stop the gen_server and close the signalfd file descriptor.
$ sleep 1000000 &
[1] 2947
$ erl -pa ebin
1> perc:kill(2947, 9).
ok
2> perc:kill(1, 1).
{error,eperm}
3> perc:kill(31337, 1).
{error,esrch}
% Get the current value for rlimit_cpu
1> perc:prlimit(0, rlimit_cpu, <<>>, <<0:128>>).
{ok,<<>>,<<"ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ">>}
% Set RLIMIT_NOFILE (7) on the Erlang VM. Sets the current and max file descriptors
% to 8.
1> perc:prlimit(0, 7, <<8:8/native-unsigned-integer-unit:8, 8:8/native-unsigned-integer-unit:8>>, <<>>).
{ok,<<8,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0>>,<<>>}
2> file:open("/etc/passwd", [read]).
{ok,<0.39.0>}
3> file:open("/etc/passwd", [read]).
{error,emfile}
% PRIO_PROCESS = 0
1> perc:getpriority(0, 0).
{ok, 0}
2> perc:setpriority(0, 0, 10).
ok
3> perc:getpriority(0, 0).
{ok, 10}
4> perc:renice({pid, 0}, "-5").
{ok, 5}
-
process lookup
-
atom rlimit_*
constants only supported for 64-bit values