Erlang interface for controlling Unix processes
Erlang C
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

perc is an Erlang interface for controlling Unix processes.





kill(Pid, Signal) -> ok | {error, posix()}

    Types   Pid = integer()
            Signal = integer()

    Send a signal to a Unix process.

    Process IDs and signals are signed 32-bit integers.

    Sending a signal to PID 0 will send the signal to the Erlang VM.

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, NewPrio} | {error, posix()}

    Types   Type = {Which, Who}
            Which = pid | pgrp | user
            Who = integer()
            Prio = integer() | string()
            NewPrio = integer()

    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 and returns the new priority. 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.
        3> Hard.

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.

    WARNING: querying the umask is destructive: it is done by
    setting the umask to 0, then re-setting it back to the original
    umask. Between successive calls to umask/1, the process may be
    swapped out. If another process queries the umask, the beam Unix
    process may end up in an inconsistent state.

    To avoid this race condition, umask/0 sets a lock by using
    process registration. This may have some unintended side effects:

    1. If the atom is registered by something other than perc,
       umask/0 will spin forever.

    2. If, between successive calls to umask/1, something else
       (another NIF or driver) changes the umask, umask/0 will crash,
       releasing the lock.

    Neither of the above is likely to happyen but at some point,
    the umask/0 code may be moved into C to prevent these problems.


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:


        start() ->
            {ok, Ref} = perc_signal:start([sighup]),

                {signal, Ref, #signalfd_siginfo{
                    ssi_signo = 1,
                    ssi_pid = Pid,
                    ssi_uid = UID,
                    }} ->
                        {sending_pid, Pid},
                        {sending_uid, UID}

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

2> perc:kill(1, 1).

3> perc:kill(31337, 1).


% Get the current value for rlimit_cpu
1> perc:prlimit(0, rlimit_cpu, <<>>, <<0:128>>).

% 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>>, <<>>).

2> file:open("/etc/passwd", [read]).

3> file:open("/etc/passwd", [read]).


1> perc:getpriority(0, 0).
{ok, 0}

2> perc:setpriority(0, 0, 10).

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