erl_nif(3)



erl_nif(3erl)                 C Library Functions                erl_nif(3erl)

NAME
       erl_nif - API functions for an Erlang NIF library.

DESCRIPTION
       A  NIF  library  contains native implementation of some functions of an
       Erlang module. The native implemented functions (NIFs) are called  like
       any other functions without any difference to the caller. A NIF library
       is built as a dynamically linked library file and loaded in runtime  by
       calling erlang:load_nif/2.

   Warning:

       Use this functionality with extreme care.

       A  native function is executed as a direct extension of the native code
       of the VM. Execution is not made in a safe environment. The  VM  cannot
       provide  the same services as provided when executing Erlang code, such
       as pre-emptive scheduling or memory protection. If the native  function
       does not behave well, the whole VM will misbehave.

         * A native function that crashes will crash the whole VM.

         * An  erroneously implemented native function can cause a VM internal
           state inconsistency, which can cause a crash of the VM, or  miscel-
           laneous  misbehaviors  of the VM at any point after the call to the
           native function.

         * A native function doing lengthy work before returning degrades  re-
           sponsiveness  of the VM, and can cause miscellaneous strange behav-
           iors. Such strange behaviors include, but are not limited  to,  ex-
           treme  memory  usage,  and  bad  load balancing between schedulers.
           Strange behaviors that can occur because of lengthy work  can  also
           vary between Erlang/OTP releases.

EXAMPLE
       A minimal example of a NIF library can look as follows:

       /* niftest.c */
       #include <erl_nif.h>

       static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
       {
           return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1);
       }

       static ErlNifFunc nif_funcs[] =
       {
           {"hello", 0, hello}
       };

       ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)

       The Erlang module can look as follows:

       -module(niftest).

       -export([init/0, hello/0]).

       -on_load(init/0).

       init() ->
             erlang:load_nif("./niftest", 0).

       hello() ->
             erlang:nif_error("NIF library not loaded").

       Compile and test can look as follows (on Linux):

       $> gcc -fPIC -shared -o niftest.so niftest.c -I $ERL_ROOT/usr/include/
       $> erl

       1> c(niftest).
       {ok,niftest}
       2> niftest:hello().
       "Hello world!"

       In  the  example  above the on_load directive is used get function init
       called automatically when the module is loaded. Function init  in  turn
       calls  erlang:load_nif/2  which  loads the NIF library and replaces the
       hello function with its native implementation in C. Once loaded, a  NIF
       library  is  persistent.  It will not be unloaded until the module code
       version that it belongs to is purged.

       Each NIF must have an implementation in Erlang to  be  invoked  if  the
       function  is  called  before  the NIF library is successfully loaded. A
       typical such stub implementation is to call erlang:nif_error which will
       raise  an exception. The Erlang function can also be used as a fallback
       implementation if the NIF library lacks implementation for some  OS  or
       hardware architecture for example.

   Note:
       A NIF does not have to be exported, it can be local to the module. How-
       ever, unused local stub functions will be optimized away  by  the  com-
       piler, causing loading of the NIF library to fail.

FUNCTIONALITY
       All  interaction between NIF code and the Erlang runtime system is per-
       formed by calling NIF API functions. Functions exist for the  following
       functionality:

         Read and write Erlang terms:
           Any  Erlang  terms can be passed to a NIF as function arguments and
           be returned as function return values.  The  terms  are  of  C-type
           ERL_NIF_TERM  and  can only be read or written using API functions.
           Most functions to read the content of a term are prefixed enif_get_
           and  usually  return true (or false) if the term is of the expected
           type (or not). The  functions  to  write  terms  are  all  prefixed
           enif_make_  and  usually return the created ERL_NIF_TERM. There are
           also  some   functions   to   query   terms,   like   enif_is_atom,
           enif_is_identical, and enif_compare.

           All  terms  of  type  ERL_NIF_TERM belong to an environment of type
           ErlNifEnv. The lifetime of a term is controlled by the lifetime  of
           its  environment object. All API functions that read or write terms
           has the environment that the term belongs to as the first  function
           argument.

         Binaries:
           Terms of type binary are accessed with the help of struct type Erl-
           NifBinary, which contains a pointer (data) to the raw  binary  data
           and  the length (size) of the data in bytes. Both data and size are
           read-only and are only to be written using calls to API  functions.
           Instances  of  ErlNifBinary  are,  however, always allocated by the
           user (usually as local variables).

           The raw data pointed to by data is only mutable  after  a  call  to
           enif_alloc_binary  or enif_realloc_binary. All other functions that
           operate on a binary leave the data as read-only. A  mutable  binary
           must  in  the  end either be freed with enif_release_binary or made
           read-only by transferring it to an Erlang term  with  enif_make_bi-
           nary.  However,  it  does  not  have to occur in the same NIF call.
           Read-only binaries do not have to be released.

           enif_make_new_binary can be used as a shortcut to allocate and  re-
           turn a binary in the same NIF call.

           Binaries are sequences of whole bytes. Bitstrings with an arbitrary
           bit length have no support yet.

         Resource objects:
           The use of resource objects is a safe way to return pointers to na-
           tive  data structures from a NIF. A resource object is only a block
           of memory  allocated  with  enif_alloc_resource.  A  handle  ("safe
           pointer")  to  this  memory block can then be returned to Erlang by
           the use of enif_make_resource. The term returned  by  enif_make_re-
           source  is  opaque  in  nature. It can be stored and passed between
           processes, but the only real end usage is to pass it back as an ar-
           gument  to  a  NIF. The NIF can then call enif_get_resource and get
           back a pointer to the memory block, which is guaranteed to still be
           valid.  A  resource object is not deallocated until the last handle
           term is garbage collected by the VM and the  resource  is  released
           with enif_release_resource (not necessarily in that order).

           All  resource  objects  are  created  as instances of some resource
           type. This makes resources from different  modules  to  be  distin-
           guishable.  A  resource  type  is  created by calling enif_open_re-
           source_type when a library is loaded. Objects of that resource type
           can then later be allocated and enif_get_resource verifies that the
           resource is of the expected type. A resource type can have a  user-
           supplied  destructor  function,  which is automatically called when
           resources of that type are released (by either the garbage  collec-
           tor  or enif_release_resource). Resource types are uniquely identi-
           fied by a supplied name string and the  name  of  the  implementing
           module.

           The  following  is a template example of how to create and return a
           resource object.

         ERL_NIF_TERM term;
         MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct));

         /* initialize struct ... */

         term = enif_make_resource(env, obj);

         if (keep_a_reference_of_our_own) {
             /* store 'obj' in static variable, private data or other resource object */
         }
         else {
             enif_release_resource(obj);
             /* resource now only owned by "Erlang" */
         }
         return term;

           Notice that once enif_make_resource creates the term to  return  to
           Erlang,  the  code can choose to either keep its own native pointer
           to the allocated struct and release it later, or release it immedi-
           ately  and rely only on the garbage collector to deallocate the re-
           source object eventually when it collects the term.

           Another use of resource objects is  to  create  binary  terms  with
           user-defined memory management. enif_make_resource_binary creates a
           binary term that is connected to a resource object. The  destructor
           of  the resource is called when the binary is garbage collected, at
           which time the binary data can be released. An example of this  can
           be  a  binary  term consisting of data from a mmap'ed file. The de-
           structor can then do munmap to release the memory region.

           Resource types support upgrade in runtime by allowing a loaded  NIF
           library  to take over an already existing resource type and by that
           "inherit" all existing objects of that type. The destructor of  the
           new  library is thereafter called for the inherited objects and the
           library with the old destructor function can  be  safely  unloaded.
           Existing  resource  objects, of a module that is upgraded, must ei-
           ther be deleted or taken over by the new NIF library. The unloading
           of  a  library is postponed as long as there exist resource objects
           with a destructor function in the library.

         Module upgrade and static data:
           A loaded NIF library is tied to the  Erlang  module  instance  that
           loaded it. If the module is upgraded, the new module instance needs
           to load its own NIF library (or maybe choose not to). The new  mod-
           ule  instance  can,  however, choose to load the exact same NIF li-
           brary as the old code if it wants to. Sharing the  dynamic  library
           means that static data defined by the library is shared as well. To
           avoid unintentionally shared static data between module  instances,
           each Erlang module version can keep its own private data. This pri-
           vate data can be set when the NIF library is loaded and  later  re-
           trieved by calling enif_priv_data.

         Threads and concurrency:
           A  NIF  is thread-safe without any explicit synchronization as long
           as it acts as a pure function and only  reads  the  supplied  argu-
           ments. When you write to a shared state either through static vari-
           ables or enif_priv_data, you need to supply your own explicit  syn-
           chronization.  This  includes terms in process independent environ-
           ments that are shared between threads. Resource  objects  also  re-
           quire synchronization if you treat them as mutable.

           The  library  initialization callbacks load and upgrade are thread-
           safe even for shared state data.

         Version Management:
           When a NIF library is built, information about the NIF API  version
           is  compiled  into  the  library. When a NIF library is loaded, the
           runtime system verifies that the library is of  a  compatible  ver-
           sion. erl_nif.h defines the following:

           ERL_NIF_MAJOR_VERSION:
             Incremented when NIF library incompatible changes are made to the
             Erlang runtime system. Normally it suffices to recompile the  NIF
             library  when  the ERL_NIF_MAJOR_VERSION has changed, but it can,
             under  rare  circumstances,  mean  that  NIF  libraries  must  be
             slightly modified. If so, this will of course be documented.

           ERL_NIF_MINOR_VERSION:
             Incremented  when new features are added. The runtime system uses
             the minor version to determine what features to use.

           The runtime system normally refuses to load a NIF  library  if  the
           major  versions  differ, or if the major versions are equal and the
           minor version used by the NIF library is greater than the one  used
           by  the runtime system. Old NIF libraries with lower major versions
           are, however, allowed after a bump of the major  version  during  a
           transition period of two major releases. Such old NIF libraries can
           however fail if deprecated features are used.

         Time Measurement:
           Support for time measurement in NIF libraries:

           * ErlNifTime

           * ErlNifTimeUnit

           * enif_monotonic_time()

           * enif_time_offset()

           * enif_convert_time_unit()

         I/O Queues:
           The Erlang nif library contains function for  easily  working  with
           I/O  vectors  as used by the unix system call writev. The I/O Queue
           is not thread safe, so some other synchronization mechanism has  to
           be used.

           * SysIOVec

           * ErlNifIOVec

           * enif_ioq_create()

           * enif_ioq_destroy()

           * enif_ioq_enq_binary()

           * enif_ioq_enqv()

           * enif_ioq_deq()

           * enif_ioq_peek()

           * enif_ioq_peek_head()

           * enif_inspect_iovec()

           * enif_free_iovec()

           Typical usage when writing to a file descriptor looks like this:

         int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail,
                        ErlNifIOQueue *q, int fd) {

             ErlNifIOVec vec, *iovec = &vec;
             SysIOVec *sysiovec;
             int saved_errno;
             int iovcnt, n;

             if (!enif_inspect_iovec(env, 64, term, tail, &iovec))
                 return -2;

             if (enif_ioq_size(q) > 0) {
                 /* If the I/O queue contains data we enqueue the iovec and
                    then peek the data to write out of the queue. */
                 if (!enif_ioq_enqv(q, iovec, 0))
                     return -3;

                 sysiovec = enif_ioq_peek(q, &iovcnt);
             } else {
                 /* If the I/O queue is empty we skip the trip through it. */
                 iovcnt = iovec->iovcnt;
                 sysiovec = iovec->iov;
             }

             /* Attempt to write the data */
             n = writev(fd, sysiovec, iovcnt);
             saved_errno = errno;

             if (enif_ioq_size(q) == 0) {
                 /* If the I/O queue was initially empty we enqueue any
                    remaining data into the queue for writing later. */
                 if (n >= 0 && !enif_ioq_enqv(q, iovec, n))
                     return -3;
             } else {
                 /* Dequeue any data that was written from the queue. */
                 if (n > 0 && !enif_ioq_deq(q, n, NULL))
                     return -4;
             }

             /* return n, which is either number of bytes written or -1 if
                some error happened */
             errno = saved_errno;
             return n;
         }

         Long-running NIFs:
           As  mentioned  in  the warning text at the beginning of this manual
           page, it is of vital importance that a native function returns rel-
           atively  fast.  It  is difficult to give an exact maximum amount of
           time that a native function is allowed to work, but usually a well-
           behaving  native  function is to return to its caller within 1 mil-
           lisecond. This can be achieved using different approaches.  If  you
           have  full control over the code to execute in the native function,
           the best approach is to divide the work  into  multiple  chunks  of
           work and call the native function multiple times. This is, however,
           not always possible,  for  example  when  calling  third-party  li-
           braries.

           The  enif_consume_timeslice()  function  can  be used to inform the
           runtime system about the length of the NIF call.  It  is  typically
           always to be used unless the NIF executes very fast.

           If  the NIF call is too lengthy, this must be handled in one of the
           following ways to avoid  degraded  responsiveness,  scheduler  load
           balancing problems, and other strange behaviors:

           Yielding NIF:
             If  the  functionality of a long-running NIF can be split so that
             its work can be achieved through a series of shorter  NIF  calls,
             the application has two options:

             * Make that series of NIF calls from the Erlang level.

             * Call  a  NIF  that first performs a chunk of the work, then in-
               vokes the enif_schedule_nif function to  schedule  another  NIF
               call  to  perform  the  next chunk. The final call scheduled in
               this manner can then return the overall result.

             Breaking up a long-running function in this manner enables the VM
             to regain control between calls to the NIFs.

             This approach is always preferred over the other alternatives de-
             scribed below. This both from a  performance  perspective  and  a
             system characteristics perspective.

           Threaded NIF:
             This  is  accomplished  by dispatching the work to another thread
             managed by the NIF library, return from the NIF, and wait for the
             result. The thread can send the result back to the Erlang process
             using enif_send. Information about thread primitives is  provided
             below.

           Dirty NIF:

       Note:
           Dirty NIF support is available only when the emulator is configured
           with dirty scheduler support. As of ERTS version 9.0, dirty  sched-
           uler  support  is enabled by default on the runtime system with SMP
           support. The Erlang runtime without SMP support  does  not  support
           dirty  schedulers  even when the dirty scheduler support is explic-
           itly enabled. To check at runtime for the presence of dirty  sched-
           uler threads, code can use the enif_system_info() API function.

             A NIF that cannot be split and cannot execute in a millisecond or
             less is called a "dirty NIF", as it performs work that the  ordi-
             nary  schedulers  of  the  Erlang  runtime  system  cannot handle
             cleanly. Applications that make use of such functions must  indi-
             cate  to  the runtime that the functions are dirty so they can be
             handled specially. This is handled by executing dirty jobs  on  a
             separate  set  of schedulers called dirty schedulers. A dirty NIF
             executing on a dirty scheduler does not have  the  same  duration
             restriction as a normal NIF.

             It  is  important to classify the dirty job correct. An I/O bound
             job should be classified as such, and a CPU bound job  should  be
             classified  as such. If you should classify CPU bound jobs as I/O
             bound jobs, dirty I/O schedulers  might  starve  ordinary  sched-
             ulers.  I/O  bound  jobs are expected to either block waiting for
             I/O, and/or spend a limited amount of time moving data.

             To schedule a dirty NIF for execution, the  application  has  two
             options:

             * Set  the  appropriate flags value for the dirty NIF in its Erl-
               NifFunc entry.

             * Call enif_schedule_nif, pass to it a pointer to the  dirty  NIF
               to be executed, and indicate with argument flags whether it ex-
               pects the operation to be CPU-bound or I/O-bound.

             A job that alternates between I/O bound and CPU bound can be  re-
             classified and rescheduled using enif_schedule_nif so that it ex-
             ecutes on the correct type of dirty scheduler at all  times.  For
             more information see the documentation of the erl(1) command line
             arguments +SDcpu, and +SDio.

             While a process executes a dirty NIF, some operations that commu-
             nicate  with it can take a very long time to complete. Suspend or
             garbage collection of a process executing a dirty NIF  cannot  be
             done  until  the  dirty  NIF  has returned. Thus, other processes
             waiting for such operations to complete might have to wait for  a
             very  long  time. Blocking multi-scheduling, that is, calling er-
             lang:system_flag(multi_scheduling, block), can also take  a  very
             long  time  to complete. This is because all ongoing dirty opera-
             tions on all dirty schedulers must complete before the block  op-
             eration can complete.

             Many  operations  communicating  with a process executing a dirty
             NIF can, however, complete while it executes the dirty  NIF.  For
             example,  retrieving  information  about it through process_info,
             setting its group leader, register/unregister its  name,  and  so
             on.

             Termination  of  a process executing a dirty NIF can only be com-
             pleted up to a certain point while it executes the dirty NIF. All
             Erlang resources, such as its registered name and its ETS tables,
             are released. All links and monitors are triggered. The execution
             of  the NIF is, however, not stopped. The NIF can safely continue
             execution, allocate heap memory, and so on, but it is  of  course
             better  to  stop executing as soon as possible. The NIF can check
             whether  a  current   process   is   alive   using   enif_is_cur-
             rent_process_alive.    Communication    using    enif_send    and
             enif_port_command is also dropped when the sending process is not
             alive.  Deallocation  of  certain  internal  resources,  such  as
             process heap and process control  block,  is  delayed  until  the
             dirty NIF has completed.

INITIALIZATION
         ERL_NIF_INIT(MODULE,  ErlNifFunc  funcs[],  load,  NULL, upgrade, un-
         load):
           This is the magic macro to initialize a NIF library. It  is  to  be
           evaluated in global file scope.

           MODULE  is  the  name of the Erlang module as an identifier without
           string quotations. It is stringified by the macro.

           funcs is a static array of function descriptors for all the  imple-
           mented NIFs in this library.

           load,  upgrade and unload are pointers to functions. One of load or
           upgrade is called to initialize the library. unload  is  called  to
           release the library. All are described individually below.

           The  fourth  argument  NULL is ignored. It was earlier used for the
           deprecated reload callback which is no longer supported  since  OTP
           20.

           If  compiling  a  NIF for static inclusion through --enable-static-
           nifs, you must define  STATIC_ERLANG_NIF  before  the  ERL_NIF_INIT
           declaration.

         int  (*load)(ErlNifEnv*  caller_env,  void**  priv_data, ERL_NIF_TERM
         load_info):
           load is called when the NIF library is  loaded  and  no  previously
           loaded library exists for this module.

           *priv_data  can be set to point to some private data if the library
           needs to keep a state between  NIF  calls.  enif_priv_data  returns
           this  pointer.  *priv_data  is  initialized  to  NULL  when load is
           called.

           load_info is the second argument to erlang:load_nif/2.

           The library fails to load if load returns anything  other  than  0.
           load can be NULL if initialization is not needed.

         int   (*upgrade)(ErlNifEnv*   caller_env,  void**  priv_data,  void**
         old_priv_data, ERL_NIF_TERM load_info):
           upgrade is called when the NIF library is loaded and there  is  old
           code of this module with a loaded NIF library.

           Works  as  load,  except  that  *old_priv_data already contains the
           value set by the last call to load or upgrade for  the  old  module
           code.  *priv_data is initialized to NULL when upgrade is called. It
           is allowed to write to both *priv_data and *old_priv_data.

           The library fails to load if upgrade returns anything other than  0
           or if upgrade is NULL.

         void (*unload)(ErlNifEnv* caller_env, void* priv_data):
           unload  is called when the module code that the NIF library belongs
           to is purged as old. New code of the same module may or may not ex-
           ist.

DATA TYPES
         ERL_NIF_TERM:
           Variables  of  type ERL_NIF_TERM can refer to any Erlang term. This
           is an opaque type and values of it can only by used either as argu-
           ments  to  API  functions  or  as  return  values  from  NIFs.  All
           ERL_NIF_TERMs belong to an environment (ErlNifEnv). A  term  cannot
           be  destructed  individually,  it is valid until its environment is
           destructed.

         ErlNifEnv:
           ErlNifEnv represents an environment that can host Erlang terms. All
           terms  in  an  environment  are valid as long as the environment is
           valid. ErlNifEnv is an opaque type; pointers  to  it  can  only  be
           passed on to API functions. Three types of environments exist:

           Process bound environment:
             Passed  as the first argument to all NIFs. All function arguments
             passed to a NIF belong to that environment. The return value from
             a NIF must also be a term belonging to the same environment.

             A  process bound environment contains transient information about
             the calling Erlang process. The environment is only valid in  the
             thread  where  it was supplied as argument until the NIF returns.
             It is thus useless and dangerous to  store  pointers  to  process
             bound environments between NIF calls.

           Callback environment:
             Passed  as  the  first argument to all the non-NIF callback func-
             tions (load, upgrade, unload, dtor, down and stop). Works like  a
             process  bound  environment  but  with a temporary pseudo process
             that "terminates" when the callback has returned.  Terms  may  be
             created in this environment but they will only be accessible dur-
             ing the callback.

           Process independent environment:
             Created by calling enif_alloc_env. This environment can  be  used
             to  store  terms  between  NIF  calls  and  to  send  terms  with
             enif_send. A process independent environment with all  its  terms
             is valid until you explicitly invalidate it with enif_free_env or
             enif_send.

           All contained terms of a list/tuple/map must belong to the same en-
           vironment as the list/tuple/map itself. Terms can be copied between
           environments with enif_make_copy.

         ErlNifFunc:

         typedef struct {
             const char* name;
             unsigned arity;
             ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
             unsigned flags;
         } ErlNifFunc;

           Describes a NIF by its name, arity, and implementation.

           fptr:
             A pointer to the function that implements the NIF.

           argv:
             Contains the function arguments passed to the NIF.

           argc:
             The array length, that is, the function arity. argv[N-1] thus de-
             notes  the Nth argument to the NIF. Notice that the argument argc
             allows for the same C function to implement several Erlang  func-
             tions with different arity (but probably with the same name).

           flags:
             Is 0 for a regular NIF (and so its value can be omitted for stat-
             ically initialized ErlNifFunc instances).

             flags can be used to indicate that the NIF is a dirty NIF that is
             to be executed on a dirty scheduler thread.

             If  the dirty NIF is expected to be CPU-bound, its flags field is
             to     be     set     to      ERL_NIF_DIRTY_JOB_CPU_BOUND      or
             ERL_NIF_DIRTY_JOB_IO_BOUND.

       Note:
           If  one of the ERL_NIF_DIRTY_JOB_*_BOUND flags is set, and the run-
           time system has no support for dirty schedulers, the runtime system
           refuses to load the NIF library.

         ErlNifBinary:

         typedef struct {
             size_t size;
             unsigned char* data;
         } ErlNifBinary;

           ErlNifBinary  contains transient information about an inspected bi-
           nary term. data is a pointer to a buffer of size bytes with the raw
           content of the binary.

           Notice that ErlNifBinary is a semi-opaque type and you are only al-
           lowed to read fields size and data.

         ErlNifBinaryToTerm:
           An enumeration of the options that can  be  specified  to  enif_bi-
           nary_to_term. For default behavior, use value 0.

           When   receiving   data   from   untrusted   sources,   use  option
           ERL_NIF_BIN2TERM_SAFE.

         ErlNifMonitor:
           This is an opaque data type that identifies a monitor.

           The nif writer is to provide the memory  for  storing  the  monitor
           when  calling  enif_monitor_process. The address of the data is not
           stored by the runtime system, so ErlNifMonitor can be used  as  any
           other  data,  it  can be copied, moved in memory, forgotten, and so
           on. To compare two monitors, enif_compare_monitors must be used.

         ErlNifPid:
           A process identifier (pid). In contrast to pid terms (instances  of
           ERL_NIF_TERM),  ErlNifPids  are self-contained and not bound to any
           environment. ErlNifPid is an opaque type. It can be  copied,  moved
           in memory, forgotten, and so on.

         ErlNifPort:
           A  port  identifier.  In  contrast  to  port ID terms (instances of
           ERL_NIF_TERM), ErlNifPorts are self-contained and not bound to  any
           environment.  ErlNifPort is an opaque type. It can be copied, moved
           in memory, forgotten, and so on.

         ErlNifResourceType:
           Each instance of ErlNifResourceType represents a class  of  memory-
           managed  resource  objects  that can be garbage collected. Each re-
           source type has a unique name and a  destructor  function  that  is
           called when objects of its type are released.

         ErlNifResourceTypeInit:

         typedef struct {
             ErlNifResourceDtor* dtor;
             ErlNifResourceStop* stop;
             ErlNifResourceDown* down;
         } ErlNifResourceTypeInit;

           Initialization structure read by  enif_open_resource_type_x.

         ErlNifResourceDtor:

         typedef void ErlNifResourceDtor(ErlNifEnv* caller_env, void* obj);

           The function prototype of a resource destructor function.

           The obj argument is a pointer to the resource. The only allowed use
           for the resource in the destructor is to access its user  data  one
           final  time.  The  destructor is guaranteed to be the last callback
           before the resource is deallocated.

         ErlNifResourceDown:

         typedef void ErlNifResourceDown(ErlNifEnv* caller_env, void* obj, ErlNifPid* pid, ErlNifMonitor* mon);

           The function prototype of a resource down function, called  on  the
           behalf  of   enif_monitor_process.  obj is the resource, pid is the
           identity of the monitored process that is exiting, and mon  is  the
           identity of the monitor.

         ErlNifResourceStop:

         typedef void ErlNifResourceStop(ErlNifEnv* caller_env, void* obj, ErlNifEvent event, int is_direct_call);

           The  function  prototype of a resource stop function, called on the
           behalf of  enif_select. obj is the resource,  event  is  OS  event,
           is_direct_call  is  true if the call is made directly from enif_se-
           lect or false if it is a scheduled call (potentially  from  another
           thread).

         ErlNifCharEncoding:

         typedef enum {
             ERL_NIF_LATIN1
         }ErlNifCharEncoding;

           The  character  encoding  used  in strings and atoms. The only sup-
           ported encoding is ERL_NIF_LATIN1 for ISO Latin-1 (8-bit ASCII).

         ErlNifSysInfo:
           Used by enif_system_info to return information  about  the  runtime
           system. Contains the same content as ErlDrvSysInfo.

         ErlNifSInt64:
           A native signed 64-bit integer type.

         ErlNifUInt64:
           A native unsigned 64-bit integer type.

         ErlNifTime:
           A signed 64-bit integer type for representation of time.

         ErlNifTimeUnit:
           An enumeration of time units supported by the NIF API:

           ERL_NIF_SEC:
             Seconds

           ERL_NIF_MSEC:
             Milliseconds

           ERL_NIF_USEC:
             Microseconds

           ERL_NIF_NSEC:
             Nanoseconds

         ErlNifUniqueInteger:
           An  enumeration  of  the  properties  that  can  be  requested from
           enif_make_unique_integer. For default properties, use value 0.

           ERL_NIF_UNIQUE_POSITIVE:
             Return only positive integers.

           ERL_NIF_UNIQUE_MONOTONIC:
             Return only  strictly  monotonically  increasing  integer  corre-
             sponding to creation time.

         ErlNifHash:
           An  enumeration  of  the supported hash types that can be generated
           using enif_hash.

           ERL_NIF_INTERNAL_HASH:
             Non-portable hash function that only guarantees the same hash for
             the same term within one Erlang VM instance.

             It   takes   32-bit  salt  values  and  generates  hashes  within
             0..2^32-1.

           ERL_NIF_PHASH2:
             Portable hash function that gives the same hash for the same  Er-
             lang term regardless of machine architecture and ERTS version.

             It ignores salt values and generates hashes within 0..2^27-1.

             Slower   than   ERL_NIF_INTERNAL_HASH.   It  corresponds  to  er-
             lang:phash2/1.

         SysIOVec:
           A system I/O vector, as used by  writev  on  Unix  and  WSASend  on
           Win32. It is used in ErlNifIOVec and by enif_ioq_peek.

         ErlNifIOVec:

         typedef struct {
           int iovcnt;
           size_t size;
           SysIOVec* iov;
         } ErlNifIOVec;

           An  I/O vector containing iovcnt SysIOVecs pointing to the data. It
           is used by enif_inspect_iovec and enif_ioq_enqv.

         ErlNifIOQueueOpts:
            Options to configure a ErlNifIOQueue.

           ERL_NIF_IOQ_NORMAL:
             Create a normal I/O Queue

EXPORTS
       void *enif_alloc(size_t size)

              Allocates memory of size bytes.

              Returns NULL if the allocation fails.

              The returned pointer is suitably aligned for any  built-in  type
              that fit in the allocated memory.

       int enif_alloc_binary(size_t size, ErlNifBinary* bin)

              Allocates  a  new  binary  of  size  size bytes. Initializes the
              structure pointed to by bin to refer to  the  allocated  binary.
              The  binary  must  either  be released by enif_release_binary or
              ownership transferred to an Erlang term  with  enif_make_binary.
              An  allocated  (and  owned) ErlNifBinary can be kept between NIF
              calls.

              If you do not need to reallocate or keep the data  alive  across
              NIF  calls,  consider  using  enif_make_new_binary instead as it
              will allocate small binaries on the process heap when possible.

              Returns true on success, or false if allocation fails.

       ErlNifEnv *enif_alloc_env()

              Allocates a new process independent environment. The environment
              can  be  used  to  hold terms that are not bound to any process.
              Such terms can later be copied to  a  process  environment  with
              enif_make_copy  or  be  sent  to  a  process  as  a message with
              enif_send.

              Returns pointer to the new environment.

       void *enif_alloc_resource(ErlNifResourceType*
               type, unsigned size)

              Allocates a memory-managed resource object of type type and size
              size bytes.

       size_t enif_binary_to_term(ErlNifEnv *env,
               const unsigned char* data, size_t size, ERL_NIF_TERM *term,
               ErlNifBinaryToTerm opts)

              Creates a term that is the result of decoding the binary data at
              data, which must be encoded according  to  the  Erlang  external
              term  format.  No more than size bytes are read from data. Argu-
              ment opts corresponds  to  the  second  argument  to  erlang:bi-
              nary_to_term/2 and must be either 0 or ERL_NIF_BIN2TERM_SAFE.

              On  success,  stores the resulting term at *term and returns the
              number of bytes read. Returns 0 if decoding fails or if opts  is
              invalid.

              See   also   ErlNifBinaryToTerm,   erlang:binary_to_term/2,  and
              enif_term_to_binary.

       void enif_clear_env(ErlNifEnv* env)

              Frees all terms in an environment and clears it for  reuse.  The
              environment must have been allocated with enif_alloc_env.

       int enif_compare(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)

              Returns  an integer < 0 if lhs < rhs, 0 if lhs = rhs, and > 0 if
              lhs > rhs. Corresponds to the Erlang operators ==,  /=,  =<,  <,
              >=, and > (but not =:= or =/=).

       int enif_compare_monitors(const ErlNifMonitor
               *monitor1, const ErlNifMonitor *monitor2)

              Compares  two ErlNifMonitors. Can also be used to imply some ar-
              tificial order on monitors, for whatever reason.

              Returns 0 if monitor1 and monitor2 are equal, < 0 if monitor1  <
              monitor2, and > 0 if monitor1 > monitor2.

       int enif_compare_pids(const ErlNifPid *pid1, const ErlNifPid *pid2)

              Compares two ErlNifPids according to term order.

              Returns  0 if pid1 and pid2 are equal, < 0 if pid1 < pid2, and >
              0 if pid1 > pid2.

       void enif_cond_broadcast(ErlNifCond *cnd)

              Same as erl_drv_cond_broadcast.

       ErlNifCond *enif_cond_create(char *name)

              Same as erl_drv_cond_create.

       void enif_cond_destroy(ErlNifCond *cnd)

              Same as erl_drv_cond_destroy.

       char*enif_cond_name(ErlNifCond* cnd)

              Same as erl_drv_cond_name.

       void enif_cond_signal(ErlNifCond *cnd)

              Same as erl_drv_cond_signal.

       void enif_cond_wait(ErlNifCond *cnd, ErlNifMutex *mtx)

              Same as erl_drv_cond_wait.

       int enif_consume_timeslice(ErlNifEnv *env, int percent)

              Gives the runtime system a hint about how much CPU time the cur-
              rent  NIF  call  has  consumed since the last hint, or since the
              start of the NIF if no previous hint  has  been  specified.  The
              time  is  specified as a percent of the timeslice that a process
              is allowed to execute Erlang code until it can be  suspended  to
              give time for other runnable processes. The scheduling timeslice
              is not an exact entity, but can usually be approximated to about
              1 millisecond.

              Notice  that  it is up to the runtime system to determine if and
              how to use this information. Implementations on  some  platforms
              can use other means to determine consumed CPU time. Lengthy NIFs
              should regardless of this frequently call enif_consume_timeslice
              to determine if it is allowed to continue execution.

              Argument  percent  must  be  an  integer between 1 and 100. This
              function must only be called from a NIF-calling thread, and  ar-
              gument env must be the environment of the calling process.

              Returns  1  if  the timeslice is exhausted, otherwise 0. If 1 is
              returned, the NIF is to return as soon as possible in order  for
              the process to yield.

              This  function is provided to better support co-operative sched-
              uling, improve system responsiveness, and make it easier to pre-
              vent  misbehaviors  of  the  VM  because of a NIF monopolizing a
              scheduler thread. It can be used to divide  length work  into  a
              number of repeated NIF calls without the need to create threads.

              See also the warning text at the beginning of this manual page.

       ErlNifTime enif_convert_time_unit(ErlNifTime
               val, ErlNifTimeUnit from, ErlNifTimeUnit to)

              Converts  the  val  value of time unit from to the corresponding
              value of time unit to. The result is  rounded  using  the  floor
              function.

                val:
                  Value to convert time unit for.

                from:
                  Time unit of val.

                to:
                  Time unit of returned value.

              Returns  ERL_NIF_TIME_ERROR  if called with an invalid time unit
              argument.

              See also ErlNifTime and ErlNifTimeUnit.

       ERL_NIF_TERM enif_cpu_time(ErlNifEnv *)

              Returns the CPU time in the same format  as  erlang:timestamp().
              The  CPU time is the time the current logical CPU has spent exe-
              cuting since some arbitrary point in the past. If  the  OS  does
              not   support   fetching   this   value,  enif_cpu_time  invokes
              enif_make_badarg.

       int enif_demonitor_process(ErlNifEnv* caller_env,
             void* obj, const ErlNifMonitor* mon)

              Cancels a monitor created earlier with enif_monitor_process. Ar-
              gument  obj is a pointer to the resource holding the monitor and
              *mon identifies the monitor.

              Argument caller_env is the environment of the calling process or
              callback. Must only be NULL if calling from a custom thread.

              Returns  0  if  the  monitor was successfully identified and re-
              moved. Returns a non-zero value if  the  monitor  could  not  be
              identified, which means it was either

                * never created for this resource

                * already cancelled

                * already triggered

                * just about to be triggered by a concurrent thread

              This  function  is  only  thread-safe when the emulator with SMP
              support is used. It can only be used in a non-SMP emulator  from
              a NIF-calling thread.

       int enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2)

              Same as erl_drv_equal_tids.

       int enif_fprintf(FILE *stream, const char *format, ...)

              Similar  to  fprintf  but  this format string also accepts "%T",
              which formats Erlang terms of type ERL_NIF_TERM.

              This function is primarily intended for debugging purpose. It is
              not  recommended to print very large terms with %T. The function
              may change errno, even if successful.

       void enif_free(void* ptr)

              Frees memory allocated by enif_alloc.

       void enif_free_env(ErlNifEnv* env)

              Frees an environment allocated with  enif_alloc_env.  All  terms
              created in the environment are freed as well.

       void enif_free_iovec(ErlNifIOVec* iov)

              Frees  an  io  vector  returned from enif_inspect_iovec. This is
              needed  only  if  a  NULL  environment  is  passed  to  enif_in-
              spect_iovec.

              ErlNifIOVec *iovec = NULL;
              size_t max_elements = 128;
              ERL_NIF_TERM tail;
              if (!enif_inspect_iovec(NULL, max_elements, term, &tail, &iovec))
                return 0;

              // Do things with the iovec

              /* Free the iovector, possibly in another thread or nif function call */
              enif_free_iovec(iovec);

       int enif_get_atom(ErlNifEnv* env, ERL_NIF_TERM
               term, char* buf, unsigned size, ErlNifCharEncoding encode)

              Writes  a NULL-terminated string in the buffer pointed to by buf
              of size size, consisting of the  string  representation  of  the
              atom term with encoding encode.

              Returns  the number of bytes written (including terminating NULL
              character) or 0 if term is not an atom with  maximum  length  of
              size-1.

       int enif_get_atom_length(ErlNifEnv* env,
               ERL_NIF_TERM term, unsigned* len, ErlNifCharEncoding encode)

              Sets  *len  to the length (number of bytes excluding terminating
              NULL character) of the atom term with encoding encode.

              Returns true on success, or false if term is not an atom.

       int enif_get_double(ErlNifEnv* env,
               ERL_NIF_TERM term, double* dp)

              Sets *dp to the floating-point value of term.

              Returns true on success, or false if term is not a float.

       int enif_get_int(ErlNifEnv* env, ERL_NIF_TERM
               term, int* ip)

              Sets *ip to the integer value of term.

              Returns true on success, or false if term is not an  integer  or
              is outside the bounds of type int.

       int enif_get_int64(ErlNifEnv* env, ERL_NIF_TERM
               term, ErlNifSInt64* ip)

              Sets *ip to the integer value of term.

              Returns  true  on success, or false if term is not an integer or
              is outside the bounds of a signed 64-bit integer.

       int enif_get_local_pid(ErlNifEnv* env,
               ERL_NIF_TERM term, ErlNifPid* pid)

              If term is the pid of a node local process, this  function  ini-
              tializes  the pid variable *pid from it and returns true. Other-
              wise returns false. No check is done to see if  the  process  is
              alive.

          Note:
              enif_get_local_pid  will  return  false  if argument term is the
              atom undefined.

       int enif_get_local_port(ErlNifEnv* env,
               ERL_NIF_TERM term, ErlNifPort* port_id)

              If term identifies a node local port, this function  initializes
              the  port  variable *port_id from it and returns true. Otherwise
              returns false. No check is done to see if the port is alive.

       int enif_get_list_cell(ErlNifEnv* env,
               ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail)

              Sets *head and *tail from list list.

              Returns true on success, or false if it is not  a  list  or  the
              list is empty.

       int enif_get_list_length(ErlNifEnv* env,
               ERL_NIF_TERM term, unsigned* len)

              Sets *len to the length of list term.

              Returns true on success, or false if term is not a proper list.

       int enif_get_long(ErlNifEnv* env, ERL_NIF_TERM
               term, long int* ip)

              Sets *ip to the long integer value of term.

              Returns  true  on success, or false if term is not an integer or
              is outside the bounds of type long int.

       int enif_get_map_size(ErlNifEnv* env,
               ERL_NIF_TERM term, size_t *size)

              Sets *size to the number of key-value pairs in the map term.

              Returns true on success, or false if term is not a map.

       int enif_get_map_value(ErlNifEnv* env,
               ERL_NIF_TERM map, ERL_NIF_TERM key, ERL_NIF_TERM* value)

              Sets *value to the value associated with key in the map map.

              Returns true on success, or false if map is not a map or if  map
              does not contain key.

       int enif_get_resource(ErlNifEnv* env,
               ERL_NIF_TERM term, ErlNifResourceType* type, void** objp)

              Sets *objp to point to the resource object referred to by term.

              Returns  true  on success, or false if term is not a handle to a
              resource object of type type.

              enif_get_resource does not add a reference to the  resource  ob-
              ject. However, the pointer received in *objp is guaranteed to be
              valid at least as long as the resource handle term is valid.

       int enif_get_string(ErlNifEnv* env,
               ERL_NIF_TERM list, char* buf, unsigned size,
               ErlNifCharEncoding encode)

              Writes a NULL-terminated string in the buffer pointed to by  buf
              with size size, consisting of the characters in the string list.
              The characters are written using encoding encode.

              Returns one of the following:

                * The number of  bytes  written  (including  terminating  NULL
                  character)

                * -size if the string was truncated because of buffer space

                * 0 if list is not a string that can be encoded with encode or
                  if size was < 1.

              The written string is always NULL-terminated, unless buffer size
              is < 1.

       int enif_get_tuple(ErlNifEnv* env, ERL_NIF_TERM
               term, int* arity, const ERL_NIF_TERM** array)

              If term is a tuple, this function sets *array to point to an ar-
              ray containing the elements of the tuple, and sets *arity to the
              number of elements. Notice that the array is read-only and (*ar-
              ray)[N-1] is the Nth element of the tuple. *array  is  undefined
              if the arity of the tuple is zero.

              Returns true on success, or false if term is not a tuple.

       int enif_get_uint(ErlNifEnv* env, ERL_NIF_TERM
               term, unsigned int* ip)

              Sets *ip to the unsigned integer value of term.

              Returns true on success, or false if term is not an unsigned in-
              teger or is outside the bounds of type unsigned int.

       int enif_get_uint64(ErlNifEnv* env,
               ERL_NIF_TERM term, ErlNifUInt64* ip)

              Sets *ip to the unsigned integer value of term.

              Returns true on success, or false if term is not an unsigned in-
              teger or is outside the bounds of an unsigned 64-bit integer.

       int enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM
               term, unsigned long* ip)

              Sets *ip to the unsigned long integer value of term.

              Returns true on success, or false if term is not an unsigned in-
              teger or is outside the bounds of type unsigned long.

       int enif_getenv(const char* key, char* value,
               size_t *value_size)

              Same as erl_drv_getenv.

       int enif_has_pending_exception(ErlNifEnv* env,
               ERL_NIF_TERM* reason)

              Returns true if a pending exception is associated with the envi-
              ronment  env. If reason is a NULL pointer, ignore it. Otherwise,
              if a pending exception associated with env exists,  set  *reason
              to   the   value   of   the  exception  term.  For  example,  if
              enif_make_badarg is called to set a pending badarg exception,  a
              later  call  to  enif_has_pending_exception(env,  &reason)  sets
              *reason to the atom badarg, then return true.

              See also enif_make_badarg and enif_raise_exception.

       ErlNifUInt64 enif_hash(ErlNifHash type, ERL_NIF_TERM term, ErlNifUInt64
       salt)

              Hashes term according to the specified ErlNifHash type.

              Ranges  of  taken salt (if any) and returned value depend on the
              hash type.

       int enif_inspect_binary(ErlNifEnv* env,
               ERL_NIF_TERM bin_term, ErlNifBinary* bin)

              Initializes the structure pointed to  by  bin  with  information
              about binary term bin_term.

              Returns true on success, or false if bin_term is not a binary.

       int enif_inspect_iolist_as_binary(ErlNifEnv*
               env, ERL_NIF_TERM term, ErlNifBinary* bin)

              Initializes  the  structure  pointed to by bin with a continuous
              buffer with the same byte content as iolist. As with inspect_bi-
              nary,  the data pointed to by bin is transient and does not need
              to be released.

              Returns true on success, or false if iolist is not an iolist.

       int enif_inspect_iovec(ErlNifEnv*
               env,    size_t    max_elements,    ERL_NIF_TERM     iovec_term,
       ERL_NIF_TERM* tail,
               ErlNifIOVec** iovec)

              Fills  iovec  with  the list of binaries provided in iovec_term.
              The number of elements handled in the call is limited to max_el-
              ements,  and tail is set to the remainder of the list. Note that
              the output may be longer than max_elements on some platforms.

              To create a list of binaries from an arbitrary iolist,  use  er-
              lang:iolist_to_iovec/1.

              When  calling  this  function, iovec should contain a pointer to
              NULL or a ErlNifIOVec structure that should be used if possible.
              e.g.

              /* Don't use a pre-allocated structure */
              ErlNifIOVec *iovec = NULL;
              enif_inspect_iovec(env, max_elements, term, &tail, &iovec);

              /* Use a stack-allocated vector as an optimization for vectors with few elements */
              ErlNifIOVec vec, *iovec = &vec;
              enif_inspect_iovec(env, max_elements, term, &tail, &iovec);

              The contents of the iovec is valid until the called nif function
              returns. If the iovec should be valid after  the  nif  call  re-
              turns, it is possible to call this function with a NULL environ-
              ment. If no environment is given the iovec owns the data in  the
              vector and it has to be explicitly freed using enif_free_iovec.

              Returns true on success, or false if iovec_term not an iovec.

       ErlNifIOQueue *enif_ioq_create(ErlNifIOQueueOpts opts)

              Create  a new I/O Queue that can be used to store data. opts has
              to be set to ERL_NIF_IOQ_NORMAL.

       void enif_ioq_destroy(ErlNifIOQueue *q)

              Destroy the I/O queue and free all of it's contents

       int enif_ioq_deq(ErlNifIOQueue *q, size_t count, size_t *size)

              Dequeue count bytes from the I/O queue. If size is not NULL, the
              new size of the queue is placed there.

              Returns  true  on  success, or false if the I/O does not contain
              count bytes. On failure the queue is left un-altered.

       int enif_ioq_enq_binary(ErlNifIOQueue  *q,  ErlNifBinary  *bin,  size_t
       skip)

              Enqueue the bin into q skipping the first skip bytes.

              Returns  true  on  success, or false if skip is greater than the
              size of bin. Any ownership of the binary data is transferred  to
              the  queue and bin is to be considered read-only for the rest of
              the NIF call and then as released.

       int enif_ioq_enqv(ErlNifIOQueue *q, ErlNifIOVec *iovec, size_t skip)

              Enqueue the iovec into q skipping the first skip bytes.

              Returns true on success, or false if skip is  greater  than  the
              size of iovec.

       SysIOVec *enif_ioq_peek(ErlNifIOQueue *q, int *iovlen)

              Get the I/O queue as a pointer to an array of SysIOVecs. It also
              returns the number of elements in iovlen.

              Nothing is removed from the queue by this function, that must be
              done with enif_ioq_deq.

              The  returned array is suitable to use with the Unix system call
              writev.

       int enif_ioq_peek_head(ErlNifEnv *env, ErlNifIOQueue *q, size_t  *size,
       ERL_NIF_TERM *bin_term)

              Get the head of the IO Queue as a binary term.

              If size is not NULL, the size of the head is placed there.

              Nothing is removed from the queue by this function, that must be
              done with enif_ioq_deq.

              Returns true on success, or false if the queue is empty.

       size_t enif_ioq_size(ErlNifIOQueue *q)

              Get the size of q.

       int enif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term)

              Returns true if term is an atom.

       int enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term)

              Returns true if term is a binary.

       int enif_is_current_process_alive(ErlNifEnv* env)

              Returns true if the currently  executing  process  is  currently
              alive, otherwise false.

              This  function  can  only be used from a NIF-calling thread, and
              with an environment corresponding to  currently  executing  pro-
              cesses.

       int enif_is_empty_list(ErlNifEnv* env,
               ERL_NIF_TERM term)

              Returns true if term is an empty list.

       int enif_is_exception(ErlNifEnv* env,
               ERL_NIF_TERM term)

              Return true if term is an exception.

       int enif_is_fun(ErlNifEnv* env, ERL_NIF_TERM
               term)

              Returns true if term is a fun.

       int enif_is_identical(ERL_NIF_TERM lhs,
               ERL_NIF_TERM rhs)

              Returns  true if the two terms are identical. Corresponds to the
              Erlang operators =:= and =/=.

       int enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term)

              Returns true if term is a list.

       int enif_is_map(ErlNifEnv* env, ERL_NIF_TERM
               term)

              Returns true if term is a map, otherwise false.

       int enif_is_number(ErlNifEnv* env, ERL_NIF_TERM
               term)

              Returns true if term is a number.

       int enif_is_pid(ErlNifEnv* env, ERL_NIF_TERM term)

              Returns true if term is a pid.

       int enif_is_pid_undefined(const ErlNifPid* pid)

              Returns  true  if   pid   has   been   set   as   undefined   by
              enif_set_pid_undefined.

       int enif_is_port(ErlNifEnv* env, ERL_NIF_TERM term)

              Returns true if term is a port.

       int enif_is_port_alive(ErlNifEnv* env,
               ErlNifPort *port_id)

              Returns true if port_id is alive.

              This  function  is  only  thread-safe when the emulator with SMP
              support is used. It can only be used in a non-SMP emulator  from
              a NIF-calling thread.

       int enif_is_process_alive(ErlNifEnv* env,
               ErlNifPid *pid)

              Returns true if pid is alive.

              This  function  is  only  thread-safe when the emulator with SMP
              support is used. It can only be used in a non-SMP emulator  from
              a NIF-calling thread.

       int enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term)

              Returns true if term is a reference.

       int enif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term)

              Returns true if term is a tuple.

       int enif_keep_resource(void* obj)

              Adds  a  reference to resource object obj obtained from enif_al-
              loc_resource. Each call to enif_keep_resource for an object must
              be balanced by a call to enif_release_resource before the object
              is destructed.

       ERL_NIF_TERM enif_make_atom(ErlNifEnv* env, const char* name)

              Creates an atom term from the NULL-terminated C-string name with
              ISO  Latin-1 encoding. If the length of name exceeds the maximum
              length allowed for an atom (255 characters), enif_make_atom  in-
              vokes enif_make_badarg.

       ERL_NIF_TERM enif_make_atom_len(ErlNifEnv* env,
               const char* name, size_t len)

              Create  an  atom term from the string name with length len. NULL
              characters are treated as any other characters. If  len  exceeds
              the  maximum  length  allowed  for  an  atom  (255  characters),
              enif_make_atom invokes enif_make_badarg.

       ERL_NIF_TERM enif_make_badarg(ErlNifEnv* env)

              Makes a badarg exception to be returned from a  NIF,  and  asso-
              ciates  it  with  environment env. Once a NIF or any function it
              calls invokes  enif_make_badarg,  the  runtime  ensures  that  a
              badarg exception is raised when the NIF returns, even if the NIF
              attempts to return a non-exception term instead.

              The return value from enif_make_badarg can be used only  as  the
              return  value  from  the  NIF that invoked it (directly or indi-
              rectly) or be passed to enif_is_exception, but not to any  other
              NIF API function.

              See also enif_has_pending_exception and enif_raise_exception.

          Note:
              Before   ERTS   7.0  (Erlang/OTP  18),  the  return  value  from
              enif_make_badarg had to be returned from the NIF. This  require-
              ment  is  now lifted as the return value from the NIF is ignored
              if enif_make_badarg has been invoked.

       ERL_NIF_TERM enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)

              Makes a binary term from bin. Any ownership of the  binary  data
              is  transferred  to the created term and bin is to be considered
              read-only for the rest of the NIF call and then as released.

       ERL_NIF_TERM enif_make_copy(ErlNifEnv* dst_env,
               ERL_NIF_TERM src_term)

              Makes a copy of term src_term. The copy is created  in  environ-
              ment dst_env. The source term can be located in any environment.

       ERL_NIF_TERM enif_make_double(ErlNifEnv* env, double d)

              Creates  a floating-point term from a double. If argument double
              is   not   finite   or   is   NaN,   enif_make_double    invokes
              enif_make_badarg.

       int enif_make_existing_atom(ErlNifEnv* env,
               const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding
               encode)

              Tries  to  create  the term of an already existing atom from the
              NULL-terminated C-string name with encoding encode.

              If the atom already exists, this function  stores  the  term  in
              *atom  and  returns true, otherwise false. Also returns false if
              the length of name exceeds the maximum  length  allowed  for  an
              atom (255 characters).

       int enif_make_existing_atom_len(ErlNifEnv* env,
               const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEn-
       coding
               encoding)

              Tries to create the term of an already existing  atom  from  the
              string name with length len and encoding encode. NULL characters
              are treated as any other characters.

              If the atom already exists, this function  stores  the  term  in
              *atom  and  returns true, otherwise false. Also returns false if
              len exceeds the maximum length allowed for an atom (255  charac-
              ters).

       ERL_NIF_TERM enif_make_int(ErlNifEnv* env, int i)

              Creates an integer term.

       ERL_NIF_TERM enif_make_int64(ErlNifEnv* env, ErlNifSInt64 i)

              Creates an integer term from a signed 64-bit integer.

       ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...)

              Creates  an ordinary list term of length cnt. Expects cnt number
              of arguments (after cnt) of type ERL_NIF_TERM as the elements of
              the list.

              Returns an empty list if cnt is 0.

       ERL_NIF_TERM enif_make_list1(ErlNifEnv* env, ERL_NIF_TERM e1)
       ERL_NIF_TERM enif_make_list2(ErlNifEnv* env,
               ERL_NIF_TERM e1, ERL_NIF_TERM e2)
       ERL_NIF_TERM enif_make_list3(ErlNifEnv* env,
               ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3)
       ERL_NIF_TERM enif_make_list4(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4)
       ERL_NIF_TERM enif_make_list5(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5)
       ERL_NIF_TERM enif_make_list6(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6)
       ERL_NIF_TERM enif_make_list7(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7)
       ERL_NIF_TERM enif_make_list8(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8)
       ERL_NIF_TERM enif_make_list9(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9)

              Creates an ordinary list term with length indicated by the func-
              tion name. Prefer these functions  (macros)  over  the  variadic
              enif_make_list  to get a compile-time error if the number of ar-
              guments does not match.

       ERL_NIF_TERM enif_make_list_cell(ErlNifEnv*
               env, ERL_NIF_TERM head, ERL_NIF_TERM tail)

              Creates a list cell [head | tail].

       ERL_NIF_TERM    enif_make_list_from_array(ErlNifEnv*     env,     const
       ERL_NIF_TERM
                 arr[], unsigned cnt)

              Creates an ordinary list containing the elements of array arr of
              length cnt.

              Returns an empty list if cnt is 0.

       ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long int i)

              Creates an integer term from a long int.

       int enif_make_map_put(ErlNifEnv* env,
               ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM value,
               ERL_NIF_TERM* map_out)

              Makes a copy of map map_in and inserts key with  value.  If  key
              already  exists  in map_in, the old associated value is replaced
              by value.

              If successful, this function sets *map_out to the  new  map  and
              returns true. Returns false if map_in is not a map.

              The map_in term must belong to environment env.

       int enif_make_map_remove(ErlNifEnv* env,
               ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM* map_out)

              If map map_in contains key, this function makes a copy of map_in
              in *map_out, and removes key and the associated  value.  If  map
              map_in does not contain key, *map_out is set to map_in.

              Returns true on success, or false if map_in is not a map.

              The map_in term must belong to environment env.

       int enif_make_map_update(ErlNifEnv* env,
               ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM new_value,
               ERL_NIF_TERM* map_out)

              Makes  a copy of map map_in and replace the old associated value
              for key with new_value.

              If successful, this function sets *map_out to the  new  map  and
              returns true. Returns false if map_in is not a map or if it does
              not contain key.

              The map_in term must belong to environment env.

       int enif_make_map_from_arrays(ErlNifEnv* env, ERL_NIF_TERM keys[],
               ERL_NIF_TERM values[], size_t cnt, ERL_NIF_TERM *map_out)

              Makes a map term from the given keys and values.

              If successful, this function sets *map_out to the  new  map  and
              returns true. Returns false there are any duplicate keys.

              All keys and values must belong to env.

       ERL_NIF_TERM  enif_make_monitor_term(ErlNifEnv*  env, const ErlNifMoni-
       tor* mon)

              Creates a term  identifying  the  given  monitor  received  from
              enif_monitor_process.

              This function is primarily intended for debugging purpose.

       unsigned char *enif_make_new_binary(ErlNifEnv*
               env, size_t size, ERL_NIF_TERM* termp)

              Allocates  a  binary  of  size  size bytes and creates an owning
              term. The binary data is mutable until the calling NIF  returns.
              This is a quick way to create a new binary without having to use
              ErlNifBinary. The drawbacks are that the binary cannot  be  kept
              between NIF calls and it cannot be reallocated.

              Returns  a pointer to the raw binary data and sets *termp to the
              binary term.

       ERL_NIF_TERM enif_make_new_map(ErlNifEnv* env)

              Makes an empty map term.

       ERL_NIF_TERM enif_make_pid(ErlNifEnv* env, const ErlNifPid* pid)

              Makes a pid term or the atom undefined from *pid.

       ERL_NIF_TERM enif_make_ref(ErlNifEnv* env)

              Creates a reference like erlang:make_ref/0.

       ERL_NIF_TERM enif_make_resource(ErlNifEnv* env, void* obj)

              Creates an opaque handle to a memory-managed resource object ob-
              tained by enif_alloc_resource. No ownership transfer is done, as
              the resource object still  needs  to  be  released  by  enif_re-
              lease_resource.  However,  notice  that  the  call  to  enif_re-
              lease_resource can occur immediately after  obtaining  the  term
              from  enif_make_resource,  in  which case the resource object is
              deallocated when the term is garbage  collected.  For  more  de-
              tails,  see the example of creating and returning a resource ob-
              ject in the User's Guide.

          Note:
              Since ERTS 9.0 (OTP-20.0), resource terms have a defined  behav-
              ior  when  compared  and  serialized  through  term_to_binary or
              passed between nodes.

                * Two resource terms will compare equal if and  only  if  they
                  would  yield the same resource object pointer when passed to
                  enif_get_resource.

                * A resource term can be serialized  with  term_to_binary  and
                  later  be  fully  recreated  if the resource object is still
                  alive when binary_to_term is called. A stale  resource  term
                  will  be returned from binary_to_term if the resource object
                  has been deallocated. enif_get_resource  will  return  false
                  for stale resource terms.

                  The  same principles of serialization apply when passing re-
                  source terms in messages to remote nodes and back  again.  A
                  resource  term  will  act stale on all nodes except the node
                  where its resource object is still alive in memory.

              Before ERTS 9.0 (OTP-20.0), all resource terms did compare equal
              to  each other and to empty binaries (<<>>). If serialized, they
              would be recreated as plain empty binaries.

       ERL_NIF_TERM enif_make_resource_binary(ErlNifEnv* env, void* obj, const
               void* data, size_t size)

              Creates a binary term that is memory-managed by a  resource  ob-
              ject  obj  obtained  by enif_alloc_resource. The returned binary
              term consists of size bytes pointed to by data. This raw  binary
              data must be kept readable and unchanged until the destructor of
              the resource is called. The binary data can be  stored  external
              to  the resource object, in which case the destructor is respon-
              sible for releasing the data.

              Several binary terms can be managed by the same resource object.
              The  destructor  is  not called until the last binary is garbage
              collected. This can be useful to return  different  parts  of  a
              larger binary buffer.

              As  with  enif_make_resource, no ownership transfer is done. The
              resource still needs to be released with enif_release_resource.

       int enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM list_in,
               ERL_NIF_TERM *list_out)

              Sets *list_out to the reverse list of the list list_in  and  re-
              turns true, or returns false if list_in is not a list.

              This  function  is  only to be used on short lists, as a copy is
              created of the list, which is not released until after  the  NIF
              returns.

              The list_in term must belong to environment env.

       ERL_NIF_TERM enif_make_string(ErlNifEnv* env,
               const char* string, ErlNifCharEncoding encoding)

              Creates  a list containing the characters of the NULL-terminated
              string string with encoding encoding.

       ERL_NIF_TERM enif_make_string_len(ErlNifEnv*
               env, const char* string, size_t len, ErlNifCharEncoding
               encoding)

              Creates a list containing the characters of  the  string  string
              with  length  len  and  encoding  encoding.  NULL characters are
              treated as any other characters.

       ERL_NIF_TERM enif_make_sub_binary(ErlNifEnv*
               env, ERL_NIF_TERM bin_term, size_t pos, size_t size)

              Makes a subbinary of binary bin_term, starting at zero-based po-
              sition  pos  with a length of size bytes. bin_term must be a bi-
              nary or bitstring. pos+size must be less or equal to the  number
              of whole bytes in bin_term.

       ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env,
               unsigned cnt, ...)

              Creates  a  tuple term of arity cnt. Expects cnt number of argu-
              ments (after cnt) of type ERL_NIF_TERM as the  elements  of  the
              tuple.

       ERL_NIF_TERM enif_make_tuple1(ErlNifEnv* env,
               ERL_NIF_TERM e1)
       ERL_NIF_TERM enif_make_tuple2(ErlNifEnv* env,
               ERL_NIF_TERM e1, ERL_NIF_TERM e2)
       ERL_NIF_TERM enif_make_tuple3(ErlNifEnv* env,
               ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3)
       ERL_NIF_TERM enif_make_tuple4(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4)
       ERL_NIF_TERM enif_make_tuple5(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5)
       ERL_NIF_TERM enif_make_tuple6(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6)
       ERL_NIF_TERM enif_make_tuple7(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7)
       ERL_NIF_TERM enif_make_tuple8(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8)
       ERL_NIF_TERM enif_make_tuple9(ErlNifEnv* env,
               ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9)

              Creates a tuple term with length indicated by the function name.
              Prefer these functions (macros) over the variadic  enif_make_tu-
              ple  to get a compile-time error if the number of arguments does
              not match.

       ERL_NIF_TERM    enif_make_tuple_from_array(ErlNifEnv*    env,     const
       ERL_NIF_TERM
               arr[], unsigned cnt)

              Creates  a  tuple containing the elements of array arr of length
              cnt.

       ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned int i)

              Creates an integer term from an unsigned int.

       ERL_NIF_TERM enif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i)

              Creates an integer term from an unsigned 64-bit integer.

       ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i)

              Creates an integer term from an unsigned long int.

       ERL_NIF_TERM enif_make_unique_integer(ErlNifEnv
               *env, ErlNifUniqueInteger properties)

              Returns a unique integer with the same properties  as  specified
              by erlang:unique_integer/1.

              env is the environment to create the integer in.

              ERL_NIF_UNIQUE_POSITIVE   and  ERL_NIF_UNIQUE_MONOTONIC  can  be
              passed as the second argument to change the  properties  of  the
              integer  returned. They can be combined by OR:ing the two values
              together.

              See also ErlNifUniqueInteger.

       int enif_map_iterator_create(ErlNifEnv *env,
               ERL_NIF_TERM map, ErlNifMapIterator *iter, ErlNifMapIteratorEn-
       try
               entry)

              Creates  an  iterator for the map map by initializing the struc-
              ture pointed to by iter. Argument entry determines the start po-
              sition    of   the   iterator:   ERL_NIF_MAP_ITERATOR_FIRST   or
              ERL_NIF_MAP_ITERATOR_LAST.

              Returns true on success, or false if map is not a map.

              A map iterator is only useful during the lifetime of environment
              env  that  the map belongs to. The iterator must be destroyed by
              calling enif_map_iterator_destroy:

              ERL_NIF_TERM key, value;
              ErlNifMapIterator iter;
              enif_map_iterator_create(env, my_map, &iter, ERL_NIF_MAP_ITERATOR_FIRST);

              while (enif_map_iterator_get_pair(env, &iter, &key, &value)) {
                  do_something(key,value);
                  enif_map_iterator_next(env, &iter);
              }
              enif_map_iterator_destroy(env, &iter);

          Note:
              The key-value pairs of a map have no  defined  iteration  order.
              The  only  guarantee is that the iteration order of a single map
              instance is preserved during the  lifetime  of  the  environment
              that the map belongs to.

       void enif_map_iterator_destroy(ErlNifEnv *env,
               ErlNifMapIterator *iter)

              Destroys a map iterator created by enif_map_iterator_create.

       int enif_map_iterator_get_pair(ErlNifEnv *env,
               ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM
               *value)

              Gets key and value terms at the current map iterator position.

              On success, sets *key and *value and returns true. Returns false
              if the iterator is positioned at head (before  first  entry)  or
              tail (beyond last entry).

       int enif_map_iterator_is_head(ErlNifEnv *env,
               ErlNifMapIterator *iter)

              Returns true if map iterator iter is positioned before the first
              entry.

       int enif_map_iterator_is_tail(ErlNifEnv *env,
               ErlNifMapIterator *iter)

              Returns true if map iterator iter is positioned after  the  last
              entry.

       int enif_map_iterator_next(ErlNifEnv *env,
               ErlNifMapIterator *iter)

              Increments map iterator to point to the next key-value entry.

              Returns  true  if the iterator is now positioned at a valid key-
              value entry, or false if the iterator is positioned at the  tail
              (beyond the last entry).

       int enif_map_iterator_prev(ErlNifEnv *env,
               ErlNifMapIterator *iter)

              Decrements  map  iterator to point to the previous key-value en-
              try.

              Returns true if the iterator is now positioned at a  valid  key-
              value  entry, or false if the iterator is positioned at the head
              (before the first entry).

       int enif_monitor_process(ErlNifEnv* caller_env,
             void* obj, const ErlNifPid* target_pid, ErlNifMonitor* mon)

              Starts monitoring a process from a resource. When a  process  is
              monitored, a process exit results in a call to the provided down
              callback associated with the resource type.

              Argument obj is pointer to the resource to hold the monitor  and
              *target_pid identifies the local process to be monitored.

              If mon is not NULL, a successful call stores the identity of the
              monitor in the ErlNifMonitor struct  pointed  to  by  mon.  This
              identifier  is  used  to  refer to the monitor for later removal
              with enif_demonitor_process or compare  with  enif_compare_moni-
              tors.  A  monitor  is  automatically removed when it triggers or
              when the resource is deallocated.

              Argument caller_env is the environment of the calling process or
              callback. Must only be NULL if calling from a custom thread.

              Returns 0 on success, < 0 if no down callback is provided, and >
              0 if the process is no longer alive or if target_pid  is   unde-
              fined.

              This  function  is  only  thread-safe when the emulator with SMP
              support is used. It can only be used in a non-SMP emulator  from
              a NIF-calling thread.

       ErlNifTime enif_monotonic_time(ErlNifTimeUnit time_unit)

              Returns  the  current   Erlang monotonic time. Notice that it is
              not uncommon with negative values.

              time_unit is the time unit of the returned value.

              Returns ERL_NIF_TIME_ERROR if called with an invalid  time  unit
              argument,  or  if  called  from a thread that is not a scheduler
              thread.

              See also ErlNifTime and ErlNifTimeUnit.

       ErlNifMutex *enif_mutex_create(char *name)

              Same as erl_drv_mutex_create.

       void enif_mutex_destroy(ErlNifMutex *mtx)

              Same as erl_drv_mutex_destroy.

       void enif_mutex_lock(ErlNifMutex *mtx)

              Same as erl_drv_mutex_lock.

       char*enif_mutex_name(ErlNifMutex* mtx)

              Same as erl_drv_mutex_name.

       int enif_mutex_trylock(ErlNifMutex *mtx)

              Same as erl_drv_mutex_trylock.

       void enif_mutex_unlock(ErlNifMutex *mtx)

              Same as erl_drv_mutex_unlock.

       ERL_NIF_TERM enif_now_time(ErlNifEnv *env)

              Returns an erlang:now() time stamp.

              This function is deprecated.

       ErlNifResourceType *enif_open_resource_type(ErlNifEnv* env, const char*
               module_str, const char* name, ErlNifResourceDtor* dtor,
               ErlNifResourceFlags flags, ErlNifResourceFlags* tried)

              Creates or takes over a resource type identified by  the  string
              name  and  gives  it the destructor function pointed to by dtor.
              Argument flags can have the following values:

                ERL_NIF_RT_CREATE:
                  Creates a new resource type that does not already exist.

                ERL_NIF_RT_TAKEOVER:
                  Opens an existing resource type and takes over ownership  of
                  all  its  instances.  The supplied destructor dtor is called
                  both for existing instances and new instances not  yet  cre-
                  ated by the calling NIF library.

              The  two  flag  values  can be combined with bitwise OR. The re-
              source type name is local to the calling module.  Argument  mod-
              ule_str  is not (yet) used and must be NULL. dtor can be NULL if
              no destructor is needed.

              On success, the function returns a pointer to the resource  type
              and    *tried    is   set   to   either   ERL_NIF_RT_CREATE   or
              ERL_NIF_RT_TAKEOVER to indicate what was done. On  failure,  re-
              turns  NULL and sets *tried to flags. It is allowed to set tried
              to NULL.

              Notice that enif_open_resource_type is only allowed to be called
              in the two callbacks load and upgrade.

              See also enif_open_resource_type_x.

       ErlNifResourceType   *enif_open_resource_type_x(ErlNifEnv*  env,  const
       char* name,      const ErlNifResourceTypeInit* init,
               ErlNifResourceFlags flags, ErlNifResourceFlags* tried)

              Same as enif_open_resource_type  except  it  accepts  additional
              callback  functions  for  resource  types that are used together
              with enif_select and enif_monitor_process.

              Argument init is a pointer to an  ErlNifResourceTypeInit  struc-
              ture  that  contains  the function pointers for destructor, down
              and stop callbacks for the resource type.

       int enif_port_command(ErlNifEnv* env, const
              ErlNifPort* to_port, ErlNifEnv *msg_env, ERL_NIF_TERM msg)

              Works as erlang:port_command/2, except that it  is  always  com-
              pletely asynchronous.

                env:
                  The environment of the calling process. Must not be NULL.

                *to_port:
                  The  port  ID of the receiving port. The port ID is to refer
                  to a port on the local node.

                msg_env:
                  The environment of the message term. Can be a process  inde-
                  pendent environment allocated with enif_alloc_env or NULL.

                msg:
                  The  message  term to send. The same limitations apply as on
                  the payload to erlang:port_command/2.

              Using a msg_env of NULL is an  optimization,  which  groups  to-
              gether  calls  to enif_alloc_env, enif_make_copy, enif_port_com-
              mand, and enif_free_env into one call. This optimization is only
              useful when a majority of the terms are to be copied from env to
              msg_env.

              Returns true if the command is successfully sent. Returns  false
              if the command fails, for example:

                * *to_port does not refer to a local port.

                * The currently executing process (that is, the sender) is not
                  alive.

                * msg is invalid.

              See also enif_get_local_port.

       void *enif_priv_data(ErlNifEnv* env)

              Returns the pointer to the private data that was set by load  or
              upgrade.

       ERL_NIF_TERM enif_raise_exception(ErlNifEnv*
               env, ERL_NIF_TERM reason)

              Creates  an  error exception with the term reason to be returned
              from a NIF, and associates it with environment env. Once  a  NIF
              or  any function it calls invokes enif_raise_exception, the run-
              time ensures that the exception it creates is  raised  when  the
              NIF  returns, even if the NIF attempts to return a non-exception
              term instead.

              The return value from enif_raise_exception can only be  used  as
              the return value from the NIF that invoked it (directly or indi-
              rectly) or be passed to enif_is_exception, but not to any  other
              NIF API function.

              See also enif_has_pending_exception and enif_make_badarg.

       void *enif_realloc(void* ptr, size_t size)

              Reallocates memory allocated by enif_alloc to size bytes.

              Returns NULL if the reallocation fails.

              The  returned  pointer is suitably aligned for any built-in type
              that fit in the allocated memory.

       int enif_realloc_binary(ErlNifBinary* bin, size_t size)

              Changes the size of a binary bin. The source binary can be read-
              only,  in  which case it is left untouched and a mutable copy is
              allocated and assigned to *bin.

              Returns true on success, or false if memory allocation failed.

       void enif_release_binary(ErlNifBinary* bin)

              Releases a binary obtained from enif_alloc_binary.

       void enif_release_resource(void* obj)

              Removes  a  reference  to  resource  object  obj  obtained  from
              enif_alloc_resource.  The resource object is destructed when the
              last reference is removed. Each  call  to  enif_release_resource
              must  correspond  to  a  previous call to enif_alloc_resource or
              enif_keep_resource. References made  by  enif_make_resource  can
              only be removed by the garbage collector.

              There are no guarantees exactly when the destructor of an unref-
              erenced resource is called.  It  could  be  called  directly  by
              enif_release_resource  but  it  could  also  be  scheduled to be
              called at a later time possibly by another thread.

       ErlNifRWLock *enif_rwlock_create(char *name)

              Same as erl_drv_rwlock_create.

       void enif_rwlock_destroy(ErlNifRWLock *rwlck)

              Same as erl_drv_rwlock_destroy.

       char*enif_rwlock_name(ErlNifRWLock* rwlck)

              Same as erl_drv_rwlock_name.

       void enif_rwlock_rlock(ErlNifRWLock *rwlck)

              Same as erl_drv_rwlock_rlock.

       void enif_rwlock_runlock(ErlNifRWLock *rwlck)

              Same as erl_drv_rwlock_runlock.

       void enif_rwlock_rwlock(ErlNifRWLock *rwlck)

              Same as erl_drv_rwlock_rwlock.

       void enif_rwlock_rwunlock(ErlNifRWLock *rwlck)

              Same as erl_drv_rwlock_rwunlock.

       int enif_rwlock_tryrlock(ErlNifRWLock *rwlck)

              Same as erl_drv_rwlock_tryrlock.

       int enif_rwlock_tryrwlock(ErlNifRWLock *rwlck)

              Same as erl_drv_rwlock_tryrwlock.

       ERL_NIF_TERM enif_schedule_nif(ErlNifEnv* env,
               const char* fun_name, int flags, ERL_NIF_TERM  (*fp)(ErlNifEnv*
       env, int
               argc, const ERL_NIF_TERM argv[]), int argc, const ERL_NIF_TERM
               argv[])

              Schedules NIF fp to execute. This function allows an application
              to break up long-running work into multiple regular NIF calls or
              to schedule a  dirty NIF to execute on a dirty scheduler thread.

                fun_name:
                  Provides a name for the NIF that is scheduled for execution.
                  If it cannot be converted to an atom, enif_schedule_nif  re-
                  turns a badarg exception.

                flags:
                  Must  be  set  to  0  for a regular NIF. If the emulator was
                  built with dirty scheduler support enabled, flags can be set
                  to either ERL_NIF_DIRTY_JOB_CPU_BOUND if the job is expected
                  to be CPU-bound, or ERL_NIF_DIRTY_JOB_IO_BOUND for jobs that
                  will be I/O-bound. If dirty scheduler threads are not avail-
                  able in the emulator, an attempt to schedule such a job  re-
                  sults in a notsup exception.

                argc and argv:
                  Can  either be the originals passed into the calling NIF, or
                  can be values created by the calling NIF.

              The calling NIF must use the return value  of  enif_schedule_nif
              as its own return value.

              Be  aware  that  enif_schedule_nif,  as  its  name implies, only
              schedules the NIF for future execution. The calling NIF does not
              block  waiting for the scheduled NIF to execute and return. This
              means that the calling NIF cannot expect to receive  the  sched-
              uled NIF return value and use it for further operations.

       int  enif_select(ErlNifEnv*  env, ErlNifEvent event, enum ErlNifSelect-
       Flags mode,      void* obj, const ErlNifPid* pid, ERL_NIF_TERM ref)

              This function can be used to receive asynchronous  notifications
              when  OS-specific  event objects become ready for either read or
              write operations.

              Argument event identifies the event object. On Unix systems, the
              functions  select/poll  are  used.  The  event  object must be a
              socket, pipe or other file descriptor  object  that  select/poll
              can use.

              Argument  mode  describes the type of events to wait for. It can
              be ERL_NIF_SELECT_READ, ERL_NIF_SELECT_WRITE  or  a  bitwise  OR
              combination to wait for both. It can also be ERL_NIF_SELECT_STOP
              or ERL_NIF_SELECT_CANCEL which are described further below. When
              a  read or write event is triggered, a notification message like
              this is sent to the process identified by pid:

              {select, Obj, Ref, ready_input | ready_output}

              ready_input or ready_output indicates if  the  event  object  is
              ready for reading or writing.

          Note:
              For complete control over the message format use the newer func-
              tions  enif_select_read  or  enif_select_write   introduced   in
              erts-11.0 (OTP-22.0).

              Argument  pid  may  be  NULL to indicate the calling process. It
              must not be set as  undefined.

              Argument obj is a resource object obtained  from  enif_alloc_re-
              source. The purpose of the resource objects is as a container of
              the event object to manage its state and lifetime. A  handle  to
              the resource is received in the notification message as Obj.

              Argument  ref  must  be  either  a  reference  obtained from er-
              lang:make_ref/0 or the atom undefined. It will be passed as  Ref
              in  the  notifications. If a selective receive statement is used
              to wait for the notification then a reference created  just  be-
              fore  the  receive  will exploit a runtime optimization that by-
              passes all earlier received messages in the queue.

              The notifications are one-shot only. To receive further  notifi-
              cations  of  the  same  type  (read or write), repeated calls to
              enif_select must be made after receiving each notification.

              ERL_NIF_SELECT_CANCEL can be used to cancel previously  selected
              events.  It  must  be  used  in  a  bitwise  OR combination with
              ERL_NIF_SELECT_READ  and/or  ERL_NIF_SELECT_WRITE  to   indicate
              which type of event to cancel. Arguments pid and ref are ignored
              when ERL_NIF_SELECT_CANCEL is specified. The return  value  will
              tell if the event was actualy cancelled or if a notification may
              already have been sent.

              Use ERL_NIF_SELECT_STOP as mode in  order  to  safely  close  an
              event object that has been passed to enif_select. The stop call-
              back of the resource obj will be called when it is safe to close
              the event object. This safe way of closing event objects must be
              used even if all notifications have been received (or cancelled)
              and  no further calls to enif_select have been made. ERL_NIF_SE-
              LECT_STOP will first cancel any selected events before it  calls
              or  schedules  the  stop callback. Arguments pid and ref are ig-
              nored when ERL_NIF_SELECT_STOP is specified.

              The first call to enif_select for a specific OS event  will  es-
              tablish  a  relation between the event object and the containing
              resource. All subsequent calls for an event must pass  its  con-
              taining resource as argument obj. The relation is dissolved when
              enif_select has been called with mode as ERL_NIF_SELECT_STOP and
              the  corresponding  stop  callback  has returned. A resource can
              contain several event objects but one event object can  only  be
              contained within one resource. A resource will not be destructed
              until all its contained relations have been dissolved.

          Note:
              Use enif_monitor_process together  with  enif_select  to  detect
              failing Erlang processes and prevent them from causing permanent
              leakage of resources and their contained OS event objects.

              Returns a non-negative value on success where the following bits
              can be set:

                ERL_NIF_SELECT_STOP_CALLED:
                  The stop callback was called directly by enif_select.

                ERL_NIF_SELECT_STOP_SCHEDULED:
                  The  stop callback was scheduled to run on some other thread
                  or later by this thread.

                ERL_NIF_SELECT_READ_CANCELLED:
                  A read  event  was  cancelled  by  ERL_NIF_SELECT_CANCEL  or
                  ERL_NIF_SELECT_STOP  and  is  guaranteed  not  to generate a
                  ready_input notification message.

                ERL_NIF_SELECT_WRITE_CANCELLED:
                  A write event  was  cancelled  by  ERL_NIF_SELECT_CANCEL  or
                  ERL_NIF_SELECT_STOP  and  is  guaranteed  not  to generate a
                  ready_output notification message.

              Returns a negative value if the call failed where the  following
              bits can be set:

                ERL_NIF_SELECT_INVALID_EVENT:
                  Argument event is not a valid OS event object.

                ERL_NIF_SELECT_FAILED:
                  The  system  call failed to add the event object to the poll
                  set.

          Note:
              Use bitwise AND to test for specific bits in the  return  value.
              New  significant  bits  may  be added in future releases to give
              more detailed information for both failed and successful  calls.
              Do NOT use equality tests like ==, as that may cause your appli-
              cation to stop working.

              Example:

              retval = enif_select(env, fd, ERL_NIF_SELECT_STOP, resource, ref);
              if (retval < 0) {
                  /* handle error */
              }
              /* Success! */
              if (retval & ERL_NIF_SELECT_STOP_CALLED) {
                  /* ... */
              }

          Note:
              The  mode  flag  ERL_NIF_SELECT_CANCEL  and  the  return   flags
              ERL_NIF_SELECT_READ_CANCELLED and ERL_NIF_SELECT_WRITE_CANCELLED
              were introduced in erts-11.0 (OTP-22.0).

       int enif_select_read(ErlNifEnv* env, ErlNifEvent event, void* obj,
             const ErlNifPid* pid, ERL_NIF_TERM msg, ErlNifEnv* msg_env)
       int enif_select_write(ErlNifEnv* env, ErlNifEvent event, void* obj,
             const ErlNifPid* pid, ERL_NIF_TERM msg, ErlNifEnv* msg_env)

              These are variants of enif_select where you can supply your  own
              message term msg that will be sent to the process instead of the
              predefined tuple {select,_,_,_}.

              Argument msg_env must either be NULL or the environment  of  msg
              allocated  with  enif_alloc_env. If argument msg_env is NULL the
              term msg will be copied, otherwise both msg and msg_env will  be
              invalidated by a successful call to enif_select_read or enif_se-
              lect_write. The environment is then  to  either  be  freed  with
              enif_free_env  or  cleared for reuse with enif_clear_env. An un-
              successful call will leave msg and msg_env still valid.

              Apart from the  message  format  enif_select_read  and  enif_se-
              lect_write behaves exactly the same as enif_select with argument
              mode as either ERL_NIF_SELECT_READ or  ERL_NIF_SELECT_WRITE.  To
              cancel or close events use enif_select.

       ErlNifPid *enif_self(ErlNifEnv* caller_env, ErlNifPid* pid)

              Initializes  the  ErlNifPid  variable  at  *pid to represent the
              calling process.

              Returns pid if successful,  or  NULL  if  caller_env  is  not  a
              process bound environment.

       int enif_send(ErlNifEnv* caller_env,
             ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg)

              Sends a message to a process.

                caller_env:
                  The  environment of the calling process or callback. Must be
                  NULL only if calling from a custom  thread  not  spawned  by
                  ERTS.

                *to_pid:
                  The  pid  of the receiving process. The pid is to refer to a
                  process on the local node.

                msg_env:
                  The environment of the message term. Must be a process inde-
                  pendent environment allocated with enif_alloc_env or NULL.

                msg:
                  The message term to send.

              Returns  true if the message is successfully sent. Returns false
              if the send operation fails, that is:

                * *to_pid does not refer to an alive local process.

                * The currently executing process (that is, the sender) is not
                  alive.

              The  message  environment  msg_env with all its terms (including
              msg) is invalidated by a successful call to enif_send. The envi-
              ronment  is to either be freed with enif_free_env or cleared for
              reuse with enif_clear_env. An unsuccessful call will  leave  msg
              and msg_env still valid.

              If msg_env is set to NULL, the msg term is copied and the origi-
              nal term and its environment is still valid after the call.

              This function is only thread-safe when  the  emulator  with  SMP
              support  is used. It can only be used in a non-SMP emulator from
              a NIF-calling thread.

          Note:
              Passing msg_env as NULL is only supported as from ERTS 8.0  (Er-
              lang/OTP 19).

       void enif_set_pid_undefined(ErlNifPid* pid)

              Sets  an  ErlNifPid variable as undefined. See enif_is_pid_unde-
              fined.

       unsigned enif_sizeof_resource(void* obj)

              Gets the byte size of resource object obj obtained  by  enif_al-
              loc_resource.

       int enif_snprintf(char *str, size_t size, const
               char *format, ...)

              Similar  to  snprintf  but this format string also accepts "%T",
              which formats Erlang terms of type ERL_NIF_TERM.

              This function is primarily intended for debugging purpose. It is
              not  recommended to print very large terms with %T. The function
              may change errno, even if successful.

       void enif_system_info(ErlNifSysInfo
               *sys_info_ptr, size_t size)

              Same as driver_system_info.

       int enif_term_to_binary(ErlNifEnv *env,
               ERL_NIF_TERM term, ErlNifBinary *bin)

              Allocates a new binary with enif_alloc_binary and stores the re-
              sult of encoding term according to the Erlang external term for-
              mat.

              Returns true on success, or false if the allocation fails.

              See also erlang:term_to_binary/1 and enif_binary_to_term.

       ErlNifTermType enif_term_type(ErlNifEnv *env, ERL_NIF_TERM term)

              Determines the type of the given term. The term must be an ordi-
              nary  Erlang  term  and not one of the special terms returned by
              enif_raise_exception, enif_schedule_nif, or similar.

              The following types are defined at the moment:

                ERL_NIF_TERM_TYPE_ATOM:

                ERL_NIF_TERM_TYPE_BITSTRING:
                  A bitstring or binary

                ERL_NIF_TERM_TYPE_FLOAT:

                ERL_NIF_TERM_TYPE_FUN:

                ERL_NIF_TERM_TYPE_INTEGER:

                ERL_NIF_TERM_TYPE_LIST:
                  A list, empty or not

                ERL_NIF_TERM_TYPE_MAP:

                ERL_NIF_TERM_TYPE_PID:

                ERL_NIF_TERM_TYPE_PORT:

                ERL_NIF_TERM_TYPE_REFERENCE:

                ERL_NIF_TERM_TYPE_TUPLE:

              Note that new types may be added in the future,  so  the  caller
              must be prepared to handle unknown types.

       int enif_thread_create(char *name,ErlNifTid
               *tid,void * (*func)(void *),void *args,ErlNifThreadOpts
               *opts)

              Same as erl_drv_thread_create.

       void enif_thread_exit(void *resp)

              Same as erl_drv_thread_exit.

       int enif_thread_join(ErlNifTid, void **respp)

              Same as erl_drv_thread_join.

       char*enif_thread_name(ErlNifTid tid)

              Same as erl_drv_thread_name.

       ErlNifThreadOpts *enif_thread_opts_create(char *name)

              Same as erl_drv_thread_opts_create.

       void enif_thread_opts_destroy(ErlNifThreadOpts *opts)

              Same as erl_drv_thread_opts_destroy.

       ErlNifTid enif_thread_self(void)

              Same as erl_drv_thread_self.

       int enif_thread_type(void)

              Determine  the  type  of  currently executing thread. A positive
              value indicates a scheduler thread while  a  negative  value  or
              zero  indicates  another type of thread. Currently the following
              specific types exist (which may be extended in the future):

                ERL_NIF_THR_UNDEFINED:
                  Undefined thread that is not a scheduler thread.

                ERL_NIF_THR_NORMAL_SCHEDULER:
                  A normal scheduler thread.

                ERL_NIF_THR_DIRTY_CPU_SCHEDULER:
                  A dirty CPU scheduler thread.

                ERL_NIF_THR_DIRTY_IO_SCHEDULER:
                  A dirty I/O scheduler thread.

       ErlNifTime enif_time_offset(ErlNifTimeUnit time_unit)

              Returns the current time offset between  Erlang  monotonic  time
              and   Erlang  system time converted into the time_unit passed as
              argument.

              time_unit is the time unit of the returned value.

              Returns ERL_NIF_TIME_ERROR if called with an invalid  time  unit
              argument  or  if  called  from  a thread that is not a scheduler
              thread.

              See also ErlNifTime and ErlNifTimeUnit.

       void *enif_tsd_get(ErlNifTSDKey key)

              Same as erl_drv_tsd_get.

       int enif_tsd_key_create(char *name, ErlNifTSDKey *key)

              Same as erl_drv_tsd_key_create.

       void enif_tsd_key_destroy(ErlNifTSDKey key)

              Same as erl_drv_tsd_key_destroy.

       void enif_tsd_set(ErlNifTSDKey key, void *data)

              Same as erl_drv_tsd_set.

       int enif_vfprintf(FILE *stream, const char *format, va_list ap)

              Equivalent to enif_fprintf except that its called with a va_list
              instead of a variable number of arguments.

       int  enif_vsnprintf(char *str, size_t size, const char *format, va_list
       ap)

              Equivalent to  enif_snprintf  except  that  its  called  with  a
              va_list instead of a variable number of arguments.

       int enif_whereis_pid(ErlNifEnv *env,
                 ERL_NIF_TERM name, ErlNifPid *pid)

              Looks up a process by its registered name.

                env:
                  The environment of the calling process. Must be NULL only if
                  calling from a created thread.

                name:
                  The name of a registered process, as an atom.

                *pid:
                  The ErlNifPid in which the resolved process id is stored.

              On success, sets *pid to the local process registered with  name
              and returns true. If name is not a registered process, or is not
              an atom, false is returned and *pid is unchanged.

              Works as erlang:whereis/1,  but  restricted  to  processes.  See
              enif_whereis_port to resolve registered ports.

       int enif_whereis_port(ErlNifEnv *env,
                 ERL_NIF_TERM name, ErlNifPort *port)

              Looks up a port by its registered name.

                env:
                  The environment of the calling process. Must be NULL only if
                  calling from a created thread.

                name:
                  The name of a registered port, as an atom.

                *port:
                  The ErlNifPort in which the resolved port id is stored.

              On success, sets *port to the port registered with name and  re-
              turns true. If name is not a registered port, or is not an atom,
              false is returned and *port is unchanged.

              Works  as  erlang:whereis/1,  but  restricted  to   ports.   See
              enif_whereis_pid to resolve registered processes.

SEE ALSO
       erlang:load_nif/2

Ericsson AB                       erts 11.0.2                    erl_nif(3erl)

Man(1) output converted with man2html
list of all man pages