kernel

v10.6.3

application behaviour

Generic OTP application functions

In OTP, application denotes a component implementing some specific functionality, that can be started and stopped as a unit, and that can be reused in other systems. This module interacts with application controller, a process started at every Erlang runtime system. This module contains functions for controlling applications (for example, starting and stopping applications), and functions to access information about applications (for example, configuration parameters).

An application is defined by an application specification. The specification is normally located in an application resource file named Application.app, where Application is the application name. For details about the application specification, see app.

This module can also be viewed as a behaviour for an application implemented according to the OTP design principles as a supervision tree. The definition of how to start and stop the tree is to be located in an application callback module, exporting a predefined set of functions.

For details about applications and behaviours, see OTP Design Principles.

See Also

OTP Design Principles, kernel, app

Summary

Types

application_opt()

The built-in options available to an application.

application_spec()

An application specification.

restart_type()

The type of restart behaviour an application should have.

start_type()

The reason for the application to be started on the current node.

tuple_of(T)

A tuple where the elements are of type T.

Callbacks

config_change(Changed, New, Removed)

This function is called by an application after a code replacement, if the configuration parameters have changed.

prep_stop(State)

This function is called when an application is about to be stopped, before shutting down the processes of the application.

start(Application, Type)

This function is called whenever an application is started using start/1,2, and is to start the processes of the application. If the application is structured according to the OTP design principles as a supervision tree, this means starting the top supervisor of the tree.

start_phase(Phase, StartType, PhaseArgs)

Starts an application with included applications, when synchronization is needed between processes in the different applications during startup.

stop(Application)

This function is called whenever an application has stopped. It is intended to be the opposite of Module:start/2 and is to do any necessary cleaning up. The return value is ignored.

Functions

ensure_all_started(Applications)

Equivalent to ensure_all_started(Applications, temporary, serial).

ensure_all_started(Applications, Type)

Equivalent to ensure_all_started(Applications, Type, serial).

ensure_all_started(Applications, Type, Mode)

Applications is either an an atom/0 or a list of atom/0 representing multiple applications.

ensure_started(Application)

Equivalent to start(Application) except it returns ok for already started applications.

ensure_started(Application, Type)

Equivalent to start(Application, Type) except it returns ok for already started applications.

get_all_env()

Equivalent to get_all_env(application:get_application()).

get_all_env(Application)

Returns the configuration parameters and their values for Application.

get_all_key()

Equivalent to get_all_key(application:get_application()).

get_all_key(Application)

Returns the application specification keys and their values for Application. If the argument is omitted, it defaults to the application of the calling process.

get_application()

Equivalent to get_application(self()).

get_application(PidOrModule)

Returns the name of the application to which the process Pid or the module Module belongs.

get_env(Par)

Equivalent to get_env(application:get_application(), Par).

get_env(Application, Par)

Returns the value of configuration parameter Par for Application.

get_env(Application, Par, Def)

Works like get_env/2 but returns value Def when configuration parameter Par does not exist.

get_key(Key)

Equivalent to get_key(application:get_application(), Key).

get_key(Application, Key)

Returns the value of the application specification key Key for Application.

get_supervisor(Application)

Returns the Pid of the supervisor running at the root of Application.

load(AppDescr)

Equivalent to load(AppDescr, []).

load(AppDescr, Distributed)

Loads the application specification for an application into the application controller. It also loads the application specifications for any included applications. Notice that the function does not load the Erlang object code.

loaded_applications()

Returns a list with information about the applications, and included applications, which are loaded using load/1,2. Application is the application name. Description and Vsn are the values of their description and vsn application specification keys, respectively.

permit(Application, Permission)

Changes the permission for Application to run at the current node. The application must be loaded using load/1,2 for the function to have effect.

set_env(Config)

Equivalent to set_env(Config, []).

set_env(Config, Opts)

Sets the configuration Config for multiple applications.

set_env(Application, Par, Val)

Equivalent to set_env(Application, Par, Val, []).

set_env(Application, Par, Val, Opts)

Sets the value of configuration parameter Par for Application.

start(Application)

Equivalent to start(Application, temporary).

start(Application, Type)

Starts Application. If it is not loaded, the application controller first loads it using load/1. It ensures that any included applications are loaded, but does not start them. That is assumed to be taken care of in the code for Application.

start_type()

This function is intended to be called by a process belonging to an application, when the application is started, to determine the start type, which is StartType or local.

stop(Application)

Stops Application. The application master calls Module:prep_stop/1, if such a function is defined, and then tells the top supervisor of the application to shut down (see supervisor).

takeover(Application, Type)

Takes over the distributed application Application, which executes at another node Node.

unload(Application)

Unloads the application specification for Application from the application controller. It also unloads the application specifications for any included applications. Notice that the function does not purge the Erlang object code.

unset_env(Application, Par)

Equivalent to unset_env(Application, Par, []).

unset_env(Application, Par, Opts)

Removes the configuration parameter Par and its value for Application.

which_applications()

Equivalent to which_applications(5000).

which_applications(Timeout)

Returns a list with information about the applications that are currently running.

Types

application_opt()

(not exported)

-type application_opt() ::
          {description, Description :: string()} |
          {vsn, Vsn :: string()} |
          {id, Id :: string()} |
          {modules, [Module :: module()]} |
          {registered, Names :: [Name :: atom()]} |
          {applications, [Application :: atom()]} |
          {included_applications, [Application :: atom()]} |
          {env, [{Par :: atom(), Val :: term()}]} |
          {start_phases, [{Phase :: atom(), PhaseArgs :: term()}] | undefined} |
          {maxT, MaxT :: timeout()} |
          {maxP, MaxP :: pos_integer() | infinity} |
          {mod, Start :: {Module :: module(), StartArgs :: term()}}.

The built-in options available to an application.

See app for descriptions of the options.

application_spec()

(not exported)

-type application_spec() :: {application, Application :: atom(), AppSpecKeys :: [application_opt()]}.

An application specification.

restart_type()

-type restart_type() :: permanent | transient | temporary.

The type of restart behaviour an application should have.

start_type()

-type start_type() :: normal | {takeover, Node :: node()} | {failover, Node :: node()}.

The reason for the application to be started on the current node.

tuple_of(T)

(not exported)

-type tuple_of(_T) :: tuple().

A tuple where the elements are of type T.

Callbacks

config_change(Changed, New, Removed)

(optional)

-callback config_change(Changed, New, Removed) -> ok
                           when
                               Changed :: [{Par, Val}],
                               New :: [{Par, Val}],
                               Removed :: [Par],
                               Par :: atom(),
                               Val :: term().

This function is called by an application after a code replacement, if the configuration parameters have changed.

Changed is a list of parameter-value tuples including all configuration parameters with changed values.

New is a list of parameter-value tuples including all added configuration parameters.

Removed is a list of all removed parameters.

prep_stop(State)

(optional)

-callback prep_stop(State) -> NewState when State :: term(), NewState :: term().

This function is called when an application is about to be stopped, before shutting down the processes of the application.

State is the state returned from Module:start/2, or [] if no state was returned. NewState is any term and is passed to Module:stop/1.

The function is optional. If it is not defined, the processes are terminated and then Module:stop(State) is called.

start(Application, Type)

-callback start(StartType :: start_type(), StartArgs :: term()) ->
                   {ok, pid()} | {ok, pid(), State :: term()} | {error, Reason :: term()}.

This function is called whenever an application is started using start/1,2, and is to start the processes of the application. If the application is structured according to the OTP design principles as a supervision tree, this means starting the top supervisor of the tree.

StartType defines the type of start:

normal if it is a normal startup.

normal also if the application is distributed and started at the current node because of a failover from another node, and the application specification key start_phases == undefined.

{takeover,Node} if the application is distributed and started at the current node because of a takeover from Node, either because takeover/2 has been called or because the current node has higher priority than Node.

{failover,Node} if the application is distributed and started at the current node because of a failover from Node, and the application specification key start_phases /= undefined.

StartArgs is the StartArgs argument defined by the application specification key mod.

The function is to return {ok,Pid} or {ok,Pid,State}, where Pid is the pid of the top supervisor and State is any term. If omitted, State defaults to []. If the application is stopped later, State is passed to Module:prep_stop/1.

start_phase(Phase, StartType, PhaseArgs)

(optional)

-callback start_phase(Phase, StartType, PhaseArgs) -> ok | {error, Reason}
                         when
                             Phase :: atom(),
                             StartType :: start_type(),
                             PhaseArgs :: term(),
                             Reason :: term().

Starts an application with included applications, when synchronization is needed between processes in the different applications during startup.

The start phases are defined by the application specification key start_phases == [{Phase,PhaseArgs}]. For included applications, the set of phases must be a subset of the set of phases defined for the including application.

The function is called for each start phase (as defined for the primary application) for the primary application and all included applications, for which the start phase is defined.

For a description of StartType, see Module:start/2.

stop(Application)

-callback stop(State :: term()) -> term().

This function is called whenever an application has stopped. It is intended to be the opposite of Module:start/2 and is to do any necessary cleaning up. The return value is ignored.

State is the return value of Module:prep_stop/1, if such a function exists. Otherwise State is taken from the return value of Module:start/2.

Functions

ensure_all_started(Applications)

(since OTP R16B02)

-spec ensure_all_started(Applications) -> {ok, Started} | {error, Reason}
                            when
                                Applications :: atom() | [atom()], Started :: [atom()], Reason :: term().

Equivalent to ensure_all_started(Applications, temporary, serial).

ensure_all_started(Applications, Type)

(since OTP R16B02)

-spec ensure_all_started(Applications, Type) -> {ok, Started} | {error, AppReason}
                            when
                                Applications :: atom() | [atom()],
                                Type :: restart_type(),
                                Started :: [atom()],
                                AppReason :: {atom(), term()}.

Equivalent to ensure_all_started(Applications, Type, serial).

ensure_all_started(Applications, Type, Mode)

(since OTP 26.0)

-spec ensure_all_started(Applications, Type, Mode) -> {ok, Started} | {error, AppReason}
                            when
                                Applications :: atom() | [atom()],
                                Type :: restart_type(),
                                Mode :: serial | concurrent,
                                Started :: [atom()],
                                AppReason :: {atom(), term()}.

Applications is either an an atom/0 or a list of atom/0 representing multiple applications.

This function is equivalent to calling start/1,2 repeatedly on all dependencies that are not yet started of each application. Optional dependencies will also be loaded and started if they are available.

The Mode argument controls if the applications should be started in serial mode (one at a time) or concurrent mode. In concurrent mode, a dependency graph is built and the leaves of the graph are started concurrently and recursively. In both modes, no assertion can be made about the order the applications are started. If not supplied, it defaults to serial.

Returns {ok, AppNames} for a successful start or for an already started application (which is, however, omitted from the AppNames list).

The function reports {error, {AppName,Reason}} for errors, where Reason is any possible reason returned by start/1,2 when starting a specific dependency.

If an error occurs, the applications started by the function are stopped to bring the set of running applications back to its initial state.

ensure_started(Application)

(since OTP R16B01)

-spec ensure_started(Application) -> ok | {error, Reason} when Application :: atom(), Reason :: term().

Equivalent to start(Application) except it returns ok for already started applications.

ensure_started(Application, Type)

(since OTP R16B01)

-spec ensure_started(Application, Type) -> ok | {error, Reason}
                        when Application :: atom(), Type :: restart_type(), Reason :: term().

Equivalent to start(Application, Type) except it returns ok for already started applications.

get_all_env()

-spec get_all_env() -> Env when Env :: [{Par :: atom(), Val :: term()}].

Equivalent to get_all_env(application:get_application()).

get_all_env(Application)

-spec get_all_env(Application) -> Env
                     when Application :: atom(), Env :: [{Par :: atom(), Val :: term()}].

Returns the configuration parameters and their values for Application.

If the specified application is not loaded, or if the process executing the call does not belong to any application, the function returns [].

get_all_key()

-spec get_all_key() -> [] | {ok, Keys} when Keys :: [{Key :: atom(), Val :: term()}, ...].

Equivalent to get_all_key(application:get_application()).

get_all_key(Application)

-spec get_all_key(Application) -> undefined | Keys
                     when Application :: atom(), Keys :: {ok, [{Key :: atom(), Val :: term()}, ...]}.

Returns the application specification keys and their values for Application. If the argument is omitted, it defaults to the application of the calling process.

If the specified application is not loaded, the function returns undefined. If the process executing the call does not belong to any application, the function returns [].

get_application()

-spec get_application() -> undefined | {ok, Application} when Application :: atom().

Equivalent to get_application(self()).

get_application(PidOrModule)

-spec get_application(PidOrModule) -> undefined | {ok, Application}
                         when
                             PidOrModule :: (Pid :: pid()) | (Module :: module()), Application :: atom().

Returns the name of the application to which the process Pid or the module Module belongs.

If the specified process does not belong to any application, or if the specified process or module does not exist, the function returns undefined.

get_env(Par)

-spec get_env(Par) -> undefined | {ok, Val} when Par :: atom(), Val :: term().

Equivalent to get_env(application:get_application(), Par).

get_env(Application, Par)

-spec get_env(Application, Par) -> undefined | {ok, Val}
                 when Application :: atom(), Par :: atom(), Val :: term().

Returns the value of configuration parameter Par for Application.

Returns undefined if any of the following applies:

The specified application is not loaded.

The configuration parameter does not exist.

The process executing the call does not belong to any application.

get_env(Application, Par, Def)

(since OTP R16B)

-spec get_env(Application, Par, Def) -> Val
                 when Application :: atom(), Par :: atom(), Def :: term(), Val :: term().

Works like get_env/2 but returns value Def when configuration parameter Par does not exist.

get_key(Key)

-spec get_key(Key) -> undefined | {ok, Val} when Key :: atom(), Val :: term().

Equivalent to get_key(application:get_application(), Key).

get_key(Application, Key)

-spec get_key(Application, Key) -> undefined | {ok, Val}
                 when Application :: atom(), Key :: atom(), Val :: term().

Returns the value of the application specification key Key for Application.

Returns undefined if any of the following applies:

The specified application is not loaded.

The specification key does not exist.

The process executing the call does not belong to any application.

get_supervisor(Application)

(since OTP 26.0)

-spec get_supervisor(Application) -> undefined | {ok, Pid} when Pid :: pid(), Application :: atom().

Returns the Pid of the supervisor running at the root of Application.

If the specified application does not exist or does not define a callback module, the function returns undefined.

load(AppDescr)

-spec load(AppDescr) -> ok | {error, Reason}
              when
                  AppDescr :: Application | (AppSpec :: application_spec()),
                  Application :: atom(),
                  Reason :: term().

Equivalent to load(AppDescr, []).

load(AppDescr, Distributed)

-spec load(AppDescr, Distributed) -> ok | {error, Reason}
              when
                  AppDescr :: Application | (AppSpec :: application_spec()),
                  Application :: atom(),
                  Distributed :: {Application, Nodes} | {Application, Time, Nodes} | default,
                  Nodes :: [node() | tuple_of(node())],
                  Time :: pos_integer(),
                  Reason :: term().

Loads the application specification for an application into the application controller. It also loads the application specifications for any included applications. Notice that the function does not load the Erlang object code.

The application can be specified by its name Application. In this case, the application controller searches the code path for the application resource file Application.app and loads the specification it contains.

The application specification can also be specified directly as a tuple AppSpec, having the format and contents as described in app.

If Distributed == {Application,[Time,]Nodes}, the application becomes distributed. The argument overrides the value for the application in the Kernel configuration parameter distributed. Application must be the application name (same as in the first argument). If a node crashes and Time is specified, the application controller waits for Time milliseconds before attempting to restart the application on another node. If Time is not specified, it defaults to 0 and the application is restarted immediately.

Nodes is a list of node names where the application can run, in priority from left to right. Node names can be grouped using tuples to indicate that they have the same priority.

Example:

Nodes = [cp1@cave, {cp2@cave, cp3@cave}]

This means that the application is preferably to be started at cp1@cave. If cp1@cave is down, the application is to be started at cp2@cave or cp3@cave.

If Distributed == default, the value for the application in the Kernel configuration parameter distributed is used.

loaded_applications()

-spec loaded_applications() -> [{Application, Description, Vsn}]
                             when Application :: atom(), Description :: string(), Vsn :: string().

Returns a list with information about the applications, and included applications, which are loaded using load/1,2. Application is the application name. Description and Vsn are the values of their description and vsn application specification keys, respectively.

permit(Application, Permission)

-spec permit(Application, Permission) -> ok | {error, Reason}
                when Application :: atom(), Permission :: boolean(), Reason :: term().

Changes the permission for Application to run at the current node. The application must be loaded using load/1,2 for the function to have effect.

If the permission of a loaded, but not started, application is set to false, start returns ok but the application is not started until the permission is set to true.

If the permission of a running application is set to false, the application is stopped. If the permission later is set to true, it is restarted.

If the application is distributed, setting the permission to false means that the application will be started at, or moved to, another node according to how its distribution is configured (see load/2).

The function does not return until the application is started, stopped, or successfully moved to another node. However, in some cases where permission is set to true, the function returns ok even though the application is not started. This is true when an application cannot start because of dependencies to other applications that are not yet started. When they are started, Application is started as well.

By default, all applications are loaded with permission true on all nodes. The permission can be configured using the Kernel configuration parameter permissions.

set_env(Config)

(since OTP 21.3)

-spec set_env(Config) -> ok
                 when
                     Config :: [{Application, Env}],
                     Application :: atom(),
                     Env :: [{Par :: atom(), Val :: term()}].

Equivalent to set_env(Config, []).

set_env(Config, Opts)

(since OTP 21.3)

-spec set_env(Config, Opts) -> ok
                 when
                     Config :: [{Application, Env}],
                     Application :: atom(),
                     Env :: [{Par :: atom(), Val :: term()}],
                     Opts :: [{timeout, timeout()} | {persistent, boolean()}].

Sets the configuration Config for multiple applications.

It is equivalent to calling set_env/4 on each application individually, except it is more efficient. The given Config is validated before the configuration is set.

set_env/2 uses the standard gen_server time-out value (5000 ms). Option timeout can be specified if another time-out value is useful, for example, in situations where the application controller is heavily loaded.

Option persistent can be set to true to guarantee that parameters set with set_env/2 are not overridden by those defined in the application resource file on load. This means that persistent values will stick after the application is loaded and also on application reload.

If an application is given more than once or if an application has the same key given more than once, the behaviour is undefined and a warning message will be logged. In future releases, an error will be raised.

Warning

Use this function only if you know what you are doing, that is, on your own applications. It is very application-dependent and configuration parameter-dependent when and how often the value is read by the application. Careless use of this function can put the application in a weird, inconsistent, and malfunctioning state.

set_env(Application, Par, Val)

-spec set_env(Application, Par, Val) -> ok when Application :: atom(), Par :: atom(), Val :: term().

Equivalent to set_env(Application, Par, Val, []).

set_env(Application, Par, Val, Opts)

-spec set_env(Application, Par, Val, Opts) -> ok
                 when
                     Application :: atom(),
                     Par :: atom(),
                     Val :: term(),
                     Opts :: [{timeout, timeout()} | {persistent, boolean()}].

Sets the value of configuration parameter Par for Application.

set_env/4 uses the standard gen_server time-out value (5000 ms). Option timeout can be specified if another time-out value is useful, for example, in situations where the application controller is heavily loaded.

If set_env/4 is called before the application is loaded, the application environment values specified in file Application.app override the ones previously set. This is also true for application reloads.

Option persistent can be set to true to guarantee that parameters set with set_env/4 are not overridden by those defined in the application resource file on load. This means that persistent values will stick after the application is loaded and also on application reload.

Warning

Use this function only if you know what you are doing, that is, on your own applications. It is very application-dependent and configuration parameter-dependent when and how often the value is read by the application. Careless use of this function can put the application in a weird, inconsistent, and malfunctioning state.

start(Application)

-spec start(Application) -> ok | {error, Reason} when Application :: atom(), Reason :: term().

Equivalent to start(Application, temporary).

start(Application, Type)

-spec start(Application, Type) -> ok | {error, Reason}
               when Application :: atom(), Type :: restart_type(), Reason :: term().

Starts Application. If it is not loaded, the application controller first loads it using load/1. It ensures that any included applications are loaded, but does not start them. That is assumed to be taken care of in the code for Application.

The application controller checks the value of the application specification key applications, to ensure that all applications needed to be started before this application are running. If an application is missing and the application is not marked as optional, {error,{not_started,App}} is returned, where App is the name of the missing application. Note this function makes no attempt to start any of the applications listed in applications, not even optional ones. See ensure_all_started/1,2 for recursively starting the current application and its dependencies.

Once validated, the application controller then creates an application master for the application. The application master becomes the group leader of all the processes in the application. I/O is forwarded to the previous group leader, though, this is just a way to identify processes that belong to the application. Used for example to find itself from any process, or, reciprocally, to kill them all when it terminates.

The application master starts the application by calling the application callback function Module:start/2 as defined by the application specification key mod.

Argument Type specifies the type of the application. If omitted, it defaults to temporary.

If a permanent application terminates, all other applications and the entire Erlang node are also terminated.

If a transient application terminates:

with Reason == normal, this is reported but no other applications are terminated.

abnormally, all other applications and the entire Erlang node are also terminated.

If a temporary application terminates, this is reported but no other applications are terminated.

Notice that an application can always be stopped explicitly by calling stop/1. Regardless of the type of the application, no other applications are affected.

Notice also that the transient type is of little practical use, because when a supervision tree terminates, the reason is set to shutdown, not normal.

start_type()

-spec start_type() -> StartType | undefined | local when StartType :: start_type().

This function is intended to be called by a process belonging to an application, when the application is started, to determine the start type, which is StartType or local.

For a description of StartType, see Module:start/2.

local is returned if only parts of the application are restarted (by a supervisor), or if the function is called outside a startup.

If the process executing the call does not belong to any application, the function returns undefined.

stop(Application)

-spec stop(Application) -> ok | {error, Reason} when Application :: atom(), Reason :: term().

Stops Application. The application master calls Module:prep_stop/1, if such a function is defined, and then tells the top supervisor of the application to shut down (see supervisor).

This means that the entire supervision tree, including included applications, is terminated in reversed start order. After the shutdown, the application master calls Module:stop/1. Module is the callback module as defined by the application specification key mod.

Last, the application master terminates. Notice that all processes with the application master as group leader, that is, processes spawned from a process belonging to the application, are also terminated.

When stopped, the application is still loaded.

To stop a distributed application, stop/1 must be called on all nodes where it can execute (that is, on all nodes where it has been started). The call to stop/1 on the node where the application currently executes stops its execution. The application is not moved between nodes, as stop/1 is called on the node where the application currently executes before stop/1 is called on the other nodes.

takeover(Application, Type)

-spec takeover(Application, Type) -> ok | {error, Reason}
                  when Application :: atom(), Type :: restart_type(), Reason :: term().

Takes over the distributed application Application, which executes at another node Node.

At the current node, the application is restarted by calling Module:start({takeover,Node},StartArgs). Module and StartArgs are retrieved from the loaded application specification. The application at the other node is not stopped until the startup is completed, that is, when Module:start/2 and any calls to Module:start_phase/3 have returned.

Thus, two instances of the application run simultaneously during the takeover, so that data can be transferred from the old to the new instance. If this is not an acceptable behavior, parts of the old instance can be shut down when the new instance is started. However, the application cannot be stopped entirely, at least the top supervisor must remain alive.

For a description of Type, see start/1,2.

unload(Application)

-spec unload(Application) -> ok | {error, Reason} when Application :: atom(), Reason :: term().

Unloads the application specification for Application from the application controller. It also unloads the application specifications for any included applications. Notice that the function does not purge the Erlang object code.

unset_env(Application, Par)

-spec unset_env(Application, Par) -> ok when Application :: atom(), Par :: atom().

Equivalent to unset_env(Application, Par, []).

unset_env(Application, Par, Opts)

-spec unset_env(Application, Par, Opts) -> ok
                   when
                       Application :: atom(),
                       Par :: atom(),
                       Opts :: [{timeout, timeout()} | {persistent, boolean()}].

Removes the configuration parameter Par and its value for Application.

unset_env/3 uses the standard gen_server time-out value (5000 ms). Option timeout can be specified if another time-out value is useful, for example, in situations where the application controller is heavily loaded.

unset_env/3 also allows the persistent option to be passed (see set_env/4).

Warning

Use this function only if you know what you are doing, that is, on your own applications. It is very application-dependent and configuration parameter-dependent when and how often the value is read by the application. Careless use of this function can put the application in a weird, inconsistent, and malfunctioning state.

which_applications()

-spec which_applications() -> [{Application, Description, Vsn}]
                            when Application :: atom(), Description :: string(), Vsn :: string().

Equivalent to which_applications(5000).

which_applications(Timeout)

-spec which_applications(Timeout) -> [{Application, Description, Vsn}]
                            when
                                Timeout :: timeout(),
                                Application :: atom(),
                                Description :: string(),
                                Vsn :: string().

Returns a list with information about the applications that are currently running.

Application is the application name. Description and Vsn are the values of their description and vsn application specification keys, respectively.

A Timeout argument can be specified in situations where the application controller is heavily loaded.

data_publisher behaviour

A behavior for building eventually consistent, replicated data stores across distributed nodes.

This module provides the infrastructure for:

Replicating data across all nodes running the same scope

Automatic peer discovery

Subscription-based notifications for data changes

Version translation for rolling upgrades

Implementing modules define how data is stored, updated, and how changes are calculated and propagated. This is a generalization of the pg module.

Summary

Types

global_view()

local_data()

options()

scope()

state()

subscribe_result()

subscription()

subscriptions()

update()

version()

Callbacks

data_diff(Old, New)

init_global_view/2

init_local_data/1

new_subscription/2

stop_global_view/1

translate_local_data/3

translate_message/2

translate_update/3

update_global_view_and_notify/4

update_local_data/2

version()

Functions

handle_call/3

handle_cast(Message, State)

handle_info/2

init/1

start(Scope, Module)

start(Scope, Module, Options)

start_link(Scope, Module)

start_link(Scope, Module, Options)

subscribe(Scope, Subscription)

terminate/2

unsubscribe(Scope, Ref)

update(Scope, Update)

Types

global_view()

(not exported) (since OTP @OTP-20055@)

-type global_view() :: dynamic().

local_data()

(not exported) (since OTP @OTP-20055@)

-type local_data() :: dynamic().

options()

(not exported) (since OTP @OTP-20055@)

-type options() :: #{standalone => boolean(), dynamic() => dynamic()}.

scope()

(not exported) (since OTP @OTP-20055@)

-type scope() :: atom().

state()

(not exported) (since OTP @OTP-20055@)

-type state() ::
          #state{scope :: atom(),
                 module :: module(),
                 options :: options(),
                 version :: version(),
                 global_view :: global_view(),
                 local_data :: local_data(),
                 peers :: #{pid() => {reference(), version(), local_data()}},
                 subscriptions :: subscriptions(),
                 subscribe_refs :: #{reference() => subscription()}}.

subscribe_result()

(not exported) (since OTP @OTP-20055@)

-type subscribe_result() :: dynamic().

subscription()

(not exported) (since OTP @OTP-20055@)

-type subscription() :: dynamic().

subscriptions()

(not exported) (since OTP @OTP-20055@)

-type subscriptions() :: #{subscription() => #{reference() => pid()}}.

update()

(not exported) (since OTP @OTP-20055@)

-type update() :: dynamic().

version()

(not exported) (since OTP @OTP-20055@)

-type version() :: dynamic().

Callbacks

data_diff(Old, New)

(since OTP @OTP-20055@)

-callback data_diff(Old :: local_data(), New :: local_data()) -> update().

init_global_view/2

(since OTP @OTP-20055@)

-callback init_global_view(scope(), options()) -> global_view().

init_local_data/1

(since OTP @OTP-20055@)

-callback init_local_data(options()) -> local_data().

new_subscription/2

(since OTP @OTP-20055@)

-callback new_subscription(subscription(), global_view()) -> subscribe_result().

stop_global_view/1

(since OTP @OTP-20055@)

-callback stop_global_view(global_view()) -> term().

translate_local_data/3

(since OTP @OTP-20055@)

-callback translate_local_data(MyVersion :: version(), PeerVersion :: version(), local_data()) ->
                                  local_data() | {'$plain_message', dynamic()}.

translate_message/2

(since OTP @OTP-20055@) (optional)

-callback translate_message(dynamic(), global_view()) ->
                               {update, update(), global_view()} |
                               {drop, global_view()} |
                               {update, pid(), update(), global_view()} |
                               {local_data, pid(), version(), local_data(), global_view()} |
                               {discover, pid(), version(), global_view()}.

translate_update/3

(since OTP @OTP-20055@)

-callback translate_update(MyVersion :: version(), PeerVersion :: version(), update()) ->
                              update() | {'$plain_messages', [dynamic()]}.

update_global_view_and_notify/4

(since OTP @OTP-20055@)

-callback update_global_view_and_notify(node(), update(), subscriptions(), global_view()) -> global_view().

update_local_data/2

(since OTP @OTP-20055@)

-callback update_local_data(update(), local_data()) -> local_data().

version()

(since OTP @OTP-20055@)

-callback version() -> version().

Functions

handle_call/3

(since OTP @OTP-20055@)

-spec handle_call({update, update()}, gen_server:from(), state()) -> {reply, ok, state()};
                 ({subscribe, subscription()}, gen_server:from(), state()) ->
                     {reply, {reference(), subscribe_result()}, state()};
                 ({unsubscribe, reference()}, gen_server:from(), state()) -> {reply, ok, state()}.

handle_cast(Message, State)

(since OTP @OTP-20055@)

-spec handle_cast(Message, state()) -> {noreply, state()}
                     when Message :: {local_data, pid(), version(), local_data()} | dynamic().

handle_info/2

(since OTP @OTP-20055@)

-spec handle_info(Message, state()) -> {noreply, state()}
                     when
                         Message ::
                             {discover, pid(), version()} |
                             {local_data, pid(), version(), local_data()} |
                             {update, pid(), update()} |
                             {nodeup, node()} |
                             {nodedown, node()} |
                             {{'DOWN', subscribe}, reference(), process, pid(), dynamic()} |
                             {{'DOWN', peer}, reference(), process, pid(), dynamic()} |
                             dynamic().

init/1

(since OTP @OTP-20055@)

-spec init({scope(), module(), options()}) -> {ok, state()}.

start(Scope, Module)

(since OTP @OTP-20055@)

-spec start(scope(), module()) -> {ok, pid()} | {error, term()}.

start(Scope, Module, Options)

(since OTP @OTP-20055@)

-spec start(scope(), module(), options()) -> {ok, pid()} | {error, term()}.

start_link(Scope, Module)

(since OTP @OTP-20055@)

-spec start_link(scope(), module()) -> {ok, pid()} | {error, term()}.

start_link(Scope, Module, Options)

(since OTP @OTP-20055@)

-spec start_link(scope(), module(), options()) -> {ok, pid()} | {error, term()}.

subscribe(Scope, Subscription)

(since OTP @OTP-20055@)

-spec subscribe(scope(), subscription()) -> {reference(), subscribe_result()}.

terminate/2

(since OTP @OTP-20055@)

-spec terminate(dynamic(), state()) -> term().

unsubscribe(Scope, Ref)

(since OTP @OTP-20055@)

-spec unsubscribe(scope(), reference()) -> ok.

update(Scope, Update)

(since OTP @OTP-20055@)

-spec update(scope(), update()) -> ok.

error_handler

Default system error handler.

This module defines what happens when certain types of errors occur.

You can change the error handler of a process by calling erlang:process_flag(error_handler, NewErrorHandler).

Notes

The code in error_handler is complex. Do not change it without fully understanding the interaction between the error handler, the init process of the code server, and the I/O mechanism of the code.

Code changes that seem small can cause a deadlock, as unforeseen consequences can occur. The use of input is dangerous in this type of code.

Summary

Functions

raise_undef_exception(Module, Function, Args)

Raises an undef exception with a stacktrace, indicating that Module:Function/N is undefined.

undefined_function(Module, Function, Args)

This function is called by the runtime system if a call is made to Module:Function(Arg1,.., ArgN) and Module:Function/N is undefined. Notice that this function is evaluated inside the process making the original call.

undefined_lambda(Module, Fun, Args)

This function is evaluated if a call is made to Fun(Arg1,.., ArgN) when the module defining the fun is not loaded. The function is evaluated inside the process making the original call.

Functions

raise_undef_exception(Module, Function, Args)

(since OTP R16B)

-spec raise_undef_exception(Module, Function, Args) -> no_return()
                               when Module :: atom(), Function :: atom(), Args :: list().

Raises an undef exception with a stacktrace, indicating that Module:Function/N is undefined.

undefined_function(Module, Function, Args)

-spec undefined_function(Module, Function, Args) -> any()
                            when Module :: atom(), Function :: atom(), Args :: list().

This function is called by the runtime system if a call is made to Module:Function(Arg1,.., ArgN) and Module:Function/N is undefined. Notice that this function is evaluated inside the process making the original call.

This function first attempts to autoload Module. If that is not possible, an undef exception is raised.

If it is possible to load Module and function Function/N is exported, it is called.

Otherwise, if function '$handle_undefined_function'/2 is exported, it is called as '$handle_undefined_function'(Function, Args).

Warning

Defining '$handle_undefined_function'/2 in ordinary application code is highly discouraged. It is very easy to make subtle errors that can take a long time to debug. Furthermore, none of the tools for static code analysis (such as Dialyzer and Xref) supports the use of '$handle_undefined_function'/2 and no such support will be added. Only use this function after having carefully considered other, less dangerous, solutions. One example of potential legitimate use is creating stubs for other sub-systems during testing and debugging.

Otherwise an undef exception is raised.

undefined_lambda(Module, Fun, Args)

-spec undefined_lambda(Module, Fun, Args) -> term() when Module :: atom(), Fun :: fun(), Args :: list().

This function is evaluated if a call is made to Fun(Arg1,.., ArgN) when the module defining the fun is not loaded. The function is evaluated inside the process making the original call.

If Module is interpreted, the interpreter is invoked and the return value of the interpreted Fun(Arg1,.., ArgN) call is returned.

Otherwise, it returns, if possible, the value of apply(Fun, Args) after an attempt is made to autoload Module. If this is not possible, the call fails with exit reason undef.

file

File interface module.

This module provides an interface to the file system.

Warning

File operations are only guaranteed to appear atomic when going through the same file server. A NIF or other OS process may observe intermediate steps on certain operations on some operating systems, eg. renaming an existing file on Windows, or write_file_info/2 on any OS at the time of writing.

Regarding filename encoding, the Erlang VM can operate in two modes. The current mode can be queried using function native_name_encoding/0. It returns latin1 or utf8.

In latin1 mode, the Erlang VM does not change the encoding of filenames. In utf8 mode, filenames can contain Unicode characters greater than 255 and the VM converts filenames back and forth to the native filename encoding (usually UTF-8, but UTF-16 on Windows).

The default mode depends on the operating system. Windows, MacOS X and Android enforce consistent filename encoding and therefore the VM uses utf8 mode.

On operating systems with transparent naming (for example, all Unix systems except MacOS X), default is utf8 if the terminal supports UTF-8, otherwise latin1. The default can be overridden using +fnl (to force latin1 mode) or +fnu (to force utf8 mode) when starting erl.

On operating systems with transparent naming, files can be inconsistently named, for example, some files are encoded in UTF-8 while others are encoded in ISO Latin-1. The concept of raw filenames is introduced to handle file systems with inconsistent naming when running in utf8 mode.

A raw filename is a filename specified as a binary. The Erlang VM does not translate a filename specified as a binary on systems with transparent naming.

When running in utf8 mode, functions list_dir/1 and read_link/1 never return raw filenames. To return all filenames including raw filenames, use functions list_dir_all/1 and read_link_all/1.

See also section Notes About Raw Filenames in the STDLIB User's Guide.

Note

File operations used to accept filenames containing null characters (integer value zero). This caused the name to be truncated and in some cases arguments to primitive operations to be mixed up. Filenames containing null characters inside the filename are now rejected and will cause primitive file operations fail.

POSIX Error Codes

eacces - Permission denied

eagain - Resource temporarily unavailable

ebadf - Bad file number

ebusy - File busy

edquot - Disk quota exceeded

eexist - File already exists

efault - Bad address in system call argument

efbig - File too large

eintr - Interrupted system call

einval - Invalid argument

eio - I/O error

eisdir - Illegal operation on a directory

eloop - Too many levels of symbolic links

emfile - Too many open files

emlink - Too many links

enametoolong - Filename too long

enfile - File table overflow

enodev - No such device

enoent - No such file or directory

enomem - Not enough memory

enospc - No space left on device

enotblk - Block device required

enotdir - Not a directory

enotsup - Operation not supported

enxio - No such device or address

eperm - Not owner

epipe - Broken pipe

erofs - Read-only file system

espipe - Invalid seek

esrch - No such process

estale - Stale remote file handle

exdev - Cross-device link

Performance

For increased performance, raw files are recommended.

A normal file is really a process so it can be used as an I/O device (see io). Therefore, when data is written to a normal file, the sending of the data to the file process, copies all data that are not binaries. Opening the file in binary mode and writing binaries is therefore recommended. If the file is opened on another node, or if the file server runs as slave to the file server of another node, also binaries are copied.

Note

Raw files use the file system of the host machine of the node. For normal files (non-raw), the file server is used to find the files, and if the node is running its file server as slave to the file server of another node, and the other node runs on some other host machine, they can have different file systems. However, this is seldom a problem.

open/2 can be given the options delayed_write and read_ahead to turn on caching, which will reduce the number of operating system calls and greatly improve performance for small reads and writes. However, the overhead won't disappear completely and it's best to keep the number of file operations to a minimum. As a contrived example, the following function writes 4MB in 2.5 seconds when tested:

create_file_slow(Name) ->
    {ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
    create_file_slow_1(Fd, 4 bsl 20),
    file:close(Fd).

create_file_slow_1(_Fd, 0) ->
    ok;
create_file_slow_1(Fd, M) ->
    ok = file:write(Fd, <<0>>),
    create_file_slow_1(Fd, M - 1).

The following functionally equivalent code writes 128 bytes per call to write/2 and so does the same work in 0.08 seconds, which is roughly 30 times faster:

create_file(Name) ->
    {ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
    create_file_1(Fd, 4 bsl 20),
    file:close(Fd),
    ok.

create_file_1(_Fd, 0) ->
    ok;
create_file_1(Fd, M) when M >= 128 ->
    ok = file:write(Fd, <<0:(128)/unit:8>>),
    create_file_1(Fd, M - 128);
create_file_1(Fd, M) ->
    ok = file:write(Fd, <<0:(M)/unit:8>>),
    create_file_1(Fd, M - 1).

When writing data it's generally more efficient to write a list of binaries rather than a list of integers. It is not needed to flatten a deep list before writing. On Unix hosts, scatter output, which writes a set of buffers in one operation, is used when possible. In this way write(FD, [Bin1, Bin2 | Bin3]) writes the contents of the binaries without copying the data at all, except for perhaps deep down in the operating system kernel.

Warning

If an error occurs when accessing an open file with module io, the process handling the file exits. The dead file process can hang if a process tries to access it later. This will be fixed in a future release.

See Also

filename

Summary

Types

date_time()

Must denote a valid date and time.

deep_list()

delete_option()

fd()

A file descriptor representing a file opened in raw mode.

file_info()

file_info_option()

filename()

A file name as returned from file API functions.

filename_all()

A file name as returned from file API functions.

io_device()

An IO device as returned by open/2.

io_server()

A process handling the I/O protocol.

location()

mode()

name()

A restricted file name used as input into file API functions.

name_all()

A file name used as input into file API functions.

posix()

An atom that is named from the POSIX error codes used in Unix, and in the runtime libraries of most C compilers.

posix_file_advise()

read_file_option()

sendfile_option()

Functions

advise(IoDevice, Offset, Length, Advise)

advise/4 can be used to announce an intention to access file data in a specific pattern in the future, thus allowing the operating system to perform appropriate optimizations.

allocate(File, Offset, Length)

allocate/3 can be used to preallocate space for a file.

change_group(Filename, Gid)

Changes group of a file. See write_file_info/2.

change_mode(Filename, Mode)

Changes permissions of a file. See write_file_info/2.

change_owner(Filename, Uid)

Changes owner of a file. See write_file_info/2.

change_owner(Filename, Uid, Gid)

Changes owner and group of a file. See write_file_info/2.

change_time(Filename, Mtime)

Changes the modification and access times of a file. See write_file_info/2.

change_time(Filename, Atime, Mtime)

Changes the modification and last access times of a file. See write_file_info/2.

close(IoDevice)

Closes the file referenced by IoDevice. It mostly returns ok, except for some severe errors such as out of memory.

consult(Filename)

Reads Erlang terms, separated by ., from Filename. Returns one of the following

copy(Source, Destination)

Equivalent to copy(Source, Destination, infinity).

copy(Source, Destination, ByteCount)

Copies ByteCount bytes from Source to Destination. Source and Destination refer to either filenames or IO devices from, for example, open/2.

datasync(IoDevice)

Ensures that any buffers kept by the operating system (not by the Erlang runtime system) are written to disk. In many ways it resembles fsync but it does not update some of the metadata of the file, such as the access time. On some platforms this function has no effect.

del_dir(Dir)

Tries to delete directory Dir. The directory must be empty before it can be deleted. Returns ok if successful.

del_dir_r(File)

Deletes file or directory File. If File is a directory, its contents is first recursively deleted. Returns

delete(Filename)

Equivalent to delete(Filename, []).

delete(Filename, Opts)

Tries to delete file Filename. Returns ok if successful.

eval(Filename)

Reads and evaluates Erlang expressions, separated by . (or ,, a sequence of expressions is also an expression) from Filename. The result of the evaluation is not returned; any expression sequence in the file must be there for its side effect.

eval(Filename, Bindings)

The same as eval/1, but the variable bindings Bindings are used in the evaluation. For information about the variable bindings, see erl_eval.

format_error(Reason)

Given the error reason returned by any function in this module, returns a descriptive string of the error in English.

get_cwd()

Returns {ok, Dir}, where Dir is the current working directory of the file server.

get_cwd(Drive)

Returns {ok, Dir} or {error, Reason}, where Dir is the current working directory of the specified drive.

list_dir(Dir)

Lists all files in a directory, except files with raw filenames. Returns {ok, Filenames} if successful, otherwise {error, Reason}. Filenames is a list of the names of all the files in the directory. The names are not sorted.

list_dir_all(Dir)

Lists all the files in a directory, including files with raw filenames. Returns {ok, Filenames} if successful, otherwise {error, Reason}. Filenames is a list of the names of all the files in the directory. The names are not sorted.

make_dir(Dir)

Tries to create directory Dir. Missing parent directories are not created. Returns ok if successful.

make_link(Existing, New)

Makes a hard link from Existing to New on platforms supporting links (Unix and Windows). This function returns ok if the link was successfully created, otherwise {error, Reason}. On platforms not supporting links, {error,enotsup} is returned.

make_symlink(Existing, New)

Creates a symbolic link New to the file or directory Existing on platforms supporting symbolic links (most Unix systems and Windows, beginning with Vista). Existing does not need to exist. Returns ok if the link is successfully created, otherwise {error, Reason}. On platforms not supporting symbolic links, {error, enotsup} is returned.

native_name_encoding()

Returns the filename encoding mode. If it is latin1, the system translates no filenames. If it is utf8, filenames are converted back and forth to the native filename encoding (usually UTF-8, but UTF-16 on Windows).

open(File, Modes)

Opens file File in the mode determined by Modes, which can contain one or more of the following options

path_consult(Path, Filename)

Searches the path Path (a list of directory names) until the file Filename is found. If Filename is an absolute filename, Path is ignored. Then reads Erlang terms, separated by ., from the file.

path_eval(Path, Filename)

Searches the path Path (a list of directory names) until the file Filename is found. If Filename is an absolute filename, Path is ignored. Then reads and evaluates Erlang expressions, separated by . (or ,, a sequence of expressions is also an expression), from the file. The result of evaluation is not returned; any expression sequence in the file must be there for its side effect.

path_open(Path, Filename, Modes)

Searches the path Path (a list of directory names) until the file Filename is found. If Filename is an absolute filename, Path is ignored. Then opens the file in the mode determined by Modes.

path_script(Path, Filename)

Searches the path Path (a list of directory names) until the file Filename is found. If Filename is an absolute filename, Path is ignored. Then reads and evaluates Erlang expressions, separated by . (or ,, a sequence of expressions is also an expression), from the file.

path_script(Path, Filename, Bindings)

The same as path_script/2 but the variable bindings Bindings are used in the evaluation. See erl_eval about variable bindings.

position(IoDevice, Location)

Sets the position of the file referenced by IoDevice to Location. Returns {ok, NewPosition} (as absolute offset) if successful, otherwise {error, Reason}. Location is one of the following

pread(IoDevice, LocNums)

Performs a sequence of pread/3 in one operation, which is more efficient than calling them one at a time. Returns {ok, [Data, ...]} or {error, Reason}, where each Data, the result of the corresponding pread, is either a list or a binary depending on the mode of the file, or eof if the requested position is beyond end of file.

pread(IoDevice, Location, Number)

Combines position/2 and read/2 in one operation, which is more efficient than calling them one at a time.

pwrite(IoDevice, LocBytes)

Performs a sequence of pwrite/3 in one operation, which is more efficient than calling them one at a time. Returns ok or {error, {N, Reason}}, where N is the number of successful writes done before the failure.

pwrite(IoDevice, Location, Bytes)

Combines position/2 and write/2 in one operation, which is more efficient than calling them one at a time.

read(IoDevice, Number)

Reads Number bytes/characters from the file referenced by IoDevice.

read_file(Filename)

Equivalent to read_file(Filename, []).

read_file(Filename, Opts)

Returns {ok, Binary}, where Binary is a binary data object that contains the contents of Filename, or {error, Reason} if an error occurs.

read_file_info(File)

Equivalent to read_file_info(File, []).

read_file_info(File, Opts)

Retrieves information about a file. Returns {ok, FileInfo} if successful, otherwise {error, Reason}.

read_line(IoDevice)

Reads a line of bytes/characters from the file referenced by IoDevice.

read_link(Name)

Returns {ok, Filename} if Name refers to a symbolic link that is not a raw filename, or {error, Reason} otherwise. On platforms that do not support symbolic links, the return value is {error,enotsup}.

read_link_all(Name)

Returns {ok, Filename} if Name refers to a symbolic link or {error, Reason} otherwise. On platforms that do not support symbolic links, the return value is {error, enotsup}.

read_link_info(Name)

Equivalent to read_link_info(Name, []).

read_link_info(Name, Opts)

Works like read_file_info/1,2 except that if Name is a symbolic link, information about the link is returned in the file_info record and the type field of the record is set to symlink.

rename(Source, Destination)

Tries to rename the file Source to Destination. It can be used to move files (and directories) between directories, but it is not sufficient to specify the destination only. The destination filename must also be specified. For example, if bar is a normal file and foo and baz are directories, rename("foo/bar", "baz") returns an error, but rename("foo/bar", "baz/bar") succeeds. Returns ok if it is successful.

script(Filename)

Reads and evaluates Erlang expressions, separated by . (or ,, a sequence of expressions is also an expression), from the file.

script(Filename, Bindings)

The same as script/1 but the variable bindings Bindings are used in the evaluation. See erl_eval about variable bindings.

sendfile(Filename, Socket)

Sends the file Filename to Socket. Returns {ok, BytesSent} if successful, otherwise {error, Reason}.

sendfile(RawFile, Socket, Offset, Bytes, Opts)

Sends Bytes from the file referenced by RawFile beginning at Offset to Socket. Returns {ok, BytesSent} if successful, otherwise {error, Reason}. If Bytes is set to 0 all data after the specified Offset is sent.

set_cwd(Dir)

Sets the current working directory of the file server to Dir. Returns ok if successful.

sync(IoDevice)

Ensures that any buffers kept by the operating system (not by the Erlang runtime system) are written to disk. On some platforms, this function might have no effect.

truncate(IoDevice)

Truncates the file referenced by IoDevice at the current position. Returns ok if successful, otherwise {error, Reason}.

write(IoDevice, Bytes)

Writes Bytes to the file referenced by IoDevice. This function is the only way to write to a file opened in raw mode (although it works for normally opened files too). Returns ok if successful, and {error, Reason} otherwise.

write_file(Filename, Bytes)

Writes the contents of the iodata term Bytes to file Filename. The file is created if it does not exist. If it exists, the previous contents are overwritten. Returns ok if successful, otherwise {error, Reason}.

write_file(Filename, Bytes, Modes)

Same as write_file/2, but takes a third argument Modes, a list of possible modes, see open/2. The mode flags binary and write are implicit, so they are not to be used.

write_file_info(Filename, FileInfo)

Equivalent to write_file_info(Filename, FileInfo, []).

write_file_info(Filename, FileInfo, Opts)

Changes file information. Returns ok if successful, otherwise {error, Reason}.

Types

date_time()

-type date_time() :: calendar:datetime().

Must denote a valid date and time.

deep_list()

(not exported)

-type deep_list() :: [char() | atom() | deep_list()].

delete_option()

(not exported)

-type delete_option() :: raw.

fd()

-type fd() :: file_descriptor().

A file descriptor representing a file opened in raw mode.

file_info()

-type file_info() ::
          #file_info{size :: non_neg_integer() | undefined,
                     type :: device | directory | other | regular | symlink | undefined,
                     access :: read | write | read_write | none | undefined,
                     atime :: file:date_time() | non_neg_integer() | undefined,
                     mtime :: file:date_time() | non_neg_integer() | undefined,
                     ctime :: file:date_time() | non_neg_integer() | undefined,
                     mode :: non_neg_integer() | undefined,
                     links :: non_neg_integer() | undefined,
                     major_device :: non_neg_integer() | undefined,
                     minor_device :: non_neg_integer() | undefined,
                     inode :: non_neg_integer() | undefined,
                     uid :: non_neg_integer() | undefined,
                     gid :: non_neg_integer() | undefined}.

file_info_option()

(not exported)

-type file_info_option() :: {time, local} | {time, universal} | {time, posix} | raw.

filename()

-type filename() :: string().

A file name as returned from file API functions.

See the documentation of the name_all/0 type.

filename_all()

-type filename_all() :: string() | (RawFilename :: binary()).

A file name as returned from file API functions.

See the documentation of the name_all/0 type.

io_device()

-type io_device() :: io_server() | fd().

An IO device as returned by open/2.

io_server/0 is returned by default and fd/0 is returned if the raw option is given.

io_server()

-type io_server() :: pid().

A process handling the I/O protocol.

location()

-type location() ::
          integer() |
          {bof, Offset :: integer()} |
          {cur, Offset :: integer()} |
          {eof, Offset :: integer()} |
          bof | cur | eof.

mode()

-type mode() ::
          read | write | append | exclusive | raw | binary |
          {delayed_write, Size :: non_neg_integer(), Delay :: non_neg_integer()} |
          delayed_write |
          {read_ahead, Size :: pos_integer()} |
          read_ahead | compressed | compressed_one |
          {zstd, zstd:compress_parameters() | zstd:decompress_parameters()} |
          {encoding, unicode:encoding()} |
          sync.

name()

-type name() :: string() | atom() | deep_list().

A restricted file name used as input into file API functions.

If VM is in Unicode filename mode, string/0 and char/0 are allowed to be > 255. See also the documentation of the name_all/0 type.

name_all()

-type name_all() :: string() | atom() | deep_list() | (RawFilename :: binary()).

A file name used as input into file API functions.

If VM is in Unicode filename mode, characters are allowed to be > 255. RawFilename is a filename not subject to Unicode translation, meaning that it can contain characters not conforming to the Unicode encoding expected from the file system (that is, non-UTF-8 characters although the VM is started in Unicode filename mode). Null characters (integer value zero) are not allowed in filenames (not even at the end).

posix()

-type posix() ::
          eacces | eagain | ebadf | ebadmsg | ebusy | edeadlk | edeadlock | edquot | eexist | efault |
          efbig | eftype | eintr | einval | eio | eisdir | eloop | emfile | emlink | emultihop |
          enametoolong | enfile | enobufs | enodev | enolck | enolink | enoent | enomem | enospc |
          enosr | enostr | enosys | enotblk | enotdir | enotsup | enxio | eopnotsupp | eoverflow |
          eperm | epipe | erange | erofs | espipe | esrch | estale | etxtbsy | exdev.

An atom that is named from the POSIX error codes used in Unix, and in the runtime libraries of most C compilers.

posix_file_advise()

(not exported)

-type posix_file_advise() :: normal | sequential | random | no_reuse | will_need | dont_need.

read_file_option()

(not exported)

-type read_file_option() :: raw.

sendfile_option()

(not exported)

-type sendfile_option() :: {chunk_size, non_neg_integer()} | {use_threads, boolean()}.

Functions

advise(IoDevice, Offset, Length, Advise)

(since OTP R14B)

-spec advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason}
                when
                    IoDevice :: io_device(),
                    Offset :: integer(),
                    Length :: integer(),
                    Advise :: posix_file_advise(),
                    Reason :: posix() | badarg.

advise/4 can be used to announce an intention to access file data in a specific pattern in the future, thus allowing the operating system to perform appropriate optimizations.

On some platforms, this function might have no effect.

allocate(File, Offset, Length)

(since OTP R16B)

-spec allocate(File, Offset, Length) -> ok | {error, posix()}
                  when File :: io_device(), Offset :: non_neg_integer(), Length :: non_neg_integer().

allocate/3 can be used to preallocate space for a file.

This function only succeeds in platforms that provide this feature.

change_group(Filename, Gid)

-spec change_group(Filename, Gid) -> ok | {error, Reason}
                      when Filename :: name_all(), Gid :: integer(), Reason :: posix() | badarg.

Changes group of a file. See write_file_info/2.

change_mode(Filename, Mode)

(since OTP R14B)

-spec change_mode(Filename, Mode) -> ok | {error, Reason}
                     when Filename :: name_all(), Mode :: integer(), Reason :: posix() | badarg.

Changes permissions of a file. See write_file_info/2.

change_owner(Filename, Uid)

-spec change_owner(Filename, Uid) -> ok | {error, Reason}
                      when Filename :: name_all(), Uid :: integer(), Reason :: posix() | badarg.

Changes owner of a file. See write_file_info/2.

change_owner(Filename, Uid, Gid)

-spec change_owner(Filename, Uid, Gid) -> ok | {error, Reason}
                      when
                          Filename :: name_all(),
                          Uid :: integer(),
                          Gid :: integer(),
                          Reason :: posix() | badarg.

Changes owner and group of a file. See write_file_info/2.

change_time(Filename, Mtime)

-spec change_time(Filename, Mtime) -> ok | {error, Reason}
                     when Filename :: name_all(), Mtime :: date_time(), Reason :: posix() | badarg.

Changes the modification and access times of a file. See write_file_info/2.

change_time(Filename, Atime, Mtime)

-spec change_time(Filename, Atime, Mtime) -> ok | {error, Reason}
                     when
                         Filename :: name_all(),
                         Atime :: date_time(),
                         Mtime :: date_time(),
                         Reason :: posix() | badarg.

Changes the modification and last access times of a file. See write_file_info/2.

close(IoDevice)

-spec close(IoDevice) -> ok | {error, Reason}
               when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.

Closes the file referenced by IoDevice. It mostly returns ok, except for some severe errors such as out of memory.

Notice that if option delayed_write was used when opening the file, close/1 can return an old write error and not even try to close the file. See open/2.

consult(Filename)

-spec consult(Filename) -> {ok, Terms} | {error, Reason}
                 when
                     Filename :: name_all(),
                     Terms :: [term()],
                     Reason ::
                         posix() |
                         badarg | terminated | system_limit |
                         {Line :: integer(), Mod :: module(), Term :: term()}.

Reads Erlang terms, separated by ., from Filename. Returns one of the following:

{ok, Terms} - The file was successfully read.

{error, atom()} - An error occurred when opening the file or reading it. For a list of typical error codes, see open/2.

{error, {Line, Mod, Term}} - An error occurred when interpreting the Erlang terms in the file. To convert the three-element tuple to an English description of the error, use format_error/1.

Example:

f.txt:  {person, "kalle", 25}.
        {person, "pelle", 30}.

1> file:consult("f.txt").
{ok,[{person,"kalle",25},{person,"pelle",30}]}

The encoding of Filename can be set by a comment, as described in epp.

copy(Source, Destination)

-spec copy(Source, Destination) -> {ok, BytesCopied} | {error, Reason}
              when
                  Source :: io_device() | Filename | {Filename, Modes},
                  Destination :: io_device() | Filename | {Filename, Modes},
                  Filename :: name_all(),
                  Modes :: [mode()],
                  BytesCopied :: non_neg_integer(),
                  Reason :: posix() | badarg | terminated.

Equivalent to copy(Source, Destination, infinity).

copy(Source, Destination, ByteCount)

-spec copy(Source, Destination, ByteCount) -> {ok, BytesCopied} | {error, Reason}
              when
                  Source :: io_device() | Filename | {Filename, Modes},
                  Destination :: io_device() | Filename | {Filename, Modes},
                  Filename :: name_all(),
                  Modes :: [mode()],
                  ByteCount :: non_neg_integer() | infinity,
                  BytesCopied :: non_neg_integer(),
                  Reason :: posix() | badarg | terminated.

Copies ByteCount bytes from Source to Destination. Source and Destination refer to either filenames or IO devices from, for example, open/2.

Argument Modes is a list of possible modes, see open/2, and defaults to [].

If both Source and Destination refer to filenames, the files are opened with [read, binary] and [write, binary] prepended to their mode lists, respectively, to optimize the copy.

If Source refers to a filename, it is opened with read mode prepended to the mode list before the copy, and closed when done.

If Destination refers to a filename, it is opened with write mode prepended to the mode list before the copy, and closed when done.

Returns {ok, BytesCopied}, where BytesCopied is the number of bytes that was copied, which can be less than ByteCount if end of file was encountered on the source. If the operation fails, {error, Reason} is returned.

Typical error reasons: as for open/2 if a file had to be opened, and as for read/2 and write/2.

datasync(IoDevice)

(since OTP R14B)

-spec datasync(IoDevice) -> ok | {error, Reason}
                  when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.

Ensures that any buffers kept by the operating system (not by the Erlang runtime system) are written to disk. In many ways it resembles fsync but it does not update some of the metadata of the file, such as the access time. On some platforms this function has no effect.

Applications that access databases or log files often write a tiny data fragment (for example, one line in a log file) and then call fsync() immediately to ensure that the written data is physically stored on the hard disk. Unfortunately, fsync() always initiates two write operations: one for the newly written data and another one to update the modification time stored in the inode. If the modification time is not a part of the transaction concept, fdatasync() can be used to avoid unnecessary inode disk write operations.

Available only in some POSIX systems, this call results in a call to fsync(), or has no effect in systems not providing the fdatasync() syscall.

del_dir(Dir)

-spec del_dir(Dir) -> ok | {error, Reason} when Dir :: name_all(), Reason :: posix() | badarg.

Tries to delete directory Dir. The directory must be empty before it can be deleted. Returns ok if successful.

Typical error reasons:

eacces - Missing search or write permissions for the parent directories of Dir.

eexist - The directory is not empty.

enoent - The directory does not exist.

enotdir - A component of Dir is not a directory. On some platforms, enoent is returned instead.

einval - Attempt to delete the current directory. On some platforms, eacces is returned instead.

del_dir_r(File)

(since OTP 23.0)

-spec del_dir_r(File) -> ok | {error, Reason} when File :: name_all(), Reason :: posix() | badarg.

Deletes file or directory File. If File is a directory, its contents is first recursively deleted. Returns:

ok - The operation completed without errors.

{error, posix()} - An error occurred when accessing or deleting File. If some file or directory under File could not be deleted, File cannot be deleted as it is non-empty, and {error, eexist} is returned.

delete(Filename)

-spec delete(Filename) -> ok | {error, Reason} when Filename :: name_all(), Reason :: posix() | badarg.

Equivalent to delete(Filename, []).

delete(Filename, Opts)

(since OTP 24.0)

-spec delete(Filename, Opts) -> ok | {error, Reason}
                when Filename :: name_all(), Opts :: [delete_option()], Reason :: posix() | badarg.

Tries to delete file Filename. Returns ok if successful.

If the option raw is set, the file server is not called. This can be useful in particular during the early boot stage when the file server is not yet registered, to still be able to delete local files.

Typical error reasons:

enoent - The file does not exist.

eacces - Missing permission for the file or one of its parents.

eperm - The file is a directory and the user is not superuser.

enotdir - A component of the filename is not a directory. On some platforms, enoent is returned instead.

einval - Filename has an improper type, such as tuple.

Warning

In a future release, a bad type for argument Filename will probably generate an exception.

eval(Filename)

-spec eval(Filename) -> ok | {error, Reason}
              when
                  Filename :: name_all(),
                  Reason ::
                      posix() |
                      badarg | terminated | system_limit |
                      {Line :: integer(), Mod :: module(), Term :: term()}.

Reads and evaluates Erlang expressions, separated by . (or ,, a sequence of expressions is also an expression) from Filename. The result of the evaluation is not returned; any expression sequence in the file must be there for its side effect.

Returns one of the following:

ok - The file was read and evaluated.

{error, atom()} - An error occurred when opening the file or reading it. For a list of typical error codes, see open/2.

{error, {Line, Mod, Term}} - An error occurred when interpreting the Erlang expressions in the file. To convert the three-element tuple to an English description of the error, use format_error/1.

The encoding of Filename can be set by a comment, as described in epp.

eval(Filename, Bindings)

-spec eval(Filename, Bindings) -> ok | {error, Reason}
              when
                  Filename :: name_all(),
                  Bindings :: erl_eval:binding_struct(),
                  Reason ::
                      posix() |
                      badarg | terminated | system_limit |
                      {Line :: integer(), Mod :: module(), Term :: term()}.

The same as eval/1, but the variable bindings Bindings are used in the evaluation. For information about the variable bindings, see erl_eval.

format_error(Reason)

-spec format_error(Reason) -> Chars
                      when
                          Reason ::
                              posix() |
                              badarg | terminated | system_limit |
                              {Line :: integer(), Mod :: module(), Term :: term()},
                          Chars :: string().

Given the error reason returned by any function in this module, returns a descriptive string of the error in English.

get_cwd()

-spec get_cwd() -> {ok, Dir} | {error, Reason} when Dir :: filename(), Reason :: posix().

Returns {ok, Dir}, where Dir is the current working directory of the file server.

Note

In rare circumstances, this function can fail on Unix. It can occur if read permission does not exist for the parent directories of the current directory.

A typical error reason:

eacces - Missing read permission for one of the parents of the current directory.

get_cwd(Drive)

-spec get_cwd(Drive) -> {ok, Dir} | {error, Reason}
                 when Drive :: string(), Dir :: filename(), Reason :: posix() | badarg.

Returns {ok, Dir} or {error, Reason}, where Dir is the current working directory of the specified drive.

Drive is to be of the form Letter:, for example, c:.

Returns {error, enotsup} on platforms that have no concept of current drive (Unix, for example).

Typical error reasons:

enotsup - The operating system has no concept of drives.

eacces - The drive does not exist.

einval - The format of Drive is invalid.

list_dir(Dir)

-spec list_dir(Dir) -> {ok, Filenames} | {error, Reason}
                  when
                      Dir :: name_all(),
                      Filenames :: [filename()],
                      Reason :: posix() | badarg | {no_translation, Filename :: unicode:latin1_binary()}.

Lists all files in a directory, except files with raw filenames. Returns {ok, Filenames} if successful, otherwise {error, Reason}. Filenames is a list of the names of all the files in the directory. The names are not sorted.

Typical error reasons:

eacces - Missing search or write permissions for Dir or one of its parent directories.

enoent - The directory does not exist.

{no_translation, Filename} - Filename is a binary/0 with characters coded in ISO Latin-1 and the VM was started with parameter +fnue.

list_dir_all(Dir)

(since OTP R16B)

-spec list_dir_all(Dir) -> {ok, Filenames} | {error, Reason}
                      when Dir :: name_all(), Filenames :: [filename_all()], Reason :: posix() | badarg.

Lists all the files in a directory, including files with raw filenames. Returns {ok, Filenames} if successful, otherwise {error, Reason}. Filenames is a list of the names of all the files in the directory. The names are not sorted.

Typical error reasons:

eacces - Missing search or write permissions for Dir or one of its parent directories.

enoent - The directory does not exist.

make_dir(Dir)

-spec make_dir(Dir) -> ok | {error, Reason} when Dir :: name_all(), Reason :: posix() | badarg.

Tries to create directory Dir. Missing parent directories are not created. Returns ok if successful.

Typical error reasons:

eacces - Missing search or write permissions for the parent directories of Dir.

eexist - A file or directory named Dir exists already.

enoent - A component of Dir does not exist.

enospc - No space is left on the device.

enotdir - A component of Dir is not a directory. On some platforms, enoent is returned instead.

make_link(Existing, New)

-spec make_link(Existing, New) -> ok | {error, Reason}
                   when Existing :: name_all(), New :: name_all(), Reason :: posix() | badarg.

Makes a hard link from Existing to New on platforms supporting links (Unix and Windows). This function returns ok if the link was successfully created, otherwise {error, Reason}. On platforms not supporting links, {error,enotsup} is returned.

Typical error reasons:

eacces - Missing read or write permissions for the parent directories of Existing or New.

eexist - New already exists.

enotsup - Hard links are not supported on this platform.

make_symlink(Existing, New)

-spec make_symlink(Existing, New) -> ok | {error, Reason}
                      when Existing :: name_all(), New :: name_all(), Reason :: posix() | badarg.

Creates a symbolic link New to the file or directory Existing on platforms supporting symbolic links (most Unix systems and Windows, beginning with Vista). Existing does not need to exist. Returns ok if the link is successfully created, otherwise {error, Reason}. On platforms not supporting symbolic links, {error, enotsup} is returned.

Typical error reasons:

eacces - Missing read or write permissions for the parent directories of Existing or New.

eexist - New already exists.

enotsup - Symbolic links are not supported on this platform.

eperm - User does not have privileges to create symbolic links (SeCreateSymbolicLinkPrivilege on Windows).

native_name_encoding()

(since OTP R14B01)

-spec native_name_encoding() -> latin1 | utf8.

Returns the filename encoding mode. If it is latin1, the system translates no filenames. If it is utf8, filenames are converted back and forth to the native filename encoding (usually UTF-8, but UTF-16 on Windows).

open(File, Modes)

-spec open(File, Modes) -> {ok, IoDevice} | {error, Reason}
              when
                  File :: Filename | iodata(),
                  Filename :: name_all(),
                  Modes :: [mode() | ram | directory],
                  IoDevice :: io_device(),
                  Reason :: posix() | badarg | system_limit.

Opens file File in the mode determined by Modes, which can contain one or more of the following options:

read - The file, which must exist, is opened for reading.

write - The file is opened for writing. It is created if it does not exist. If the file exists and write is not combined with read, the file is truncated.

append - The file is opened for writing. It is created if it does not exist. Every write operation to a file opened with append takes place at the end of the file.

exclusive - The file is opened for writing. It is created if it does not exist. If the file exists, {error, eexist} is returned.

Warning

This option does not guarantee exclusiveness on file systems not supporting O_EXCL properly, such as NFS. Do not depend on this option unless you know that the file system supports it (in general, local file systems are safe).

raw - Allows faster access to a file, as no Erlang process is needed to handle the file. However, a file opened in this way has the following limitations:

The functions in the io module cannot be used, as they can only talk to an Erlang process. Instead, use functions read/2, read_line/1, and write/2.

Especially if read_line/1 is to be used on a raw file, it is recommended to combine this option with option {read_ahead, Size} as line-oriented I/O is inefficient without buffering.

Only the Erlang process that opened the file can use it.

A remote Erlang file server cannot be used. The computer on which the Erlang node is running must have access to the file system (directly or through NFS).

binary - Read operations on the file return binaries rather than lists.

{delayed_write, Size, Delay} - Data in subsequent write/2 calls is buffered until at least Size bytes are buffered, or until the oldest buffered data is Delay milliseconds old. Then all buffered data is written in one operating system call. The buffered data is also flushed before some other file operation than write/2 is executed.

The purpose of this option is to increase performance by reducing the number of operating system calls. Thus, the write/2 calls must be for sizes significantly less than Size, and not interspersed by too many other file operations.

When this option is used, the result of write/2 calls can prematurely be reported as successful, and if a write error occurs, the error is reported as the result of the next file operation, which is not executed.

For example, when delayed_write is used, after a number of write/2 calls, close/1 can return {error, enospc}, as there is not enough space on the disc for previously written data. close/1 must probably be called again, as the file is still open.

delayed_write - The same as {delayed_write, Size, Delay} with reasonable default values for Size and Delay (roughly some 64 KB, 2 seconds).

{read_ahead, Size} - Activates read data buffering. If read/2 calls are for significantly less than Size bytes, read operations to the operating system are still performed for blocks of Size bytes. The extra data is buffered and returned in subsequent read/2 calls, giving a performance gain as the number of operating system calls is reduced.

The read_ahead buffer is also highly used by function read_line/1 in raw mode, therefore this option is recommended (for performance reasons) when accessing raw files using that function.

If read/2 calls are for sizes not significantly less than, or even greater than Size bytes, no performance gain can be expected.

read_ahead - The same as {read_ahead, Size} with a reasonable default value for Size (roughly some 64 KB).

compressed - Makes it possible to read or write gzip compressed files. Option compressed must be combined with read or write, but not both. Notice that the file size obtained with read_file_info/1 does probably not match the number of bytes that can be read from a compressed file.

{zstd, Opts} - Makes it possible to read or write zstd compressed files. Option compressed must be combined with read or write, but not both. Notice that the file size obtained with read_file_info/1 does probably not match the number of bytes that can be read from a compressed file.

compressed_one - Read one member of a gzip compressed file. Option compressed_one can only be combined with read.

{encoding, Encoding} - Makes the file perform automatic translation of characters to and from a specific (Unicode) encoding. Notice that the data supplied to write/2 or returned by read/2 still is byte-oriented; this option denotes only how data is stored in the disk file.

Depending on the encoding, different methods of reading and writing data is preferred. The default encoding of latin1 implies using this module (file) for reading and writing data as the interfaces provided here work with byte-oriented data. Using other (Unicode) encodings makes the io functions get_chars, get_line, and put_chars more suitable, as they can work with the full Unicode range.

If data is sent to an io_device/0 in a format that cannot be converted to the specified encoding, or if data is read by a function that returns data in a format that cannot cope with the character range of the data, an error occurs and the file is closed.

Allowed values for Encoding:

latin1 - The default encoding. Bytes supplied to the file, that is, write/2 are written "as is" on the file. Likewise, bytes read from the file, that is, read/2 are returned "as is". If module io is used for writing, the file can only cope with Unicode characters up to code point 255 (the ISO Latin-1 range).

unicode or utf8 - Characters are translated to and from UTF-8 encoding before they are written to or read from the file. A file opened in this way can be readable using function read/2, as long as no data stored on the file lies beyond the ISO Latin-1 range (0..255), but failure occurs if the data contains Unicode code points beyond that range. The file is best read with the functions in the Unicode aware module io.

Bytes written to the file by any means are translated to UTF-8 encoding before being stored on the disk file.

utf16 or {utf16,big} - Works like unicode, but translation is done to and from big endian UTF-16 instead of UTF-8.

{utf16,little} - Works like unicode, but translation is done to and from little endian UTF-16 instead of UTF-8.

utf32 or {utf32,big} - Works like unicode, but translation is done to and from big endian UTF-32 instead of UTF-8.

{utf32,little} - Works like unicode, but translation is done to and from little endian UTF-32 instead of UTF-8.

The Encoding can be changed for a file "on the fly" by using function io:setopts/2. So a file can be analyzed in latin1 encoding for, for example, a BOM, positioned beyond the BOM and then be set for the right encoding before further reading. For functions identifying BOMs, see module unicode.

This option is not allowed on raw files.

ram - File must be iodata/0. Returns an fd/0, which lets module file operate on the data in-memory as if it is a file.

sync - On platforms supporting it, enables the POSIX O_SYNC synchronous I/O flag or its platform-dependent equivalent (for example, FILE_FLAG_WRITE_THROUGH on Windows) so that writes to the file block until the data is physically written to disk. However, be aware that the exact semantics of this flag differ from platform to platform. For example, none of Linux or Windows guarantees that all file metadata are also written before the call returns. For precise semantics, check the details of your platform documentation. On platforms with no support for POSIX O_SYNC or equivalent, use of the sync flag causes open to return {error, enotsup}.

directory - Allows open to work on directories.

Returns:

{ok, IoDevice} - The file is opened in the requested mode. IoDevice is a reference to the file.

{error, Reason} - The file cannot be opened.

IoDevice is really the pid of the process that handles the file. This process monitors the process that originally opened the file (the owner process). If the owner process terminates, the file is closed and the process itself terminates too. An IoDevice returned from this call can be used as an argument to the I/O functions (see io).

Warning

While this function can be used to open any file, we recommend against using it for NFS-mounted files, FIFOs, devices, or similar since they can cause IO threads to hang forever.

If your application needs to interact with these kinds of files we recommend breaking out those parts to a port program instead.

Note

In previous versions of file, modes were specified as one of the atoms read, write, or read_write instead of a list. This is still allowed for reasons of backwards compatibility, but is not to be used for new code. Also note that read_write is not allowed in a mode list.

Typical error reasons:

enoent - The file does not exist.

eacces - Missing permission for reading the file or searching one of the parent directories.

eisdir - The named file is a directory.

enotdir - A component of the filename is not a directory, or the filename itself is not a directory if directory mode was specified. On some platforms, enoent is returned instead.

enospc - There is no space left on the device (if write access was specified).

path_consult(Path, Filename)

-spec path_consult(Path, Filename) -> {ok, Terms, FullName} | {error, Reason}
                      when
                          Path :: [Dir],
                          Dir :: name_all(),
                          Filename :: name_all(),
                          Terms :: [term()],
                          FullName :: filename_all(),
                          Reason ::
                              posix() |
                              badarg | terminated | system_limit |
                              {Line :: integer(), Mod :: module(), Term :: term()}.

Searches the path Path (a list of directory names) until the file Filename is found. If Filename is an absolute filename, Path is ignored. Then reads Erlang terms, separated by ., from the file.

Returns one of the following:

{ok, Terms, FullName} - The file is successfully read. FullName is the full name of the file.

{error, enoent} - The file cannot be found in any of the directories in Path.

{error, atom()} - An error occurred when opening the file or reading it. For a list of typical error codes, see open/2.

{error, {Line, Mod, Term}} - An error occurred when interpreting the Erlang terms in the file. Use format_error/1 to convert the three-element tuple to an English description of the error.

The encoding of Filename can be set by a comment as described in epp.

path_eval(Path, Filename)

-spec path_eval(Path, Filename) -> {ok, FullName} | {error, Reason}
                   when
                       Path :: [Dir :: name_all()],
                       Filename :: name_all(),
                       FullName :: filename_all(),
                       Reason ::
                           posix() |
                           badarg | terminated | system_limit |
                           {Line :: integer(), Mod :: module(), Term :: term()}.

Searches the path Path (a list of directory names) until the file Filename is found. If Filename is an absolute filename, Path is ignored. Then reads and evaluates Erlang expressions, separated by . (or ,, a sequence of expressions is also an expression), from the file. The result of evaluation is not returned; any expression sequence in the file must be there for its side effect.

Returns one of the following:

{ok, FullName} - The file is read and evaluated. FullName is the full name of the file.

{error, enoent} - The file cannot be found in any of the directories in Path.

{error, atom()} - An error occurred when opening the file or reading it. For a list of typical error codes, see open/2.

{error, {Line, Mod, Term}} - An error occurred when interpreting the Erlang expressions in the file. Use format_error/1 to convert the three-element tuple to an English description of the error.

The encoding of Filename can be set by a comment as described in epp.

path_open(Path, Filename, Modes)

-spec path_open(Path, Filename, Modes) -> {ok, IoDevice, FullName} | {error, Reason}
                   when
                       Path :: [Dir :: name_all()],
                       Filename :: name_all(),
                       Modes :: [mode() | directory],
                       IoDevice :: io_device(),
                       FullName :: filename_all(),
                       Reason :: posix() | badarg | system_limit.

Searches the path Path (a list of directory names) until the file Filename is found. If Filename is an absolute filename, Path is ignored. Then opens the file in the mode determined by Modes.

Returns one of the following:

{ok, IoDevice, FullName} - The file is opened in the requested mode. IoDevice is a reference to the file and FullName is the full name of the file.

{error, enoent} - The file cannot be found in any of the directories in Path.

{error, atom()} - The file cannot be opened.

path_script(Path, Filename)

-spec path_script(Path, Filename) -> {ok, Value, FullName} | {error, Reason}
                     when
                         Path :: [Dir :: name_all()],
                         Filename :: name_all(),
                         Value :: term(),
                         FullName :: filename_all(),
                         Reason ::
                             posix() |
                             badarg | terminated | system_limit |
                             {Line :: integer(), Mod :: module(), Term :: term()}.

Searches the path Path (a list of directory names) until the file Filename is found. If Filename is an absolute filename, Path is ignored. Then reads and evaluates Erlang expressions, separated by . (or ,, a sequence of expressions is also an expression), from the file.

Returns one of the following:

{ok, Value, FullName} - The file is read and evaluated. FullName is the full name of the file and Value the value of the last expression.

{error, enoent} - The file cannot be found in any of the directories in Path.

{error, atom()} - An error occurred when opening the file or reading it. For a list of typical error codes, see open/2.

{error, {Line, Mod, Term}} - An error occurred when interpreting the Erlang expressions in the file. Use format_error/1 to convert the three-element tuple to an English description of the error.

The encoding of Filename can be set by a comment as described in epp.

path_script(Path, Filename, Bindings)

-spec path_script(Path, Filename, Bindings) -> {ok, Value, FullName} | {error, Reason}
                     when
                         Path :: [Dir :: name_all()],
                         Filename :: name_all(),
                         Bindings :: erl_eval:binding_struct(),
                         Value :: term(),
                         FullName :: filename_all(),
                         Reason ::
                             posix() |
                             badarg | terminated | system_limit |
                             {Line :: integer(), Mod :: module(), Term :: term()}.

The same as path_script/2 but the variable bindings Bindings are used in the evaluation. See erl_eval about variable bindings.

position(IoDevice, Location)

-spec position(IoDevice, Location) -> {ok, NewPosition} | {error, Reason}
                  when
                      IoDevice :: io_device(),
                      Location :: location(),
                      NewPosition :: integer(),
                      Reason :: posix() | badarg | terminated.

Sets the position of the file referenced by IoDevice to Location. Returns {ok, NewPosition} (as absolute offset) if successful, otherwise {error, Reason}. Location is one of the following:

Offset - The same as {bof, Offset}.

{bof, Offset} - Absolute offset.

{cur, Offset} - Offset from the current position.

{eof, Offset} - Offset from the end of file.

bof | cur | eof - The same as above with Offset 0.

Notice that offsets are counted in bytes, not in characters. If the file is opened using some other encoding than latin1, one byte does not correspond to one character. Positioning in such a file can only be done to known character boundaries. That is, to a position earlier retrieved by getting a current position, to the beginning/end of the file or to some other position known to be on a correct character boundary by some other means (typically beyond a byte order mark in the file, which has a known byte-size).

A typical error reason is:

einval - Either Location is illegal, or it is evaluated to a negative offset in the file. Notice that if the resulting position is a negative value, the result is an error, and after the call the file position is undefined.

pread(IoDevice, LocNums)

-spec pread(IoDevice, LocNums) -> {ok, DataL} | eof | {error, Reason}
               when
                   IoDevice :: io_device(),
                   LocNums :: [{Location :: location(), Number :: non_neg_integer()}],
                   DataL :: [Data],
                   Data :: string() | binary() | eof,
                   Reason :: posix() | badarg | terminated.

Performs a sequence of pread/3 in one operation, which is more efficient than calling them one at a time. Returns {ok, [Data, ...]} or {error, Reason}, where each Data, the result of the corresponding pread, is either a list or a binary depending on the mode of the file, or eof if the requested position is beyond end of file.

As the position is specified as a byte-offset, take special caution when working with files where encoding is set to something else than latin1, as not every byte position is a valid character boundary on such a file.

pread(IoDevice, Location, Number)

-spec pread(IoDevice, Location, Number) -> {ok, Data} | eof | {error, Reason}
               when
                   IoDevice :: io_device(),
                   Location :: location(),
                   Number :: non_neg_integer(),
                   Data :: string() | binary(),
                   Reason :: posix() | badarg | terminated.

Combines position/2 and read/2 in one operation, which is more efficient than calling them one at a time.

Location is only allowed to be an integer for raw and ram modes.

The current position of the file after the operation is undefined for raw mode and unchanged for ram mode.

As the position is specified as a byte-offset, take special caution when working with files where encoding is set to something else than latin1, as not every byte position is a valid character boundary on such a file.

pwrite(IoDevice, LocBytes)

-spec pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}}
                when
                    IoDevice :: io_device(),
                    LocBytes :: [{Location :: location(), Bytes :: iodata()}],
                    N :: non_neg_integer(),
                    Reason :: posix() | badarg | terminated.

Performs a sequence of pwrite/3 in one operation, which is more efficient than calling them one at a time. Returns ok or {error, {N, Reason}}, where N is the number of successful writes done before the failure.

When positioning in a file with other encoding than latin1, caution must be taken to set the position on a correct character boundary. For details, see position/2.

pwrite(IoDevice, Location, Bytes)

-spec pwrite(IoDevice, Location, Bytes) -> ok | {error, Reason}
                when
                    IoDevice :: io_device(),
                    Location :: location(),
                    Bytes :: iodata(),
                    Reason :: posix() | badarg | terminated.

Combines position/2 and write/2 in one operation, which is more efficient than calling them one at a time.

Location is only allowed to be an integer for raw and ram modes.

The current position of the file after the operation is undefined for raw mode and unchanged for ram mode.

When positioning in a file with other encoding than latin1, caution must be taken to set the position on a correct character boundary. For details, see position/2.

read(IoDevice, Number)

-spec read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason}
              when
                  IoDevice :: io_device() | io:device(),
                  Number :: non_neg_integer(),
                  Data :: string() | binary(),
                  Reason :: posix() | badarg | terminated | {no_translation, unicode, latin1}.

Reads Number bytes/characters from the file referenced by IoDevice.

The functions read/2, pread/3, and read_line/1 are the only ways to read from a file opened in raw mode (although they work for normally opened files, too).

For files where encoding is set to something else than latin1, one character can be represented by more than one byte on the file. The parameter Number always denotes the number of characters read from the file, while the position in the file can be moved much more than this number when reading a Unicode file.

Also, if encoding is set to something else than latin1, the read/2 call fails if the data contains characters larger than 255, which is why io:get_chars/3 is to be preferred when reading such a file.

The function returns:

{ok, Data} - If the file was opened in binary mode, the read bytes are returned in a binary, otherwise in a list. The list or binary is shorter than the number of bytes requested if end of file was reached.

eof - Returned if Number>0 and end of file was reached before anything at all could be read.

{error, Reason} - An error occurred.

Typical error reasons:

ebadf - The file is not opened for reading.

{no_translation, unicode, latin1} - The file is opened with another encoding than latin1 and the data in the file cannot be translated to the byte-oriented data that this function returns.

read_file(Filename)

-spec read_file(Filename) -> {ok, Binary} | {error, Reason}
                   when
                       Filename :: name_all(),
                       Binary :: binary(),
                       Reason :: posix() | badarg | terminated | system_limit.

Equivalent to read_file(Filename, []).

read_file(Filename, Opts)

(since OTP 27.0)

-spec read_file(Filename, Opts) -> {ok, Binary} | {error, Reason}
                   when
                       Filename :: name_all(),
                       Opts :: [read_file_option()],
                       Binary :: binary(),
                       Reason :: posix() | badarg | terminated | system_limit.

Returns {ok, Binary}, where Binary is a binary data object that contains the contents of Filename, or {error, Reason} if an error occurs.

If the option raw is set, the file server is not called.

Typical error reasons:

enoent - The file does not exist.

eacces - Missing permission for reading the file, or for searching one of the parent directories.

eisdir - The named file is a directory.

enotdir - A component of the filename is not a directory. On some platforms, enoent is returned instead.

enomem - There is not enough memory for the contents of the file.

read_file_info(File)

-spec read_file_info(File) -> {ok, FileInfo} | {error, Reason}
                        when
                            File :: name_all() | io_device(),
                            FileInfo :: file_info(),
                            Reason :: posix() | badarg.

Equivalent to read_file_info(File, []).

read_file_info(File, Opts)

(since OTP R15B)

-spec read_file_info(File, Opts) -> {ok, FileInfo} | {error, Reason}
                        when
                            File :: name_all() | io_device(),
                            Opts :: [file_info_option()],
                            FileInfo :: file_info(),
                            Reason :: posix() | badarg.

Retrieves information about a file. Returns {ok, FileInfo} if successful, otherwise {error, Reason}.

FileInfo is a record file_info, defined in the Kernel include file file.hrl. Include the following directive in the module from which the function is called:

-include_lib("kernel/include/file.hrl").

The time type returned in atime, mtime, and ctime is dependent on the time type set in Opts :: {time, Type} as follows:

local - Returns local time.

universal - Returns universal time.

posix - Returns seconds since or before Unix time epoch, which is 1970-01-01 00:00 UTC.

Default is {time, local}.

If the option raw is set, the file server is not called and only information about local files is returned. Note that this will break this module's atomicity guarantees as it can race with a concurrent call to write_file_info/1,2 .

This option has no effect when the function is given an I/O device instead of a file name. Use open/2 with the raw mode to obtain a file descriptor first.

Note

As file times are stored in POSIX time on most OS, it is faster to query file information with option posix.

The record file_info contains the following fields:

size = non_neg_integer/0 - Size of file in bytes.

type = device | directory | other | regular - The type of the file. Can also contain symlink when returned from read_link_info/1,2.

access = read | write | read_write | none - The current system access to the file.

atime = date_time/0 | non_neg_integer/0 - The last time the file was read.

mtime = date_time/0 | non_neg_integer/0 - The last time the file was written.

ctime = date_time/0 | non_neg_integer/0 - The interpretation of this time field depends on the operating system. On Unix, it is the last time the file or the inode was changed. In Windows, it is the create time.

mode = non_neg_integer/0 - The file permissions as the sum of the following bit values:

8#00400 - read permission: owner

8#00200 - write permission: owner

8#00100 - execute permission: owner

8#00040 - read permission: group

8#00020 - write permission: group

8#00010 - execute permission: group

8#00004 - read permission: other

8#00002 - write permission: other

8#00001 - execute permission: other

16#800 - set user id on execution

16#400 - set group id on execution

On Unix platforms, other bits than those listed above may be set.

links = non_neg_integer/0 - Number of links to the file (this is always 1 for file systems that have no concept of links).

major_device = non_neg_integer/0 - Identifies the file system where the file is located. In Windows, the number indicates a drive as follows: 0 means A:, 1 means B:, and so on.

minor_device = non_neg_integer/0 - Only valid for character devices on Unix. In all other cases, this field is zero.

inode = non_neg_integer/0 - Gives the inode number. On non-Unix file systems, this field is zero.

uid = non_neg_integer/0 - Indicates the owner of the file. On non-Unix file systems, this field is zero.

gid = non_neg_integer/0 - Gives the group that the owner of the file belongs to. On non-Unix file systems, this field is zero.

Typical error reasons:

eacces - Missing search permission for one of the parent directories of the file.

enoent - The file does not exist.

enotdir - A component of the filename is not a directory. On some platforms, enoent is returned instead.

read_line(IoDevice)

-spec read_line(IoDevice) -> {ok, Data} | eof | {error, Reason}
                   when
                       IoDevice :: io_device() | io:device(),
                       Data :: string() | binary(),
                       Reason :: posix() | badarg | terminated | {no_translation, unicode, latin1}.

Reads a line of bytes/characters from the file referenced by IoDevice.

Lines are defined to be delimited by the linefeed (LF, \n) character, but any carriage return (CR, \r) followed by a newline is also treated as a single LF character (the carriage return is silently ignored). The line is returned including the LF, but excluding any CR immediately followed by an LF. This behaviour is consistent with the behaviour of io:get_line/2. If end of file is reached without any LF ending the last line, a line with no trailing LF is returned.

The function can be used on files opened in raw mode. However, it is inefficient to use it on raw files if the file is not opened with option {read_ahead, Size} specified. Thus, combining raw and {read_ahead, Size} is highly recommended when opening a text file for raw line-oriented reading.

If encoding is set to something else than latin1, the read_line/1 call fails if the data contains characters larger than 255, why io:get_line/2 is to be preferred when reading such a file.

The function returns:

{ok, Data} - One line from the file is returned, including the trailing LF, but with CRLF sequences replaced by a single LF (see above).

If the file is opened in binary mode, the read bytes are returned in a binary, otherwise in a list.

eof - Returned if end of file was reached before anything at all could be read.

{error, Reason} - An error occurred.

Typical error reasons:

ebadf - The file is not opened for reading.

{no_translation, unicode, latin1} - The file is opened with another encoding than latin1 and the data on the file cannot be translated to the byte-oriented data that this function returns.

read_link(Name)

-spec read_link(Name) -> {ok, Filename} | {error, Reason}
                   when Name :: name_all(), Filename :: filename(), Reason :: posix() | badarg.

Returns {ok, Filename} if Name refers to a symbolic link that is not a raw filename, or {error, Reason} otherwise. On platforms that do not support symbolic links, the return value is {error,enotsup}.

Typical error reasons:

einval - Name does not refer to a symbolic link or the name of the file that it refers to does not conform to the expected encoding.

enoent - The file does not exist.

enotsup - Symbolic links are not supported on this platform.

read_link_all(Name)

(since OTP R16B)

-spec read_link_all(Name) -> {ok, Filename} | {error, Reason}
                       when Name :: name_all(), Filename :: filename_all(), Reason :: posix() | badarg.

Returns {ok, Filename} if Name refers to a symbolic link or {error, Reason} otherwise. On platforms that do not support symbolic links, the return value is {error, enotsup}.

Notice that Filename can be either a list or a binary.

Typical error reasons:

einval - Name does not refer to a symbolic link.

enoent - The file does not exist.

enotsup - Symbolic links are not supported on this platform.

read_link_info(Name)

-spec read_link_info(Name) -> {ok, FileInfo} | {error, Reason}
                        when Name :: name_all(), FileInfo :: file_info(), Reason :: posix() | badarg.

Equivalent to read_link_info(Name, []).

read_link_info(Name, Opts)

(since OTP R15B)

-spec read_link_info(Name, Opts) -> {ok, FileInfo} | {error, Reason}
                        when
                            Name :: name_all(),
                            Opts :: [file_info_option()],
                            FileInfo :: file_info(),
                            Reason :: posix() | badarg.

Works like read_file_info/1,2 except that if Name is a symbolic link, information about the link is returned in the file_info record and the type field of the record is set to symlink.

If the option raw is set, the file server is not called and only information about local files is returned. Note that this will break this module's atomicity guarantees as it can race with a concurrent call to write_file_info/1,2

If Name is not a symbolic link, this function returns the same result as read_file_info/1. On platforms that do not support symbolic links, this function is always equivalent to read_file_info/1.

rename(Source, Destination)

-spec rename(Source, Destination) -> ok | {error, Reason}
                when Source :: name_all(), Destination :: name_all(), Reason :: posix() | badarg.

Tries to rename the file Source to Destination. It can be used to move files (and directories) between directories, but it is not sufficient to specify the destination only. The destination filename must also be specified. For example, if bar is a normal file and foo and baz are directories, rename("foo/bar", "baz") returns an error, but rename("foo/bar", "baz/bar") succeeds. Returns ok if it is successful.

Note

Renaming of open files is not allowed on most platforms (see eacces below).

Typical error reasons:

eacces - Missing read or write permissions for the parent directories of Source or Destination. On some platforms, this error is given if either Source or Destination is open.

eexist - Destination is not an empty directory. On some platforms, also given when Source and Destination are not of the same type.

einval - Source is a root directory, or Destination is a subdirectory of Source.

eisdir - Destination is a directory, but Source is not.

enoent - Source does not exist.

enotdir - Source is a directory, but Destination is not.

exdev - Source and Destination are on different file systems.

script(Filename)

-spec script(Filename) -> {ok, Value} | {error, Reason}
                when
                    Filename :: name_all(),
                    Value :: term(),
                    Reason ::
                        posix() |
                        badarg | terminated | system_limit |
                        {Line :: integer(), Mod :: module(), Term :: term()}.

Reads and evaluates Erlang expressions, separated by . (or ,, a sequence of expressions is also an expression), from the file.

Returns one of the following:

{ok, Value} - The file is read and evaluated. Value is the value of the last expression.

{error, atom()} - An error occurred when opening the file or reading it. For a list of typical error codes, see open/2.

{error, {Line, Mod, Term}} - An error occurred when interpreting the Erlang expressions in the file. Use format_error/1 to convert the three-element tuple to an English description of the error.

The encoding of Filename can be set by a comment as described in epp.

script(Filename, Bindings)

-spec script(Filename, Bindings) -> {ok, Value} | {error, Reason}
                when
                    Filename :: name_all(),
                    Bindings :: erl_eval:binding_struct(),
                    Value :: term(),
                    Reason ::
                        posix() |
                        badarg | terminated | system_limit |
                        {Line :: integer(), Mod :: module(), Term :: term()}.

The same as script/1 but the variable bindings Bindings are used in the evaluation. See erl_eval about variable bindings.

sendfile(Filename, Socket)

(since OTP R15B)

-spec sendfile(Filename, Socket) ->
                  {ok, non_neg_integer()} | {error, inet:posix() | closed | badarg | not_owner}
                  when
                      Filename :: name_all(),
                      Socket ::
                          inet:socket() |
                          socket:socket() |
                          fun((iolist()) -> ok | {error, inet:posix() | closed}).

Sends the file Filename to Socket. Returns {ok, BytesSent} if successful, otherwise {error, Reason}.

sendfile(RawFile, Socket, Offset, Bytes, Opts)

(since OTP R15B)

-spec sendfile(RawFile, Socket, Offset, Bytes, Opts) ->
                  {ok, non_neg_integer()} | {error, inet:posix() | closed | badarg | not_owner}
                  when
                      RawFile :: fd(),
                      Socket ::
                          inet:socket() |
                          socket:socket() |
                          fun((iolist()) -> ok | {error, inet:posix() | closed}),
                      Offset :: non_neg_integer(),
                      Bytes :: non_neg_integer(),
                      Opts :: [sendfile_option()].

Sends Bytes from the file referenced by RawFile beginning at Offset to Socket. Returns {ok, BytesSent} if successful, otherwise {error, Reason}. If Bytes is set to 0 all data after the specified Offset is sent.

The file used must be opened using the raw flag, and the process calling sendfile must be the controlling process of the socket. See gen_tcp:controlling_process/2 or module socket's level otp socket option controlling_process.

If the OS used does not support non-blocking sendfile, an Erlang fallback using read/2 and gen_tcp:send/2 is used.

The option list can contain the following options:

chunk_size - The chunk size used by the Erlang fallback to send data. If using the fallback, set this to a value that comfortably fits in the systems memory. Default is 20 MB.

set_cwd(Dir)

-spec set_cwd(Dir) -> ok | {error, Reason}
                 when
                     Dir :: name() | EncodedBinary,
                     EncodedBinary :: binary(),
                     Reason :: posix() | badarg | no_translation.

Sets the current working directory of the file server to Dir. Returns ok if successful.

The functions in the module file usually treat binaries as raw filenames, that is, they are passed "as is" even when the encoding of the binary does not agree with native_name_encoding(). However, this function expects binaries to be encoded according to the value returned by native_name_encoding/0.

Typical error reasons are:

enoent - The directory does not exist.

enotdir - A component of Dir is not a directory. On some platforms, enoent is returned.

eacces - Missing permission for the directory or one of its parents.

badarg - Dir has an improper type, such as tuple.

no_translation - Dir is a binary/0 with characters coded in ISO-latin-1 and the VM is operating with unicode filename encoding.

Warning

In a future release, a bad type for argument Dir will probably generate an exception.

sync(IoDevice)

-spec sync(IoDevice) -> ok | {error, Reason}
              when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.

Ensures that any buffers kept by the operating system (not by the Erlang runtime system) are written to disk. On some platforms, this function might have no effect.

A typical error reason is:

enospc - Not enough space left to write the file.

truncate(IoDevice)

-spec truncate(IoDevice) -> ok | {error, Reason}
                  when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.

Truncates the file referenced by IoDevice at the current position. Returns ok if successful, otherwise {error, Reason}.

write(IoDevice, Bytes)

-spec write(IoDevice, Bytes) -> ok | {error, Reason}
               when
                   IoDevice :: io_device() | io:device(),
                   Bytes :: iodata(),
                   Reason :: posix() | badarg | terminated.

Writes Bytes to the file referenced by IoDevice. This function is the only way to write to a file opened in raw mode (although it works for normally opened files too). Returns ok if successful, and {error, Reason} otherwise.

If the file is opened with encoding set to something else than latin1, each byte written can result in many bytes being written to the file, as the byte range 0..255 can represent anything between one and four bytes depending on value and UTF encoding type. If you want to write unicode:chardata/0 to the IoDevice you should use io:put_chars/2 instead.

Typical error reasons:

ebadf - The file is not opened for writing.

enospc - No space is left on the device.

write_file(Filename, Bytes)

-spec write_file(Filename, Bytes) -> ok | {error, Reason}
                    when
                        Filename :: name_all(),
                        Bytes :: iodata(),
                        Reason :: posix() | badarg | terminated | system_limit.

Writes the contents of the iodata term Bytes to file Filename. The file is created if it does not exist. If it exists, the previous contents are overwritten. Returns ok if successful, otherwise {error, Reason}.

Typical error reasons:

enoent - A component of the filename does not exist.

enotdir - A component of the filename is not a directory. On some platforms, enoent is returned instead.

enospc - No space is left on the device.

eacces - Missing permission for writing the file or searching one of the parent directories.

eisdir - The named file is a directory.

write_file(Filename, Bytes, Modes)

-spec write_file(Filename, Bytes, Modes) -> ok | {error, Reason}
                    when
                        Filename :: name_all(),
                        Bytes :: iodata(),
                        Modes :: [mode()],
                        Reason :: posix() | badarg | terminated | system_limit.

Same as write_file/2, but takes a third argument Modes, a list of possible modes, see open/2. The mode flags binary and write are implicit, so they are not to be used.

write_file_info(Filename, FileInfo)

-spec write_file_info(Filename, FileInfo) -> ok | {error, Reason}
                         when
                             Filename :: name_all(), FileInfo :: file_info(), Reason :: posix() | badarg.

Equivalent to write_file_info(Filename, FileInfo, []).

write_file_info(Filename, FileInfo, Opts)

(since OTP R15B)

-spec write_file_info(Filename, FileInfo, Opts) -> ok | {error, Reason}
                         when
                             Filename :: name_all(),
                             Opts :: [file_info_option()],
                             FileInfo :: file_info(),
                             Reason :: posix() | badarg.

Changes file information. Returns ok if successful, otherwise {error, Reason}.

FileInfo is a record file_info, defined in the Kernel include file file.hrl. Include the following directive in the module from which the function is called:

-include_lib("kernel/include/file.hrl").

The time type set in atime, mtime, and ctime depends on the time type set in Opts :: {time, Type} as follows:

local - Interprets the time set as local.

universal - Interprets it as universal time.

posix - Must be seconds since or before Unix time epoch, which is 1970-01-01 00:00 UTC.

Default is {time, local}.

If the option raw is set, the file server is not called and only information about local files is returned.

The following fields are used from the record, if they are specified:

atime = date_time/0 | non_neg_integer/0 - The last time the file was read.

mtime = date_time/0 | non_neg_integer/0 - The last time the file was written.

ctime = date_time/0 | non_neg_integer/0 - On Unix, any value specified for this field is ignored (the "ctime" for the file is set to the current time). On Windows, this field is the new creation time to set for the file.

mode = non_neg_integer/0 - The file permissions as the sum of the following bit values:

8#00400 - Read permission: owner

8#00200 - Write permission: owner

8#00100 - Execute permission: owner

8#00040 - Read permission: group

8#00020 - Write permission: group

8#00010 - Execute permission: group

8#00004 - Read permission: other

8#00002 - Write permission: other

8#00001 - Execute permission: other

16#800 - Set user id on execution

16#400 - Set group id on execution

On Unix platforms, other bits than those listed above may be set.

uid = non_neg_integer/0 - Indicates the file owner. Ignored for non-Unix file systems.

gid = non_neg_integer/0 - Gives the group that the file owner belongs to. Ignored for non-Unix file systems.

Typical error reasons:

eacces - Missing search permission for one of the parent directories of the file.

enoent - The file does not exist.

enotdir - A component of the filename is not a directory. On some platforms, enoent is returned instead.

heart

Heartbeat monitoring of an Erlang runtime system.

This modules contains the interface to the heart process. heart sends periodic heartbeats to an external port program, which is also named heart. The purpose of the heart port program is to check that the Erlang runtime system it is supervising is still running. If the port program has not received any heartbeats within HEART_BEAT_TIMEOUT seconds (defaults to 60 seconds), the system can be rebooted.

An Erlang runtime system to be monitored by a heart program is to be started with command-line flag -heart (see also erl(1)). The heart process is then started automatically:

% erl -heart ...

If the system is to be rebooted because of missing heartbeats, or a terminated Erlang runtime system, environment variable HEART_COMMAND must be set before the system is started. If this variable is not set, a warning text is printed but the system does not reboot.

To reboot on Windows, HEART_COMMAND can be set to heart -shutdown (included in the Erlang delivery) or to any other suitable program that can activate a reboot.

The environment variable HEART_BEAT_TIMEOUT can be used to configure the heart time-outs; it can be set in the operating system shell before Erlang is started or be specified at the command line:

% erl -heart -env HEART_BEAT_TIMEOUT 30 ...

The value (in seconds) must be in the range 10 < X <= 65535.

When running on OSs lacking support for monotonic time, heart is susceptible to system clock adjustments of more than HEART_BEAT_TIMEOUT seconds. When this happens, heart times out and tries to reboot the system. This can occur, for example, if the system clock is adjusted automatically by use of the Network Time Protocol (NTP).

If a crash occurs, an erl_crash.dump is not written unless environment variable ERL_CRASH_DUMP_SECONDS is set:

% erl -heart -env ERL_CRASH_DUMP_SECONDS 10 ...

If a regular core dump is wanted, let heart know by setting the kill signal to abort using environment variable HEART_KILL_SIGNAL=SIGABRT. If unset, or not set to SIGABRT, the default behavior is a kill signal using SIGKILL:

% erl -heart -env HEART_KILL_SIGNAL SIGABRT ...

If heart should not kill the Erlang runtime system, this can be indicated using the environment variable HEART_NO_KILL=TRUE. This can be useful if the command executed by heart takes care of this, for example as part of a specific cleanup sequence. If unset, or not set to TRUE, the default behaviour will be to kill as described above.

% erl -heart -env HEART_NO_KILL 1 ...

Furthermore, ERL_CRASH_DUMP_SECONDS has the following behavior on heart:

ERL_CRASH_DUMP_SECONDS=0 - Suppresses the writing of a crash dump file entirely, thus rebooting the runtime system immediately. This is the same as not setting the environment variable.

ERL_CRASH_DUMP_SECONDS=-1 - Setting the environment variable to a negative value does not reboot the runtime system until the crash dump file is completely written.

ERL_CRASH_DUMP_SECONDS=S - heart waits for S seconds to let the crash dump file be written. After S seconds, heart reboots the runtime system, whether the crash dump file is written or not.

In the following descriptions, all functions fail with reason badarg if heart is not started.

Summary

Types

heart_option()

Functions

clear_callback()

Removes the validation callback call before heartbeats.

clear_cmd()

Clears the temporary boot command. If the system terminates, the normal HEART_COMMAND is used to reboot.

get_callback()

Get the validation callback. If the callback is cleared, none will be returned.

get_cmd()

Gets the temporary reboot command. If the command is cleared, the empty string is returned.

get_options()

Returns {ok, Options} where Options is a list of current options enabled for heart. If the callback is cleared, none will be returned.

set_callback(Module, Function)

This validation callback will be executed before any heartbeat is sent to the port program. For the validation to succeed it needs to return with the value ok.

set_cmd(Cmd)

Sets a temporary reboot command. This command is used if a HEART_COMMAND other than the one specified with the environment variable is to be used to reboot the system. The new Erlang runtime system uses (if it misbehaves) environment variable HEART_COMMAND to reboot.

set_options(Options)

Valid options set_options are

Types

heart_option()

(not exported)

-type heart_option() :: check_schedulers.

Functions

clear_callback()

(since OTP 18.3)

-spec clear_callback() -> ok.

Removes the validation callback call before heartbeats.

clear_cmd()

-spec clear_cmd() -> ok.

Clears the temporary boot command. If the system terminates, the normal HEART_COMMAND is used to reboot.

get_callback()

(since OTP 18.3)

-spec get_callback() -> {ok, {Module, Function}} | none when Module :: atom(), Function :: atom().

Get the validation callback. If the callback is cleared, none will be returned.

get_cmd()

-spec get_cmd() -> {ok, Cmd} when Cmd :: string().

Gets the temporary reboot command. If the command is cleared, the empty string is returned.

get_options()

(since OTP 18.3)

-spec get_options() -> {ok, Options} | none when Options :: [atom()].

Returns {ok, Options} where Options is a list of current options enabled for heart. If the callback is cleared, none will be returned.

set_callback(Module, Function)

(since OTP 18.3)

-spec set_callback(Module, Function) -> ok | {error, {bad_callback, {Module, Function}}}
                      when Module :: atom(), Function :: atom().

This validation callback will be executed before any heartbeat is sent to the port program. For the validation to succeed it needs to return with the value ok.

An exception within the callback will be treated as a validation failure.

The callback will be removed if the system reboots.

set_cmd(Cmd)

-spec set_cmd(Cmd) -> ok | {error, {bad_cmd, Cmd}} when Cmd :: string().

Sets a temporary reboot command. This command is used if a HEART_COMMAND other than the one specified with the environment variable is to be used to reboot the system. The new Erlang runtime system uses (if it misbehaves) environment variable HEART_COMMAND to reboot.

Limitations: Command string Cmd is sent to the heart program as an ISO Latin-1 or UTF-8 encoded binary, depending on the filename encoding mode of the emulator (see file:native_name_encoding/0). The size of the encoded binary must be less than 2047 bytes.

set_options(Options)

(since OTP 18.3)

-spec set_options(Options) -> ok | {error, {bad_options, Options}} when Options :: [heart_option()].

Valid options set_options are:

check_schedulers - If enabled, a signal will be sent to each scheduler to check its responsiveness. The system check occurs before any heartbeat sent to the port program. If any scheduler is not responsive enough the heart program will not receive its heartbeat and thus eventually terminate the node.

Returns with the value ok if the options are valid.

os

Operating system-specific functions.

The functions in this module are operating system-specific. Careless use of these functions results in programs that will only run on a specific platform. On the other hand, with careful use, these functions can be of help in enabling a program to run on most platforms.

Note

The functions in this module will raise a badarg exception if their arguments contain invalid characters according to the description in the "Data Types" section.

Summary

Types

env_var_name()

A string containing valid characters on the specific OS for environment variable names using file:native_name_encoding() encoding.

env_var_name_value()

Assuming that environment variables has been correctly set, a strings containing valid characters on the specific OS for environment variable names and values using file:native_name_encoding() encoding.

env_var_value()

A string containing valid characters on the specific OS for environment variable values using file:native_name_encoding() encoding.

os_command()

All characters needs to be valid characters on the specific OS using file:native_name_encoding() encoding. Null characters (integer value zero) are not allowed.

os_command_opts()

Options for os:cmd/2.

Functions

cmd(Command)

Equivalent to cmd(Command, #{}).

cmd(Command, Options)

Executes Command in a command shell of the target OS, captures the standard output and standard error of the command, and returns this result as a string.

env()

Returns a list of all environment variables. Each environment variable is expressed as a tuple {VarName,Value}, where VarName is the name of the variable and Value its value.

find_executable(Name)

Equivalent to find_executable(Name, Path) where Path is the current execution path (that is, the environment variable PATH on Unix and Windows).

find_executable(Name, Path)

Look up an executable program, with the specified name and a search path, in the same way as the underlying OS.

getenv()

Returns a list of all environment variables. Each environment variable is expressed as a single string on the format "VarName=Value", where VarName is the name of the variable and Value its value.

getenv(VarName)

Returns the Value of the environment variable VarName, or false if the environment variable is undefined.

getenv(VarName, DefaultValue)

Returns the Value of the environment variable VarName, or DefaultValue if the environment variable is undefined.

getpid()

Returns the process identifier of the current Erlang emulator in the format most commonly used by the OS environment.

perf_counter()

Returns the current performance counter value in perf_counter time unit. This is a highly optimized call that might not be traceable.

perf_counter(Unit)

Returns a performance counter that can be used as a very fast and high resolution timestamp.

putenv(VarName, Value)

Sets a new Value for environment variable VarName.

set_signal(Signal, Option)

Enables or disables OS signals.

system_time()

Returns the current OS system time in native time unit.

system_time(Unit)

Returns the current OS system time converted into the Unit passed as argument.

timestamp()

Returns the current OS system time in the same format as erlang:timestamp/0.

type()

Returns the Osfamily and, in some cases, the Osname of the current OS.

unsetenv(VarName)

Deletes the environment variable VarName.

version()

Returns the OS version. On most systems, this function returns a tuple, but a string is returned instead if the system has versions that cannot be expressed as three numbers.

Types

env_var_name()

-type env_var_name() :: nonempty_string().

A string containing valid characters on the specific OS for environment variable names using file:native_name_encoding() encoding.

Null characters (integer value zero) are not allowed. On Unix, = characters are not allowed. On Windows, a = character is only allowed as the very first character in the string.

env_var_name_value()

-type env_var_name_value() :: nonempty_string().

Assuming that environment variables has been correctly set, a strings containing valid characters on the specific OS for environment variable names and values using file:native_name_encoding() encoding.

The first = characters appearing in the string separates environment variable name (on the left) from environment variable value (on the right).

env_var_value()

-type env_var_value() :: string().

A string containing valid characters on the specific OS for environment variable values using file:native_name_encoding() encoding.

Null characters (integer value zero) are not allowed.

os_command()

-type os_command() :: atom() | io_lib:chars().

All characters needs to be valid characters on the specific OS using file:native_name_encoding() encoding. Null characters (integer value zero) are not allowed.

os_command_opts()

-type os_command_opts() ::
          #{max_size => non_neg_integer() | infinity, exception_on_failure => boolean()}.

Options for os:cmd/2.

max_size - The maximum size of the data returned by the os:cmd/2 call. See the os:cmd/2 documentation for more details.

Since OTP 20.2.3

exception_on_failure - If set to true, cmd/2 will throw an error exception if the command exits with a non-zero exit code.

Since OTP 28.0

Functions

cmd(Command)

-spec cmd(Command) -> string() when Command :: os_command().

Equivalent to cmd(Command, #{}).

cmd(Command, Options)

(since OTP 20.2.3)

-spec cmd(Command, Options) -> string() when Command :: os_command(), Options :: os_command_opts().

Executes Command in a command shell of the target OS, captures the standard output and standard error of the command, and returns this result as a string.

Examples:

LsOut = os:cmd("ls"), % on unix platform
DirOut = os:cmd("dir"), % on Win32 platform

Notice that in some cases, standard output of a command when called from another program can differ, compared with the standard output of the command when called directly from an OS command shell.

The possible options are:

max_size - The maximum size of the data returned by the os:cmd/2 call. This option is a safety feature that should be used when the command executed can return a very large, possibly infinite, result.

Example:

> os:cmd("cat /dev/zero", #{ max_size => 20 }).
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

Since OTP 20.2.3

exception_on_failure - If set to true, os:cmd/2 will throw an error exception if the command exits with a non-zero exit code. The exception reason looks like this: {command_failed, ResultBeforeFailure, ExitCode} where ResultBeforeFailure is the result written to stdout by the command before the error happened and ExitCode is the exit code from the command.

Example:

> catch os:cmd("echo hello && exit 123", #{ exception_on_failure => true }).
{'EXIT',{{command_failed,"hello\n",123},
         [{os,cmd,2,[{file,"os.erl"},{line,579}]},
...

Since OTP 28.0

The command shell can be set using the kernel configuration parameter, by default the shell is detected upon system startup.

env()

(since OTP 24.0)

-spec env() -> [{env_var_name(), env_var_value()}].

Returns a list of all environment variables. Each environment variable is expressed as a tuple {VarName,Value}, where VarName is the name of the variable and Value its value.

If Unicode filename encoding is in effect (see the erl manual page), the strings can contain characters with codepoints > 255.

find_executable(Name)

-spec find_executable(Name) -> Filename | false when Name :: string(), Filename :: string().

Equivalent to find_executable(Name, Path) where Path is the current execution path (that is, the environment variable PATH on Unix and Windows).

find_executable(Name, Path)

-spec find_executable(Name, Path) -> Filename | false
                         when Name :: string(), Path :: string(), Filename :: string().

Look up an executable program, with the specified name and a search path, in the same way as the underlying OS.

Path is to conform to the syntax of execution paths on the OS. Returns the absolute filename of the executable program Name, or false if the program is not found.

getenv()

-spec getenv() -> [env_var_name_value()].

Returns a list of all environment variables. Each environment variable is expressed as a single string on the format "VarName=Value", where VarName is the name of the variable and Value its value.

If Unicode filename encoding is in effect (see the erl manual page), the strings can contain characters with codepoints > 255.

Consider using env/0 for a nicer 2-tuple format.

getenv(VarName)

-spec getenv(VarName) -> Value | false when VarName :: env_var_name(), Value :: env_var_value().

Returns the Value of the environment variable VarName, or false if the environment variable is undefined.

If Unicode filename encoding is in effect (see the erl manual page), the strings VarName and Value can contain characters with codepoints > 255.

getenv(VarName, DefaultValue)

(since OTP 18.0)

-spec getenv(VarName, DefaultValue) -> Value
                when
                    VarName :: env_var_name(), DefaultValue :: env_var_value(), Value :: env_var_value().

Returns the Value of the environment variable VarName, or DefaultValue if the environment variable is undefined.

If Unicode filename encoding is in effect (see the erl manual page), the strings VarName and Value can contain characters with codepoints > 255.

getpid()

-spec getpid() -> Value when Value :: string().

Returns the process identifier of the current Erlang emulator in the format most commonly used by the OS environment.

Returns Value as a string containing the (usually) numerical identifier for a process.

On Unix, this is typically the return value of the getpid/0 system call.

On Windows, the process id as returned by the GetCurrentProcessId() system call is used.

perf_counter()

(since OTP 19.0)

-spec perf_counter() -> Counter when Counter :: integer().

Returns the current performance counter value in perf_counter time unit. This is a highly optimized call that might not be traceable.

perf_counter(Unit)

(since OTP 19.0)

-spec perf_counter(Unit) -> integer() when Unit :: erlang:time_unit().

Returns a performance counter that can be used as a very fast and high resolution timestamp.

This counter is read directly from the hardware or operating system with the same guarantees. This means that two consecutive calls to the function are not guaranteed to be monotonic, though it most likely will be. The performance counter will be converted to the resolution passed as an argument.

1> T1 = os:perf_counter(1000),receive after 10000 -> ok end,T2 = os:perf_counter(1000).
176525861
2> T2 - T1.
10004

putenv(VarName, Value)

-spec putenv(VarName, Value) -> true when VarName :: env_var_name(), Value :: env_var_value().

Sets a new Value for environment variable VarName.

If Unicode filename encoding is in effect (see the erl manual page), the strings VarName and Value can contain characters with codepoints > 255.

On Unix platforms, the environment is set using UTF-8 encoding if Unicode filename translation is in effect. On Windows, the environment is set using wide character interfaces.

set_signal(Signal, Option)

(since OTP 20.0)

-spec set_signal(Signal, Option) -> ok
                    when
                        Signal ::
                            sighup | sigquit | sigabrt | sigalrm | sigterm | sigusr1 | sigusr2 |
                            sigchld | sigstop | sigtstp | sigcont | sigwinch | siginfo,
                        Option :: default | handle | ignore.

Enables or disables OS signals.

Each signal my be set to one of the following options:

ignore - This signal will be ignored.

default - This signal will use the default signal handler for the operating system.

handle - This signal will notify erl_signal_server when it is received by the Erlang runtime system.

system_time()

(since OTP 18.0)

-spec system_time() -> integer().

Returns the current OS system time in native time unit.

Note

This time is not a monotonically increasing time.

system_time(Unit)

(since OTP 18.0)

-spec system_time(Unit) -> integer() when Unit :: erlang:time_unit().

Returns the current OS system time converted into the Unit passed as argument.

Calling os:system_time(Unit) is equivalent to erlang:convert_time_unit(os:system_time(), native, Unit).

Note

This time is not a monotonically increasing time.

timestamp()

-spec timestamp() -> Timestamp when Timestamp :: erlang:timestamp().

Returns the current OS system time in the same format as erlang:timestamp/0.

The tuple can be used together with function calendar:now_to_universal_time/1 or calendar:now_to_local_time/1 to get calendar time. Using the calendar time, together with the MicroSecs part of the return tuple from this function, allows you to log time stamps in high resolution and consistent with the time in the rest of the OS.

Example of code formatting a string in format "DD Mon YYYY HH:MM:SS.mmmmmm", where DD is the day of month, Mon is the textual month name, YYYY is the year, HH:MM:SS is the time, and mmmmmm is the microseconds in six positions:

-module(print_time).
-export([format_utc_timestamp/0]).
format_utc_timestamp() ->
    TS = {_,_,Micro} = os:timestamp(),
    {{Year,Month,Day},{Hour,Minute,Second}} =
calendar:now_to_universal_time(TS),
    Mstr = element(Month,{"Jan","Feb","Mar","Apr","May","Jun","Jul",
    "Aug","Sep","Oct","Nov","Dec"}),
    io_lib:format("~2w ~s ~4w ~2w:~2..0w:~2..0w.~6..0w",
    [Day,Mstr,Year,Hour,Minute,Second,Micro]).

This module can be used as follows:

1> io:format("~s~n",[print_time:format_utc_timestamp()]).
29 Apr 2009  9:55:30.051711

OS system time can also be retrieved by system_time/0 and system_time/1.

type()

-spec type() -> {Osfamily, Osname} when Osfamily :: unix | win32, Osname :: atom().

Returns the Osfamily and, in some cases, the Osname of the current OS.

On Unix, Osname has the same value as uname -s returns, but in lower case. For example, on Solaris 1 and 2, it is sunos.

On Windows, Osname is nt.

Note

Think twice before using this function. Use module filename if you want to inspect or build filenames in a portable way. Avoid matching on atom Osname.

unsetenv(VarName)

(since OTP R16B03)

-spec unsetenv(VarName) -> true when VarName :: env_var_name().

Deletes the environment variable VarName.

If Unicode filename encoding is in effect (see the erl manual page), the string VarName can contain characters with codepoints > 255.

version()

-spec version() -> VersionString | {Major, Minor, Release}
                 when
                     VersionString :: string(),
                     Major :: non_neg_integer(),
                     Minor :: non_neg_integer(),
                     Release :: non_neg_integer().

Returns the OS version. On most systems, this function returns a tuple, but a string is returned instead if the system has versions that cannot be expressed as three numbers.

Note

Think twice before using this function. If you still need to use it, always call os:type() first.

gen_sctp

Interface to SCTP sockets.

This module provides functions for communicating over SCTP sockets. The implementation assumes that the OS kernel supports SCTP (RFC 2960) through the user-level Sockets API Extensions.

During development, this implementation was tested on:

Linux Fedora Core 5.0 (kernel 2.6.15-2054 or later is needed)

Solaris 10, 11

During OTP adaptation it was tested on:

SUSE Linux Enterprise Server 10 (x86_64) kernel 2.6.16.27-0.6-smp, with lksctp-tools-1.0.6

Briefly on Solaris 10

SUSE Linux Enterprise Server 10 Service Pack 1 (x86_64) kernel 2.6.16.54-0.2.3-smp with lksctp-tools-1.0.7

FreeBSD 8.2

This module was written for one-to-many style sockets (type seqpacket). With the addition of peeloff/2, one-to-one style sockets (type stream) were introduced.

Record definitions for this module can be found using:

-include_lib("kernel/include/inet_sctp.hrl").

These record definitions use the "new" spelling 'adaptation', not the deprecated 'adaption', regardless of which spelling the underlying C API uses.

SCTP Socket Options

The set of admissible SCTP socket options is by construction orthogonal to the sets of TCP, UDP, and generic inet options. Here are only options listed that are allowed for SCTP sockets.

Options can be set on the socket when calling open/1,2, and changed when calling connect/4,5 or by calling inet:setopts/2. They can be retrieved using inet:getopts/2.

{mode, list|binary} | list | binary - Determines the type of data returned from recv/1,2 or in active mode data messages.

{active, false|true|once|N}

If false (passive mode, the default), the caller must do an explicit recv call to retrieve the available data from the socket.

If true|once|N (active modes) received data or events are sent to the owning process. See open/0..2 for the message format.

If true (fully active mode) there is no flow control.

Note

Note that this can cause the message queue to overflow causing for example the virtual machine to run out of memory and crash.

If once, only one message is automatically placed in the message queue, and the mode resets to passive. This provides flow control and the possibility for the receiver to listen for incoming SCTP data interleaved with other inter-process messages.

If active is specified as an integer N in the range -32768 to 32767 (inclusive), that number is added to the socket's data messages counter. If the result of the addition is negative, the counter is set to 0. Once the counter reaches 0, either through the delivery of messages or by being explicitly set with inet:setopts/2, the socket mode resets to passive ({active, false}). When a socket in {active, N} mode transitions to passive mode, the message {sctp_passive, Socket} is sent to the controlling process to notify that if it wants to receive more data messages from the socket, it must call inet:setopts/2 to set the socket back into an active mode.

{tos, integer()} - Sets the Type-Of-Service field on the IP datagrams that are sent, to the specified value. This effectively determines a prioritization policy for the outbound packets. The acceptable values are system-dependent.

{priority, integer()} - A protocol-independent equivalent of tos above. Setting priority implies setting tos as well.

{dontroute, true|false} - Defaults to false. If true, the kernel does not send packets through any gateway, but only sends them to directly connected hosts.

{reuseaddr, true|false} - Defaults to false. If true, the local binding address {IP,Port} of the socket can be reused immediately. No waiting in state CLOSE_WAIT is performed (can be required for some types of servers).

{sndbuf, integer()} - The size, in bytes, of the OS kernel send buffer for this socket. Sending errors would occur for datagrams larger than val(sndbuf). Setting this option also adjusts the size of the driver buffer (see buffer above).

{recbuf, integer()} - The size, in bytes, of the OS kernel receive buffer for this socket. Sending errors would occur for datagrams larger than val(recbuf). Setting this option also adjusts the size of the driver buffer (see buffer above).

{non_block_send, boolean()} - A send call that would otherwise block (hang), will instead immediately return with e.g. {error, eagain} if this option has been set to true. Defaults to false.

{sctp_module, module()} - Overrides which callback module is used. Defaults to inet_sctp for IPv4 and inet6_sctp for IPv6.

{sctp_rtoinfo, #sctp_rtoinfo{}}

#sctp_rtoinfo{
      assoc_id = assoc_id(),
      initial  = integer(),
      max      = integer(),
      min      = integer()
}

Determines retransmission time-out parameters, in milliseconds, for the association(s) specified by assoc_id.

assoc_id = 0 (default) indicates the whole endpoint. See RFC 2960 and Sockets API Extensions for SCTP for the exact semantics of the field values.

{sctp_associnfo, #sctp_assocparams{}}

#sctp_assocparams{
      assoc_id                 = assoc_id(),
      asocmaxrxt               = integer(),
      number_peer_destinations = integer(),
      peer_rwnd                = integer(),
      local_rwnd               = integer(),
      cookie_life              = integer()
}

Determines association parameters for the association(s) specified by assoc_id.

assoc_id = 0 (default) indicates the whole endpoint. See Sockets API Extensions for SCTP for the discussion of their semantics. Rarely used.

{sctp_initmsg, #sctp_initmsg{}}

#sctp_initmsg{
     num_ostreams   = integer(),
     max_instreams  = integer(),
     max_attempts   = integer(),
     max_init_timeo = integer()
}

Determines the default parameters that this socket tries to negotiate with its peer while establishing an association with it. Is to be set after open/* but before the first connect/*. #sctp_initmsg{} can also be used as ancillary data with the first call of send/* to a new peer (when a new association is created).

num_ostreams - Number of outbound streams

max_instreams - Maximum number of inbound streams

max_attempts - Maximum retransmissions while establishing an association

max_init_timeo - Time-out, in milliseconds, for establishing an association

{sctp_autoclose, integer() >= 0} - Determines the time, in seconds, after which an idle association is automatically closed. 0 means that the association is never automatically closed.

{sctp_nodelay, true|false} - Turns off (true) / on (false) the Nagle algorithm for merging small packets into larger ones. This improves throughput at the expense of latency.

{sctp_disable_fragments, true|false} - If true, induces an error on an attempt to send a message larger than the current PMTU size (which would require fragmentation/reassembling). Notice that message fragmentation does not affect the logical atomicity of its delivery; this option is provided for performance reasons only.

{sctp_i_want_mapped_v4_addr, true|false} - Turns on|off automatic mapping of IPv4 addresses into IPv6 ones (if the socket address family is AF_INET6).

{sctp_maxseg, integer()} - Determines the maximum chunk size if message fragmentation is used. If 0, the chunk size is limited by the Path MTU only.

{sctp_primary_addr, #sctp_prim{}}

#sctp_prim{
      assoc_id = assoc_id(),
      addr     = {IP, Port}
}
 IP = ip_address()
 Port = port_number()

For the association specified by assoc_id, {IP,Port} must be one of the peer addresses. This option determines that the specified address is treated by the local SCTP stack as the primary address of the peer.

{sctp_set_peer_primary_addr, #sctp_setpeerprim{}}

#sctp_setpeerprim{
      assoc_id = assoc_id(),
      addr     = {IP, Port}
}
 IP = ip_address()
 Port = port_number()

When set, informs the peer to use {IP, Port} as the primary address of the local endpoint for the association specified by assoc_id.

{sctp_adaptation_layer, #sctp_setadaptation{}}

#sctp_setadaptation{
      adaptation_ind = integer()
}

When set, requests that the local endpoint uses the value specified by adaptation_ind as the Adaptation Indication parameter for establishing new associations. For details, see RFC 2960 and Sockets API Extensions for SCTP.

{sctp_peer_addr_params, #sctp_paddrparams{}}

#sctp_paddrparams{
      assoc_id   = assoc_id(),
      address    = {IP, Port},
      hbinterval = integer(),
      pathmaxrxt = integer(),
      pathmtu    = integer(),
      sackdelay  = integer(),
      flags      = list()
}
IP = ip_address()
Port = port_number()

Determines various per-address parameters for the association specified by assoc_id and the peer address address (the SCTP protocol supports multi-homing, so more than one address can correspond to a specified association).

hbinterval - Heartbeat interval, in milliseconds

pathmaxrxt - Maximum number of retransmissions before this address is considered unreachable (and an alternative address is selected)

pathmtu - Fixed Path MTU, if automatic discovery is disabled (see flags below)

sackdelay - Delay, in milliseconds, for SAC messages (if the delay is enabled, see flags below)

flags - The following flags are available:

hb_enable - Enables heartbeat

hb_disable - Disables heartbeat

hb_demand - Initiates heartbeat immediately

pmtud_enable - Enables automatic Path MTU discovery

pmtud_disable - Disables automatic Path MTU discovery

sackdelay_enable - Enables SAC delay

sackdelay_disable - Disables SAC delay

{sctp_default_send_param, #sctp_sndrcvinfo{}}

#sctp_sndrcvinfo{
      stream     = integer(),
      ssn        = integer(),
      flags      = list(),
      ppid       = integer(),
      context    = integer(),
      timetolive = integer(),
      tsn        = integer(),
      cumtsn     = integer(),
      assoc_id   = assoc_id()
}

#sctp_sndrcvinfo{} is used both in this socket option, and as ancillary data while sending or receiving SCTP messages. When set as an option, it provides default values for subsequent send calls on the association specified by assoc_id.

assoc_id = 0 (default) indicates the whole endpoint.

The following fields typically must be specified by the sender:

sinfo_stream - Stream number (0-base) within the association to send the messages through;

sinfo_flags - The following flags are recognised:

unordered - The message is to be sent unordered

addr_over - The address specified in send overwrites the primary peer address

abort - Aborts the current association without flushing any unsent data

eof - Gracefully shuts down the current association, with flushing of unsent data

Other fields are rarely used. For complete information, see RFC 2960 and Sockets API Extensions for SCTP.

{sctp_events, #sctp_event_subscribe{}}

#sctp_event_subscribe{
        data_io_event          = true | false,
        association_event      = true | false,
        address_event          = true | false,
        send_failure_event     = true | false,
        peer_error_event       = true | false,
        shutdown_event         = true | false,
        partial_delivery_event = true | false,
        adaptation_layer_event = true | false
}

This option determines which SCTP Events that are to be received (through recv/*) along with the data. The only exception is data_io_event, which enables or disables receiving of #sctp_sndrcvinfo{} ancillary data, not events. By default, all flags except adaptation_layer_event are enabled, although sctp_data_io_event and association_event are used by the driver itself and not exported to the user level.

{sctp_delayed_ack_time, #sctp_assoc_value{}}

#sctp_assoc_value{
      assoc_id    = assoc_id(),
      assoc_value = integer()
}

Rarely used. Determines the ACK time (specified by assoc_value, in milliseconds) for the specified association or the whole endpoint if assoc_value = 0 (default).

{sctp_status, #sctp_status{}}

#sctp_status{
      assoc_id            = assoc_id(),
      state               = atom(),
      rwnd                = integer(),
      unackdata           = integer(),
      penddata            = integer(),
      instrms             = integer(),
      outstrms            = integer(),
      fragmentation_point = integer(),
      primary             = #sctp_paddrinfo{}
}

This option is read-only. It determines the status of the SCTP association specified by assoc_id. The following are the possible values of state (the state designations are mostly self-explanatory):

sctp_state_empty - Default. Means that no other state is active.

sctp_state_closed

sctp_state_cookie_wait

sctp_state_cookie_echoed

sctp_state_established

sctp_state_shutdown_pending

sctp_state_shutdown_sent

sctp_state_shutdown_received

sctp_state_shutdown_ack_sent

Semantics of the other fields:

sstat_rwnd - Current receiver window size of the association

sstat_unackdata - Number of unacked data chunks

sstat_penddata - Number of data chunks pending receipt

sstat_instrms - Number of inbound streams

sstat_outstrms - Number of outbound streams

sstat_fragmentation_point - Message size at which SCTP fragmentation occurs

sstat_primary - Information on the current primary peer address (see below for the format of #sctp_paddrinfo{})

{sctp_get_peer_addr_info, #sctp_paddrinfo{}}

#sctp_paddrinfo{
      assoc_id  = assoc_id(),
      address   = {IP, Port},
      state     = inactive | active | unconfirmed,
      cwnd      = integer(),
      srtt      = integer(),
      rto       = integer(),
      mtu       = integer()
}
IP = ip_address()
Port = port_number()

This option is read-only. It determines the parameters specific to the peer address specified by address within the association specified by assoc_id. Field address fmust be set by the caller; all other fields are filled in on return. If assoc_id = 0 (default), the address is automatically translated into the corresponding association ID. This option is rarely used. For the semantics of all fields, see RFC 2960 and Sockets API Extensions for SCTP.

SCTP Examples

Example of an Erlang SCTP server that receives SCTP messages and prints them on the standard output:

-module(sctp_server).

-export([server/0,server/1,server/2]).
-include_lib("kernel/include/inet.hrl").
-include_lib("kernel/include/inet_sctp.hrl").

server() ->
    server(any, 2006).

server([Host,Port]) when is_list(Host), is_list(Port) ->
    {ok, #hostent{h_addr_list = [IP|_]}} = inet:gethostbyname(Host),
    io:format("~w -> ~w~n", [Host, IP]),
    server([IP, list_to_integer(Port)]).

server(IP, Port) when is_tuple(IP) orelse IP == any orelse IP == loopback,
                      is_integer(Port) ->
    {ok,S} = gen_sctp:open(Port, [{recbuf,65536}, {ip,IP}]),
    io:format("Listening on ~w:~w. ~w~n", [IP,Port,S]),
    ok     = gen_sctp:listen(S, true),
    server_loop(S).

server_loop(S) ->
    case gen_sctp:recv(S) of
    {error, Error} ->
        io:format("SCTP RECV ERROR: ~p~n", [Error]);
    Data ->
        io:format("Received: ~p~n", [Data])
    end,
    server_loop(S).

Example of an Erlang SCTP client interacting with the above server. Note that in this example the client creates an association with the server with 5 outbound streams. Therefore, sending of "Test 0" over stream 0 succeeds, but sending of "Test 5" over stream 5 fails. The client then aborts the association, which results in that the corresponding event is received on the server side.

-module(sctp_client).

-export([client/0, client/1, client/2]).
-include_lib("kernel/include/inet.hrl").
-include_lib("kernel/include/inet_sctp.hrl").

client() ->
    client([localhost]).

client([Host]) ->
    client(Host, 2006);

client([Host, Port]) when is_list(Host), is_list(Port) ->
    client(Host,list_to_integer(Port)),
    init:stop().

client(Host, Port) when is_integer(Port) ->
    {ok,S}     = gen_sctp:open(),
    {ok,Assoc} = gen_sctp:connect
        (S, Host, Port, [{sctp_initmsg,#sctp_initmsg{num_ostreams=5}}]),
    io:format("Connection Successful, Assoc=~p~n", [Assoc]),

    io:write(gen_sctp:send(S, Assoc, 0, <<"Test 0">>)),
    io:nl(),
    timer:sleep(10000),
    io:write(gen_sctp:send(S, Assoc, 5, <<"Test 5">>)),
    io:nl(),
    timer:sleep(10000),
    io:write(gen_sctp:abort(S, Assoc)),
    io:nl(),

    timer:sleep(1000),
    gen_sctp:close(S).

A simple Erlang SCTP client that uses the connect_init API:

-module(ex3).

-export([client/4]).
-include_lib("kernel/include/inet.hrl").
-include_lib("kernel/include/inet_sctp.hrl").

client(Peer1, Port1, Peer2, Port2)
  when is_tuple(Peer1), is_integer(Port1), is_tuple(Peer2), is_integer(Port2) ->
    {ok,S}     = gen_sctp:open(),
    SctpInitMsgOpt = {sctp_initmsg,#sctp_initmsg{num_ostreams=5}},
    ActiveOpt = {active, true},
    Opts = [SctpInitMsgOpt, ActiveOpt],
    ok = gen_sctp:connect(S, Peer1, Port1, Opts),
    ok = gen_sctp:connect(S, Peer2, Port2, Opts),
    io:format("Connections initiated~n", []),
    client_loop(S, Peer1, Port1, undefined, Peer2, Port2, undefined).

client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) ->
    receive
        {sctp, S, Peer1, Port1, {_Anc, SAC}}
          when is_record(SAC, sctp_assoc_change), AssocId1 == undefined ->
            io:format("Association 1 connect result: ~p. AssocId: ~p~n",
                      [SAC#sctp_assoc_change.state,
                       SAC#sctp_assoc_change.assoc_id]),
            client_loop(S, Peer1, Port1, SAC#sctp_assoc_change.assoc_id,
                        Peer2, Port2, AssocId2);

        {sctp, S, Peer2, Port2, {_Anc, SAC}}
          when is_record(SAC, sctp_assoc_change), AssocId2 == undefined ->
            io:format("Association 2 connect result: ~p. AssocId: ~p~n",
                      [SAC#sctp_assoc_change.state, SAC#sctp_assoc_change.assoc_id]),
            client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2,
                       SAC#sctp_assoc_change.assoc_id);

        {sctp, S, Peer1, Port1, Data} ->
            io:format("Association 1: received ~p~n", [Data]),
            client_loop(S, Peer1, Port1, AssocId1,
                        Peer2, Port2, AssocId2);

        {sctp, S, Peer2, Port2, Data} ->
            io:format("Association 2: received ~p~n", [Data]),
            client_loop(S, Peer1, Port1, AssocId1,
                        Peer2, Port2, AssocId2);

        {sctp_error, S, _Peer, _Port, {_Anc, Error}} ->
            io:format("SCTP error: ~p~n", [Error]),
            client_loop(S, Peer1, Port1, AssocId1,
                        Peer2, Port2, AssocId2);

        Other ->
            io:format("Other ~p~n", [Other]),
            client_loop(S, Peer1, Port1, AssocId1,
                        Peer2, Port2, AssocId2)

    after 5000 ->
            ok
    end.

See Also

gen_tcp, gen_udp, inet, RFC 2960 (Stream Control Transmission Protocol), Sockets API Extensions for SCTP

Summary

Types

assoc_id()

Association ID.

elementary_option()

elementary_option_name()

option()

SCTP Socket Option name and value, to set.

option_name()

SCTP Socket Option name, to get.

option_value()

SCTP Socket Option name and value, what you get.

record_option()

ro_option()

sctp_socket()

Socket identifier returned from open/*.

Functions

abort(Socket, Assoc)

Abort an association.

close(Socket)

Close an SCTP socket.

connect(Socket, SockAddr, Opts)

Equivalent to connect(Socket, SockAddr, Opts, infinity).

connect/4

Establish an association with a peer.

connect(Socket, Addr, Port, Opts, Timeout)

Establish an association with a peer.

connect_init(Socket, SockAddr, Opts)

Equivalent to connect_init(Socket, SockAddr, Opts, infinity).

connect_init/4

Start establishing an association with a peer.

connect_init(Socket, Addr, Port, Opts, Timeout)

Start establishing an association with a peer.

connectx_init(Socket, SockAddrs, Opts)

Start establishing an association with a peer (multiple addresses).

connectx_init(Socket, Addrs, Port, Opts)

Equivalent to connectx_init(Socket, Addrs, Port, Opts, infinity).

connectx_init(Socket, Addrs, Port, Opts, Timeout)

Start establishing an association with a peer (multiple addresses).

controlling_process(Socket, Pid)

Change the controlling process (owner) of a socket.

eof(Socket, Assoc)

Terminate an association gracefully.

error_string(ErrorNumber)

Translate an error number into a string or atom.

listen/2

Make an SCTP socket listen to incoming associations.

open()

Equivalent to open([]).

open/1

Create an SCTP socket.

open(Port, Opts)

Equivalent to open([{port, Port} | Opts]).

peeloff(Socket, Assoc)

Branch off an association into a new socket of type stream.

recv(Socket)

Equivalent to recv(Socket, infinity).

recv(Socket, Timeout)

Receive a Data message.

send(Socket, SndRcvInfo, Data)

Send a Data message, full-featured.

send(Socket, Assoc, Stream, Data)

Send a data message.

Types

assoc_id()

-type assoc_id() :: term().

Association ID.

An opaque term returned in, for example, #sctp_paddr_change{}, which identifies an association for an SCTP socket. The term is opaque except for the special value 0, which has a meaning such as "the whole endpoint" or "all future associations".

elementary_option()

(not exported)

-type elementary_option() ::
          {active, true | false | once | -32768..32767} |
          {buffer, non_neg_integer()} |
          {non_block_send, boolean()} |
          {debug, boolean()} |
          {dontroute, boolean()} |
          {exclusiveaddruse, boolean()} |
          {high_msgq_watermark, pos_integer()} |
          {linger, {boolean(), non_neg_integer()}} |
          {low_msgq_watermark, pos_integer()} |
          {mode, list | binary} |
          list | binary |
          {priority, non_neg_integer()} |
          {recbuf, non_neg_integer()} |
          {reuseaddr, boolean()} |
          {reuseport, boolean()} |
          {reuseport_lb, boolean()} |
          {ipv6_v6only, boolean()} |
          {sndbuf, non_neg_integer()} |
          {sctp_autoclose, non_neg_integer()} |
          {sctp_disable_fragments, boolean()} |
          {sctp_i_want_mapped_v4_addr, boolean()} |
          {sctp_maxseg, non_neg_integer()} |
          {sctp_nodelay, boolean()} |
          {tos, non_neg_integer()} |
          {tclass, non_neg_integer()} |
          {ttl, non_neg_integer()} |
          {recvtos, boolean()} |
          {recvtclass, boolean()} |
          {recvttl, boolean()}.

elementary_option_name()

(not exported)

-type elementary_option_name() ::
          active | buffer | non_block_send | debug | dontroute | exclusiveaddruse |
          high_msgq_watermark | linger | low_msgq_watermark | mode | priority | recbuf | reuseaddr |
          reuseport | reuseport_lb | ipv6_v6only | sctp_autoclose | sctp_disable_fragments |
          sctp_i_want_mapped_v4_addr | sctp_maxseg | sctp_nodelay | sndbuf | tos | tclass | ttl |
          recvtos | recvtclass | recvttl.

option()

-type option() :: elementary_option() | record_option().

SCTP Socket Option name and value, to set.

option_name()

-type option_name() :: elementary_option_name() | record_option() | ro_option().

SCTP Socket Option name, to get.

option_value()

-type option_value() :: elementary_option() | record_option() | ro_option().

SCTP Socket Option name and value, what you get.

record_option()

(not exported)

-type record_option() ::
          {sctp_adaptation_layer, #sctp_setadaptation{adaptation_ind :: term()}} |
          {sctp_associnfo,
           #sctp_assocparams{assoc_id :: term(),
                             asocmaxrxt :: term(),
                             number_peer_destinations :: term(),
                             peer_rwnd :: term(),
                             local_rwnd :: term(),
                             cookie_life :: term()}} |
          {sctp_default_send_param,
           #sctp_sndrcvinfo{stream :: term(),
                            ssn :: term(),
                            flags :: term(),
                            ppid :: term(),
                            context :: term(),
                            timetolive :: term(),
                            tsn :: term(),
                            cumtsn :: term(),
                            assoc_id :: term()}} |
          {sctp_delayed_ack_time, #sctp_assoc_value{assoc_id :: term(), assoc_value :: term()}} |
          {sctp_events,
           #sctp_event_subscribe{data_io_event :: term(),
                                 association_event :: term(),
                                 address_event :: term(),
                                 send_failure_event :: term(),
                                 peer_error_event :: term(),
                                 shutdown_event :: term(),
                                 partial_delivery_event :: term(),
                                 adaptation_layer_event :: term(),
                                 authentication_event :: term()}} |
          {sctp_initmsg,
           #sctp_initmsg{num_ostreams :: term(),
                         max_instreams :: term(),
                         max_attempts :: term(),
                         max_init_timeo :: term()}} |
          {sctp_peer_addr_params,
           #sctp_paddrparams{assoc_id :: term(),
                             address :: term(),
                             hbinterval :: term(),
                             pathmaxrxt :: term(),
                             pathmtu :: term(),
                             sackdelay :: term(),
                             flags :: term()}} |
          {sctp_primary_addr, #sctp_prim{assoc_id :: term(), addr :: term()}} |
          {sctp_rtoinfo,
           #sctp_rtoinfo{assoc_id :: term(), initial :: term(), max :: term(), min :: term()}} |
          {sctp_set_peer_primary_addr, #sctp_setpeerprim{assoc_id :: term(), addr :: term()}}.

ro_option()

(not exported)

-type ro_option() ::
          {sctp_get_peer_addr_info,
           #sctp_paddrinfo{assoc_id :: term(),
                           address :: term(),
                           state :: term(),
                           cwnd :: term(),
                           srtt :: term(),
                           rto :: term(),
                           mtu :: term()}} |
          {sctp_status,
           #sctp_status{assoc_id :: term(),
                        state :: term(),
                        rwnd :: term(),
                        unackdata :: term(),
                        penddata :: term(),
                        instrms :: term(),
                        outstrms :: term(),
                        fragmentation_point :: term(),
                        primary :: term()}}.

sctp_socket()

-type sctp_socket() :: port().

Socket identifier returned from open/*.

Functions

abort(Socket, Assoc)

-spec abort(Socket, Assoc) -> ok | {error, inet:posix()}
               when
                   Socket :: sctp_socket(),
                   Assoc ::
                       #sctp_assoc_change{state :: term(),
                                          error :: term(),
                                          outbound_streams :: term(),
                                          inbound_streams :: term(),
                                          assoc_id :: term()}.

Abort an association.

Abnormally terminates the association specified by Assoc, without flushing unsent data. The socket itself remains open. Other associations opened on this socket are still valid, and the socket can be used in new associations.

close(Socket)

-spec close(Socket) -> ok | {error, inet:posix()} when Socket :: sctp_socket().

Close an SCTP socket.

Closes the socket and all associations on it. The unsent data is flushed as for eof/2. The close/1 call is blocking depending of the value of the linger socket [option]. If it is false or the linger time-out expires, the call returns and unsent data is flushed in the background.

connect(Socket, SockAddr, Opts)

(since OTP 24.3)

-spec connect(Socket, SockAddr, Opts) ->
                 {ok,
                  #sctp_assoc_change{state :: comm_up,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error,
                  #sctp_assoc_change{state :: cant_assoc,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error, inet:posix()}
                 when
                     Socket :: sctp_socket(),
                     SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                     Opts :: [Opt :: option()].

Equivalent to connect(Socket, SockAddr, Opts, infinity).

connect/4

-spec connect(Socket, SockAddr, Opts, Timeout) ->
                 {ok,
                  #sctp_assoc_change{state :: comm_up,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error,
                  #sctp_assoc_change{state :: cant_assoc,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error, inet:posix()}
                 when
                     Socket :: sctp_socket(),
                     SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                     Opts :: [Opt :: option()],
                     Timeout :: timeout();
             (Socket, Addr, Port, Opts) ->
                 {ok,
                  #sctp_assoc_change{state :: comm_up,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error,
                  #sctp_assoc_change{state :: cant_assoc,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error, inet:posix()}
                 when
                     Socket :: sctp_socket(),
                     Addr :: inet:ip_address() | inet:hostname(),
                     Port :: inet:port_number(),
                     Opts :: [Opt :: option()].

Establish an association with a peer.

With arguments Addr and Port, equivalent to connect(Socket, Addr, Port, Opts, infinity).

With arguments SockAddr and Opts (since OTP 24.3), equivalent to connect(Socket, Addr, Port, Opts, Timeout) where Addr and Port are extracted from SockAddr.

connect(Socket, Addr, Port, Opts, Timeout)

-spec connect(Socket, Addr, Port, Opts, Timeout) ->
                 {ok,
                  #sctp_assoc_change{state :: comm_up,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error,
                  #sctp_assoc_change{state :: cant_assoc,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error, inet:posix()}
                 when
                     Socket :: sctp_socket(),
                     Addr :: inet:ip_address() | inet:hostname(),
                     Port :: inet:port_number(),
                     Opts :: [Opt :: option()],
                     Timeout :: timeout().

Establish an association with a peer.

Establishes a new association for socket Socket, with the peer (SCTP server socket) specified by Addr and Port. Timeout, is expressed in milliseconds. A socket can be associated with multiple peers. The socket has to be of type seqpacket.

Warning

Using a value of Timeout less than the maximum time taken by the OS to establish an association (around 4.5 minutes if the default values from RFC 4960 are used), can result in inconsistent or incorrect return values. This is especially relevant for associations sharing the same Socket (that is, source address and port), as the controlling process blocks until connect/* returns. connect_init/* provides an alternative without this limitation.

#sctp_assoc_change{}

The result of connect/* is an #sctp_assoc_change{} event that contains, in particular, the new Association ID: l

#sctp_assoc_change{
      state             = atom(),
      error             = integer(),
      outbound_streams  = integer(),
      inbound_streams   = integer(),
      assoc_id          = assoc_id()
}

The number of outbound and inbound streams for the association can be set by giving an sctp_initmsg option to connect as in:

connect(Socket, Ip, Port>,
      [{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams,
                                   max_instreams=MaxInStreams}}])

All options Opt are set on the socket before the association is attempted. If an option record has undefined field values, the options record is first read from the socket for those values. In effect, Opt option records only need to define field values to change before connecting.

The returned outbound_streams and inbound_streams are the number of stream on the socket. These can be different from the requested values (OutStreams and MaxInStreams, respectively), if the peer requires lower values.

state can have the following values:

comm_up - Association is successfully established. This indicates a successful completion of connect.

cant_assoc - The association cannot be established (connect/* failure).

Other states do not normally occur in the output from connect/*. Rather, they can occur in #sctp_assoc_change{} events received instead of data from recv/* calls or socket messages. All of them indicate losing the association because of various error conditions, and are listed here for the sake of completeness:

comm_lost

restart

shutdown_comp

The field error can provide more detailed diagnostics. Its value can be converted into a string using error_string/1.

connect_init(Socket, SockAddr, Opts)

(since OTP 24.3)

-spec connect_init(Socket, SockAddr, Opts) -> ok | {error, inet:posix()}
                      when
                          Socket :: sctp_socket(),
                          SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                          Opts :: [option()].

Equivalent to connect_init(Socket, SockAddr, Opts, infinity).

connect_init/4

(since OTP R13B04)

-spec connect_init(Socket, SockAddr, Opts, Timeout) -> ok | {error, inet:posix()}
                      when
                          Socket :: sctp_socket(),
                          SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                          Opts :: [option()],
                          Timeout :: timeout();
                  (Socket, Addr, Port, Opts) -> ok | {error, inet:posix()}
                      when
                          Socket :: sctp_socket(),
                          Addr :: inet:ip_address() | inet:hostname(),
                          Port :: inet:port_number(),
                          Opts :: [option()].

Start establishing an association with a peer.

With arguments Addr and Port, equivalent to connect_init(Socket, Addr, Port, Opts, infinity).

With arguments SockAddr and Opts (since OTP 24.3), equivalent to connect_init(Socket, Addr, Port, Opts, Timeout) where Addr and Port are extracted from SockAddr.

connect_init(Socket, Addr, Port, Opts, Timeout)

(since OTP R13B04)

-spec connect_init(Socket, Addr, Port, Opts, Timeout) -> ok | {error, inet:posix()}
                      when
                          Socket :: sctp_socket(),
                          Addr :: inet:ip_address() | inet:hostname(),
                          Port :: inet:port_number(),
                          Opts :: [option()],
                          Timeout :: timeout().

Start establishing an association with a peer.

Initiates a new association for socket Socket, with the peer (SCTP server socket) specified by Addr and Port.

The fundamental difference between this API and connect/* is that the return value is that of the underlying OS connect(2) system call. If ok is returned, the operation has been succesfully initiated, and the final result result of the association establishment is sent to the socket owner (controlling process) as an #sctp_assoc_change{} event. The socket owner must be prepared to receive this, the recv/* call has to be polled, depending on the value of the active option.

The parameters are as described for connect/*, except the Timeout value since for this function, the time-out only applies to the name resolving of Addr when it is a inet:hostname/0.

connectx_init(Socket, SockAddrs, Opts)

(since OTP 25.0)

-spec connectx_init(Socket, SockAddrs, Opts) -> {ok, assoc_id()} | {error, inet:posix()}
                       when
                           Socket :: sctp_socket(),
                           SockAddrs ::
                               [{inet:ip_address(), inet:port_number()} |
                                inet:family_address() |
                                socket:sockaddr_in() |
                                socket:sockaddr_in6()],
                           Opts :: [option()].

Start establishing an association with a peer (multiple addresses).

Similar to connectx_init/5 except using socket addresses, and not having a Timeout. Since the addresses do not need lookup and the connect is non-blocking this call returns immediately.

The value of each socket address port must be the same or zero. At least one socket address must have a non-zero port

connectx_init(Socket, Addrs, Port, Opts)

(since OTP 25.0)

-spec connectx_init(Socket, Addrs, Port, Opts) -> {ok, assoc_id()} | {error, inet:posix()}
                       when
                           Socket :: sctp_socket(),
                           Addrs :: [inet:ip_address() | inet:hostname()],
                           Port :: inet:port_number() | atom(),
                           Opts :: [option()].

Equivalent to connectx_init(Socket, Addrs, Port, Opts, infinity).

connectx_init(Socket, Addrs, Port, Opts, Timeout)

(since OTP 25.0)

-spec connectx_init(Socket, Addrs, Port, Opts, Timeout) -> {ok, assoc_id()} | {error, inet:posix()}
                       when
                           Socket :: sctp_socket(),
                           Addrs :: [inet:ip_address() | inet:hostname()],
                           Port :: inet:port_number() | atom(),
                           Opts :: [option()],
                           Timeout :: timeout().

Start establishing an association with a peer (multiple addresses).

Initiates a new association for socket Socket, with the peer (SCTP server socket) specified by Addrs and Port.

This API is similar to connect_init/* except the underlying OS sctp_connectx(3) system call is used, that accepts multiple destination addresses.

If successful, the association ID is returned which will be received in a subsequent #sctp_assoc_change{} event.

The parameters are as described in connect_init/5

Note

This API allows the OS to use all Addrs when establishing an association, but does not guarantee it will. Therefore, if the connection fails, the user may want to rotate the order of addresses for a subsequent call.

controlling_process(Socket, Pid)

-spec controlling_process(Socket, Pid) -> ok | {error, Reason}
                             when
                                 Socket :: sctp_socket(),
                                 Pid :: pid(),
                                 Reason :: closed | not_owner | badarg | inet:posix().

Change the controlling process (owner) of a socket.

Assigns a new controlling process Pid to Socket. See gen_udp:controlling_process/2.

eof(Socket, Assoc)

-spec eof(Socket, Assoc) -> ok | {error, Reason}
             when
                 Socket :: sctp_socket(),
                 Assoc ::
                     #sctp_assoc_change{state :: term(),
                                        error :: term(),
                                        outbound_streams :: term(),
                                        inbound_streams :: term(),
                                        assoc_id :: term()},
                 Reason :: term().

Terminate an association gracefully.

Gracefully terminates the association specified by Assoc, flushing all unsent data. The socket itself remains open. Other associations opened on this socket are still valid. The socket can be used in new associations.

error_string(ErrorNumber)

-spec error_string(ErrorNumber) -> ok | string() | unknown_error when ErrorNumber :: integer().

Translate an error number into a string or atom.

Translates an SCTP error number from, for example, #sctp_remote_error{} or #sctp_send_failed{} into an explanatory string, or into one of the atoms ok for no error, or unknown_error for an unrecognized integer.

listen/2

-spec listen(Socket, IsServer) -> ok | {error, Reason}
                when Socket :: sctp_socket(), IsServer :: boolean(), Reason :: term();
            (Socket, Backlog) -> ok | {error, Reason}
                when Socket :: sctp_socket(), Backlog :: integer(), Reason :: term().

Make an SCTP socket listen to incoming associations.

The socket will listen on the IP address(es) and port number it is bound to.

For type seqpacket, sockets (the default), the argumentIsServer must be a boolean/0. In contrast to stream sockets, there is no listening queue length. If IsServer is true, the socket accepts new associations, that is, it becomes an SCTP server socket.

For type stream sockets, the argument Backlog sets the backlog queue length just like for TCP.

open()

-spec open() -> {ok, Socket} | {error, inet:posix()} when Socket :: sctp_socket().

Equivalent to open([]).

open/1

-spec open(Port) -> {ok, Socket} | {error, inet:posix()}
              when Port :: inet:port_number(), Socket :: sctp_socket();
          (Opts) -> {ok, Socket} | {error, inet:posix()}
              when
                  Opts :: [Opt],
                  Opt ::
                      {ifaddr, IP | SockAddr} |
                      {ip, IP} |
                      {port, Port} |
                      inet:address_family() |
                      {type, SockType} |
                      {netns, file:filename_all()} |
                      {bind_to_device, binary()} |
                      option(),
                  IP :: inet:ip_address() | any | loopback,
                  SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                  Port :: inet:port_number(),
                  SockType :: seqpacket | stream,
                  Socket :: sctp_socket().

Create an SCTP socket.

With argument Port, equivalent toopen([{port, Port}].

Creates an SCTP socket and binds it to the local addresses specified by all {ip,IP} (or synonymously {ifaddr,IP}) options (this feature is called SCTP multi-homing). The default IP and Port are any and 0, meaning bind to all local addresses on any free port.

It is also possible to use {ifaddr, SockAddr}, in which case it takes precedence over the ip and port options. These options can however be used to update the address and port of ifaddr (if they occur after ifaddr in the options list), although this is not recommended.

Other options:

inet6 - Sets up the socket for IPv6.

inet - Sets up the socket for IPv4. This is the default.

A default set of socket options is used. In particular, the socket is opened in binary and passive mode, with SockType seqpacket, and with reasonably large kernel and driver buffers.

When the socket is in passive mode, data can be received through the recv/1,2 calls.

When the socket is in active mode, received data is delivered to the controlling process as messages:

{sctp, Socket, FromIP, FromPort, {AncData, Data}}

Error-related events - such as #sctp_send_failed{}, #sctp_pdapi_event{}, and #sctp_remote_error{} - are also delivered to the controlling process as messages, but use a different tuple tag:

{sctp_error, Socket, FromIP, FromPort, {AncData, Data}}

See recv/1,2 for a description of the message fields.

Note

This message format unfortunately differs slightly from the gen_udp message format with ancillary data, and from the recv/1,2 return tuple format.

open(Port, Opts)

-spec open(Port :: integer(), Opts :: [term()]) -> _.

Equivalent to open([{port, Port} | Opts]).

peeloff(Socket, Assoc)

(since OTP R15B)

-spec peeloff(Socket, Assoc) -> {ok, NewSocket} | {error, Reason}
                 when
                     Socket :: sctp_socket(),
                     Assoc ::
                         #sctp_assoc_change{state :: term(),
                                            error :: term(),
                                            outbound_streams :: term(),
                                            inbound_streams :: term(),
                                            assoc_id :: term()} |
                         assoc_id(),
                     NewSocket :: sctp_socket(),
                     Reason :: term().

Branch off an association into a new socket of type stream.

The existing association Assoc in the socket Socket (that has to be of type seqpacket; one-to-many style) is branched off into a new socket NewSocket of type stream (one-to-one style).

The existing association argument Assoc can be a #sctp_assoc_change{} record as returned from, for example, recv/*, connect/*, or from a listening socket in active mode. It can also be just the field assoc_id integer/0 from such a record.

recv(Socket)

-spec recv(Socket) -> {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}
              when
                  Socket :: sctp_socket(),
                  FromIP :: inet:ip_address(),
                  FromPort :: inet:port_number(),
                  AncData ::
                      [#sctp_sndrcvinfo{stream :: term(),
                                        ssn :: term(),
                                        flags :: term(),
                                        ppid :: term(),
                                        context :: term(),
                                        timetolive :: term(),
                                        tsn :: term(),
                                        cumtsn :: term(),
                                        assoc_id :: term()} |
                       inet:ancillary_data()],
                  Data ::
                      binary() |
                      string() |
                      #sctp_sndrcvinfo{stream :: term(),
                                       ssn :: term(),
                                       flags :: term(),
                                       ppid :: term(),
                                       context :: term(),
                                       timetolive :: term(),
                                       tsn :: term(),
                                       cumtsn :: term(),
                                       assoc_id :: term()} |
                      #sctp_assoc_change{state :: term(),
                                         error :: term(),
                                         outbound_streams :: term(),
                                         inbound_streams :: term(),
                                         assoc_id :: term()} |
                      #sctp_paddr_change{addr :: term(),
                                         state :: term(),
                                         error :: term(),
                                         assoc_id :: term()} |
                      #sctp_adaptation_event{adaptation_ind :: term(), assoc_id :: term()},
                  Reason ::
                      inet:posix() |
                      #sctp_send_failed{flags :: term(),
                                        error :: term(),
                                        info :: term(),
                                        assoc_id :: term(),
                                        data :: term()} |
                      #sctp_paddr_change{addr :: term(),
                                         state :: term(),
                                         error :: term(),
                                         assoc_id :: term()} |
                      #sctp_pdapi_event{indication :: term(), assoc_id :: term()} |
                      #sctp_remote_error{error :: term(), assoc_id :: term(), data :: term()} |
                      #sctp_shutdown_event{assoc_id :: term()}.

Equivalent to recv(Socket, infinity).

recv(Socket, Timeout)

-spec recv(Socket, Timeout) -> {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}
              when
                  Socket :: sctp_socket(),
                  Timeout :: timeout(),
                  FromIP :: inet:ip_address(),
                  FromPort :: inet:port_number(),
                  AncData ::
                      [#sctp_sndrcvinfo{stream :: term(),
                                        ssn :: term(),
                                        flags :: term(),
                                        ppid :: term(),
                                        context :: term(),
                                        timetolive :: term(),
                                        tsn :: term(),
                                        cumtsn :: term(),
                                        assoc_id :: term()} |
                       inet:ancillary_data()],
                  Data ::
                      binary() |
                      string() |
                      #sctp_sndrcvinfo{stream :: term(),
                                       ssn :: term(),
                                       flags :: term(),
                                       ppid :: term(),
                                       context :: term(),
                                       timetolive :: term(),
                                       tsn :: term(),
                                       cumtsn :: term(),
                                       assoc_id :: term()} |
                      #sctp_assoc_change{state :: term(),
                                         error :: term(),
                                         outbound_streams :: term(),
                                         inbound_streams :: term(),
                                         assoc_id :: term()} |
                      #sctp_paddr_change{addr :: term(),
                                         state :: term(),
                                         error :: term(),
                                         assoc_id :: term()} |
                      #sctp_adaptation_event{adaptation_ind :: term(), assoc_id :: term()},
                  Reason ::
                      inet:posix() |
                      #sctp_send_failed{flags :: term(),
                                        error :: term(),
                                        info :: term(),
                                        assoc_id :: term(),
                                        data :: term()} |
                      #sctp_paddr_change{addr :: term(),
                                         state :: term(),
                                         error :: term(),
                                         assoc_id :: term()} |
                      #sctp_pdapi_event{indication :: term(), assoc_id :: term()} |
                      #sctp_remote_error{error :: term(), assoc_id :: term(), data :: term()} |
                      #sctp_shutdown_event{assoc_id :: term()}.

Receive a Data message.

Receives the Data message from any association of the socket. If the receive times out, {error,timeout} is returned. The default time-out is infinity. FromIP and FromPort indicate the address of the sender.

AncData is a list of ancillary data items received with the main Data. This list can be empty, or contain a single #sctp_sndrcvinfo{} record, if receiving ancillary data is enabled (see option sctp_events). Per default, it is enabled, as such ancillary data provides an easy way to determine the association and stream over which the message was received. (An alternative way is to get the association ID from FromIP and FromPort using socket option sctp_get_peer_addr_info, but this does still not give the stream number).

AncData may also contain ancillary data from the socket options recvtos, recvtclass or recvttl, if that is supported for the socket by the platform.

The Data received can, depending on the socket mode be a binary/0 or a list/0 of bytes (integers in the range 0 through 255), or it can be an SCTP event.

Possible SCTP events

#sctp_sndrcvinfo{}

#sctp_assoc_change{}

#sctp_paddr_change{
      addr      = {ip_address(),port()},
      state     = atom(),
      error     = integer(),
      assoc_id  = assoc_id()
}

Indicates change of the status of the IP address of the peer specified by addr within association assoc_id. Possible values of state (mostly self-explanatory) include:

addr_unreachable

addr_available

addr_removed

addr_added

addr_made_prim

addr_confirmed

In case of an error (for example, addr_unreachable), the field error provides more diagnostics. In such cases, event #sctp_paddr_change{} is automatically converted into an error term returned by recv. The error field value can be converted into a string using error_string/1.

#sctp_send_failed{
      flags     = true | false,
      error     = integer(),
      info      = #sctp_sndrcvinfo{},
      assoc_id  = assoc_id()
      data      = binary()
}

The sender can receive this event if a send operation fails.

flags - A Boolean specifying if the data has been transmitted over the wire.

error - Provides extended diagnostics, use error_string/1.

info - The original #sctp_sndrcvinfo{} record used in the failed send/*.

data - The whole original data chunk attempted to be sent.

In the current implementation of the Erlang/SCTP binding, this event is internally converted into an error term returned by recv/*.

#sctp_adaptation_event{
      adaptation_ind = integer(),
      assoc_id       = assoc_id()
}

Delivered when a peer sends an adaptation layer indication parameter (configured through option sctp_adaptation_layer). Notie that with the current implementation of the Erlang/SCTP binding, this event is disabled by default.

#sctp_pdapi_event{
      indication = sctp_partial_delivery_aborted,
      assoc_id   = assoc_id()
}

A partial delivery failure. In the current implementation of the Erlang/SCTP binding, this event is internally converted into an error term returned by recv/*.

send(Socket, SndRcvInfo, Data)

-spec send(Socket, SndRcvInfo, Data) -> ok | {error, Reason}
              when
                  Socket :: sctp_socket(),
                  SndRcvInfo ::
                      #sctp_sndrcvinfo{stream :: term(),
                                       ssn :: term(),
                                       flags :: term(),
                                       ppid :: term(),
                                       context :: term(),
                                       timetolive :: term(),
                                       tsn :: term(),
                                       cumtsn :: term(),
                                       assoc_id :: term()},
                  Data :: binary() | iolist(),
                  Reason :: term().

Send a Data message, full-featured.

Sends the Data message with all sending parameters from a #sctp_sndrcvinfo{} record. This way, the user can specify the PPID (passed to the remote end) and context (passed to the local SCTP layer), which can be used, for example, for error identification. However, such a fine grained user control is rarely required. The function send/4 is sufficient for most applications.

Note

Send is normally blocking, but if the socket option non_block_send is set to true, the function will return with e.g. {error, eagain} in the case when the function would otherwise block. It is then up to the user to try again later.

send(Socket, Assoc, Stream, Data)

-spec send(Socket, Assoc, Stream, Data) -> ok | {error, Reason}
              when
                  Socket :: sctp_socket(),
                  Assoc ::
                      #sctp_assoc_change{state :: term(),
                                         error :: term(),
                                         outbound_streams :: term(),
                                         inbound_streams :: term(),
                                         assoc_id :: term()} |
                      assoc_id(),
                  Stream :: integer(),
                  Data :: binary() | iolist(),
                  Reason :: term().

Send a data message.

Sends a Data message on the association Assoc and Stream.

Assoc can be specified with a #sctp_assoc_change{} record from an association establishment, or as the assoc_id/0 integer/0 field value.

Note

Send is normally blocking, but if the socket option non_block_send is set to true, the function will return with e.g. {error, eagain} in the case when the function would otherwise block. It is then up to the user to try again later.

gen_tcp

Interface to TCP/IP sockets.

This module provides functions for communicating over TCP/IP protocol sockets.

The following code fragment is a simple example of a client connecting to a server at port 5678, transferring a binary, and closing the connection:

client() ->
    SomeHostInNet = "localhost", % to make it runnable on one machine
    {ok, Sock} = gen_tcp:connect(SomeHostInNet, 5678,
                                 [binary, {packet, 0}]),
    ok = gen_tcp:send(Sock, "Some Data"),
    ok = gen_tcp:close(Sock).

At the other end, a server is listening on port 5678, accepts the connection, and receives the binary:

server() ->
    {ok, LSock} = gen_tcp:listen(5678, [binary, {packet, 0},
                                        {active, false}]),
    {ok, Sock} = gen_tcp:accept(LSock),
    {ok, Bin} = do_recv(Sock, []),
    ok = gen_tcp:close(Sock),
    ok = gen_tcp:close(LSock),
    Bin.

do_recv(Sock, Bs) ->
    case gen_tcp:recv(Sock, 0) of
        {ok, B} ->
            do_recv(Sock, [Bs, B]);
        {error, closed} ->
            {ok, list_to_binary(Bs)}
    end.

For more examples, see section Examples.

Note

Functions that create sockets can take an optional option; {inet_backend, Backend} that, if specified, has to be the first option. This selects the implementation backend towards the platform's socket API.

This is a temporary option that will be ignored in a future release.

The default is Backend = inet that selects the traditional inet_drv.c driver. The other choice is Backend = socket that selects the new socket module and its NIF implementation.

The system default can be changed when the node is started with the application kernel's configuration variable inet_backend.

For gen_tcp with inet_backend = socket we have tried to be as "compatible" as possible which has sometimes been impossible. Here is a list of cases when the behaviour of inet-backend inet (default) and socket are different:

Non-blocking send

If a user calling gen_tcp:send/2 with inet_backend = inet, tries to send more data than there is room for in the OS buffers, the "rest data" is buffered by the inet driver (and later sent in the background). The effect for the user is that the call is non-blocking.

This is not the effect when inet_backend = socket, since there is no buffering. Instead the user hangs either until all data has been sent or the send_timeout timeout has been reached.

shutdown/2 may hide errors

The call does not involve the receive process state, and is done right on the underlying socket. On for example Linux, it is a known misbehaviour that it skips some checks so doing shutdown on a listen socket returns ok while the logical result should have been {error, enotconn}. The inet_drv.c driver did an extra check and simulated the correct error, but with Backend = socket it would introduce overhead to involve the receive process.

The option nodelay is a TCP specific option that is not compatible with domain = local.

When using inet_backend = socket, trying to create a socket (via listen or connect) with domain = local (for example with option {ifaddr, {local,"/tmp/test"}}) will fail with {error, enotsup}.

This does not actually work for inet_backend = inet either, but in that case the error is simply ignored, which is a bad idea. We have chosen to not ignore this error for inet_backend = socket.

Async shutdown write

Calling gen_tcp:shutdown(Socket, write | read_write) on a socket created with inet_backend = socket will take immediate effect, unlike for a socket created with inet_backend = inet.

See async shutdown write for more info.

Windows require sockets (domain = inet | inet6) to be bound.

Currently all sockets created on Windows with inet_backend = socket will be bound. If the user does not provide an address, gen_tcp will try to 'figure out' an address itself.

Examples

The following example illustrates use of option {active,once} and multiple accepts by implementing a server as a number of worker processes doing accept on a single listening socket. Function start/2 takes the number of worker processes and the port number on which to listen for incoming connections. If LPort is specified as 0, an ephemeral port number is used, which is why the start function returns the actual port number allocated:

start(Num,LPort) ->
    case gen_tcp:listen(LPort,[{active, false},{packet,2}]) of
        {ok, ListenSock} ->
            start_servers(Num,ListenSock),
            {ok, Port} = inet:port(ListenSock),
            Port;
        {error,Reason} ->
            {error,Reason}
    end.

start_servers(0,_) ->
    ok;
start_servers(Num,LS) ->
    spawn(?MODULE,server,[LS]),
    start_servers(Num-1,LS).

server(LS) ->
    case gen_tcp:accept(LS) of
        {ok,S} ->
            loop(S),
            server(LS);
        Other ->
            io:format("accept returned ~w - goodbye!~n",[Other]),
            ok
    end.

loop(S) ->
    inet:setopts(S,[{active,once}]),
    receive
        {tcp,S,Data} ->
            Answer = process(Data), % Not implemented in this example
            gen_tcp:send(S,Answer),
            loop(S);
        {tcp_closed,S} ->
            io:format("Socket ~w closed [~w]~n",[S,self()]),
            ok
    end.

Example of a simple client:

client(PortNo,Message) ->
    {ok,Sock} = gen_tcp:connect("localhost",PortNo,[{active,false},
                                                    {packet,2}]),
    gen_tcp:send(Sock,Message),
    A = gen_tcp:recv(Sock,0),
    gen_tcp:close(Sock),
    A.

The send call does not accept a time-out option because time-outs on send is handled through socket option send_timeout. The behavior of a send operation with no receiver is mainly defined by the underlying TCP stack and the network infrastructure. To write code that handles a hanging receiver that can eventually cause the sender to hang on a send do like the following.

Consider a process that receives data from a client process to be forwarded to a server on the network. The process is connected to the server through TCP/IP and does not get any acknowledge for each message it sends, but has to rely on the send time-out option to detect that the other end is unresponsive. Option send_timeout can be used when connecting:

...
{ok,Sock} = gen_tcp:connect(HostAddress, Port,
                            [{active,false},
                             {send_timeout, 5000},
                             {packet,2}]),
                loop(Sock), % See below
...

In the loop where requests are handled, send time-outs can now be detected:

loop(Sock) ->
    receive
        {Client, send_data, Binary} ->
            case gen_tcp:send(Sock,[Binary]) of
                {error, timeout} ->
                    io:format("Send timeout, closing!~n",
                              []),
                    handle_send_timeout(), % Not implemented here
                    Client ! {self(),{error_sending, timeout}},
                    %% Usually, it's a good idea to give up in case of a
                    %% send timeout, as you never know how much actually
                    %% reached the server, maybe only a packet header?!
                    gen_tcp:close(Sock);
                {error, OtherSendError} ->
                    io:format("Some other error on socket (~p), closing",
                              [OtherSendError]),
                    Client ! {self(),{error_sending, OtherSendError}},
                    gen_tcp:close(Sock);
                ok ->
                    Client ! {self(), data_sent},
                    loop(Sock)
            end
    end.

Usually it suffices to detect time-outs on receive, as most protocols include some sort of acknowledgment from the server, but if the protocol is strictly one way, option send_timeout comes in handy.

Summary

Types

connect_option()

listen_option()

option()

option_name()

pktoptions_value()

Value from socket option pktoptions.

socket()

As returned by accept/1,2 and connect/3,4.

Functions

accept(ListenSocket)

Equivalent to accept(ListenSocket, infinity).

accept(ListenSocket, Timeout)

Accept an incoming connection request on a listen socket.

close(Socket)

Close a TCP socket.

connect(SockAddr, Opts)

Equivalent to connect(SockAddr, Opts, infinity).

connect/3

Create a socket connected to the specified address.

connect(Address, Port, Opts, Timeout)

Create a socket connected to the specified address.

controlling_process(Socket, Pid)

Change the controlling process (owner) of a socket.

listen(Port, Options)

Create a listen socket.

recv(Socket, Length)

Equivalent to recv(Socket, Length, infinity).

recv(Socket, Length, Timeout)

Receive a packet, from a socket in passive mode.

send(Socket, Packet)

Send a packet on a socket.

shutdown(Socket, How)

Close the socket in one or both directions.

Types

connect_option()

-type connect_option() ::
          {fd, Fd :: non_neg_integer()} |
          inet:address_family() |
          {ifaddr, socket:sockaddr_in() | socket:sockaddr_in6() | inet:socket_address()} |
          {ip, inet:socket_address()} |
          {port, inet:port_number()} |
          {tcp_module, module()} |
          {netns, file:filename_all()} |
          {bind_to_device, binary()} |
          option().

listen_option()

-type listen_option() ::
          {fd, Fd :: non_neg_integer()} |
          inet:address_family() |
          {ifaddr, socket:sockaddr_in() | socket:sockaddr_in6() | inet:socket_address()} |
          {ip, inet:socket_address()} |
          {port, inet:port_number()} |
          {backlog, B :: non_neg_integer()} |
          {tcp_module, module()} |
          {netns, file:filename_all()} |
          {bind_to_device, binary()} |
          option().

option()

-type option() ::
          {active, true | false | once | -32768..32767} |
          {buffer, non_neg_integer()} |
          {debug, boolean()} |
          {delay_send, boolean()} |
          {deliver, port | term} |
          {dontroute, boolean()} |
          {exit_on_close, boolean()} |
          {exclusiveaddruse, boolean()} |
          {header, non_neg_integer()} |
          {high_msgq_watermark, pos_integer()} |
          {high_watermark, non_neg_integer()} |
          {keepalive, boolean()} |
          {keepcnt, integer()} |
          {keepidle, integer()} |
          {keepintvl, integer()} |
          {linger, {boolean(), non_neg_integer()}} |
          {low_msgq_watermark, pos_integer()} |
          {low_watermark, non_neg_integer()} |
          {mode, list | binary} |
          list | binary |
          {nodelay, boolean()} |
          {packet,
           0 | 1 | 2 | 4 | raw | sunrm | asn1 | cdr | fcgi | line | tpkt | http | httph | http_bin |
           httph_bin} |
          {packet_size, non_neg_integer()} |
          {priority, non_neg_integer()} |
          {raw, Protocol :: non_neg_integer(), OptionNum :: non_neg_integer(), ValueBin :: binary()} |
          {recbuf, non_neg_integer()} |
          {reuseaddr, boolean()} |
          {reuseport, boolean()} |
          {reuseport_lb, boolean()} |
          {send_timeout, timeout()} |
          {send_timeout_close, boolean()} |
          {show_econnreset, boolean()} |
          {sndbuf, non_neg_integer()} |
          {tos, non_neg_integer()} |
          {tclass, non_neg_integer()} |
          {ttl, non_neg_integer()} |
          {recvtos, boolean()} |
          {recvtclass, boolean()} |
          {recvttl, boolean()} |
          {user_timeout, non_neg_integer()} |
          {ipv6_v6only, boolean()}.

option_name()

-type option_name() ::
          active | buffer | debug | delay_send | deliver | dontroute | exit_on_close |
          exclusiveaddruse | header | high_msgq_watermark | high_watermark | keepalive | keepcnt |
          keepidle | keepintvl | linger | low_msgq_watermark | low_watermark | mode | nodelay | packet |
          packet_size | priority |
          {raw,
           Protocol :: non_neg_integer(),
           OptionNum :: non_neg_integer(),
           ValueSpec :: (ValueSize :: non_neg_integer()) | (ValueBin :: binary())} |
          recbuf | reuseaddr | reuseport | reuseport_lb | send_timeout | send_timeout_close |
          show_econnreset | sndbuf | tos | tclass | ttl | recvtos | recvtclass | recvttl | pktoptions |
          user_timeout | ipv6_v6only.

pktoptions_value()

-type pktoptions_value() :: {pktoptions, inet:ancillary_data()}.

Value from socket option pktoptions.

If the platform implements the IPv4 option IP_PKTOPTIONS, or the IPv6 option IPV6_PKTOPTIONS or IPV6_2292PKTOPTIONS for the socket; this value is returned from inet:getopts/2 when called with the option name pktoptions.

Note

This option appears to be VERY Linux specific, and its existence in future Linux kernel versions is also worrying since the option is part of RFC 2292 which is since long (2003) obsoleted by RFC 3542 that explicitly removes this possibility to get packet information from a stream socket. For comparison: it has existed in FreeBSD but is now removed, at least since FreeBSD 10.

socket()

-type socket() :: inet:socket().

As returned by accept/1,2 and connect/3,4.

Functions

accept(ListenSocket)

-spec accept(ListenSocket) -> {ok, Socket} | {error, Reason}
                when
                    ListenSocket :: socket(),
                    Socket :: socket(),
                    Reason :: closed | system_limit | inet:posix().

Equivalent to accept(ListenSocket, infinity).

accept(ListenSocket, Timeout)

-spec accept(ListenSocket, Timeout) -> {ok, Socket} | {error, Reason}
                when
                    ListenSocket :: socket(),
                    Timeout :: timeout(),
                    Socket :: socket(),
                    Reason :: closed | timeout | system_limit | inet:posix().

Accept an incoming connection request on a listen socket.

ListenSocket must be a socket returned from listen/2. Timeout specifies a time-out value in milliseconds. Defaults to infinity.

Returns:

{ok, Socket} if a connection is established

{error, closed} if ListenSocket is closed

{error, timeout} if no connection is established within Timeout

{error, system_limit} if all available ports in the Erlang emulator are in use

A POSIX error value if something else goes wrong, see inet about possible values

To send packets (outbound) on the returned Socket, use send/2. Packets sent from the peer (inbound) are delivered as messages to the socket owner; the process that created the socket. Unless {active, false} is specified in the option list when creating the listening socket.

See connect/4 about active mode socket messages and passive mode.

Note

The accept call doesn't have to be issued from the socket owner process. Using version 5.5.3 and higher of the emulator, multiple simultaneous accept calls can be issued from different processes, which allows for a pool of acceptor processes handling incoming connections.

close(Socket)

-spec close(Socket) -> ok when Socket :: socket().

Close a TCP socket.

Note that in most implementations of TCP, doing a close does not guarantee that the data sent is delivered to the recipient. It is guaranteed that the recepient will see all sent data before getting the close, but the sender gets no indication of that.

If the sender needs to know that the recepient has received all data there are two common ways to achieve this:

Use gen_tcp:shutdown(Sock, write) to signal that no more data is to be sent and wait for the other side to acknowledge seeing its read side being closed, by closing its write side, which shows as a socket close on this side.

Implement an acknowledgement in the protocol on top of TCP that both connection ends adhere to, indicating that all data has been seen. The socket option {packet, N} may be useful.

connect(SockAddr, Opts)

(since OTP 24.3)

-spec connect(SockAddr, Opts) -> {ok, Socket} | {error, Reason}
                 when
                     SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                     Opts :: [inet:inet_backend() | connect_option()],
                     Socket :: socket(),
                     Reason :: inet:posix().

Equivalent to connect(SockAddr, Opts, infinity).

connect/3

-spec connect(Address, Port, Opts) -> {ok, Socket} | {error, Reason}
                 when
                     Address :: inet:socket_address() | inet:hostname(),
                     Port :: inet:port_number(),
                     Opts :: [inet:inet_backend() | connect_option()],
                     Socket :: socket(),
                     Reason :: inet:posix();
             (SockAddr, Opts, Timeout) -> {ok, Socket} | {error, Reason}
                 when
                     SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                     Opts :: [inet:inet_backend() | connect_option()],
                     Timeout :: timeout(),
                     Socket :: socket(),
                     Reason :: timeout | inet:posix().

Create a socket connected to the specified address.

With arguments Address and Port

Equivalent to connect(Address, Port, Opts, infinity).

With argument SockAddr (since OTP 24.3)

Connects to a remote listen socket specified by SockAddr where socket:sockaddr_in6/0 for example allows specifying the scope_id for link local IPv6 addresses.

IPv4 addresses on the same map/0 format is also allowed.

Equivalent to connect/4, besides the format of the destination address.

connect(Address, Port, Opts, Timeout)

-spec connect(Address, Port, Opts, Timeout) -> {ok, Socket} | {error, Reason}
                 when
                     Address :: inet:socket_address() | inet:hostname(),
                     Port :: inet:port_number(),
                     Opts :: [inet:inet_backend() | connect_option()],
                     Timeout :: timeout(),
                     Socket :: socket(),
                     Reason :: timeout | inet:posix().

Create a socket connected to the specified address.

Creates a socket and connects it to a server on TCP port Port on the host with IP address Address, that may also be a hostname.

Opts (connect options)

{ip, Address} - If the local host has many IP addresses, this option specifies which one to use.

{ifaddr, Address} - Same as {ip, Address}.

However, if Address instead is a socket:sockaddr_in/0 or socket:sockaddr_in6/0 this takes precedence over any value previously set with the ip and port options. If these options (ip or/and port) however comes after this option, they may be used to update the corresponding fields of this option (for ip, the addr field, and for port, the port field).

{fd, integer() >= 0} - If a socket has somehow been connected without using gen_tcp, use this option to pass the file descriptor for it. If {ip, Address} and/or {port, port_number()} is combined with this option, the fd is bound to the specified interface and port before connecting. If these options are not specified, it is assumed that the fd is already bound appropriately.

inet - Sets up the socket for IPv4.

inet6 - Sets up the socket for IPv6.

local - Sets up a Unix Domain Socket. See inet:local_address/0

{port, Port} - Specifies which local port number to use.

{tcp_module, module()} - Overrides which callback module is used. Defaults to inet_tcp for IPv4 and inet6_tcp for IPv6.

{protocol, tcp|mptcp} - With mptcp creates the socket with protocol IPPROTO_MPTCP, if that is defined on the system. Other than that the socket is regarded as a tcp socket. If IPPROTO_MPTCP is not defined, {error, eprotonosupport} is returned. tcp is the default value.

option/0 - See inet:setopts/2.

Socket Data

Packets can be sent to the peer (outbound) with send(Socket, Packet). Packets sent from the peer (inbound) are delivered as messages to the socket owner; the process that created the socket, unless {active, false} is specified in the Options list.

Active mode socket messages

{tcp, Socket, Data} - Inbound data from the socket.

{tcp_passive, Socket} - The socket was in {active, N} mode (see inet:setopts/2 for details) and its message counter reached 0, indicating that the socket has transitioned to passive ({active, false}) mode.

{tcp_closed, Socket} - The socket was closed.

{tcp_error, Socket, Reason} A socket error occurred.

Passive mode

If {active, false} is specified in the option list for the socket, packets and errors are retrieved by calling recv/2,3 (send/2 may also return errors).

Timeout

The optional Timeout parameter specifies a connect time-out in milliseconds. Defaults to infinity.

Note

Keep in mind that if the underlying OS connect() call returns a timeout, gen_tcp:connect will also return a timeout (i.e. {error, etimedout}), even if a larger Timeout was specified (for example infinity).

Note

The default values for options specified to connect can be affected by the Kernel configuration parameter inet_default_connect_options. For details, see inet.

controlling_process(Socket, Pid)

-spec controlling_process(Socket, Pid) -> ok | {error, Reason}
                             when
                                 Socket :: socket(),
                                 Pid :: pid(),
                                 Reason :: closed | not_owner | badarg | inet:posix().

Change the controlling process (owner) of a socket.

Assigns a new controlling process Pid to Socket. The controlling process is the process that the socket sends messages to. If this function is called from any other process than the current controlling process, {error, not_owner} is returned.

If the process identified by Pid is not an existing local pid/0, {error, badarg} is returned. {error, badarg} may also be returned in some cases when Socket is closed during the execution of this function.

If the socket is in active mode, this function will transfer any messages from the socket in the mailbox of the caller to the new controlling process.

If any other process is interacting with the socket during the transfer, it may not work correctly and messages may remain in the caller's mailbox. For instance, changing the sockets active mode during the transfer could cause this.

listen(Port, Options)

-spec listen(Port, Options) -> {ok, ListenSocket} | {error, Reason}
                when
                    Port :: inet:port_number(),
                    Options :: [inet:inet_backend() | listen_option()],
                    ListenSocket :: socket(),
                    Reason :: system_limit | inet:posix().

Create a listen socket.

Creates a socket and sets it to listen on port Port on the local host.

If Port == 0, the underlying OS assigns an available (ephemeral) port number, use inet:port/1 to retrieve it.

The following options are available:

list - Received Packets are delivered as lists of bytes, [byte/0].

binary - Received Packets are delivered as binary/0s.

{backlog, B} - B :: non_neg_integer/0. The backlog value defines the maximum length that the queue of pending connections can grow to. Defaults to 5.

inet6 - Sets up the socket for IPv6.

inet - Sets up the socket for IPv4.

{fd, Fd} - If a socket has somehow been created without using gen_tcp, use this option to pass the file descriptor for it.

{ip, Address} - If the host has many IP addresses, this option specifies which one to listen on.

{port, Port} - Specifies which local port number to use.

{ifaddr, Address} - Same as {ip, Address}.

However, if this instead is an socket:sockaddr_in/0 or socket:sockaddr_in6/0 this takes precedence over any value previously set with the ip and port options. If these options (ip or/and port) however comes after this option, they may be used to update their corresponding fields of this option (for ip, the addr field, and for port, the port field).

{tcp_module, module()} - Overrides which callback module is used. Defaults to inet_tcp for IPv4 and inet6_tcp for IPv6.

{protocol, tcp|mptcp} - With mptcp creates the socket with protocol IPPROTO_MPTCP, if that is defined on the system. Other than that the socket is regarded as a tcp socket. If IPPROTO_MPTCP is not defined, {error, eprotonosupport} is returned. tcp is the default value.

option/0 - See inet:setopts/2.

The returned socket ListenSocket should be used when calling accept/1,2 to accept an incoming connection request.

Note

The default values for options specified to listen can be affected by the Kernel configuration parameter inet_default_listen_options. For details, see inet.

recv(Socket, Length)

-spec recv(Socket, Length) -> {ok, Packet} | {error, Reason}
              when
                  Socket :: socket(),
                  Length :: non_neg_integer(),
                  Packet :: string() | binary() | HttpPacket,
                  Reason :: closed | inet:posix(),
                  HttpPacket :: term().

Equivalent to recv(Socket, Length, infinity).

recv(Socket, Length, Timeout)

-spec recv(Socket, Length, Timeout) -> {ok, Packet} | {error, Reason}
              when
                  Socket :: socket(),
                  Length :: non_neg_integer(),
                  Timeout :: timeout(),
                  Packet :: string() | binary() | HttpPacket,
                  Reason :: closed | timeout | inet:posix(),
                  HttpPacket :: term().

Receive a packet, from a socket in passive mode.

A closed socket is indicated by the return value {error, closed}. If the socket is not in passive mode, the return value is {error, einval}.

Argument Length is only meaningful when the socket is in raw mode and denotes the number of bytes to read. If Length is 0, all available bytes are returned. If Length > 0, exactly Length bytes are returned, or an error; except if the socket is closed from the other side, then the last read before the one returning {error, closed} may return less than Length bytes of data.

The optional Timeout parameter specifies a time-out in milliseconds. Defaults to infinity.

Any process can receive data from a passive socket, even if that process is not the controlling process of the socket. However, only one process can call this function on a socket at any given time. Using simultaneous calls to recv is not recommended as the behavior depends on the socket implementation, and could return errors such as {error, ealready}.

send(Socket, Packet)

-spec send(Socket, Packet) -> ok | {error, Reason}
              when
                  Socket :: socket(),
                  Packet :: iodata(),
                  Reason :: closed | {timeout, RestData} | inet:posix(),
                  RestData :: binary() | erlang:iovec().

Send a packet on a socket.

There is no send/2 call with a time-out option; use socket option send_timeout if time-outs are desired. See section Examples.

The return value {error, {timeout, RestData}} can only be returned when inet_backend = socket.

Note

Non-blocking send.

If the user tries to send more data than there is room for in the OS send buffers, the 'rest data' is stored in (inet driver) internal buffers and later sent in the background. The function immediately returns ok (not informing the caller that some date isn'nt sent yet). Any issue while sending the 'rest data' may be returned later.

When using inet_backend = socket, the behaviour is different. There is no buffering, instead the caller will "hang" until all of the data has been sent or the send timeout (as specified by the send_timeout option) expires (the function can "hang" even when using the inet backend if the internal buffers are full).

If this happens when using packet =/= raw, a partial packet has been written. A new packet therefore mustn't be written at this point, as there is no way for the peer to distinguish this from data in the current packet. Instead, set the packet option to raw, send the rest data (as raw data) and then set packet back to the correct type.

shutdown(Socket, How)

-spec shutdown(Socket, How) -> ok | {error, Reason}
                  when Socket :: socket(), How :: read | write | read_write, Reason :: inet:posix().

Close the socket in one or both directions.

How == write means closing the socket for writing, reading from it is still possible.

If How == read or there is no outgoing data buffered in the Socket port, the shutdown is performed immediately and any error encountered is returned in Reason.

If there is data buffered in the socket port, shutdown isn't performed on the socket until that buffered data has been written to the OS protocol stack. If any errors are encountered, the socket is closed and {error, closed} is returned by the next recv/2 or send/2 call.

Option {exit_on_close, false} is useful if the peer performs a shutdown of its write side. Then the socket stays open for writing after receive has indicated that the socket was closed.

Note

Async shutdown write (How :: write | read_write).

If the shutdown attempt is made while the inet driver is sending buffered data in the background, the shutdown is postponed until all buffered data has been sent. This function immediately returns ok, and the caller isn't informed (that the shutdown has been postponed).

When using inet_backend = socket, the behaviour is different. A shutdown with How :: write | read_write will always be performed immediately.

gen_udp

Interface to UDP sockets.

This module provides functions for communicating over UDP protocol sockets.

Note

Functions that create sockets can take an optional option; {inet_backend, Backend} that, if specified, has to be the first option. This selects the implementation backend towards the platform's socket API.

This is a temporary option that will be ignored in a future release.

The default is Backend = inet that selects the traditional inet_drv.c driver. The other choice is Backend = socket that selects the new socket module and its NIF implementation.

The system default can be changed when the node is started with the application kernel's configuration variable inet_backend.

For gen_udp with inet_backend = socket we have tried to be as "compatible" as possible which has sometimes been impossible. Here is a list of cases when the behaviour of inet-backend inet (default) and socket are different:

The option read_packets is currently ignored.

Windows require sockets (domain = inet | inet6) to be bound.

Currently all sockets created on Windows with inet_backend = socket will be bound. If the user does not provide an address, gen_udp will try to 'figure out' an address itself.

Summary

Types

ip6_membership()

ip6_multicast_if()

IPv6 this multicast interface index (an integer).

ip_membership()

IP multicast membership.

ip_multicast_if()

membership()

multicast_if()

open_option()

option()

option_name()

socket()

A socket as returned by open/1,2.

Functions

close(Socket)

Closes a UDP socket.

connect(Socket, SockAddr)

Connect a UDP socket.

connect(Socket, Address, Port)

Connect a UDP socket.

controlling_process(Socket, Pid)

Change the controlling process (owner) of a socket.

open(Port)

Equivalent to open(Port, []).

open(Port, Opts)

Open a UDP socket.

recv(Socket, Length)

Equivalent to recv(Socket, Length, infinity).

recv(Socket, Length, Timeout)

Receive a packet from a socket in passive mode.

send(Socket, Packet)

Send a packet on a connected UDP socket.

send(Socket, Destination, Packet)

Equivalent to send(Socket, Destination, [], Packet).

send/4

Send a UDP packet to the specified destination.

send(Socket, Host, Port, AncData, Packet)

Send a packet to the specified destination, with ancillary data.

Types

ip6_membership()

-type ip6_membership() :: {MultiAddress :: inet:ip6_address(), IfIndex :: integer()}.

ip6_multicast_if()

-type ip6_multicast_if() :: integer().

IPv6 this multicast interface index (an integer).

ip_membership()

-type ip_membership() ::
          {MultiAddress :: inet:ip4_address(), Interface :: inet:ip4_address()} |
          {MultiAddress :: inet:ip4_address(), Address :: inet:ip4_address(), IfIndex :: integer()}.

IP multicast membership.

The 3-tuple form isn't supported on all platforms. 'ifindex' defaults to zero (0) on platforms that supports the 3-tuple variant.

ip_multicast_if()

-type ip_multicast_if() :: inet:ip4_address().

membership()

-type membership() :: ip_membership() | ip6_membership().

multicast_if()

-type multicast_if() :: ip_multicast_if() | ip6_multicast_if().

open_option()

-type open_option() ::
          {ip, inet:socket_address()} |
          {fd, non_neg_integer()} |
          {ifaddr, socket:sockaddr_in() | socket:sockaddr_in6() | inet:socket_address()} |
          inet:address_family() |
          {port, inet:port_number()} |
          {netns, file:filename_all()} |
          {bind_to_device, binary()} |
          option().

option()

-type option() ::
          {active, true | false | once | -32768..32767} |
          {add_membership, membership()} |
          {broadcast, boolean()} |
          {buffer, non_neg_integer()} |
          {debug, boolean()} |
          {deliver, port | term} |
          {dontroute, boolean()} |
          {drop_membership, membership()} |
          {exclusiveaddruse, boolean()} |
          {header, non_neg_integer()} |
          {high_msgq_watermark, pos_integer()} |
          {low_msgq_watermark, pos_integer()} |
          {mode, list | binary} |
          list | binary |
          {multicast_if, multicast_if()} |
          {multicast_loop, boolean()} |
          {multicast_ttl, non_neg_integer()} |
          {priority, non_neg_integer()} |
          {raw, Protocol :: non_neg_integer(), OptionNum :: non_neg_integer(), ValueBin :: binary()} |
          {read_packets, non_neg_integer()} |
          {recbuf, non_neg_integer()} |
          {reuseaddr, boolean()} |
          {reuseport, boolean()} |
          {reuseport_lb, boolean()} |
          {sndbuf, non_neg_integer()} |
          {tos, non_neg_integer()} |
          {tclass, non_neg_integer()} |
          {ttl, non_neg_integer()} |
          {recvtos, boolean()} |
          {recvtclass, boolean()} |
          {recvttl, boolean()} |
          {ipv6_v6only, boolean()}.

option_name()

-type option_name() ::
          active | broadcast | buffer | debug | deliver | dontroute | exclusiveaddruse | header |
          high_msgq_watermark | low_msgq_watermark | mode | multicast_if | multicast_loop |
          multicast_ttl | priority |
          {raw,
           Protocol :: non_neg_integer(),
           OptionNum :: non_neg_integer(),
           ValueSpec :: (ValueSize :: non_neg_integer()) | (ValueBin :: binary())} |
          read_packets | recbuf | reuseaddr | reuseport | reuseport_lb | sndbuf | tos | tclass | ttl |
          recvtos | recvtclass | recvttl | pktoptions | ipv6_v6only.

socket()

-type socket() :: inet:socket().

A socket as returned by open/1,2.

Functions

close(Socket)

-spec close(Socket) -> ok when Socket :: socket().

Closes a UDP socket.

connect(Socket, SockAddr)

(since OTP 24.3)

-spec connect(Socket, SockAddr) -> ok | {error, Reason}
                 when
                     Socket :: socket(),
                     SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                     Reason :: inet:posix().

Connect a UDP socket.

Connecting a UDP socket only means storing the specified (destination) socket address, as specified by SockAddr, so that the system knows where to send data.

When the socket is "connected" it is not necessary to specify the destination address when sending a datagram. That is; send/2 may be used.

It also means that the socket will only receive data from the connected address. Other messages are discarded on arrival by the OS protocol stack.

connect(Socket, Address, Port)

(since OTP 24.3)

-spec connect(Socket, Address, Port) -> ok | {error, Reason}
                 when
                     Socket :: socket(),
                     Address :: inet:socket_address() | inet:hostname(),
                     Port :: inet:port_number(),
                     Reason :: inet:posix().

Connect a UDP socket.

See connect/2.

With this function the destination is specified with separate Address and Port arguments where Address may be an IP address or a host name.

controlling_process(Socket, Pid)

-spec controlling_process(Socket, Pid) -> ok | {error, Reason}
                             when
                                 Socket :: socket(),
                                 Pid :: pid(),
                                 Reason :: closed | not_owner | badarg | inet:posix().

Change the controlling process (owner) of a socket.

Assigns a new controlling process Pid to Socket. The controlling process is the process that the socket sends messages to. If this function is called from any other process than the current controlling process, {error, not_owner} is returned.

If the process identified by Pid is not an existing local pid/0, {error, badarg} is returned. {error, badarg} may also be returned in some cases when Socket is closed during the execution of this function.

If the socket is in active mode, this function will transfer any messages from the socket in the mailbox of the caller to the new controlling process.

If any other process is interacting with the socket during the transfer, it may not work correctly and messages may remain in the caller's mailbox. For instance, changing the sockets active mode during the transfer could cause this.

open(Port)

-spec open(Port) -> {ok, Socket} | {error, Reason}
              when Port :: inet:port_number(), Socket :: socket(), Reason :: system_limit | inet:posix().

Equivalent to open(Port, []).

open(Port, Opts)

-spec open(Port, Opts) -> {ok, Socket} | {error, Reason}
              when
                  Port :: inet:port_number(),
                  Opts :: [inet:inet_backend() | open_option()],
                  Socket :: socket(),
                  Reason :: system_limit | inet:posix().

Open a UDP socket.

The created socket is bound to the UDP port number Port. If Port == 0, the underlying OS assigns a free (ephemeral) UDP port; use inet:port/1 to retrieve it.

The process that calls this function becomes the Socket's controlling process (socket owner).

UDP socket options

list - Received Packet is delivered as a list.

binary - Received Packet is delivered as a binary.

{ip, Address} - If the local host has many IP addresses, this option specifies which one to use.

{ifaddr, Address} - Same as {ip, Address}.

However, if this instead is a socket:sockaddr_in/0 or socket:sockaddr_in6/0 this takes precedence over any value previously set with the ip options. If the ip option comes after the ifaddr option, it may be used to update its corresponding field of the ifaddr option (the addr field).

{fd, integer() >= 0} - If a socket has somehow been opened without using gen_udp, use this option to pass the file descriptor for it. If Port is not set to 0 and/or {ip, ip_address()} is combined with this option, the fd is bound to the specified interface and port after it is being opened. If these options are not specified, it is assumed that the fd is already bound appropriately.

inet6 - Sets up the socket for IPv6.

inet - Sets up the socket for IPv4.

local - Sets up a Unix Domain Socket. See inet:local_address/0

{udp_module, module()} - Overrides which callback module is used. Defaults to inet_udp for IPv4 and inet6_udp for IPv6.

{multicast_if, Address} - Sets the local device for a multicast socket.

{multicast_loop, true | false} - When true, sent multicast packets are looped back to the local sockets.

{multicast_ttl, Integer} - Option multicast_ttl changes the time-to-live (TTL) for outgoing multicast datagrams to control the scope of the multicasts.

Datagrams with a TTL of 1 are not forwarded beyond the local network. Defaults to 1.

{add_membership, {MultiAddress, InterfaceAddress}} - Joins a multicast group.

{drop_membership, {MultiAddress, InterfaceAddress}} - Leaves a multicast group.

option/0 - See inet:setopts/2.

UDP packets are sent with this socket using send(Socket, ...). When UDP packets arrive to the Socket's UDP port, and the socket is in an active mode, the packets are delivered as messages to the controlling process (socket owner):

{udp, Socket, PeerIP, PeerPort, Packet} % Without ancillary data
{udp, Socket, PeerIP, PeerPort, AncData, Packet} % With ancillary data

PeerIP and PeerPort are the address from which Packet was sent. Packet is a list of bytes ([byte/0] if option list is active and a binary/0 if option binaryis active (they are mutually exclusive).

The message contains an AncData field only if any of the socket options recvtos, recvtclass or recvttl are active.

When a socket in {active, N} mode (see inet:setopts/2 for details), transitions to passive ({active, false}) mode (N counts down to 0), the controlling process is notified by a message on this form:

{udp_passive, Socket}

If the OS protocol stack reports an error for the socket, the following message is sent to the controlling process:

{udp_error, Socket, Reason}

Reason is mostly a POSIX Error Code.

If the socket is in passive mode (not in an active mode), received data can be retrieved with therecv/2,3](recv/2) calls. Note that incoming UDP packets that are longer than the receive buffer option specifies can be truncated without warning.

The default value for the receive buffer option is {recbuf, 9216}.

recv(Socket, Length)

-spec recv(Socket, Length) -> {ok, RecvData} | {error, Reason}
              when
                  Socket :: socket(),
                  Length :: non_neg_integer(),
                  RecvData :: {Address, Port, Packet} | {Address, Port, AncData, Packet},
                  Address :: inet:ip_address() | inet:returned_non_ip_address(),
                  Port :: inet:port_number(),
                  AncData :: inet:ancillary_data(),
                  Packet :: string() | binary(),
                  Reason :: not_owner | inet:posix().

Equivalent to recv(Socket, Length, infinity).

recv(Socket, Length, Timeout)

-spec recv(Socket, Length, Timeout) -> {ok, RecvData} | {error, Reason}
              when
                  Socket :: socket(),
                  Length :: non_neg_integer(),
                  Timeout :: timeout(),
                  RecvData :: {Address, Port, Packet} | {Address, Port, AncData, Packet},
                  Address :: inet:ip_address() | inet:returned_non_ip_address(),
                  Port :: inet:port_number(),
                  AncData :: inet:ancillary_data(),
                  Packet :: string() | binary(),
                  Reason :: not_owner | timeout | inet:posix().

Receive a packet from a socket in passive mode.

Timeout specifies a time-out in milliseconds.

If any of the socket options recvtos, recvtclass or recvttl are active, the RecvData tuple contains an AncData field, otherwise it doesn't.

send(Socket, Packet)

(since OTP 24.3)

-spec send(Socket, Packet) -> ok | {error, Reason}
              when Socket :: socket(), Packet :: iodata(), Reason :: not_owner | inet:posix().

Send a packet on a connected UDP socket.

To connect a UDP socket, use connect/2 or connect/3.

send(Socket, Destination, Packet)

(since OTP 22.1)

-spec send(Socket, Destination, Packet) -> ok | {error, Reason}
              when
                  Socket :: socket(),
                  Destination ::
                      {inet:ip_address(), inet:port_number()} |
                      inet:family_address() |
                      socket:sockaddr_in() |
                      socket:sockaddr_in6(),
                  Packet :: iodata(),
                  Reason :: not_owner | inet:posix().

Equivalent to send(Socket, Destination, [], Packet).

send/4

-spec send(Socket, Host, Port, Packet) -> ok | {error, Reason}
              when
                  Socket :: socket(),
                  Host :: inet:hostname() | inet:ip_address(),
                  Port :: inet:port_number() | atom(),
                  Packet :: iodata(),
                  Reason :: not_owner | inet:posix();
          (Socket, Destination, AncData, Packet) -> ok | {error, Reason}
              when
                  Socket :: socket(),
                  Destination ::
                      {inet:ip_address(), inet:port_number()} |
                      inet:family_address() |
                      socket:sockaddr_in() |
                      socket:sockaddr_in6(),
                  AncData :: inet:ancillary_data(),
                  Packet :: iodata(),
                  Reason :: not_owner | inet:posix();
          (Socket, Destination, PortZero, Packet) -> ok | {error, Reason}
              when
                  Socket :: socket(),
                  Destination :: {inet:ip_address(), inet:port_number()} | inet:family_address(),
                  PortZero :: inet:port_number(),
                  Packet :: iodata(),
                  Reason :: not_owner | inet:posix().

Send a UDP packet to the specified destination.

With arguments Host and Port

Argument Host can be a hostname or a socket address, and Port can be a port number or a service name atom. These are resolved to a Destination and then this function is equivalent to send(Socket, Destination, [], Packet) just below.

With arguments Destination and AncData (since OTP 22.1)

Sends a packet to the specified Destination with ancillary data AncData.

Note

The ancillary data AncData contains options that for this single message override the default options for the socket, an operation that may not be supported on all platforms, and if so return {error, einval}. Using more than one of an ancillary data item type may also not be supported. AncData =:= [] is always supported.

With arguments Destination and PortZero (since OTP 22.1)

Sends a packet to the specified Destination. Since Destination is a complete address, PortZero is redundant and has to be 0.

This is a legacy clause mostly for Destination = {local, Binary} where PortZero is superfluous. Equivalent to send(Socket, Destination, [], Packet), right above here.

send(Socket, Host, Port, AncData, Packet)

(since OTP 22.1)

-spec send(Socket, Host, Port, AncData, Packet) -> ok | {error, Reason}
              when
                  Socket :: socket(),
                  Host :: inet:hostname() | inet:ip_address() | inet:local_address(),
                  Port :: inet:port_number() | atom(),
                  AncData :: inet:ancillary_data(),
                  Packet :: iodata(),
                  Reason :: not_owner | inet:posix().

Send a packet to the specified destination, with ancillary data.

Equivalent to send(Socket, Host, Port, Packet) regarding Host and Port and also equivalent to send(Socket, Destination, AncData, Packet) regarding the ancillary data: AncData.

inet

Access to Network protocols.

This module, together with gen_tcp, gen_udp and gen_sctp provides access to the Network protocols TCP, SCTP and UDP over IP, as well as stream and datagram protocols over the local (unix) address domain / protocol domain.

See also ERTS User's Guide: Inet Configuration or more information about how to configure an Erlang runtime system for IP communication.

The following four Kernel configuration parameters affect the behavior of all gen_tcp, gen_udp and gen_sctp sockets opened on an Erlang node:

inet_default_connect_options can contain a list of default options used for all sockets created by a gen_tcp:connect/2,3,4](gen_tcp:connect/2) call.

inet_default_listen_options can contain a list of default options used for sockets created by a gen_tcp:listen/2 call.

inet_default_udp_options can contain a list of default options used for all sockets created by a gen_udp:open/1,2](gen_udp:open/2) call.

inet_default_sctp_options can contain a list of default options used for all sockets created by a gen_sctp:open/0,1](gen_sctp:open/1) call.

For the gen_tcp:accept/1,2 call, the values of the listening socket options are inherited. Therefore there is no corresponding application variable for accept.

Using the Kernel configuration parameters above, one can set default options for all TCP sockets on a node, but use this with care. Options such as {delay_send,true} can be specified in this way. The following is an example of starting an Erlang node with all sockets using delayed send:

$ erl -sname test -kernel \
inet_default_connect_options '[{delay_send,true}]' \
inet_default_listen_options '[{delay_send,true}]'

Please note that the default option {active, true} cannot be changed, for internal implementation reasons.

Addresses as inputs to functions can be either a string or a tuple. For example, the IP address 150.236.20.73 can be passed to gethostbyaddr/1, either as a string "150.236.20.73" or as a tuple {150, 236, 20, 73}.

IPv4 address examples:

Address          ip_address()
-------          ------------
127.0.0.1        {127,0,0,1}
192.168.42.2     {192,168,42,2}

IPv6 address examples:

Address          ip_address()
-------          ------------
::1             {0,0,0,0,0,0,0,1}
::192.168.42.2  {0,0,0,0,0,0,(192 bsl 8) bor 168,(42 bsl 8) bor 2}
::FFFF:192.168.42.2
                {0,0,0,0,0,16#FFFF,(192 bsl 8) bor 168,(42 bsl 8) bor 2}
3ffe:b80:1f8d:2:204:acff:fe17:bf38
                {16#3ffe,16#b80,16#1f8d,16#2,16#204,16#acff,16#fe17,16#bf38}
fe80::204:acff:fe17:bf38
                {16#fe80,0,0,0,16#204,16#acff,16#fe17,16#bf38}

Function parse_address/1 can be useful:

1> inet:parse_address("192.168.42.2").
{ok,{192,168,42,2}}
2> inet:parse_address("::FFFF:192.168.42.2").
{ok,{0,0,0,0,0,65535,49320,10754}}

POSIX Error Codes

e2big - Too long argument list

eacces - Permission denied

eaddrinuse - Address already in use

eaddrnotavail - Cannot assign requested address

eadv - Advertise error

eafnosupport - Address family not supported by protocol family

eagain - Resource temporarily unavailable

ealign - EALIGN

ealready - Operation already in progress

ebade - Bad exchange descriptor

ebadf - Bad file number

ebadfd - File descriptor in bad state

ebadmsg - Not a data message

ebadr - Bad request descriptor

ebadrpc - Bad RPC structure

ebadrqc - Bad request code

ebadslt - Invalid slot

ebfont - Bad font file format

ebusy - File busy

echild - No children

echrng - Channel number out of range

ecomm - Communication error on send

econnaborted - Software caused connection abort

econnrefused - Connection refused

econnreset - Connection reset by peer

edeadlk - Resource deadlock avoided

edeadlock - Resource deadlock avoided

edestaddrreq - Destination address required

edirty - Mounting a dirty fs without force

edom - Math argument out of range

edotdot - Cross mount point

edquot - Disk quota exceeded

eduppkg - Duplicate package name

eexist - File already exists

efault - Bad address in system call argument

efbig - File too large

ehostdown - Host is down

ehostunreach - Host is unreachable

eidrm - Identifier removed

einit - Initialization error

einprogress - Operation now in progress

eintr - Interrupted system call

einval - Invalid argument

eio - I/O error

eisconn - Socket is already connected

eisdir - Illegal operation on a directory

eisnam - Is a named file

el2hlt - Level 2 halted

el2nsync - Level 2 not synchronized

el3hlt - Level 3 halted

el3rst - Level 3 reset

elbin - ELBIN

elibacc - Cannot access a needed shared library

elibbad - Accessing a corrupted shared library

elibexec - Cannot exec a shared library directly

elibmax - Attempting to link in more shared libraries than system limit

elibscn - .lib section in a.out corrupted

elnrng - Link number out of range

eloop - Too many levels of symbolic links

emfile - Too many open files

emlink - Too many links

emsgsize - Message too long

emultihop - Multihop attempted

enametoolong - Filename too long

enavail - Unavailable

enet - ENET

enetdown - Network is down

enetreset - Network dropped connection on reset

enetunreach - Network is unreachable

enfile - File table overflow

enoano - Anode table overflow

enobufs - No buffer space available

enocsi - No CSI structure available

enodata - No data available

enodev - No such device

enoent - No such file or directory

enoexec - Exec format error

enolck - No locks available

enolink - Link has been severed

enomem - Not enough memory

enomsg - No message of desired type

enonet - Machine is not on the network

enopkg - Package not installed

enoprotoopt - Bad protocol option

enospc - No space left on device

enosr - Out of stream resources or not a stream device

enosym - Unresolved symbol name

enosys - Function not implemented

enotblk - Block device required

enotconn - Socket is not connected

enotdir - Not a directory

enotempty - Directory not empty

enotnam - Not a named file

enotsock - Socket operation on non-socket

enotsup - Operation not supported

enotty - Inappropriate device for ioctl

enotuniq - Name not unique on network

enxio - No such device or address

eopnotsupp - Operation not supported on socket

eperm - Not owner

epfnosupport - Protocol family not supported

epipe - Broken pipe

eproclim - Too many processes

eprocunavail - Bad procedure for program

eprogmismatch - Wrong program version

eprogunavail - RPC program unavailable

eproto - Protocol error

eprotonosupport - Protocol not supported

eprototype - Wrong protocol type for socket

erange - Math result unrepresentable

erefused - EREFUSED

eremchg - Remote address changed

eremdev - Remote device

eremote - Pathname hit remote filesystem

eremoteio - Remote I/O error

eremoterelease - EREMOTERELEASE

erofs - Read-only filesystem

erpcmismatch - Wrong RPC version

erremote - Object is remote

eshutdown - Cannot send after socket shutdown

esocktnosupport - Socket type not supported

espipe - Invalid seek

esrch - No such process

esrmnt - Srmount error

estale - Stale remote file handle

esuccess - Error 0

etime - Timer expired

etimedout - Connection timed out

etoomanyrefs - Too many references

etxtbsy - Text file or pseudo-device busy

euclean - Structure needs cleaning

eunatch - Protocol driver not attached

eusers - Too many users

eversion - Version mismatch

ewouldblock - Operation would block

exdev - Cross-device link

exfull - Message tables full

nxdomain - Hostname or domain name cannot be found

Summary

Types

address_family()

ancillary_data()

Ancillary data / control messages.

ether_address()

family_address()

A general network address.

getifaddrs_ifopts()

Interface address description list.

hostent()

A record describing a host; name and address.

hostname()

i_option()

Options for selecting statistics items.

inet6_address()

A network address for the inet6 family (AF_INET6, IPv6)

inet_address()

A network address for the inet family (AF_INET, IPv4)

inet_backend()

Implementation backend selector for socket/0.

ip4_address()

ip6_address()

ip_address()

local_address()

A network address for the local family (AF_LOCAL | AF_UNIX)

module_socket()

port_number()

posix()

POSIX Error Code atom/0.

returned_non_ip_address()

a non-IP network address.

socket()

A socket recognized by this module and its siblings.

socket_address()

socket_getopt()

socket_optval()

socket_protocol()

socket_setopt()

stat_option()

Functions

cancel_monitor(MRef)

Cancel a socket monitor.

close(Socket)

Close a socket of any type.

format_error(Reason)

Format an error code into a string/0.

get_rc()

Get the inet configuration.

getaddr(Host, Family)

Resolve a host to an address, in a specific addresss family.

getaddrs(Host, Family)

Resolve a host to a list of addresses, in a specific address family.

gethostbyaddr(Address)

Resolve (reverse) an address to a #hostent{} record.

gethostbyname(Hostname)

Resolve a hostname to a #hostent{} record.

gethostbyname(Hostname, Family)

Resolve a hostname to a #hostent{} record, in a specific address family.

gethostname()

Get the local hostname.

getifaddrs()

Get interface names and addresses.

getifaddrs/1

Get interface names and addresses, in a specific namespace.

getopts(Socket, Options)

Get one or more options for a socket.

getstat(Socket)

Equivalent to getstat/2.

getstat(Socket, Options)

Get one or more statistics options for a socket.

i()

Equivalent to i/1 for the protocols tcp, udp, and sctp

i/1

List network sockets.

i/2

List network sockets.

info(Socket)

Get information about a socket.

ipv4_mapped_ipv6_address/1

Convert between an IPv4 address and an IPv4-mapped IPv6 address.

is_ip_address(IPAddress)

Test for an IP address.

is_ipv4_address(IPv4Address)

Test for an IPv4 address.

is_ipv6_address(IPv6Address)

Test for an IPv6 address.

monitor(Socket)

Start a socket monitor.

ntoa(IpAddress)

Parse an ip_address/0 to an IPv4 or IPv6 address string.

parse_address(Address)

Parse an IP address string to an ip_address/0.

parse_ipv4_address(Address)

Parse (relaxed) an IPv4 address string to an ip4_address/0.

parse_ipv4strict_address(Address)

Parse an IPv4 address string to an ip4_address/0.

parse_ipv6_address(Address)

Parse (relaxed) an IPv6 address string to an ip6_address/0.

parse_ipv6strict_address(Address)

Parse an IPv6 address string to an ip6_address/0.

parse_strict_address(Address)

Parse an IP address string to an ip_address/0.

peername(Socket)

Return the address of the socket's remote end.

peernames(Socket)

Equivalent to peernames(Socket, 0).

peernames(Socket, Assoc)

Return the addresses of all remote ends of a socket.

port(Socket)

Return the local port number for a socket.

setopts(Socket, Options)

Set one or more options for a socket.

sockname(Socket)

Return the local address and port number for a socket.

socknames(Socket)

Equivalent to socknames(Socket, 0).

socknames(Socket, Assoc)

Return all localaddresses for a socket.

Types

address_family()

-type address_family() :: inet | inet6 | local.

ancillary_data()

-type ancillary_data() :: [{tos, byte()} | {tclass, byte()} | {ttl, byte()}].

Ancillary data / control messages.

Ancillary data received with a data packet, read with the socket option pktoptions from a TCP socket, or to set in a call to gen_udp:send/4 or gen_udp:send/5.

The value(s) correspond to the currently active socket options recvtos, recvtclass and recvttl, or for a single send operation the option(s) to override the currently active socket option(s).

ether_address()

(not exported)

-type ether_address() :: [0..255].

family_address()

-type family_address() :: inet_address() | inet6_address() | local_address().

A general network address.

A general network address format of the form {Family, Destination} where Family is an atom such as local and the format of Destination depends on Family. Destination is a complete address (for example an IP address with port number).

getifaddrs_ifopts()

(not exported)

-type getifaddrs_ifopts() ::
          [Ifopt ::
               {flags, Flags :: [up | broadcast | loopback | pointtopoint | running | multicast]} |
               {addr, Addr :: ip_address()} |
               {netmask, Netmask :: ip_address()} |
               {broadaddr, Broadaddr :: ip_address()} |
               {dstaddr, Dstaddr :: ip_address()} |
               {hwaddr, Hwaddr :: [byte()]}].

Interface address description list.

A list returned from getifaddrs/0,1 for a named interface, translated from the returned data of the POSIX API function getaddrinfo().

Hwaddr is hardware dependent, for example, on Ethernet interfaces it is the 6-byte Ethernet address (MAC address (EUI-48 address)).

The tuples {addr,Addr}, {netmask,Netmask}, and possibly {broadaddr,Broadaddr} or {dstaddr,Dstaddr} are repeated in the list if the interface has got multiple addresses. An interface may have multiple {flag,_} tuples for example if it has different flags for different address families.

Multiple {hwaddr,Hwaddr} tuples is hard to say anything definite about, though. The tuple {flag,Flags} is mandatory, all others are optional.

Do not rely too much on the order of Flags atoms or the Ifopt tuples. There are however some rules:

A {flag,_} tuple applies to all other tuples that follow.

Immediately after {addr,_} follows {netmask,_}.

Immediately thereafter may {broadaddr,_} follow if broadcast is member of Flags, or {dstaddr,_} if pointtopoint is member of Flags. Both {dstaddr,_} and {broadaddr,_} doesn't occur for the same {addr,_}.

Any {netmask,_}, {broadaddr,_}, or {dstaddr,_} tuples that follow an {addr,Addr} tuple concerns the address Addr.

The tuple {hwaddr,_} is not returned on Solaris, as the hardware address historically belongs to the link layer and it is not returned by the Solaris API function getaddrinfo().

Warning

On Windows, the data is fetched from different OS API functions, so the Netmask and Broadaddr values may be calculated, just as some Flags values.

hostent()

-type hostent() ::
          #hostent{h_name :: inet:hostname(),
                   h_aliases :: [inet:hostname()],
                   h_addrtype :: inet | inet6,
                   h_length :: non_neg_integer(),
                   h_addr_list :: [inet:ip_address()]}.

A record describing a host; name and address.

Corresponds to the C: struct hostent as returned by for example gethostbyname(3).

The record is defined in the Kernel include file "inet.hrl".

Add the following directive to the module:

-include_lib("kernel/include/inet.hrl").

hostname()

-type hostname() :: atom() | string().

i_option()

(not exported)

-type i_option() ::
          port | module | recv | sent | owner | local_address |
          {local_address, ShowPorts :: boolean()} |
          foreign_address |
          {foreign_address, ShowPorts :: boolean()} |
          state | type.

Options for selecting statistics items.

Regarding ShowPorts, see show_ports as described in the i/2 function, defaults to false.

inet6_address()

(not exported)

-type inet6_address() :: {inet6, {ip6_address() | any | loopback, port_number()}}.

A network address for the inet6 family (AF_INET6, IPv6)

Warning

This address format is currently experimental and for completeness to make all address families have a {Family, Destination} representation.

inet_address()

(not exported)

-type inet_address() :: {inet, {ip4_address() | any | loopback, port_number()}}.

A network address for the inet family (AF_INET, IPv4)

Warning

This address format is currently experimental and for completeness to make all address families have a {Family, Destination} representation.

inet_backend()

-type inet_backend() :: {inet_backend, inet | socket}.

Implementation backend selector for socket/0.

Selects the implementation backend for sockets. The current default is inet which uses inet_drv.c to call the platform's socket API. The value socket instead uses the socket module and its NIF implementation.

This is a temporary option that will be ignored in a future release.

ip4_address()

-type ip4_address() :: {0..255, 0..255, 0..255, 0..255}.

ip6_address()

-type ip6_address() :: {0..65535, 0..65535, 0..65535, 0..65535, 0..65535, 0..65535, 0..65535, 0..65535}.

ip_address()

-type ip_address() :: ip4_address() | ip6_address().

local_address()

-type local_address() :: {local, File :: binary() | string()}.

A network address for the local family (AF_LOCAL | AF_UNIX)

This address family, also known as "Unix domain sockets" only works on Unix-like systems.

File is normally a file pathname in a local filesystem. It is limited in length by the operating system, traditionally to 108 bytes.

A binary/0 is passed as is to the operating system, but a string/0 is encoded according to the system filename encoding mode.

Other addresses are possible, for example Linux implements "Abstract Addresses". See the documentation for Unix Domain Sockets on your system, normally unix in manual section 7.

In most API functions where you can use this address family the port number must be 0.

module_socket()

(not exported)

-type module_socket() :: {'$inet', Handler :: module(), Handle :: term()}.

port_number()

-type port_number() :: 0..65535.

posix()

-type posix() ::
          eaddrinuse | eaddrnotavail | eafnosupport | ealready | econnaborted | econnrefused |
          econnreset | edestaddrreq | ehostdown | ehostunreach | einprogress | eisconn | emsgsize |
          enetdown | enetunreach | enopkg | enoprotoopt | enotconn | enotty | enotsock | eproto |
          eprotonosupport | eprototype | esocktnosupport | etimedout | ewouldblock | exbadport |
          exbadseq |
          file:posix().

POSIX Error Code atom/0.

An atom that is named from the POSIX error codes used in Unix, and in the runtime libraries of most C compilers. See section POSIX Error Codes.

returned_non_ip_address()

-type returned_non_ip_address() :: {local, binary()} | {unspec, <<>>} | {undefined, any()}.

a non-IP network address.

Addresses besides ip_address/0 ones that are returned from socket API functions. See in particular local_address/0. The unspec family corresponds to AF_UNSPEC and can occur if the other side has no socket address. The undefined family can only occur in the unlikely event of an address family that the VM doesn't recognize.

socket()

-type socket() :: port() | module_socket().

A socket recognized by this module and its siblings.

See gen_tcp:socket/0 and gen_udp:socket/0.

socket_address()

-type socket_address() :: ip_address() | any | loopback | local_address().

socket_getopt()

-type socket_getopt() :: gen_sctp:option_name() | gen_tcp:option_name() | gen_udp:option_name().

socket_optval()

-type socket_optval() ::
          gen_sctp:option_value() | gen_tcp:option() | gen_udp:option() | gen_tcp:pktoptions_value().

socket_protocol()

-type socket_protocol() :: tcp | udp | sctp.

socket_setopt()

-type socket_setopt() :: gen_sctp:option() | gen_tcp:option() | gen_udp:option().

stat_option()

-type stat_option() ::
          recv_cnt | recv_max | recv_avg | recv_oct | recv_dvi | send_cnt | send_max | send_avg |
          send_oct | send_pend.

Functions

cancel_monitor(MRef)

(since OTP 24.0)

-spec cancel_monitor(MRef) -> boolean() when MRef :: reference().

Cancel a socket monitor.

If MRef is a reference that the calling process obtained by calling monitor/1, this monitor is removed. If the monitoring is already removed, nothing happens.

The returned value is one of the following:

true - The monitor was found and removed. In this case, no 'DOWN' message corresponding to this monitor has been delivered and will not be delivered.

false - The monitor was not found and couldn't be removed. Probably because the monitor has already triggered and there is a corresponding 'DOWN' message in the caller message queue.

close(Socket)

-spec close(Socket) -> ok when Socket :: socket().

Close a socket of any type.

format_error(Reason)

-spec format_error(Reason) -> string() when Reason :: posix() | system_limit.

Format an error code into a string/0.

Returns a diagnostic error string. For possible POSIX values and corresponding strings, see section POSIX Error Codes.

get_rc()

-spec get_rc() -> [{Par :: atom(), Val :: any()} | {Par :: atom(), Val1 :: any(), Val2 :: any()}].

Get the inet configuration.

Returns the state of the inet configuration database in form of a list of recorded configuration parameters. For more information, see ERTS User's Guide: Inet Configuration.

Only actual parameters with other than default values are returned, for example not directives that specify other sources for configuration parameters nor directives that clear parameters.

getaddr(Host, Family)

-spec getaddr(Host, Family) -> {ok, Address} | {error, posix()}
                 when
                     Host :: ip_address() | hostname(),
                     Family :: address_family(),
                     Address :: ip_address().

Resolve a host to an address, in a specific addresss family.

Returns the IP address for Host as a tuple of integers. Host can be an IP address, a single hostname/0, or a fully qualified hostname/0.

getaddrs(Host, Family)

-spec getaddrs(Host, Family) -> {ok, Addresses} | {error, posix()}
                  when
                      Host :: ip_address() | hostname(),
                      Family :: address_family(),
                      Addresses :: [ip_address()].

Resolve a host to a list of addresses, in a specific address family.

Returns a list of all IP addresses for Host. Host can be an IP address, a single hostname/0, or a fully qualified hostname/0.

gethostbyaddr(Address)

-spec gethostbyaddr(Address) -> {ok, Hostent} | {error, posix()}
                       when Address :: string() | ip_address(), Hostent :: hostent().

Resolve (reverse) an address to a #hostent{} record.

Returns a #hostent{} record for the host with the specified address.

gethostbyname(Hostname)

-spec gethostbyname(Hostname) -> {ok, Hostent} | {error, posix()}
                       when Hostname :: hostname(), Hostent :: hostent().

Resolve a hostname to a #hostent{} record.

Returns a #hostent{} record for the host with the specified Hostname.

This function uses the resolver, which is often the native (OS) resolver.

If resolver option inet6 is true, an IPv6 address is looked up.

See ERTS User's Guide: Inet Configuration for information about the resolver configuration.

A quirk of many resolvers is that an integer string is interpreted as an IP address. For instance, the integer string "3232235521" and the string "192.168.0.1" are both translated to the IP address {192,168,0,1}.

gethostbyname(Hostname, Family)

-spec gethostbyname(Hostname, Family) -> {ok, Hostent} | {error, posix()}
                       when Hostname :: hostname(), Family :: address_family(), Hostent :: hostent().

Resolve a hostname to a #hostent{} record, in a specific address family.

Returns a #hostent{} record for the host with the specified Hostname, restricted to the specified address Family.

See also gethostbyname/1.

gethostname()

-spec gethostname() -> {ok, Hostname} when Hostname :: string().

Get the local hostname.

Returns the local hostname. Never fails.

getifaddrs()

(since OTP R14B01)

-spec getifaddrs() -> {ok, [{Ifname :: string(), Ifopts :: getifaddrs_ifopts()}]} | {error, posix()}.

Get interface names and addresses.

Returns a list of 2-tuples containing interface names and the interfaces' addresses. Ifname is a Unicode string and Ifopts is a list of interface address description tuples.

The interface address description tuples are documented under the type of the Ifopts value.

getifaddrs/1

(since OTP 21.2)

-spec getifaddrs([Option :: inet_backend() | {netns, Namespace :: file:filename_all()}] | socket()) ->
                    {ok, [{Ifname :: string(), Ifopts :: getifaddrs_ifopts()}]} | {error, posix()}.

Get interface names and addresses, in a specific namespace.

Equivalent to getifaddrs/0, but accepts an Option {netns, Namespace} that, on platforms that support the feature (Linux), sets a network namespace for the OS call. Also, If the option 'inet_backend' is first in the options list, the specified backend will be used (for 'inet', inet and for 'socket' the equivalent net functions will be used).

See the socket option {netns, Namespace} under setopts/2.

getopts(Socket, Options)

-spec getopts(Socket, Options) -> {ok, OptionValues} | {error, posix()}
                 when
                     Socket :: socket(), Options :: [socket_getopt()], OptionValues :: [socket_optval()].

Get one or more options for a socket.

Gets all options in the list Options from Socket. See setopts/2 for a list of available options. See also the descriptions of protocol specific types referenced by socket_optval() .

The number of elements in the returned OptionValues list does not necessarily correspond to the number of options asked for. If the operating system fails to support an option, it is left out in the returned list. An error tuple is returned only when getting options for the socket is impossible (that is, the socket is closed or the buffer size in a raw request is too large). This behavior is kept for backward compatibility reasons.

A raw option request RawOptReq = {raw, Protocol, OptionNum, ValueSpec} can be used to get information about socket options not (explicitly) supported by the emulator. The use of raw socket options makes the code non-portable, but allows the Erlang programmer to take advantage of unusual features present on a particular platform.

RawOptReq consists of tag raw followed by the protocol level, the option number, and either a binary or the size, in bytes, of the buffer in which the option value is to be stored. A binary is to be used when the underlying getsockopt requires input in the argument field. In this case, the binary size shall correspond to the required buffer size of the return value. The supplied values in a RawOptReq correspond to the second, third, and fourth/fifth parameters to the getsockopt call in the C socket API. The value stored in the buffer is returned as a binary ValueBin, where all values are coded in native endianness.

Asking for and inspecting raw socket options require low-level information about the current operating system and TCP stack.

Example:

Consider a Linux machine where option TCP_INFO can be used to collect TCP statistics for a socket. Assume you are interested in field tcpi_sacked of struct tcp_info filled in when asking for TCP_INFO. To be able to access this information, you need to know the following:

The numeric value of protocol level IPPROTO_TCP

The numeric value of option TCP_INFO

The size of struct tcp_info

The size and offset of the specific field

By inspecting the headers or writing a small C program, it is found that IPPROTO_TCP is 6, TCP_INFO is 11, the structure size is 92 (bytes), the offset of tcpi_sacked is 28 bytes, and the value is a 32-bit integer. The following code can be used to retrieve the value:

get_tcpi_sacked(Sock) ->
    {ok,[{raw,_,_,Info}]} = inet:getopts(Sock,[{raw,6,11,92}]),
    <<_:28/binary,TcpiSacked:32/native,_/binary>> = Info,
    TcpiSacked.

Preferably, you would check the machine type, the operating system, and the Kernel version before executing anything similar to this code.

getstat(Socket)

-spec getstat(Socket) -> {ok, OptionValues} | {error, posix()}
                 when Socket :: socket(), OptionValues :: [{stat_option(), integer()}].

Equivalent to getstat/2.

getstat(Socket, Options)

-spec getstat(Socket, Options) -> {ok, OptionValues} | {error, posix()}
                 when
                     Socket :: socket(),
                     Options :: [stat_option()],
                     OptionValues :: [{stat_option(), integer()}].

Get one or more statistics options for a socket.

getstat(Socket) is equivalent to getstat(Socket, [recv_avg, recv_cnt, recv_dvi, recv_max, recv_oct, send_avg, send_cnt, send_pend, send_max, send_oct]).

The following options are available:

recv_avg - Average size of packets, in bytes, received by the socket.

recv_cnt - Number of packets received by the socket.

recv_dvi - Average packet size deviation, in bytes, received by the socket.

recv_max - Size of the largest packet, in bytes, received by the socket.

recv_oct - Number of bytes received by the socket.

send_avg - Average size of packets, in bytes, sent from the socket.

send_cnt - Number of packets sent from the socket.

send_pend - Number of bytes waiting to be sent by the socket.

send_max - Size of the largest packet, in bytes, sent from the socket.

send_oct - Number of bytes sent from the socket.

i()

(since OTP 21.0)

-spec i() -> ok.

Equivalent to i/1 for the protocols tcp, udp, and sctp

i/1

(since OTP 21.0)

-spec i(show_ports | socket_protocol() | [i_option()]) -> ok.

List network sockets.

With argument Proto equivalent to i(Proto, Options) where Options is a list of all atom/0s in i_option/0.

With argument Options, equivalent to `i(Proto, Options) for Proto: tcp, udp, and sctp.

With argument show_ports (since OTP 27.0) equivalent to `i(Proto, Options) where Option is a list of all options in i_option/0 with ShowPorts = true.

i/2

(since OTP 21.0)

-spec i(socket_protocol(), show_ports | (Options :: [i_option()])) -> ok.

List network sockets.

Lists all TCP, UDP and SCTP sockets on the terminal, those created by the Erlang runtime system as well as by the application.

The following options are available:

port - An internal index of the port.

module - The callback module of the socket.

recv - Number of bytes received by the socket.

sent - Number of bytes sent from the socket.

owner - The socket owner process.

local_address - The local address of the socket.

foreign_address - The address and port of the other end of the connection.

state - The connection state.

type - STREAM or DGRAM or SEQPACKET.

The Options argument may also be (since OTP 27.0):

show_ports - Do not translate the port numbers (of 'local_address' and 'foreign_address') to service name(s).

info(Socket)

(since OTP 24.0)

-spec info(Socket) -> Info when Socket :: socket(), Info :: term().

Get information about a socket.

Returns a term containing miscellaneous information about a socket.

ipv4_mapped_ipv6_address/1

(since OTP 21.0)

-spec ipv4_mapped_ipv6_address(ip_address()) -> ip_address().

Convert between an IPv4 address and an IPv4-mapped IPv6 address.

Convert an IPv4 address to an IPv4-mapped IPv6 address or the reverse. When converting from an IPv6 address all but the 2 low words are ignored so this function also works on some other types of IPv6 addresses than IPv4-mapped.

is_ip_address(IPAddress)

(since OTP 25.0)

-spec is_ip_address(IPAddress) -> boolean() when IPAddress :: ip_address() | term().

Test for an IP address.

Tests if the argument IPAddress is an ip_address/0 and if so returns true, otherwise false.

is_ipv4_address(IPv4Address)

(since OTP 25.0)

-spec is_ipv4_address(IPv4Address) -> boolean() when IPv4Address :: ip4_address() | term().

Test for an IPv4 address.

Tests if the argument IPv4Address is an ip4_address/0 and if so returns true, otherwise false.

is_ipv6_address(IPv6Address)

(since OTP 25.0)

-spec is_ipv6_address(IPv6Address) -> boolean() when IPv6Address :: ip6_address() | term().

Test for an IPv6 address.

Tests if the argument IPv6Address is an ip6_address/0 and if so returns true, otherwise false.

monitor(Socket)

(since OTP 24.0)

-spec monitor(Socket) -> reference() when Socket :: socket().

Start a socket monitor.

If the Socket to monitor doesn't exist or when the monitor is triggered, a 'DOWN' message is sent that has the following pattern:

	    {'DOWN', MonitorRef, Type, Object, Info}

MonitorRef - The return value from this function.

Type - The type of socket, can be one of the following atom/0s: port or socket.

Object - The monitored entity, the socket, which triggered the event.

Info - Either the termination reason of the socket or nosock (the Socket did not exist when this function was called).

Making several calls to inet:monitor/1 for the same Socket is not an error; one monitor is created per call.

The monitor is triggered when the socket is closed in any way such as an API call, remote end close, closed by signal when owner exits, ...

ntoa(IpAddress)

(since OTP R16B02)

-spec ntoa(IpAddress) -> Address | {error, einval} when Address :: string(), IpAddress :: ip_address().

Parse an ip_address/0 to an IPv4 or IPv6 address string.

parse_address(Address)

(since OTP R16B)

-spec parse_address(Address) -> {ok, IPAddress} | {error, einval}
                       when Address :: string(), IPAddress :: ip_address().

Parse an IP address string to an ip_address/0.

Returns an ip4_address/0 or an ip6_address/0 depending on which parsing that succeeds.

Accepts a short form IPv4 address string like parse_ipv4_address/1.

parse_ipv4_address(Address)

(since OTP R16B)

-spec parse_ipv4_address(Address) -> {ok, IPv4Address} | {error, einval}
                            when Address :: string(), IPv4Address :: ip4_address().

Parse (relaxed) an IPv4 address string to an ip4_address/0.

Accepts a short form IPv4 address string (less than 4 fields) such as "127.1" or "0x7f000001".

parse_ipv4strict_address(Address)

(since OTP R16B)

-spec parse_ipv4strict_address(Address) -> {ok, IPv4Address} | {error, einval}
                                  when Address :: string(), IPv4Address :: ip4_address().

Parse an IPv4 address string to an ip4_address/0.

Requires an IPv4 address string containing four fields, that is; not a short form address string.

parse_ipv6_address(Address)

(since OTP R16B)

-spec parse_ipv6_address(Address) -> {ok, IPv6Address} | {error, einval}
                            when Address :: string(), IPv6Address :: ip6_address().

Parse (relaxed) an IPv6 address string to an ip6_address/0.

Also accepts a (relaxed) IPv4 address string like parse_ipv4_address/1 and returns an IPv4-mapped IPv6 address.

parse_ipv6strict_address(Address)

(since OTP R16B)

-spec parse_ipv6strict_address(Address) -> {ok, IPv6Address} | {error, einval}
                                  when Address :: string(), IPv6Address :: ip6_address().

Parse an IPv6 address string to an ip6_address/0.

Doesn't accept an IPv4 address string. An IPv6 address string, though, allows an IPv4 tail like this: "::127.0.0.1" (which is the same as "::7f00:0001").

parse_strict_address(Address)

(since OTP R16B)

-spec parse_strict_address(Address) -> {ok, IPAddress} | {error, einval}
                              when Address :: string(), IPAddress :: ip_address().

Parse an IP address string to an ip_address/0.

Like parse_address/1 but doesn't accept a short form IPv4 address string.

peername(Socket)

-spec peername(Socket :: socket()) ->
                  {ok, {ip_address(), port_number()} | returned_non_ip_address()} | {error, posix()}.

Return the address of the socket's remote end.

Returns the address and port for the other end of a connection.

Notice that for SCTP sockets, this function returns only one of the peer addresses of the socket. Function peernames/1,2 returns all.

peernames(Socket)

(since OTP R16B03)

-spec peernames(Socket :: socket()) ->
                   {ok, [{ip_address(), port_number()} | returned_non_ip_address()]} | {error, posix()}.

Equivalent to peernames(Socket, 0).

Notice that the behavior of this function for an SCTP one-to-many style socket is not defined by the SCTP Sockets API Extensions.

peernames(Socket, Assoc)

(since OTP R16B03)

-spec peernames(Socket, Assoc) -> {ok, [{Address, Port}]} | {error, posix()}
                   when
                       Socket :: socket(),
                       Assoc ::
                           #sctp_assoc_change{state :: term(),
                                              error :: term(),
                                              outbound_streams :: term(),
                                              inbound_streams :: term(),
                                              assoc_id :: term()} |
                           gen_sctp:assoc_id(),
                       Address :: ip_address(),
                       Port :: non_neg_integer().

Return the addresses of all remote ends of a socket.

Returns a list of all address/port number pairs for the remote end of an association Assoc of a socket.

This function can return multiple addresses for multihomed sockets, such as SCTP sockets. For other sockets it returns a one-element list.

Notice that parameter Assoc is by the SCTP Sockets API Extensions defined to be ignored for one-to-one style sockets. What the special value 0 means, is unfortunately undefined, and hence the behavior for one-to-many style sockets.

port(Socket)

-spec port(Socket) -> {ok, Port} | {error, any()} when Socket :: socket(), Port :: port_number().

Return the local port number for a socket.

setopts(Socket, Options)

-spec setopts(Socket, Options) -> ok | {error, posix()}
                 when Socket :: socket(), Options :: [socket_setopt()].

Set one or more options for a socket.

Sets the list of Options on Socket.

The following options are available:

{active, true | false | once | N} - If the value is true, which is the default, everything received from the socket is sent as messages to the receiving process.

If the value is false (passive mode), the process must explicitly receive incoming data by calling gen_tcp:recv/2,3, gen_udp:recv/2,3, or gen_sctp:recv/1,2 (depending on the type of socket).

If the value is once ({active, once}), one data message from the socket is sent to the process. To receive one more message, setopts/2 must be called again with option {active, once}.

If the value is an integer N in the range -32768 to 32767 (inclusive), the value is added to the socket's count of data messages sent to the controlling process. A socket's default message count is 0. If a negative value is specified, and its magnitude is equal to or greater than the socket's current message count, the socket's message count is set to 0. Once the socket's message count reaches 0, either because of sending received data messages to the process or by being explicitly set, the process is then notified by a special message, specific to the type of socket, that the socket has entered passive mode. Once the socket enters passive mode, to receive more messages setopts/2 must be called again to set the socket back into an active mode.

When using {active, once} or {active, N}, the socket changes behavior automatically when data is received. This can be confusing in combination with connection-oriented sockets (that is, gen_tcp), as a socket with {active, false} behavior reports closing differently than a socket with {active, true} behavior. To simplify programming, a socket where the peer closed, and this is detected while in {active, false} mode, still generates message {tcp_closed, Socket} when set to {active, once}, {active, true}, or {active, N} mode. It is therefore safe to assume that message {tcp_closed, Socket}, possibly followed by socket port termination (depending on option exit_on_close) eventually appears when a socket changes back and forth between {active, true} and {active, false} mode. However, when peer closing is detected it is all up to the underlying TCP/IP stack and protocol.

Notice that {active, true} mode provides no flow control; a fast sender can easily overflow the receiver with incoming messages. The same is true for {active, N} mode, while the message count is greater than zero.

Use active mode only if your high-level protocol provides its own flow control (for example, acknowledging received messages) or the amount of data exchanged is small. Using {active, false} mode, {active, once} mode, or {active, N} mode with values of N appropriate for the application to provide flow control, ensures the other side cannot send faster than the receiver can read.

{broadcast, Boolean} (UDP sockets) - Enables/disables permission to send broadcasts.

{buffer, Size} - The size of the user-level buffer used by the driver. Not to be confused with options sndbuf and recbuf, which correspond to the Kernel socket buffers. For TCP it is recommended to have val(buffer) >= val(recbuf) to avoid performance issues because of unnecessary copying. For UDP the same recommendation applies, but the max should not be larger than the MTU of the network path. val(buffer) is automatically set to the above maximum when recbuf is set. However, as the size set for recbuf usually become larger, you are encouraged to use getopts/2 to analyze the behavior of your operating system.

Note that this is also the maximum amount of data that can be received from a single recv call. If you are using higher than normal MTU consider setting buffer higher.

{delay_send, Boolean} - Normally, when an Erlang process sends to a socket, the driver tries to send the data immediately. If that fails, the driver uses any means available to queue up the message to be sent whenever the operating system says it can handle it. Setting {delay_send, true} makes all messages queue up. The messages sent to the network are then larger but fewer. The option affects the scheduling of send requests versus Erlang processes instead of changing any real property of the socket. The option is implementation-specific. Defaults to false.

{deliver, port | term} - When {active, true}, data is delivered on the form port : {S, {data, [H1,..Hsz | Data]}} or term : {tcp, S, [H1..Hsz | Data]}.

{dontroute, Boolean} - Enables/disables routing bypass for outgoing messages.

{exit_on_close, Boolean} - This option is set to true by default.

The only reason to set it to false is if you want to continue sending data to the socket after a close is detected, for example, if the peer uses gen_tcp:shutdown/2 to shut down the write side.

{exclusiveaddruse, Boolean} - Enables/disables exclusive address/port usage on Windows. That is, by enabling this option you can prevent other sockets from binding to the same address/port. By default this option is disabled. That is, other sockets may use the same address/port by setting {reuseaddr, true} in combination with {reuseport, true} unless {exclusiveaddruse, true} has been set on Socket. On non-Windows systems this option is silently ignored.

Note

This option is currently not supported for socket created with inet_backend = socket

{header, Size} - This option is only meaningful if option binary was specified when the socket was created. If option header is specified, the first Size number bytes of data received from the socket are elements of a list, and the remaining data is a binary specified as the tail of the same list. For example, if Size == 2, the data received matches [Byte1, Byte2 | Binary].

{high_msgq_watermark, Size} - The socket message queue is set to a busy state when the amount of data on the message queue reaches this limit. Notice that this limit only concerns data that has not yet reached the ERTS internal socket implementation. Defaults to 8 kB.

Senders of data to the socket are suspended if either the socket message queue is busy or the socket itself is busy.

For more information, see options low_msgq_watermark, high_watermark, and low_watermark.

Notice that distribution sockets disable the use of high_msgq_watermark and low_msgq_watermark. Instead use the distribution buffer busy limit, which is a similar feature.

{high_watermark, Size} (TCP/IP sockets) - The socket is set to a busy state when the amount of data queued internally by the ERTS socket implementation reaches this limit. Defaults to 8 kB.

Senders of data to the socket are suspended if either the socket message queue is busy or the socket itself is busy.

For more information, see options low_watermark, high_msgq_watermark, and low_msqg_watermark.

{ipv6_v6only, Boolean} - Restricts the socket to use only IPv6, prohibiting any IPv4 connections. This is only applicable for IPv6 sockets (option inet6).

On most platforms this option must be set on the socket before associating it to an address. It is therefore only reasonable to specify it when creating the socket and not to use it when calling function (setopts/2) containing this description.

The behavior of a socket with this option set to true is the only portable one. The original idea when IPv6 was new of using IPv6 for all traffic is now not recommended by FreeBSD (you can use {ipv6_v6only,false} to override the recommended system default value), forbidden by OpenBSD (the supported GENERIC kernel), and impossible on Windows (which has separate IPv4 and IPv6 protocol stacks). Most Linux distros still have a system default value of false. This policy shift among operating systems to separate IPv6 from IPv4 traffic has evolved, as it gradually proved hard and complicated to get a dual stack implementation correct and secure.

On some platforms, the only allowed value for this option is true, for example, OpenBSD and Windows. Trying to set this option to false, when creating the socket, fails in this case.

Setting this option on platforms where it does not exist is ignored. Getting this option with getopts/2 returns no value, that is, the returned list does not contain an {ipv6_v6only,_} tuple. On Windows, the option does not exist, but it is emulated as a read-only option with value true.

Therefore, setting this option to true when creating a socket never fails, except possibly on a platform where you have customized the kernel to only allow false, which can be doable (but awkward) on, for example, OpenBSD.

If you read back the option value using getopts/2 and get no value, the option does not exist in the host operating system. The behavior of both an IPv6 and an IPv4 socket listening on the same port, and for an IPv6 socket getting IPv4 traffic is then no longer predictable.

{keepalive, Boolean} (TCP/IP sockets) - Enables/disables periodic transmission on a connected socket when no other data is exchanged. If the other end does not respond, the connection is considered broken and an error message is sent to the controlling process. Defaults to false.

{keepcnt, Integer} (TCP/IP sockets) - Linux specific TCP_KEEPCNT.

{keepidle, Integer} (TCP/IP sockets) - Linux specific TCP_KEEPIDLE.

{keepintvl, Integer} (TCP/IP sockets) - Linux specific TCP_KEEPINTVL.

{linger, {true|false, Seconds}} - Determines the time-out, in seconds, for flushing unsent data in the close/1 socket call.

The first component is if linger is enabled, the second component is the flushing time-out, in seconds. There are 3 alternatives:

{false, _} - close/1 or shutdown/2 returns immediately, not waiting for data to be flushed, with closing happening in the background.

{true, 0} - Aborts the connection when it is closed. Discards any data still remaining in the send buffers and sends RST to the peer.

This avoids TCP's TIME_WAIT state, but leaves open the possibility that another "incarnation" of this connection being created.

{true, Time} when Time > 0 - close/1 or shutdown/2 will not return until all queued messages for the socket have been successfully sent or the linger timeout (Time) has been reached.

{low_msgq_watermark, Size} - If the socket message queue is in a busy state, the socket message queue is set in a not busy state when the amount of data queued in the message queue falls below this limit. Notice that this limit only concerns data that has not yet reached the ERTS internal socket implementation. Defaults to 4 kB.

Senders that are suspended because of either a busy message queue or a busy socket are resumed when the socket message queue and the socket are not busy.

For more information, see options high_msgq_watermark, high_watermark, and low_watermark.

Notice that distribution sockets disable the use of high_msgq_watermark and low_msgq_watermark. Instead they use the distribution buffer busy limit, which is a similar feature.

{low_watermark, Size} (TCP/IP sockets) - If the socket is in a busy state, the socket is set in a not busy state when the amount of data queued internally by the ERTS socket implementation falls below this limit. Defaults to 4 kB.

Senders that are suspended because of a busy message queue or a busy socket are resumed when the socket message queue and the socket are not busy.

For more information, see options high_watermark, high_msgq_watermark, and low_msgq_watermark.

{mode, Mode :: binary | list} - Received Packet is delivered as defined by Mode.

{netns, Namespace :: file:filename_all()} - Sets a network namespace for the socket. Parameter Namespace is a filename defining the namespace, for example, "/var/run/netns/example", typically created by command ip netns add example. This option must be used in a function call that creates a socket, that is, gen_tcp:connect/3,4, gen_tcp:listen/2, gen_udp:open/1,2 or gen_sctp:open/0,1,2, and also getifaddrs/1.

This option uses the Linux-specific syscall setns(), such as in Linux kernel 3.0 or later, and therefore only exists when the runtime system is compiled for such an operating system.

The virtual machine also needs elevated privileges, either running as superuser or (for Linux) having capability CAP_SYS_ADMIN according to the documentation for setns(2). However, during testing also CAP_SYS_PTRACE and CAP_DAC_READ_SEARCH have proven to be necessary.

Example:

setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp

Notice that the filesystem containing the virtual machine executable (beam.smp in the example) must be local, mounted without flag nosetuid, support extended attributes, and the kernel must support file capabilities. All this runs out of the box on at least Ubuntu 12.04 LTS, except that SCTP sockets appear to not support network namespaces.

Namespace is a filename and is encoded and decoded as discussed in module file, with the following exceptions:

Emulator flag +fnu is ignored.

getopts/2 for this option returns a binary for the filename if the stored filename cannot be decoded. This is only to occur if you set the option using a binary that cannot be decoded with the emulator's filename encoding: file:native_name_encoding/0.

{bind_to_device, Ifname :: binary()} - Binds a socket to a specific network interface. This option must be used in a function call that creates a socket, that is, gen_tcp:connect/3,4, gen_tcp:listen/2, gen_udp:open/1,2, or gen_sctp:open/0,1,2.

Unlike getifaddrs/0, Ifname is encoded a binary. In the unlikely case that a system is using non-7-bit-ASCII characters in network device names, special care has to be taken when encoding this argument.

This option uses the Linux-specific socket option SO_BINDTODEVICE, such as in Linux kernel 2.0.30 or later, and therefore only exists when the runtime system is compiled for such an operating system.

Before Linux 3.8, this socket option could be set, but could not retrieved with getopts/2. Since Linux 3.8, it is readable.

The virtual machine also needs elevated privileges, either running as superuser or (for Linux) having capability CAP_NET_RAW.

The primary use case for this option is to bind sockets into Linux VRF instances.

list - Received Packet is delivered as a list.

binary - Received Packet is delivered as a binary.

{nodelay, Boolean} (TCP/IP sockets) - If Boolean == true, option TCP_NODELAY is turned on for the socket, which means that also small amounts of data are sent immediately.

This option is not supported for domain = local, but if inet_backend =/= socket this error will be ignored.

{nopush, Boolean} (TCP/IP sockets) - This translates to TCP_NOPUSH on BSD and to TCP_CORK on Linux.

If Boolean == true, the corresponding option is turned on for the socket, which means that small amounts of data are accumulated until a full MSS-worth of data is available or this option is turned off.

Note that while TCP_NOPUSH socket option is available on OSX, its semantics is very different (e.g., unsetting it does not cause immediate send of accumulated data). Hence, nopush option is intentionally ignored on OSX.

{packet, PacketType} (TCP/IP sockets) - Defines the type of packets to use for a socket. Possible values:

raw | 0 - No packaging is done.

1 | 2 | 4 - Packets consist of a header specifying the number of bytes in the packet, followed by that number of bytes. The header length can be one, two, or four bytes, and containing an unsigned integer in big-endian byte order. Each send operation generates the header, and the header is stripped off on each receive operation.

The 4-byte header is limited to 2Gb.

asn1 | cdr | sunrm | fcgi | tpkt | line - These packet types only have effect on receiving. When sending a packet, it is the responsibility of the application to supply a correct header. On receiving, however, one message is sent to the controlling process for each complete packet received, and, similarly, each call to gen_tcp:recv/2,3 returns one complete packet. The header is not stripped off.

The meanings of the packet types are as follows:

asn1 - ASN.1 BER

sunrm - Sun's RPC encoding

cdr - CORBA (GIOP 1.1)

fcgi - Fast CGI

tpkt - TPKT format [RFC1006]

line - Line mode, a packet is a line-terminated with newline, lines longer than the receive buffer are truncated

http | http_bin - The Hypertext Transfer Protocol. The packets are returned with the format according to HttpPacket described in erlang:decode_packet/3 in ERTS. A socket in passive mode returns {ok, HttpPacket} from gen_tcp:recv while an active socket sends messages like {http, Socket, HttpPacket}.

httph | httph_bin - These two types are often not needed, as the socket automatically switches from http/http_bin to httph/httph_bin internally after the first line is read. However, there can be occasions when they are useful, such as parsing trailers from chunked encoding.

{packet_size, Integer}(TCP/IP sockets) - Sets the maximum allowed length of the packet body. If the packet header indicates that the length of the packet is longer than the maximum allowed length, the packet is considered invalid. The same occurs if the packet header is too large for the socket receive buffer.

For line-oriented protocols (line, http*), option packet_size also guarantees that lines up to the indicated length are accepted and not considered invalid because of internal buffer limitations.

{line_delimiter, Char} (TCP/IP sockets) - Sets the line delimiting character for line-oriented protocols (line). Defaults to $\n.

{raw, Protocol, OptionNum, ValueBin} - See below.

{read_ahead, Boolean} - If set to false avoids reading ahead from the OS socket layer. The default for this option is true which speeds up packet header parsing. Setting false has a performance penalty because the packet header has to be read first, to know exactly how many bytes to read for the body, which roughly doubles the number of read operations.

The use of this option is essential for example before switching to kTLS which activates OS socket layer encryption and decryption by setting special (raw) socket options. So if the Erlang socket layer has read ahead, it has read bytes that was for the OS socket layer to decrypt, which makes packet decryption derail for the connection.

Warning

For packet modes that doesn't have the packet length at a fixed location in a packet header, such as line or asn1, not reading ahead can become very inefficient since sometimes the only way to accomplish this is to read one byte at the time until the length or packet end is found.

{read_packets, Integer} (UDP sockets) - Sets the maximum number of UDP packets to read without intervention from the socket when data is available. When this many packets have been read and delivered to the destination process, new packets are not read until a new notification of available data has arrived. Defaults to 5. If this parameter is set too high, the system can become unresponsive because of UDP packet flooding.

{recbuf, Size} - The minimum size of the receive buffer to use for the socket. You are encouraged to use getopts/2 to retrieve the size set by your operating system.

{recvtclass, Boolean} - If set to true activates returning the received TCLASS value on platforms that implements the protocol IPPROTO_IPV6 option IPV6_RECVTCLASS or IPV6_2292RECVTCLASS for the socket. The value is returned as a {tclass,TCLASS} tuple regardless of if the platform returns an IPV6_TCLASS or an IPV6_RECVTCLASS CMSG value.

For packet oriented sockets that supports receiving ancillary data with the payload data (gen_udp and gen_sctp), the TCLASS value is returned in an extended return tuple contained in an ancillary data list. For stream oriented sockets (gen_tcp) the only way to get the TCLASS value is if the platform supports the pktoptions option.

{recvtos, Boolean} - If set to true activates returning the received TOS value on platforms that implements the protocol IPPROTO_IP option IP_RECVTOS for the socket. The value is returned as a {tos,TOS} tuple regardless of if the platform returns an IP_TOS or an IP_RECVTOS CMSG value.

For packet oriented sockets that supports receiving ancillary data with the payload data (gen_udp and gen_sctp), the TOS value is returned in an extended return tuple contained in an ancillary data list. For stream oriented sockets (gen_tcp) the only way to get the TOS value is if the platform supports the pktoptions option.

{recvttl, Boolean} - If set to true activates returning the received TTL value on platforms that implements the protocol IPPROTO_IP option IP_RECVTTL for the socket. The value is returned as a {ttl,TTL} tuple regardless of if the platform returns an IP_TTL or an IP_RECVTTL CMSG value.

For packet oriented sockets that supports receiving ancillary data with the payload data (gen_udp and gen_sctp), the TTL value is returned in an extended return tuple contained in an ancillary data list. For stream oriented sockets (gen_tcp) the only way to get the TTL value is if the platform supports the pktoptions option.

{reuseaddr, Boolean} - Allows or disallows reuse of local address. By default, reuse is disallowed.

Note

On windows {reuseaddr, true} will have no effect unless also {reuseport, true} is set. If both are set, the SO_REUSEADDR Windows socket option will be enabled. This since setting SO_REUSEADDR on Windows more or less has the same behavior as setting both SO_REUSEADDR and SO_REUSEPORT on BSD. This behavior was introduced as of OTP 26.0.

Change

Previous behavior on Windows:

Prior to OTP 25.0, the {reuseaddr, true} option was silently ignored.

Between OTP 25.0 and up to the predecessor of OTP 25.2, the underlying SO_REUSEADDR socket option was set if {reuseaddr, true} was set.

Between OTP 25.2 and up to the predecessor of OTP 26.0, the underlying SO_REUSEADDR socket option was only set on UDP sockets if {reuseaddr, true} was set, and silently ignored on other sockets.

See also the exclusiveaddruse option.

{reuseport, Boolean} - Allows or disallows reuse of local port which may or may not have load balancing depending on the underlying OS. By default, reuse is disallowed. See also reuseport_lb.

Note

On windows {reuseport, true} will have no effect unless also {reuseaddr, true} is set. If both are set, the SO_REUSEADDR Windows socket option will be enabled. This since setting SO_REUSEADDR on Windows more or less has the same behavior as setting both SO_REUSEADDR and SO_REUSEPORT on BSD. The reuseport option was introduced as of OTP 26.0.

See also the exclusiveaddruse option.

Note

reuseport may or may not be the same underlying option as reuseport_lb depending on the underlying OS. They, for example, are on Linux. When they are the same underlying option, operating on both may cause them to interact in surprising ways. For example, by enabling reuseport and then disabling reuseport_lb both will end up being disabled.

{reuseport_lb, Boolean} - Allows or disallows reuse of local port with load balancing. By default, reuse is disallowed. See also reuseport.

Note

reuseport_lb may or may not be the same underlying option as reuseport depending on the underlying OS. On Linux, for example, they are. And when they are the same underlying option, operating on both may cause them to interact in surprising ways. For example, by enabling reuseport_lb, and then disabling reuseport, both will end up being disabled.

{send_timeout, Integer} - Only allowed for connection-oriented sockets.

Specifies a longest time to wait for a send operation to be accepted by the underlying TCP stack. When the limit is exceeded, the send operation returns {error, timeout}. How much of a packet that got sent is unknown; the socket is therefore to be closed whenever a time-out has occurred (see send_timeout_close below). Defaults to infinity.

{send_timeout_close, Boolean} - Only allowed for connection-oriented sockets.

Used together with send_timeout to specify whether the socket is to be automatically closed when the send operation returns {error, timeout}. The recommended setting is true, which automatically closes the socket. Defaults to false because of backward compatibility.

{show_econnreset, Boolean} (TCP/IP sockets) - When this option is set to false, which is default, an RST received from the TCP peer is treated as a normal close (as though an FIN was sent). A caller to gen_tcp:recv/2 gets {error, closed}. In active mode, the controlling process receives a {tcp_closed, Socket} message, indicating that the peer has closed the connection.

Setting this option to true allows you to distinguish between a connection that was closed normally, and one that was aborted (intentionally or unintentionally) by the TCP peer. A call to gen_tcp:recv/2 returns {error, econnreset}. In active mode, the controlling process receives a {tcp_error, Socket, econnreset} message before the usual {tcp_closed, Socket}, as is the case for any other socket error. Calls to gen_tcp:send/2 also returns {error, econnreset} when it is detected that a TCP peer has sent an RST.

A connected socket returned from gen_tcp:accept/1 inherits the show_econnreset setting from the listening socket.

{sndbuf, Size} - The minimum size of the send buffer to use for the socket. You are encouraged to use getopts/2, to retrieve the size set by your operating system.

{priority, Integer} - Sets the SO_PRIORITY socket level option on platforms where this is implemented. The behavior and allowed range varies between different systems. The option is ignored on platforms where it is not implemented. Use with caution.

{tos, Integer} - Sets IP_TOS IP level options on platforms where this is implemented. The behavior and allowed range varies between different systems. The option is ignored on platforms where it is not implemented. Use with caution.

{tclass, Integer} - Sets IPV6_TCLASS IP level options on platforms where this is implemented. The behavior and allowed range varies between different systems. The option is ignored on platforms where it is not implemented. Use with caution.

{user_timeout, Integer} (TCP/IP sockets) - Linux specific TCP_USER_TIMEOUT.

In addition to these options, raw option specifications can be used. The raw options are specified as a tuple of arity four, beginning with tag raw, followed by the protocol level, the option number, and the option value specified as a binary. This corresponds to the second, third, and fourth arguments to the setsockopt call in the C socket API. The option value must be coded in the native endianness of the platform and, if a structure is required, must follow the structure alignment conventions on the specific platform.

Using raw socket options requires detailed knowledge about the current operating system and TCP stack.

Example:

This example concerns the use of raw options. Consider a Linux system where you want to set option TCP_LINGER2 on protocol level IPPROTO_TCP in the stack. You know that on this particular system it defaults to 60 (seconds), but you want to lower it to 30 for a particular socket. Option TCP_LINGER2 is not explicitly supported by inet, but you know that the protocol level translates to number 6, the option number to number 8, and the value is to be specified as a 32-bit integer. You can use this code line to set the option for the socket named Sock:

inet:setopts(Sock, [{raw,6,8,<<30:32/native>>}]),

As many options are silently discarded by the stack if they are specified out of range; it can be a good idea to check that a raw option is accepted. The following code places the value in variable TcpLinger2:

{ok,[{raw,6,8,<<TcpLinger2:32/native>>}]}=inet:getopts(Sock,[{raw,6,8,4}]),

Code such as these examples is inherently non-portable, even different versions of the same OS on the same platform can respond differently to this kind of option manipulation. Use with care.

Notice that the default options for TCP/IP sockets can be changed with the Kernel configuration parameters mentioned in the beginning of this manual page.

sockname(Socket)

-spec sockname(Socket :: socket()) ->
                  {ok, {ip_address(), port_number()} | returned_non_ip_address()} | {error, posix()}.

Return the local address and port number for a socket.

Notice that for SCTP sockets this function returns only one of the socket addresses. Function socknames/1,2 returns all.

socknames(Socket)

(since OTP R16B03)

-spec socknames(Socket :: socket()) ->
                   {ok, [{ip_address(), port_number()} | returned_non_ip_address()]} | {error, posix()}.

Equivalent to socknames(Socket, 0).

socknames(Socket, Assoc)

(since OTP R16B03)

-spec socknames(Socket, Assoc) -> {ok, [{Address, Port}]} | {error, posix()}
                   when
                       Socket :: socket(),
                       Assoc ::
                           #sctp_assoc_change{state :: term(),
                                              error :: term(),
                                              outbound_streams :: term(),
                                              inbound_streams :: term(),
                                              assoc_id :: term()} |
                           gen_sctp:assoc_id(),
                       Address :: ip_address(),
                       Port :: non_neg_integer().

Return all localaddresses for a socket.

Returns a list of all local address/port number pairs for a socket, for the specified association Assoc.

This function can return multiple addresses for multihomed sockets, such as SCTP sockets. For other sockets it returns a one-element list.

Notice that parameter Assoc is by the SCTP Sockets API Extensions defined to be ignored for one-to-one style sockets. For one-to-many style sockets, the special value 0 is defined to mean that the returned addresses must be without any particular association. How different SCTP implementations interpret this varies somewhat.

inet_res

A rudimentary DNS client.

This module performs DNS name resolving towards recursive name servers.

See also ERTS User's Guide: Inet Configuration or more information about how to configure an Erlang runtime system for IP communication, and how to enable this DNS client by defining 'dns' as a lookup method. The DNS client then acts as a backend for the resolving functions in inet.

This DNS client can resolve DNS records even if it is not used for normal name resolving in the node.

Warning

This is not a full-fledged resolver, only a DNS client that relies on being in trusted network shielded from DNS reply spoofing by firewalls, and on asking only trusted recursive name servers.

If the Crypto application is loaded, this implementation does its best to not be fooled by spoofed DNS replies. This is nevertheless a meager remedy compared to using encrypted and signed DNS methods like TSIG or DNSSEC, as full fledged resolvers do.

Note

If the Crypto application is loaded, this resolver client uses cryptographically random transaction IDs and port numbers, which should render the probability for a sucessfully brute force spoofed reply to be too low to be a usable exploit. An Erlang node that is installed in an exposed network environment should already have the Crypto application loaded for example to run the SSL application. If this is not the case, the Crypto application can be explicitly loaded with application:load(crypto).

Name Resolving

UDP queries are used unless resolver option usevc is true, which forces TCP queries. If the query is too large for UDP, TCP is used instead. For regular DNS queries, 512 bytes is the size limit.

When EDNS is enabled (resolver option edns is set to the EDNS version (that is; 0 instead of false), resolver option udp_payload_size sets the payload size limit. If a name server replies with the TC bit set (truncation), indicating that the answer is incomplete, the query is retried towards the same name server using TCP. Resolver option udp_payload_size also sets the advertised size for the maximum allowed reply size, if EDNS is enabled, otherwise the name server uses the limit 512 bytes. If the reply is larger, it gets truncated, forcing a TCP requery.

For UDP queries, resolver options timeout and retry control retransmission. Each name server in the nameservers list is tried with a time-out of timeout/retry. Then all name servers are tried again, doubling the time-out, for a total of retry times.

But before all name servers are tried again, there is a (user configurable) time-out, servfail_retry_timeout. The point of this is to prevent the new query to be handled by a server's servfail cache (a client that is too eager will actually only get what is in the servfail cache). If there is too little time left of the resolver call's time-out to do a retry, the resolver call may return before the call's time-out has expired.

For queries not using the search list, if the query to all nameservers results in {error,nxdomain} or an empty answer, the same query is tried for alt_nameservers.

If randomization of transaction ID:s and port numbers is too costly for an Erlang node in a trusted network shielded from DNS reply spoofing, the legacy behaviour to reuse the UDP socket on retries and use sequential transaction ID:s can be configured by setting the resolver option random to false.

Resolver Types

The following data types concern the resolver:

DNS Types

The following data types concern the DNS client:

Example

This access functions example shows how lookup/3 can be implemented using resolve/3 from outside the module:

example_lookup(Name, Class, Type) ->
    case inet_res:resolve(Name, Class, Type) of
        {ok,Msg} ->
            [inet_dns:rr(RR, data)
             || RR <- inet_dns:msg(Msg, anlist),
                 inet_dns:rr(RR, type) =:= Type,
                 inet_dns:rr(RR, class) =:= Class];
        {error,_} ->
            []
     end.

Summary

Types

dns_class()

dns_data()

DNS record data (content)

dns_msg()

A DNS message.

dns_name()

A string with no adjacent dots.

dns_rr_type()

hostent()

Extended variant of inet:hostent/0.

nameserver()

res_error()

res_option()

Legacy Functions

nnslookup(Name, Class, Type, Nameservers)

Equivalent to nnslookup(Name, Class, Type, NSs, infinity).

nnslookup(Name, Class, Type, Nameservers, Timeout)

Resolve a DNS query.

nslookup(Name, Class, Type)

Equivalent to nslookup(Name, Class, Type, infinity).

nslookup/4

Resolve a DNS query.

Functions

getbyname(Name, Type)

Equivalent to getbyname(Name, Type, [], infinity).

getbyname(Name, Type, Timeout)

Equivalent to getbyname(Name, Type, [], Timeout).

getbyname(Name, Type, Opts, Timeout)

Resolve a DNS query.

gethostbyaddr(Address)

Equivalent to gethostbyaddr(Address, infinity).

gethostbyaddr(Address, Timeout)

Backend function used by inet:gethostbyaddr/1.

gethostbyaddr(Address, Opts, Timeout)

Backend function used by inet:gethostbyaddr/1.

gethostbyname(Name)

Backend functions used by inet:gethostbyname/1,2.

gethostbyname(Name, Family)

Equivalent to gethostbyname(Name, Family, infinity).

gethostbyname(Name, Family, Timeout)

Equivalent to gethostbyname(Name, Family, [], Timeout).

gethostbyname(Name, Family, Opts, Timeout)

Backend functions used by inet:gethostbyname/1,2.

lookup(Name, Class, Type)

Equivalent to lookup(Name, Class, Type, [], infinity).

lookup(Name, Class, Type, Opts)

Equivalent to lookup(Name, Class, Type, Opts, infinity).

lookup(Name, Class, Type, Opts, Timeout)

Look up DNS data.

resolve(Name, Class, Type)

Equivalent to resolve(Name, Class, Type, [], infinity).

resolve(Name, Class, Type, Opts)

Equivalent to resolve(Name, Class, Type, Opts, infinity).

resolve(Name, Class, Type, Opts, Timeout)

Resolve a DNS query.

Types

dns_class()

(not exported)

-type dns_class() :: in | chaos | hs | any.

dns_data()

(not exported)

-type dns_data() ::
          dns_name() |
          inet:ip4_address() |
          inet:ip6_address() |
          {MName :: dns_name(),
           RName :: dns_name(),
           Serial :: integer(),
           Refresh :: integer(),
           Retry :: integer(),
           Expiry :: integer(),
           Minimum :: integer()} |
          {inet:ip4_address(), Proto :: integer(), BitMap :: binary()} |
          {CpuString :: string(), OsString :: string()} |
          {RM :: dns_name(), EM :: dns_name()} |
          {Prio :: integer(), dns_name()} |
          {Prio :: integer(), Weight :: integer(), Port :: integer(), dns_name()} |
          {Order :: integer(),
           Preference :: integer(),
           Flags :: string(),
           Services :: string(),
           Regexp :: string(),
           dns_name()} |
          [string()] |
          binary().

DNS record data (content)

The basic type of each data element is specified in this type.

Regexp is a UTF-8 string/0. The other string/0s are actually Latin-1 strings.

dns_msg()

(not exported)

-type dns_msg() :: term().

A DNS message.

This is the start of a hierarchy of opaque data structures that can be examined with access functions in inet_dns, which return lists of {Field,Value} tuples. The arity 2 functions return the value for a specified field.

dns_msg() = DnsMsg
    inet_dns:msg(DnsMsg) ->
        [ {header, dns_header()}
        | {qdlist, dns_query()}
        | {anlist, dns_rr()}
        | {nslist, dns_rr()}
        | {arlist, dns_rr()} ]
    inet_dns:msg(DnsMsg, header) -> dns_header() % for example
    inet_dns:msg(DnsMsg, Field) -> Value

dns_header() = DnsHeader
    inet_dns:header(DnsHeader) ->
        [ {id, integer()}
        | {qr, boolean()}
        | {opcode, query | iquery | status | integer()}
        | {aa, boolean()}
        | {tc, boolean()}
        | {rd, boolean()}
        | {ra, boolean()}
        | {pr, boolean()}
        | {rcode, integer(0..16)} ]
    inet_dns:header(DnsHeader, Field) -> Value

query_type() = axfr | mailb | maila | any | dns_rr_type()

dns_query() = DnsQuery
    inet_dns:dns_query(DnsQuery) ->
        [ {domain, dns_name()}
        | {type, query_type()}
        | {class, dns_class()} ]
    inet_dns:dns_query(DnsQuery, Field) -> Value

dns_rr() = DnsRr
    inet_dns:rr(DnsRr) -> DnsRrFields | DnsRrOptFields
    DnsRrFields = [ {domain, dns_name()}
                  | {type, dns_rr_type()}
                  | {class, dns_class()}
                  | {ttl, integer()}
                  | {data, dns_data()} ]
    DnsRrOptFields = [ {domain, dns_name()}
                     | {type, opt}
                     | {udp_payload_size, integer()}
                     | {ext_rcode, integer()}
                     | {version, integer()}
                     | {z, integer()}
                     | {data, dns_data()} ]
    inet_dns:rr(DnsRr, Field) -> Value

There is an information function for the types above:

inet_dns:record_type(dns_msg()) -> msg;
inet_dns:record_type(dns_header()) -> header;
inet_dns:record_type(dns_query()) -> dns_query;
inet_dns:record_type(dns_rr()) -> rr;
inet_dns:record_type(_) -> undefined.

So, inet_dns:(inet_dns:record_type(X))(X) converts any of these data structures into a {Field,Value} list.

dns_name()

(not exported)

-type dns_name() :: string().

A string with no adjacent dots.

dns_rr_type()

(not exported)

-type dns_rr_type() ::
          a | aaaa | caa | cname | gid | hinfo | ns | mb | md | mg | mf | minfo | mx | naptr | null |
          ptr | soa | spf | srv | txt | uid | uinfo | unspec | uri | wks.

hostent()

-type hostent() ::
          inet:hostent() |
          {hostent,
           H_name :: inet:hostname(),
           H_aliases :: [inet:hostname()],
           H_addrtype :: dns_rr_type(),
           H_length :: non_neg_integer(),
           H_addr_list :: [dns_data()]}.

Extended variant of inet:hostent/0.

Allows dns_rr_type/0 for the #hostent{}.h_addrtype field, and [dns_data/0] for the #hostent{}.h_addr_list field.

nameserver()

-type nameserver() :: {inet:ip_address(), Port :: 1..65535}.

res_error()

-type res_error() :: formerr | qfmterror | servfail | nxdomain | notimp | refused | badvers | timeout.

res_option()

-type res_option() ::
          {alt_nameservers, [nameserver()]} |
          {edns, 0 | false} |
          {inet6, boolean()} |
          {nameservers, [nameserver()]} |
          {recurse, boolean()} |
          {retry, integer()} |
          {timeout, integer()} |
          {udp_payload_size, integer()} |
          {dnssec_ok, boolean()} |
          {usevc, boolean()} |
          {random, boolean()} |
          {nxdomain_reply, boolean()}.

Legacy Functions

nnslookup(Name, Class, Type, Nameservers)

-spec nnslookup(Name, Class, Type, Nameservers) -> {ok, dns_msg()} | {error, Reason}
                   when
                       Name :: dns_name() | inet:ip_address(),
                       Class :: dns_class(),
                       Type :: dns_rr_type(),
                       Nameservers :: [nameserver()],
                       Reason :: inet:posix().

Equivalent to nnslookup(Name, Class, Type, NSs, infinity).

nnslookup(Name, Class, Type, Nameservers, Timeout)

-spec nnslookup(Name, Class, Type, Nameservers, Timeout) -> {ok, dns_msg()} | {error, Reason}
                   when
                       Name :: dns_name() | inet:ip_address(),
                       Class :: dns_class(),
                       Type :: dns_rr_type(),
                       Timeout :: timeout(),
                       Nameservers :: [nameserver()],
                       Reason :: inet:posix().

Resolve a DNS query.

Like nslookup/4 but calls resolve/5 with both the arguments Opts = [{nameservers, Nameservers}] and Timeout.

nslookup(Name, Class, Type)

-spec nslookup(Name, Class, Type) -> {ok, dns_msg()} | {error, Reason}
                  when
                      Name :: dns_name() | inet:ip_address(),
                      Class :: dns_class(),
                      Type :: dns_rr_type(),
                      Reason :: inet:posix() | res_error().

Equivalent to nslookup(Name, Class, Type, infinity).

nslookup/4

-spec nslookup(Name, Class, Type, Timeout) -> {ok, dns_msg()} | {error, Reason}
                  when
                      Name :: dns_name() | inet:ip_address(),
                      Class :: dns_class(),
                      Type :: dns_rr_type(),
                      Timeout :: timeout(),
                      Reason :: inet:posix() | res_error();
              (Name, Class, Type, Nameservers) -> {ok, dns_msg()} | {error, Reason}
                  when
                      Name :: dns_name() | inet:ip_address(),
                      Class :: dns_class(),
                      Type :: dns_rr_type(),
                      Nameservers :: [nameserver()],
                      Reason :: inet:posix() | res_error().

Resolve a DNS query.

This function is a legacy wrapper to resolve/5 that simplifies errors matching {error, {Reason, _}} into {error, Reason} or {error, einval}.

With argument Timeout calls resolve/5 with Opts = [].

With argument Nameservers calls resolve/5 with Opts = [{nameservers, Nameservers}] and Timeout = infinity.

Functions

getbyname(Name, Type)

-spec getbyname(Name, Type) -> {ok, Hostent} | {error, Reason}
                   when
                       Name :: dns_name(),
                       Type :: dns_rr_type(),
                       Hostent :: inet:hostent() | hostent(),
                       Reason :: inet:posix() | res_error().

Equivalent to getbyname(Name, Type, [], infinity).

getbyname(Name, Type, Timeout)

-spec getbyname(Name, Type, Timeout) -> {ok, Hostent} | {error, Reason}
                   when
                       Name :: dns_name(),
                       Type :: dns_rr_type(),
                       Timeout :: timeout(),
                       Hostent :: inet:hostent() | hostent(),
                       Reason :: inet:posix() | res_error().

Equivalent to getbyname(Name, Type, [], Timeout).

getbyname(Name, Type, Opts, Timeout)

(since OTP 28.1)

-spec getbyname(Name, Type, Opts, Timeout) -> {ok, Hostent} | {error, Reason}
                   when
                       Name :: dns_name(),
                       Type :: dns_rr_type(),
                       Opts :: [Opt],
                       Opt :: res_option() | verbose | atom(),
                       Timeout :: timeout(),
                       Hostent :: inet:hostent() | hostent(),
                       Reason :: inet:posix() | res_error().

Resolve a DNS query.

Resolves a DNS query of the specified Type for the specified host, of classin. Returns, on success, when resolving a Type = a|aaaa DNS record, a #hostent{} record with #hostent.h_addrtype = inet|inet6, respectively; see inet:hostent/0.

When resolving other Type = dns_rr_type():s (of class in), also returns a #hostent{} record but with dns_rr_type/0 in #hostent.h_addrtype, and the resolved dns_data/0 in #hostent.h_addr_list; see hostent/0.

This function uses resolver option search that is a list of domain names. If the name to resolve contains no dots, it is prepended to each domain name in the search list, and they are tried in order. If the name contains dots, it is first tried as an absolute name and if that fails, the search list is used. If the name has a trailing dot, it is supposed to be an absolute name and the search list is not used.

See resolve/5 about Opts.

gethostbyaddr(Address)

-spec gethostbyaddr(Address) -> {ok, Hostent} | {error, Reason}
                       when
                           Address :: inet:ip_address(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

Equivalent to gethostbyaddr(Address, infinity).

gethostbyaddr(Address, Timeout)

-spec gethostbyaddr(Address, Timeout) -> {ok, Hostent} | {error, Reason}
                       when
                           Address :: inet:ip_address(),
                           Timeout :: timeout(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

Backend function used by inet:gethostbyaddr/1.

gethostbyaddr(Address, Opts, Timeout)

(since OTP 28.1)

-spec gethostbyaddr(Address, Opts, Timeout) -> {ok, Hostent} | {error, Reason}
                       when
                           Address :: inet:ip_address(),
                           Opts :: [Opt],
                           Opt :: res_option() | verbose | atom(),
                           Timeout :: timeout(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

Backend function used by inet:gethostbyaddr/1.

gethostbyname(Name)

-spec gethostbyname(Name) -> {ok, Hostent} | {error, Reason}
                       when
                           Name :: dns_name(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

Backend functions used by inet:gethostbyname/1,2.

If resolver option inet6 is true, equivalent to gethostbyname(Name, inet6, infinity), otherwise gethostbyname(Name, inet, infinity).

gethostbyname(Name, Family)

-spec gethostbyname(Name, Family) -> {ok, Hostent} | {error, Reason}
                       when
                           Name :: dns_name(),
                           Family :: inet:address_family(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

Equivalent to gethostbyname(Name, Family, infinity).

gethostbyname(Name, Family, Timeout)

-spec gethostbyname(Name, Family, Timeout) -> {ok, Hostent} | {error, Reason}
                       when
                           Name :: dns_name(),
                           Family :: inet:address_family(),
                           Timeout :: timeout(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

Equivalent to gethostbyname(Name, Family, [], Timeout).

gethostbyname(Name, Family, Opts, Timeout)

(since OTP 28.1)

-spec gethostbyname(Name, Family, Opts, Timeout) -> {ok, Hostent} | {error, Reason}
                       when
                           Name :: dns_name(),
                           Family :: inet:address_family(),
                           Opts :: [Opt],
                           Opt :: res_option() | verbose | atom(),
                           Timeout :: timeout(),
                           Hostent :: inet:hostent(),
                           Reason :: inet:posix() | res_error().

Backend functions used by inet:gethostbyname/1,2.

This function uses resolver option search just like getbyname/2,3.

lookup(Name, Class, Type)

-spec lookup(Name, Class, Type) -> [dns_data()]
                when Name :: dns_name() | inet:ip_address(), Class :: dns_class(), Type :: dns_rr_type().

Equivalent to lookup(Name, Class, Type, [], infinity).

lookup(Name, Class, Type, Opts)

-spec lookup(Name, Class, Type, Opts) -> [dns_data()]
                when
                    Name :: dns_name() | inet:ip_address(),
                    Class :: dns_class(),
                    Type :: dns_rr_type(),
                    Opts :: [res_option() | verbose].

Equivalent to lookup(Name, Class, Type, Opts, infinity).

lookup(Name, Class, Type, Opts, Timeout)

-spec lookup(Name, Class, Type, Opts, Timeout) -> [dns_data()]
                when
                    Name :: dns_name() | inet:ip_address(),
                    Class :: dns_class(),
                    Type :: dns_rr_type(),
                    Opts :: [res_option() | verbose],
                    Timeout :: timeout().

Look up DNS data.

Resolves the DNS data for the record Name of the specified Type and Class. On success, filters out the answer records with the correct Class and Type, and returns a list of their data fields. So, a lookup for type any gives an empty answer, as the answer records have specific types that are not any. An empty answer or a failed lookup returns an empty list.

Calls resolve/* with the same arguments and filters the result, so Opts is described for those functions.

resolve(Name, Class, Type)

-spec resolve(Name, Class, Type) -> {ok, dns_msg()} | Error
                 when
                     Name :: dns_name() | inet:ip_address(),
                     Class :: dns_class(),
                     Type :: dns_rr_type(),
                     Error :: {error, Reason} | {error, {Reason, dns_msg()}},
                     Reason :: inet:posix() | res_error().

Equivalent to resolve(Name, Class, Type, [], infinity).

resolve(Name, Class, Type, Opts)

-spec resolve(Name, Class, Type, Opts) -> {ok, dns_msg()} | Error
                 when
                     Name :: dns_name() | inet:ip_address(),
                     Class :: dns_class(),
                     Type :: dns_rr_type(),
                     Opts :: [Opt],
                     Opt :: res_option() | verbose | atom(),
                     Error :: {error, Reason} | {error, {Reason, dns_msg()}},
                     Reason :: inet:posix() | res_error().

Equivalent to resolve(Name, Class, Type, Opts, infinity).

resolve(Name, Class, Type, Opts, Timeout)

-spec resolve(Name, Class, Type, Opts, Timeout) -> {ok, dns_msg()} | Error
                 when
                     Name :: dns_name() | inet:ip_address(),
                     Class :: dns_class(),
                     Type :: dns_rr_type(),
                     Opts :: [Opt],
                     Opt :: res_option() | verbose | atom(),
                     Timeout :: timeout(),
                     Error :: {error, Reason} | {error, {Reason, dns_msg()}},
                     Reason :: inet:posix() | res_error().

Resolve a DNS query.

Resolves a DNS query for the specified Type, Class, and Name, into a DNS message possibly containing Resource Records. The returned dns_msg/0 can be examined using access functions in inet_db, as described in section in DNS Types.

If Name is an ip_address(), the domain name to query about is generated as the standard reverse ".IN-ADDR.ARPA." name for an IPv4 address, or the ".IP6.ARPA." name for an IPv6 address. In this case, you most probably want to use Class = in and Type = ptr, but it is not done automatically.

Opts overrides the corresponding resolver options. If option nameservers is specified, it is assumed that it is the complete list of name serves, so resolver option alt_nameserves is ignored. However, if option alt_nameserves is also specified to this function, it is used.

Option verbose (or rather {verbose,true}) causes diagnostics printout through io:format/2 of queries, replies, retransmissions, and so on, similar to utilities such as dig and nslookup.

Option nxdomain_reply (or rather {nxdomain_reply, true}) causes NXDOMAIN errors from DNS servers to be returned as {error, {nxdomain, dns_msg()}}. dns_msg/0 contains the additional sections that where included by the answering server. This is mainly useful to inspect the SOA record to get the TTL for negative caching.

If Opt is any atom, it is interpreted as {Opt,true} unless the atom string starts with "no", making the interpretation {Opt,false}. For example, usevc is an alias for {usevc, true} and nousevc is an alias for {usevc, false}.

Option inet6 has no effect on this function. You probably want to use Type = a | aaaa instead.

net

Network interface.

This module provides an API for the network interface.

Summary

Types

address_info()

ifaddrs()

Interface addresses and flags.

ifaddrs_filter()

Interface address filtering selector.

ifaddrs_filter_fun()

Interface address filtering selector function/0.

ifaddrs_filter_map()

Interface address filtering selector map.

ifaddrs_flag()

ifaddrs_flags()

name_info()

name_info_flag()

name_info_flag_ext()

name_info_flags()

network_interface_index()

network_interface_name()

Functions

getaddrinfo(Host)

Equivalent to getaddrinfo(Host, undefined).

getaddrinfo(Host, Service)

Network address and service translation.

gethostname()

Return the name of the current host.

getifaddrs()

Equivalent to getifaddrs(default).

getifaddrs/1

Get interface addresses.

getifaddrs(Filter, Namespace)

Get interface addresses in a namespace.

getnameinfo(SockAddr)

Equivalent to getnameinfo(SockAddr, undefined).

getnameinfo(SockAddr, Flags)

Address-to-name translation in a protocol-independant manner.

getservbyname(Name)

Equivalent to getservbyname(Name, any).

getservbyname(Name, Protocol)

Get service by name.

getservbyport(PortNumber)

Equivalent to getservbyport(PortNumber, any).

getservbyport(PortNumber, Protocol)

Get service by name.

if_index2name(Idx)

Mappings between network interface index and names.

if_name2index(Name)

Mappings between network interface names and indexes.

if_names()

Get network interface names and indexes.

Types

address_info()

(since OTP 22.0)

-type address_info() ::
          #{family := socket:domain(),
            socktype := any | socket:type() | integer(),
            protocol := socket:protocol(),
            address := socket:sockaddr()}.

ifaddrs()

(since OTP 22.0)

-type ifaddrs() ::
          #{name := string(),
            flags := ifaddrs_flags(),
            addr => socket:sockaddr(),
            netmask => socket:sockaddr(),
            broadaddr => socket:sockaddr(),
            dstaddr => socket:sockaddr()}.

Interface addresses and flags.

This type defines addresses and flags for an interface.

Note

Not all fields of this map has to be present. The flags field can be used to test for some of the fields. For example broadaddr will only be present if the broadcast flag is present in flags.

ifaddrs_filter()

(not exported) (since OTP 22.0)

-type ifaddrs_filter() ::
          all | default | inet | inet6 | packet | link | hwaddr |
          ifaddrs_filter_map() |
          ifaddrs_filter_fun().

Interface address filtering selector.

all - All interfaces

default - Interfaces with address family inet or inet6

inet | inet6 | packet | link - Interfaces with only the specified address family

hwaddr - Interfaces with address family packet or link

ifaddrs_filter_fun()

(not exported) (since OTP 22.0)

-type ifaddrs_filter_fun() :: fun((ifaddrs()) -> boolean()).

Interface address filtering selector function/0.

For each ifaddrs entry, return either true to keep the entry or false to discard the entry.

For example, to get an interface list which only contains non-loopback inet interfaces:

net:getifaddrs(
    fun (#{ addr  := #{family := inet},
            flags := Flags}) ->
          not lists:member(loopback, Flags);
        (_) ->
          false
    end).

ifaddrs_filter_map()

(not exported) (since OTP 22.0)

-type ifaddrs_filter_map() ::
          #{family :=
                all | default | local | inet | inet6 | packet | link |
                [local | inet | inet6 | packet | link],
            flags := any | [ifaddrs_flag()]}.

Interface address filtering selector map.

The family field can only have the (above) specified values (and not all the values of socket:domain()). It can also be a list of values, to cover the situation when any of the specified families are accepted. For example, family can be set to [inet,inet6] if either inet or inet6 is accepted.

The use of the flags field is that any flag provided must exist for the interface.

For example, if family is set to inet and flags to [broadcast, multicast] only interfaces with address family inet and the flags broadcast and multicast will be listed.

ifaddrs_flag()

(since OTP 22.0)

-type ifaddrs_flag() ::
          up | broadcast | debug | loopback | pointopoint | notrailers | running | noarp | promisc |
          master | slave | multicast | portsel | automedia | dynamic.

ifaddrs_flags()

(since OTP 22.0)

-type ifaddrs_flags() :: [ifaddrs_flag()].

name_info()

(since OTP 22.0)

-type name_info() :: #{host := string(), service := string()}.

name_info_flag()

(since OTP 22.0)

-type name_info_flag() :: namereqd | dgram | nofqdn | numerichost | numericserv.

name_info_flag_ext()

(since OTP 22.0)

-type name_info_flag_ext() :: idn.

name_info_flags()

(since OTP 22.0)

-type name_info_flags() :: [name_info_flag() | name_info_flag_ext()].

network_interface_index()

(since OTP 22.0)

-type network_interface_index() :: non_neg_integer().

network_interface_name()

(since OTP 22.0)

-type network_interface_name() :: string().

Functions

getaddrinfo(Host)

(since OTP 22.0)

-spec getaddrinfo(Host) -> {ok, Info} | {error, Reason}
                     when Host :: string(), Info :: [address_info()], Reason :: term().

Equivalent to getaddrinfo(Host, undefined).

getaddrinfo(Host, Service)

(since OTP 22.0)

-spec getaddrinfo(Host, undefined) -> {ok, Info} | {error, Reason}
                     when Host :: string(), Info :: [address_info()], Reason :: term();
                 (undefined, Service) -> {ok, Info} | {error, Reason}
                     when Service :: string(), Info :: [address_info()], Reason :: term();
                 (Host, Service) -> {ok, Info} | {error, Reason}
                     when
                         Host :: string(),
                         Service :: string(),
                         Info :: [address_info()],
                         Reason :: term().

Network address and service translation.

This function is the inverse of getnameinfo. It converts host and service to a corresponding socket address.

One of the Host and Service may be undefined but not both.

gethostname()

(since OTP 22.0)

-spec gethostname() -> {ok, HostName} | {error, Reason} when HostName :: string(), Reason :: term().

Return the name of the current host.

getifaddrs()

(since OTP 22.3)

-spec getifaddrs() -> {ok, IfAddrs} | {error, Reason} when IfAddrs :: [ifaddrs()], Reason :: term().

Equivalent to getifaddrs(default).

getifaddrs/1

(since OTP 22.3)

-spec getifaddrs(Filter) -> {ok, IfAddrs} | {error, Reason}
                    when Filter :: ifaddrs_filter(), IfAddrs :: [ifaddrs()], Reason :: term();
                (Namespace) -> {ok, IfAddrs} | {error, Reason}
                    when Namespace :: file:filename_all(), IfAddrs :: [ifaddrs()], Reason :: term().

Get interface addresses.

With argument 'Filter: get the machines interface addresses, filtered according to Filter.

With argument Namespace: equivalent to getifaddrs(default, Namespace).

getifaddrs(Filter, Namespace)

(since OTP 22.3)

-spec getifaddrs(Filter, Namespace) -> {ok, IfAddrs} | {error, Reason}
                    when
                        Filter :: ifaddrs_filter(),
                        Namespace :: file:filename_all(),
                        IfAddrs :: [ifaddrs()],
                        Reason :: term().

Get interface addresses in a namespace.

The same as getifaddrs(Filter) but in the specified Namespace.

getnameinfo(SockAddr)

(since OTP 22.0)

-spec getnameinfo(SockAddr) -> {ok, Info} | {error, Reason}
                     when SockAddr :: socket:sockaddr(), Info :: name_info(), Reason :: term().

Equivalent to getnameinfo(SockAddr, undefined).

getnameinfo(SockAddr, Flags)

(since OTP 22.0)

-spec getnameinfo(SockAddr, Flags) -> {ok, Info} | {error, Reason}
                     when
                         SockAddr :: socket:sockaddr(),
                         Flags :: name_info_flags() | undefined,
                         Info :: name_info(),
                         Reason :: term().

Address-to-name translation in a protocol-independant manner.

This function is the inverse of getaddrinfo. It converts a socket address to a corresponding host and service.

getservbyname(Name)

(since OTP 27.1)

-spec getservbyname(Name) -> {ok, PortNumber} | {error, Reason}
                       when
                           Name :: atom() | string(),
                           PortNumber :: socket:port_number(),
                           Reason :: term().

Equivalent to getservbyname(Name, any).

getservbyname(Name, Protocol)

(since OTP 27.1)

-spec getservbyname(Name, Protocol) -> {ok, PortNumber} | {error, Reason}
                       when
                           Name :: atom() | string(),
                           PortNumber :: socket:port_number(),
                           Protocol :: any | socket:protocol(),
                           Reason :: term().

Get service by name.

This function is used to get the port number of the specified protocol for the named service.

getservbyport(PortNumber)

(since OTP 27.1)

-spec getservbyport(PortNumber) -> {ok, Name} | {error, Reason}
                       when
                           PortNumber :: socket:port_number(),
                           Name :: atom() | string(),
                           Reason :: term().

Equivalent to getservbyport(PortNumber, any).

getservbyport(PortNumber, Protocol)

(since OTP 27.1)

-spec getservbyport(PortNumber, Protocol) -> {ok, Name} | {error, Reason}
                       when
                           PortNumber :: socket:port_number(),
                           Protocol :: any | socket:protocol(),
                           Name :: atom() | string(),
                           Reason :: term().

Get service by name.

This function is used to get the service name of the specified protocol for the given port number.

if_index2name(Idx)

(since OTP 22.0)

-spec if_index2name(Idx) -> {ok, Name} | {error, Reason}
                       when
                           Idx :: network_interface_index(),
                           Name :: network_interface_name(),
                           Reason :: term().

Mappings between network interface index and names.

if_name2index(Name)

(since OTP 22.0)

-spec if_name2index(Name) -> {ok, Idx} | {error, Reason}
                       when
                           Name :: network_interface_name(),
                           Idx :: network_interface_index(),
                           Reason :: term().

Mappings between network interface names and indexes.

if_names()

(since OTP 22.0)

-spec if_names() -> {ok, Names} | {error, Reason}
                  when
                      Names :: [{Idx, If}],
                      Idx :: network_interface_index(),
                      If :: network_interface_name(),
                      Reason :: term().

Get network interface names and indexes.

socket

Socket interface.

This module provides an API for network sockets. Functions are provided to create, delete and manipulate the sockets as well as sending and receiving data on them.

The intent is that it shall be as "close as possible" to the OS level socket interface. The only significant additions are that some of the functions, e.g. recv/3, have a time-out argument, and that recv/* for a stream socket iterates until the requested amount of data has been received.

Note

Asynchronous Calls

Some functions feature asynchronous calls. This is achieved by setting the Timeout argument to nowait or to a Handle :: reference/0. See the respective function's type specification.

This module has two different implementations of asynchronous calls. One on the Unix family of operating systems: select - based on the standard socket interface's select(3)/poll(3) calls, and one on Windows: completion - based on asynchronous I/O Completion Ports. The difference shows in the return values and message formats because they have slightly different semantics.

The completion and select Return Values

For instance, the call recv(Socket, 0, nowait), when there is no data available for reading, will, depending on the operating system, return one of:

{completion,CompletionInfo}

{select,SelectInfo}

Where CompletionInfo is {completion_info, _,CompletionHandle} and SelectInfo is {select_info, _,SelectHandle}. Both the CompletionHandle and the SelectHandle are of type reference/0.

When the operation can continue, a completion message containing the CompletionHandle or a select message containing the SelectHandle is sent to the calling process.

On select systems, recv/2,3,4 may also return:

{select, {SelectInfo, Data}

This may happen for sockets of type stream when Length > 1 since the OS may split a data stream at any point and deliver just the first part of the requested data. For the next recv/2,3,4 call; the Length to receive will probably have to be adjusted due to the already delivered data in this return value.

On select systems, when the {otp, select_read} option is true, the asynchronous recv/3,4, recvfrom/3,4, and recvmsg/3,4,5 functions may also return:

{select_read, {SelectInfo, Data}

This indicates that the receive operation was completed; all requested data has been delivered, and that the calling process will get a select message when there is data available for the next receive operation.

The completion and select Messages

The completion message has the format:

{'$socket',Socket, completion, {CompletionHandle, CompletionStatus}}

The select message has the format:

{'$socket',Socket, select,SelectHandle}

When a completion message is received (which contains the result of the operation), it means that the operation has been completed and CompletionStatus is the return value for the operation, which is what the function that initiated the operation could have returned, with the nowait argument, except for the completion and select return values.

When a select message is received, it only means that the operation may now continue, by retrying the operation (which may return a new {select, _} value). Some operations are retried by repeating the same function call, and some have a dedicated function variant to be used for the retry. See the respective function's documentation.

Operation Queuing on select Systems

On select systems, all other processes are locked out until the current process has completed the operation as in a continuation call has returned a value indicating success or failure (not a select or select_read return). Other processes are queued and get a select return which makes them wait for their turn.

Note that receiving data from parallel processes is only suitable for some protocols. For a stream socket it is in general a recipe for disaster.

Cancelling an operation

An operation that is in progress (not completed) may be canceled using cancel/2 both on completion and select systems.

Cancelling an operation ensures that there is no completion, select, nor abort message in the inbox after the cancel/2 call.

Using a Handle

If creating a reference/0 with make_ref() and using that as the Timeout | Handle argument, the same Handle will then be the SelectHandle in the returned select_info/0 and the received select message, or be the CompletionHandle in the returned completion_info/0 and the received completion message.

The compiler may then optimize a following receive statement to only scan the messages that arrive after the reference/0 is created. If the message queue is large this is a big optimization.

It is not possible to have more than one operation in progress with the same reference/0.

Repeating an Operation on a select Systems

Onselect systems, if a call would be repeated before the select message has been received it replaces the operation in progress:

    {select, {select_info, Handle}} = socket:accept(LSock, nowait),
    {ok, Socket} = socket:accept(LSock, 1000),
    :

Above, Handle is no longer valid once the second accept/2, call has been made (the first call is automatically canceled). After the second accept/2 call returns, the accept operation has completed.

Note that there is a race here; there is no way to know if the call is repeated before the select message is sent since it may have been sent just before the repeated call. So now there might be a select message containing Handle in the inbox.

The abort Message

Another message the user must be prepared for (when using nowait | Handle) is the abort message:

{'$socket',Socket, abort, Info}

This message indicates that the operation in progress has been aborted. For instance, if the socket has been closed by another process; Info will be {Handle, closed}.

Note

Support for IPv6 has been implemented but not fully tested.

This module was introduced in OTP 22.0, as experimental code.

In OTP 22.1, the nowait argument was added for many functions, and the cancel/2 and info/1 functions were also added.

In OTP 22.3, the number_of/0 function was added.

In OTP 23.0, the functions is_supported/1,2 and the open/1,2 functions with an FD argument were added.

In OTP 23.1, the use_registry/1 function was added.

In OTP 24.0, the select_handle/0 argument was added for many functions, the cancel/1, cancel_monitor/1, getopt/3 with tuple options, getopt_native/3, info/0, monitor/1, open/3 with an option list, many variants of the recv/*, recvfrom/*, recvmsg/*, send/*, sendmsg/*, the sendto/* functions, the sendfile/* functions, and the setopt/3, setopt_native/3 functions, were added.

In OTP 24.1, the i/* functions were added.

In OTP 24.2, the ioctl/* functions were added.

In OTP 26.0, the completion_handle/0 argument was added for many functions, and the cancel/2 function with completion_info/0 argument was added. That is: support for Windows asynchronous I/O Completion Ports was added. The Unix-ish flavored (select handle) API features could be considered no longer experimental.

In OTP 27.0, the Windows flavored (completion handle) API features could be considered no longer experimental.

In OTP @OTP-19834@, (experimental) complete support for SCTP was added (functionally feature compatible with inet). Not (yet) supported for FreeBSD.

Examples

client(SAddr, SPort) ->
   {ok, Sock} = socket:open(inet, stream, tcp),
   ok = socket:connect(Sock, #{family => inet,
                               addr   => SAddr,
                               port   => SPort}),
   Msg = <<"hello">>,
   ok = socket:send(Sock, Msg),
   ok = socket:shutdown(Sock, write),
   {ok, Msg} = socket:recv(Sock),
   ok = socket:close(Sock).

server(Addr, Port) ->
   {ok, LSock} = socket:open(inet, stream, tcp),
   ok = socket:bind(LSock, #{family => inet,
                             port   => Port,
                             addr   => Addr}),
   ok = socket:listen(LSock),
   {ok, Sock} = socket:accept(LSock),
   {ok, Msg} = socket:recv(Sock),
   ok = socket:send(Sock, Msg),
   ok = socket:close(Sock),
   ok = socket:close(LSock).

Summary

Types

cmsg()

Control messages (ancillary messages).

cmsg_recv()

Control messages (ancillary messages) returned by recvmsg/1,2,3,5.

cmsg_send()

Control messages (ancillary messages) accepted by sendmsg/2,3,4.

completion_handle()

Completion operation handle.

completion_info()

Completion operation info.

completion_tag()

Completion operation tag.

domain()

Protocol domain a.k.a address family.

ee_origin()

eei()

Extended Error Information.

extended_err()

hatype()

icmp_dest_unreach()

icmpv6_dest_unreach()

in6_addr()

in6_flow_info()

in6_scope_id()

in_addr()

info()

Platform dependent information items.

info_keys()

Information element designators for the i/1 and i/2 functions.

interface_type()

The interface type (of the datalink). We only translate a few values to atoms, the rest are left as (unsigned) integer values.

invalid()

ioctl_device_flag()

ioctl_device_map()

ip_mreq()

C: struct ip_mreq

ip_mreq_source()

C: struct ip_mreq_source

ip_msfilter()

C: struct ip_msfilter

ip_pktinfo()

C: struct ip_pktinfo

ip_pmtudisc()

C: IP_PMTUDISC_* values. => Lowercase atom/0 values corresponding to the C library constants IP_PMTUDISC_*. Some constant(s) may be unsupported by the platform.

ip_tos()

C: IPTOS_* values.

ipv6_hops()

IPv6 hop limit value.

ipv6_mreq()

C: struct ipv6_mreq

ipv6_pktinfo()

C: struct in6_pktinfo

ipv6_pmtudisc()

C: IPV6_PMTUDISC_* values

level()

Protocol level.

linger()

C: struct linger

msg()

C: struct msghdr

msg_data_recv()

Message returned by recvmsg/1,2,3,5.

msg_flag()

Platform dependent message flags.

msg_notification_recv()

Notifications can be received on a SCTP socket (type = seqpacket and protocol = sctp).

msg_recv()

Message returned by recvmsg/1,2,3,5.

msg_send()

Message sent by sendmsg/2,3,4.

native_value()

otp_socket_option()

Protocol level otp socket option.

packet_type()

port_number()

posix()

Posix error codes.

protocol()

Protocol name.

sctp_adapt_event()

A peer has sent a Adaptation Layer Indication parameter.

sctp_assoc_change()

An SCTP association has either begun or ended.

sctp_assoc_change_state()

sctp_assoc_id()

C: sctp_assoc_t

sctp_assoc_reset_event()

C: struct sctp_assoc_reset_event

sctp_assoc_stats()

C: struct sctp_assoc_stats.

sctp_assocparams()

C: struct sctp_assocparams

sctp_authkey()

When a receiver is using authentication, info about new keys and errors are provided in this notification.

sctp_event_subscribe()

C: struct sctp_event_subscribe.

sctp_initmsg()

C: struct sctp_initmsg.

sctp_notification()

All possible notification types. All of them has at least two fields: 'type' and 'flags' ('flags' are not allways used).

sctp_notification_generic()

C: union sctp_notification

sctp_operation_error()

These error codes are (currently) defined in RFC 4960, and named as Operation Errors.

sctp_paddr_change()

A destination address on a multi-homed peer has encountered a change.

sctp_pap_flag()

C: enum sctp_spp_flags.

sctp_pap_flags()

There are three pairs of flags that cannot be both be set (maybe obviously) at the same time

sctp_pdapi_event()

A receiver is engaged in a partial delivery.

sctp_peer_addr_change_state()

sctp_peer_address_info()

C: struct sctp_paddrinfo.

sctp_peer_address_parameters()

C: struct sctp_paddrparams.

sctp_peer_address_state()

C: enum sctp_spinfo_state.

sctp_remote_error()

A remote peer may send an operational error message to its peer.

sctp_rtoinfo()

C: struct sctp_rtoinfo.

sctp_send_failed()

SCTP cannot deliver a message.

sctp_send_failed_event()

SCTP cannot deliver a message.

sctp_sender_dry()

The SCTP stack has no more user data to send or retransmit.

sctp_set_adaptation_layer_ind()

C: struct sctp_setadaptation.

sctp_set_peer_primary_address()

C: struct sctp_setpeerprim.

sctp_set_primary_address()

C: struct sctp_prim.

sctp_setadaption()

C: struct sctp_setadaption

sctp_shutdown_event()

A peer has sent a SHUTDOWN.

sctp_snd_info()

C: struct sctp_sndinfo

sctp_snd_rcv_info()

SCTP options for sendmsg() and SCTP header information about a received message through recvmsg().

sctp_snd_rcv_info_flags()

sctp_status()

C: struct sctp_status.

sctp_stream_change_event()

C: struct sctp_stream_change_event

sctp_stream_reset_event()

C: struct sctp_stream_reset_event

select_handle()

Select operation handle.

select_info()

Select operation info.

select_tag()

Select operation tag.

sockaddr()

sockaddr_dl()

C: struct sockaddr_dl

sockaddr_in6()

C: struct sockaddr_in6

sockaddr_in()

C: struct sockaddr_in

sockaddr_ll()

C: struct sockaddr_ll

sockaddr_native()

C: struct sockaddr

sockaddr_recv()

sockaddr_un()

C: struct sockaddr_un.

sockaddr_unspec()

C: struct sockaddr of AF_UNSPEC

socket()

A socket, according to this module.

socket_counters()

A map/0 of Name := Counter associations.

socket_handle()

Opaque socket handle unique for the socket.

socket_info()

socket_option()

Socket option.

timespec()

C: struct timespec

timeval()

C: struct timeval

type()

Protocol type.

uint8()

uint16()

uint32()

uint64()

Functions

accept(ListenSocket)

Equivalent to accept(ListenSocket, infinity).

accept/2

Accept a connection on a listening socket.

bind(Socket, Addr)

Bind a name to a socket.

bind(Socket, Addrs, Action)

Bind a list of socket addreses to a socket.

cancel/2

Cancel an asynchronous call in progress.

cancel_monitor(MRef)

Cancel a socket monitor.

close(Socket)

Close a socket.

connect(Socket)

Finalize a connect/3 operation.

connect(Socket, SockAddr)

Equivalent to connect(Socket, SockAddr, infinity) or connect(Socket, SockAddrs, undefined, infinity).

connect/3

Connect the socket to the given address(s).

getopt/2

Get the value of a socket option.

getopt/3

Get a socket option, with a specifier (extra input) OptValue.

getopt_native/3

Get a "native" socket option.

i()

Print information to the erlang shell in table format for all sockets.

i/1

Print information to the erlang shell in table format for all sockets.

i/2

Print information to the erlang shell in table format for a selection of sockets.

info()

Get miscellaneous information about this socket library.

info(Socket)

Get miscellaneous info about a socket.

ioctl/2

Set socket (device) parameters.

ioctl/3

Get or set socket (device) parameters.

ioctl(Socket, SetRequest, Name, Value)

Set socket (device) parameters.

is_supported(Key1)

Check if a socket feature is supported.

is_supported(Key1, Key2)

Check if a socket feature is supported.

listen(Socket)

Make a socket listen for connections.

listen/2

Make a socket listen for connections.

monitor(Socket)

Start a socket monitor.

number_of()

Return the number of active sockets.

open(FD)

Equivalent to open(FD, #{}).

open/2

Create a socket.

open/3

Create a socket.

open(Domain, Type, Protocol, Opts)

Create a socket.

peeloff(Socket, AssocId)

Branch off an association into a separate socket.

peeloff(Socket, AssocId, InheritOpts)

Branch off an association into a separate socket.

peername(Socket)

Return the remote address of a socket.

peernames(Socket, AssocId)

Return the remote (peer) address(s) of an association of a socket.

recv(Socket)

Equivalent to recv(Socket, 0, [], infinity).

recv/2

Receive data on a connected socket.

recv/3

Receive data on a connected socket.

recv/4

Receive data on a connected socket.

recvfrom(Socket)

Equivalent to recvfrom(Socket, 0, [], infinity).

recvfrom/2

Receive a message on a socket.

recvfrom/3

Receive a message on a socket.

recvfrom/4

Receive a message on a socket.

recvmmsg/6

Receive multiple messages on a socket.

recvmsg(Socket)

Equivalent to recvmsg(Socket, 0, 0, [], infinity).

recvmsg/2

Receive a message on a socket.

recvmsg/3

Receive a message on a socket.

recvmsg(Socket, BufSz, CtrlSz, TimeoutOrHandle)

Equivalent to recvmsg(Socket, BufSz, CtrlSz, [], TimeoutOrHandle).

recvmsg/5

Receive a message on a socket.

rest_iov(Written, IOV)

Calculate the rest I/O vector after a partially successful sendv (CompletionStatus was {ok, Written}).

send(Socket, Data)

Equivalent to send(Socket, Data, [], infinity).

send/3

Send data on a connected socket.

send/4

Send data on a connected socket.

sendfile(Socket, FileHandle_Cont)

Send a file on a socket.

sendfile(Socket, FileHandle_Cont, Timeout_Handle)

Send a file on a socket.

sendfile(Socket, FileHandle_Cont, Offset, Count)

Send a file on a socket.

sendfile/5

Send a file on a socket.

sendmmsg/4

Send multiple messages on a socket.

sendmsg(Socket, Msg)

Equivalent to sendmsg(Socket, Msg, [], infinity).

sendmsg/3

Send data and control messages on a socket.

sendmsg/4

Send data and control messages on a socket.

sendto/3

Send data on a socket.

sendto/4

Send data on a socket.

sendto/5

Send data on a socket.

sendv(Socket, IOV)

Equivalent to sendv(Socket, IOV, infinity).

sendv/3

Send erlang:iovec/0 data on a connected socket.

sendv/4

Send data on a connected socket, continuation.

setopt/3

Set a socket option.

setopt/4

Set a socket option (backwards compatibility function).

setopt_native(Socket, Option, Value)

Set a "native" socket option.

shutdown(Socket, How)

Shut down all or part of a full-duplex connection.

sockname(Socket)

Get the socket's address.

socknames(Socket, AssocId)

Get the socket's address.

supports()

Retrieve information about what socket features the module and the platform supports.

supports(Key1)

Retrieve information about what socket features the module and the platform supports.

supports(Key1, Key2)

Retrieve information about what socket features the module and the platform supports.

use_registry(D)

Set the global use_registry option default value.

which_sockets()

Return a list of all known sockets.

which_sockets(FilterRule)

Return a filtered list of known sockets.

Types

cmsg()

(since OTP 22.0)

-type cmsg() :: cmsg_recv() | cmsg_send().

Control messages (ancillary messages).

cmsg_recv()

(since OTP 22.0)

-type cmsg_recv() ::
          #{level := socket, type := timestamp, data := binary(), value => timeval()} |
          #{level := socket, type := timestampns, data := binary(), value => timespec()} |
          #{level := socket, type := rights, data := binary()} |
          #{level := socket, type := credentials, data := binary()} |
          #{level := ip, type := tos, data := binary(), value => ip_tos() | integer()} |
          #{level := ip, type := recvtos, data := binary(), value := ip_tos() | integer()} |
          #{level := ip, type := ttl, data := binary(), value => integer()} |
          #{level := ip, type := recvttl, data := binary(), value := integer()} |
          #{level := ip, type := pktinfo, data := binary(), value => ip_pktinfo()} |
          #{level := ip, type := origdstaddr, data := binary(), value => sockaddr_recv()} |
          #{level := ip, type := recverr, data := binary(), value => extended_err()} |
          #{level := ipv6, type := hoplimit, data := binary(), value => integer()} |
          #{level := ipv6, type := pktinfo, data := binary(), value => ipv6_pktinfo()} |
          #{level := ipv6, type := recverr, data := binary(), value => extended_err()} |
          #{level := ipv6, type := tclass, data := binary(), value => integer()}.

Control messages (ancillary messages) returned by recvmsg/1,2,3,5.

A control message has got a data field with a native (binary) value for the message data, and may also have a decoded value field if this socket library successfully decoded the data.

cmsg_send()

(since OTP 22.0)

-type cmsg_send() ::
          #{level := sctp, type := sndrcv, value := sctp_snd_rcv_info()} |
          #{level := socket, type := timestamp, data => native_value(), value => timeval()} |
          #{level := socket, type := rights, data := native_value()} |
          #{level := socket, type := credentials, data := native_value()} |
          #{level := ip, type := tos, data => native_value(), value => ip_tos() | integer()} |
          #{level := ip, type := ttl, data => native_value(), value => integer()} |
          #{level := ip, type := hoplimit, data => native_value(), value => integer()} |
          #{level := ipv6, type := tclass, data => native_value(), value => integer()}.

Control messages (ancillary messages) accepted by sendmsg/2,3,4.

A control message may for some message types have a value field with a symbolic value, or a data field with a native value, that has to be binary compatible what is defined in the platform's header files.

completion_handle()

(since OTP 26.0)

-type completion_handle() :: reference().

Completion operation handle.

A reference/0 that uniquely identifies the (completion) operation, contained in the returned completion_info/0.

completion_info()

(since OTP 26.0)

-type completion_info() ::
          {completion_info, CompletionTag :: completion_tag(), CompletionHandle :: completion_handle()}.

Completion operation info.

Returned by an operation that requires the caller to wait for a completion message containing the CompletionHandle and the result of the operation; the CompletionStatus.

completion_tag()

(since OTP 26.0)

-type completion_tag() ::
          accept | connect |
          recv | recvfrom | recvmsg | recvmmsg | send | sendv | sendto | sendmsg | sendmmsg | sendfile.

Completion operation tag.

A tag that describes the ongoing (completion) operation (= function name), contained in the returned completion_info/0.

domain()

(since OTP 22.0)

-type domain() :: inet | inet6 | local | unspec.

Protocol domain a.k.a address family.

A lowercase atom/0 representing a protocol domain on the platform named AF_* (or PF_*). For example inet corresponds to AF_INET.

is_supported(ipv6) tells if the IPv6 protocol, protocol domain inet6, is supported.

is_supported(local) tells if the protocol domain local is supported.

supports/0 reports both values, but also many more, with a single call.

ee_origin()

(since OTP 22.0)

-type ee_origin() :: none | local | icmp | icmp6.

eei()

(since OTP 22.0)

-type eei() ::
          #{info := econnreset | econnaborted | netname_deleted | too_many_cmds | atom(),
            raw_info := term()}.

Extended Error Information.

A term containing additional (error) information if the socket NIF has been configured to produce it.

extended_err()

(since OTP 22.0)

-type extended_err() ::
          #{error := posix(),
            origin := icmp,
            type := dest_unreach,
            code := icmp_dest_unreach() | 0..255,
            info := 0..4294967295,
            data := 0..4294967295,
            offender := sockaddr_recv()} |
          #{error := posix(),
            origin := icmp,
            type := time_exceeded | 0..255,
            code := 0..255,
            info := 0..4294967295,
            data := 0..4294967295,
            offender := sockaddr_recv()} |
          #{error := posix(),
            origin := icmp6,
            type := dest_unreach,
            code := icmpv6_dest_unreach() | 0..255,
            info := 0..4294967295,
            data := 0..4294967295,
            offender := sockaddr_recv()} |
          #{error := posix(),
            origin := icmp6,
            type := pkt_toobig | time_exceeded | 0..255,
            code := 0..255,
            info := 0..4294967295,
            data := 0..4294967295,
            offender := sockaddr_recv()} |
          #{error := posix(),
            origin := ee_origin() | 0..255,
            type := 0..255,
            code := 0..255,
            info := 0..4294967295,
            data := 0..4294967295,
            offender := sockaddr_recv()}.

hatype()

(not exported) (since OTP 22.0)

-type hatype() ::
          netrom | eether | ether | ax25 | pronet | chaos | ieee802 | arcnet | appletlk | dlci | atm |
          metricom | ieee1394 | eui64 | infiniband | tunnel | tunnel6 | loopback | localtlk | none |
          void |
          non_neg_integer().

icmp_dest_unreach()

(since OTP 22.0)

-type icmp_dest_unreach() ::
          net_unreach | host_unreach | port_unreach | frag_needed | net_unknown | host_unknown.

icmpv6_dest_unreach()

(since OTP 22.0)

-type icmpv6_dest_unreach() ::
          noroute | adm_prohibited | not_neighbour | addr_unreach | port_unreach | policy_fail |
          reject_route.

in6_addr()

(since OTP 22.0)

-type in6_addr() :: {0..65535, 0..65535, 0..65535, 0..65535, 0..65535, 0..65535, 0..65535, 0..65535}.

in6_flow_info()

(not exported) (since OTP 22.0)

-type in6_flow_info() :: 0..1048575.

in6_scope_id()

(not exported) (since OTP 22.0)

-type in6_scope_id() :: 0..4294967295.

in_addr()

(since OTP 22.0)

-type in_addr() :: {0..255, 0..255, 0..255, 0..255}.

info()

(not exported) (since OTP 22.0)

-type info() ::
          #{counters := #{atom() := non_neg_integer()},
            iov_max := non_neg_integer(),
            use_registry := boolean(),
            io_backend := #{name := atom()},
            load_nif_result := undefined | ok | {error, term()}}.

Platform dependent information items.

The value of iov_max is the value of the IOV_MAX constant in the system headers, which is the largest allowed I/O vector. See also sendmsg/4 regarding the iov key of msg_send/0. The smallest allowed IOV_MAX value according to POSIX is 16, but check your platform documentation to be sure.

About the use_registry key, see use_registry/1 and the otp_socket_option/0 with the same name.

info_keys()

(since OTP 22.0)

-type info_keys() ::
          [domain | type | protocol | fd | owner | local_address | remote_address | recv | sent | state].

Information element designators for the i/1 and i/2 functions.

interface_type()

(since OTP 22.0)

-type interface_type() ::
          other | hdh1822 | x25ddh | x25 | ether | ppp | loop | ipv4 | ipv6 | '6to4' | gif | faith |
          stf | bridge | cellular |
          non_neg_integer().

The interface type (of the datalink). We only translate a few values to atoms, the rest are left as (unsigned) integer values.

invalid()

(since OTP 22.0)

-type invalid() :: {invalid, What :: term()}.

ioctl_device_flag()

(since OTP 22.0)

-type ioctl_device_flag() ::
          up | broadcast | debug | loopback | pointopoint | notrailers | knowsepoch | running | noarp |
          promisc | allmulti | master | oactive | slave | simplex | link0 | link1 | link2 | multicast |
          portsel | automedia | cantconfig | ppromisc | dynamic | monitor | staticarp | dying |
          renaming | nogroup | lower_up | dormant | echo.

ioctl_device_map()

(since OTP 22.0)

-type ioctl_device_map() ::
          #{mem_start := non_neg_integer(),
            mem_end := non_neg_integer(),
            base_addr := non_neg_integer(),
            irq := non_neg_integer(),
            dma := non_neg_integer(),
            port := non_neg_integer()}.

ip_mreq()

(since OTP 22.0)

-type ip_mreq() :: #{multiaddr := in_addr(), interface := in_addr()}.

C: struct ip_mreq

Corresponds to the C struct ip_mreq for managing multicast groups.

ip_mreq_source()

(since OTP 22.0)

-type ip_mreq_source() :: #{multiaddr := in_addr(), interface := in_addr(), sourceaddr := in_addr()}.

C: struct ip_mreq_source

Corresponds to the C struct ip_mreq_source for managing multicast groups.

ip_msfilter()

(since OTP 22.0)

-type ip_msfilter() ::
          #{multiaddr := in_addr(),
            interface := in_addr(),
            mode := include | exclude,
            slist := [in_addr()]}.

C: struct ip_msfilter

Corresponds to the C struct ip_msfilter for managing multicast source filtering (RFC 3376).

ip_pktinfo()

(since OTP 22.0)

-type ip_pktinfo() :: #{ifindex := non_neg_integer(), spec_dst := in_addr(), addr := in_addr()}.

C: struct ip_pktinfo

ip_pmtudisc()

(since OTP 22.0)

-type ip_pmtudisc() :: want | dont | do | probe.

C: IP_PMTUDISC_* values. => Lowercase atom/0 values corresponding to the C library constants IP_PMTUDISC_*. Some constant(s) may be unsupported by the platform.

ip_tos()

(since OTP 22.0)

-type ip_tos() :: lowdelay | throughput | reliability | mincost.

C: IPTOS_* values.

Lowercase atom/0 values corresponding to the C library constants IPTOS_*. Some constant(s) may be unsupported by the platform.

ipv6_hops()

(since OTP 22.0)

-type ipv6_hops() :: default | 0..255.

IPv6 hop limit value.

The value default is only valid to set and is translated to the C value -1, meaning the route default.

ipv6_mreq()

(since OTP 22.0)

-type ipv6_mreq() :: #{multiaddr := in6_addr(), interface := non_neg_integer()}.

C: struct ipv6_mreq

Corresponds to the C struct ipv6_mreq for managing multicast groups. See also RFC 2553.

ipv6_pktinfo()

(since OTP 22.0)

-type ipv6_pktinfo() :: #{addr := in6_addr(), ifindex := integer()}.

C: struct in6_pktinfo

ipv6_pmtudisc()

(since OTP 22.0)

-type ipv6_pmtudisc() :: want | dont | do | probe.

C: IPV6_PMTUDISC_* values

Lowercase atom/0 values corresponding to the C library constants IPV6_PMTUDISC_*. Some constant(s) may be unsupported by the platform.

level()

(since OTP 22.0)

-type level() :: socket | protocol().

Protocol level.

A lowercase atom/0 OS protocol level, that is: socket or a protocol/0 name.

socket is the SOL_SOCKET protocol level in the OS header files, with options named SO_* .

linger()

(since OTP 22.0)

-type linger() :: #{onoff := boolean(), linger := non_neg_integer()}.

C: struct linger

Corresponds to the C struct linger for managing the socket option {socket, linger}.

msg()

(since OTP 22.0)

-type msg() :: msg_send() | msg_recv().

C: struct msghdr

msg_data_recv()

(not exported) (since OTP 22.0)

-type msg_data_recv() ::
          #{addr => sockaddr_recv(),
            iov := erlang:iovec(),
            ctrl := [cmsg_recv() | #{level := level() | integer(), type := integer(), data := binary()}],
            flags := [msg_flag() | integer()]}.

Message returned by recvmsg/1,2,3,5.

Corresponds to a C struct msghdr, see your platform documentation for recvmsg(2).

addr - Optional peer address, used on unconnected sockets. Corresponds to msg_name and msg_namelen fields of a struct msghdr. If NULL the map key is not present.

iov - Data as a list of binaries. The msg_iov and msg_iovlen fields of a struct msghdr.

ctrl - A possibly empty list of control messages (CMSG). Corresponds to the msg_control and msg_controllen fields of a struct msghdr.

flags - Message flags. Corresponds to the msg_flags field of a struct msghdr. Unknown flags, if any, are returned in one integer/0, last in the containing list.

msg_flag()

(since OTP 22.0)

-type msg_flag() ::
          cmsg_cloexec | confirm | ctrunc | dontroute | eor | errqueue | more | oob | peek | trunc.

Platform dependent message flags.

Translates to/from message flag constants on the platform. These flags are lowercase while the constants are uppercase with prefix MSG_; for example oob translates to MSG_OOB.

Some flags are only used for sending, some only for receiving, some in received control messages, and some for several of these. Not all flags are supported on all platforms. See the platform's documentation, supports(msg_flags), and is_supported(msg_flags, MsgFlag).

msg_notification_recv()

(not exported) (since OTP @OTP-19834@)

-type msg_notification_recv() ::
          #{addr => sockaddr_recv(),
            notification := sctp_notification(),
            ctrl := [#{level := level() | integer(), type := integer(), data := binary()}],
            flags := [notification | [msg_flag() | integer()]]}.

Notifications can be received on a SCTP socket (type = seqpacket and protocol = sctp).

msg_recv()

(since OTP 22.0)

-type msg_recv() :: msg_data_recv() | msg_notification_recv().

Message returned by recvmsg/1,2,3,5.

msg_send()

(since OTP 22.0)

-type msg_send() ::
          #{addr => sockaddr(),
            iov := erlang:iovec(),
            ctrl => [cmsg_send() | #{level := level() | integer(), type := integer(), data := binary()}]}.

Message sent by sendmsg/2,3,4.

Corresponds to a C struct msghdr, see your platform documentation for sendmsg(2).

addr - Optional peer address, used on unconnected sockets. Corresponds to msg_name and msg_namelen fields of a struct msghdr. If not used they are set to NULL, 0.

iov - Mandatory data as a list of binaries. The msg_iov and msg_iovlen fields of a struct msghdr.

ctrl - Optional list of control messages (CMSG). Corresponds to the msg_control and msg_controllen fields of a struct msghdr. If not used they are set to NULL, 0.

The msg_flags field of the struct msghdr is set to 0.

native_value()

(not exported) (since OTP 22.0)

-type native_value() :: integer() | boolean() | binary().

otp_socket_option()

(since OTP 22.0)

-type otp_socket_option() ::
          debug | iow | controlling_process | rcvbuf | rcvctrlbuf | sndctrlbuf | select_read | meta |
          use_registry | fd | domain.

Protocol level otp socket option.

Socket options for the otp pseudo protocol level, that is: {otp, Name} options.

This protocol level is the Erlang/OTP's socket implementation layer, hence above all OS protocol levels.

debug - boolean/0 - Activate debug logging.

iow - boolean/0 - Inform On Wrap of statistics counters.

controlling_process - pid/0 - The socket "owner". Only the current controlling process can set this option.

rcvbuf - BufSize :: (default | integer()>0) | {N :: integer()>0, BufSize :: (default | integer()>0)}- Receive buffer size.

The value default is only valid to set.

N specifies the number of read attempts to do in a tight loop before assuming no more data is pending.

This is the allocation size for the receive buffer used when calling the OS protocol stack's receive API, when no specific size (size 0) is requested. When the receive function returns the receive buffer is reallocated to the actually received size. If the data is copied or shrunk in place is up to the allocator, and can to some extent be configured in the Erlang VM.

The similar socket option; {socket,rcvbuf} is a related option for the OS' protocol stack that on Unix corresponds to SOL_SOCKET,SO_RCVBUF.

rcvctrlbuf - BufSize :: (default | integer()>0)- Allocation size for the ancillary data buffer used when calling the OS protocol stack's receive API.

The value default is only valid to set.

sndctrlbuf - BufSize :: (default | integer()>0)- Allocation size for the ancillary data buffer used when calling the OS protocol stack's sendmsg API.

The value default is only valid to set.

It is the user's responsibility to set a buffer size that has room for the encoded ancillary data in the message to send.

See sendmsg and also the ctrl field of the msg_send/0 type.

select_read - boolean/0 - On select implementations, see Asynchronous Calls, automatically activate select after a completed read.

Instead of {ok, Data} the receive operation returns {select_read, {SelectInfo, Data}}, and the calling process can wait for a select message containing SelectInfo when there is data available again.

Setting this option locks out other processes from receiving any data since the current process continues its operation, so it effectively disables receive operation queuing.

fd - integer/0 - Only valid to get. The OS protocol levels' socket descriptor. Functions open/1,2 can be used to create a socket according to this module from an existing OS socket descriptor.

use_registry - boolean/0 - Only valid to get. The value is set when the socket is created with open/2 or open/4.

Options not described here are intentionally undocumented and for Erlang/OTP internal use only.

packet_type()

(not exported) (since OTP 22.0)

-type packet_type() ::
          host | broadcast | multicast | otherhost | outgoing | loopback | user | kernel | fastroute |
          non_neg_integer().

port_number()

(since OTP 22.0)

-type port_number() :: 0..65535.

posix()

(not exported) (since OTP 22.0)

-type posix() :: inet:posix().

Posix error codes.

Local alias for inet:posix/0, a set of atom/0s.

protocol()

(since OTP 22.0)

-type protocol() :: atom().

Protocol name.

A lowercase atom/0 representing an OS protocol name. To be used for example in socket_option/0 in control messages.

They have the following names in the OS header files:

ip - IPPROTO_IP a.k.a SOL_IP with options named IP_*.

ipv6 - IPPROTO_IPV6 a.k.a SOL_IPV6 with options named IPV6_*.

tcp - IPPROTO_TCP with options named TCP_*.

mptcp - IPPROTO_MPTCP with a few options named MPTCP_*. Most TCP_* options apply which is the purpose of Multi-Path TCP.

udp - IPPROTO_UDP with options named UDP_*.

sctp - IPPROTO_SCTP with options named SCTP_*.

There are many other possible protocols, but the ones above are those for which this socket library implements socket options and/or control messages.

All protocols known to the OS are enumerated when the Erlang VM is started, through the C library call getprotoent(). See the OS man page for protocols(5). Those in the list above are valid if supported by the platform, even if they aren't enumerated.

The calls is_supported(ipv6) , is_supported(sctp) and is_supported(mptcp) can be used to find out if the protocols ipv6, sctp and mptcp are supported on the platform as in; appropriate header file and libraries exist.

The call is_supported(protocols, Protocol) can only be used to find out if the platform knows the protocol number for a named Protocol.

See open/2,3,4

sctp_adapt_event()

(not exported) (since OTP 22.0)

-type sctp_adapt_event() ::
          #{type := adaptation_event,
            flags := uint16(),
            adaption_ind := uint32(),
            assoc_id := sctp_assoc_id()}.

A peer has sent a Adaptation Layer Indication parameter.

C: struct sctp_adaptation_event

sctp_assoc_change()

(not exported) (since OTP 22.0)

-type sctp_assoc_change() ::
          #{type := assoc_change,
            flags := integer(),
            state := sctp_assoc_change_state(),
            error := sctp_operation_error(),
            outbound_streams := integer(),
            inbound_streams := integer(),
            assoc_id := sctp_assoc_id()}.

An SCTP association has either begun or ended.

C: struct sctp_assoc_change

sctp_assoc_change_state()

(not exported) (since OTP 22.0)

-type sctp_assoc_change_state() ::
          comm_up | comm_lost | restart | shutdown_comp | cant_str_assoc | integer().

sctp_assoc_id()

(since OTP 22.0)

-type sctp_assoc_id() :: integer().

C: sctp_assoc_t

sctp_assoc_reset_event()

(not exported) (since OTP 22.0)

-type sctp_assoc_reset_event() ::
          #{type := assoc_reset,
            flags := [denied | failed],
            assoc_id := sctp_assoc_id(),
            local_tsn := uint32(),
            remote_tsn := uint32()}.

C: struct sctp_assoc_reset_event

sctp_assoc_stats()

(since OTP 22.0)

-type sctp_assoc_stats() ::
          #{assoc_id := sctp_assoc_id(),
            max_rto_addr := sockaddr(),
            max_rto := uint64(),
            in_sacks := uint64(),
            out_sacks := uint64(),
            in_packets := uint64(),
            out_packets := uint64(),
            rtx_chunks := uint64(),
            out_of_seq_tsns := uint64(),
            in_dup_chunks := uint64(),
            gap_ack_recv := uint64(),
            in_unordered_chunks := uint64(),
            out_unordered_chunks := uint64(),
            in_ordered_chunks := uint64(),
            out_ordered_chunks := uint64(),
            in_ctrl_chunks := uint64(),
            out_ctrl_chunks := uint64()}.

C: struct sctp_assoc_stats.

sctp_assocparams()

(since OTP 22.0)

-type sctp_assocparams() ::
          #{assoc_id := sctp_assoc_id(),
            asocmaxrxt := uint16(),
            number_peer_destinations := uint16(),
            peer_rwnd := uint32(),
            local_rwnd := uint32(),
            cookie_life := uint32()}.

C: struct sctp_assocparams

sctp_authkey()

(not exported) (since OTP 22.0)

-type sctp_authkey() ::
          #{type := authkey,
            flags := uint16(),
            keynumber := uint16(),
            altkeynumber := uint16(),
            indication := uint32(),
            assoc_id := sctp_assoc_id()}.

When a receiver is using authentication, info about new keys and errors are provided in this notification.

C: struct sctp_authkey_event

sctp_event_subscribe()

(since OTP 22.0)

-type sctp_event_subscribe() ::
          #{data_io := boolean(),
            association := boolean(),
            address := boolean(),
            send_failure := boolean(),
            peer_error := boolean(),
            shutdown := boolean(),
            partial_delivery := boolean(),
            adaptation_layer => boolean(),
            sender_dry => boolean(),
            stream_reset => boolean(),
            assoc_reset => boolean(),
            stream_change => boolean()}.

C: struct sctp_event_subscribe.

Not all fields are implemented on all platforms; unimplemented fields are ignored, but implemented fields are mandatory. Note that the '_event' suffixes have been stripped from the C struct field names, for convenience.

sctp_initmsg()

(since OTP 22.0)

-type sctp_initmsg() ::
          #{num_ostreams := uint16(),
            max_instreams := uint16(),
            max_attempts := uint16(),
            max_init_timeo := uint16()}.

C: struct sctp_initmsg.

sctp_notification()

(not exported) (since OTP 22.0)

-type sctp_notification() ::
          sctp_assoc_change() |
          sctp_paddr_change() |
          sctp_send_failed() |
          sctp_remote_error() |
          sctp_shutdown_event() |
          sctp_adapt_event() |
          sctp_pdapi_event() |
          sctp_authkey() |
          sctp_sender_dry() |
          sctp_stream_reset_event() |
          sctp_assoc_reset_event() |
          sctp_stream_change_event() |
          sctp_send_failed_event() |
          sctp_notification_generic().

All possible notification types. All of them has at least two fields: 'type' and 'flags' ('flags' are not allways used).

C: union sctp_notification

sctp_notification_generic()

(not exported) (since OTP 22.0)

-type sctp_notification_generic() :: #{type := uint16(), flags := uint16()}.

C: union sctp_notification

This is intended as a fallback type for any notification we have not yet implemented.

sctp_operation_error()

(not exported) (since OTP 22.0)

-type sctp_operation_error() ::
          unknown | bad_sid | missing_parm | stale_cookie | no_resources | bad_addr | unrec_chunk |
          bad_mandparm | unrec_parm | no_usr_data | cookie_shut | restart_new_addrs | user_abort |
          delete_lastaddr | resource_shortage | delete_srcaddr | auth_err |
          pos_integer().

These error codes are (currently) defined in RFC 4960, and named as Operation Errors.

sctp_paddr_change()

(not exported) (since OTP 22.0)

-type sctp_paddr_change() ::
          #{type := peer_addr_change,
            flags := pos_integer(),
            addr := socket:sockaddr(),
            state := sctp_peer_addr_change_state(),
            error := pos_integer(),
            assoc_id := sctp_assoc_id()}.

A destination address on a multi-homed peer has encountered a change.

C: struct sctp_paddr_change

sctp_pap_flag()

(since OTP 22.0)

-type sctp_pap_flag() ::
          enable_heartbeats | disable_heartbeats | send_heartbeat_immediately | enable_pmtu_discovery |
          disable_pmtu_discovery | enable_sack | disable_sack | set_heartbeat_delay_to_zero |
          ipv6_flowlabel | dscp.

C: enum sctp_spp_flags.

sctp_pap_flags()

(since OTP 22.0)

-type sctp_pap_flags() :: integer() | [sctp_pap_flag()].

There are three pairs of flags that cannot be both be set (maybe obviously) at the same time:

enable_heartbeats and disable_heartbeats

enable_pmtu_discovery and disable_pmtu_discovery

enable_sack and disable_sack

sctp_pdapi_event()

(not exported) (since OTP 22.0)

-type sctp_pdapi_event() ::
          #{type := partial_delivery_event,
            flags := uint16(),
            indication := uint16(),
            assoc_id := sctp_assoc_id(),
            stream => uint32(),
            seq => uint32()}.

A receiver is engaged in a partial delivery.

Note that not all fields are available on all platforms. The stream and/or seq fields may not be present.

C: struct sctp_pdapi_event

sctp_peer_addr_change_state()

(not exported) (since OTP 22.0)

-type sctp_peer_addr_change_state() ::
          addr_available | addr_unreachable | addr_removed | addr_added | addr_made_prim |
          addr_confirmed | addr_potentially_failed |
          integer().

sctp_peer_address_info()

(since OTP 22.0)

-type sctp_peer_address_info() ::
          #{assoc_id := sctp_assoc_id(),
            address := sockaddr(),
            state := sctp_peer_address_state(),
            cwnd := uint32(),
            srtt := uint32(),
            rto := uint32(),
            mtu := uint32()}.

C: struct sctp_paddrinfo.

sctp_peer_address_parameters()

(since OTP 22.0)

-type sctp_peer_address_parameters() ::
          #{assoc_id := sctp_assoc_id(),
            addr := sockaddr(),
            heatbeat_interval := uint32(),
            path_max_rxt := uint16(),
            path_mtu => uint32(),
            sack_delay => uint32(),
            flags => sctp_pap_flags(),
            ipv6_flowlabel => uint32(),
            dscp => uint8()}.

C: struct sctp_paddrparams.

sctp_peer_address_state()

(since OTP 22.0)

-type sctp_peer_address_state() :: inactive | potentially_failed | active | unconfirmed | unknown.

C: enum sctp_spinfo_state.

sctp_remote_error()

(not exported) (since OTP 22.0)

-type sctp_remote_error() ::
          #{type := remote_error,
            flags := uint16(),
            error := sctp_operation_error(),
            assoc_id := sctp_assoc_id(),
            remote_causes := [integer()]}.

A remote peer may send an operational error message to its peer.

C: struct sctp_remote_error

sctp_rtoinfo()

(since OTP 22.0)

-type sctp_rtoinfo() ::
          #{assoc_id := sctp_assoc_id(), initial := uint32(), max := uint32(), min := uint32()}.

C: struct sctp_rtoinfo.

sctp_send_failed()

(not exported) (since OTP 22.0)

-type sctp_send_failed() ::
          #{type := send_failed,
            flags := uint16(),
            error := uint32(),
            info := sctp_snd_rcv_info(),
            assoc_id := sctp_assoc_id(),
            data := binary()}.

SCTP cannot deliver a message.

C: struct sctp_send_failed

Deprecated.

sctp_send_failed_event()

(not exported) (since OTP 22.0)

-type sctp_send_failed_event() ::
          #{type := send_failed_event,
            flags := [data_unsent | data_sent],
            error := uint32(),
            info := sctp_snd_info(),
            assoc_id := sctp_assoc_id(),
            data := binary()}.

SCTP cannot deliver a message.

C: struct sctp_send_failed_event

sctp_sender_dry()

(not exported) (since OTP 22.0)

-type sctp_sender_dry() :: #{type := sender_dry, flags := uint16(), assoc_id := sctp_assoc_id()}.

The SCTP stack has no more user data to send or retransmit.

C: struct sctp_sender_dry_event

sctp_set_adaptation_layer_ind()

(since OTP 22.0)

-type sctp_set_adaptation_layer_ind() :: #{ind := uint32()}.

C: struct sctp_setadaptation.

sctp_set_peer_primary_address()

(since OTP 22.0)

-type sctp_set_peer_primary_address() :: #{assoc_id := sctp_assoc_id(), addr := sockaddr()}.

C: struct sctp_setpeerprim.

sctp_set_primary_address()

(since OTP 22.0)

-type sctp_set_primary_address() :: #{assoc_id := sctp_assoc_id(), addr := sockaddr()}.

C: struct sctp_prim.

sctp_setadaption()

(since OTP 22.0)

-type sctp_setadaption() :: #{adaption_ind := uint32()}.

C: struct sctp_setadaption

sctp_shutdown_event()

(not exported) (since OTP 22.0)

-type sctp_shutdown_event() :: #{type := shutdown_event, flags := uint16(), assoc_id := sctp_assoc_id()}.

A peer has sent a SHUTDOWN.

C: struct sctp_shutdown_event

sctp_snd_info()

(not exported) (since OTP 22.0)

-type sctp_snd_info() ::
          #{sid := uint16(),
            flags := uint16(),
            ppid := uint16(),
            context := uint32(),
            assic_id := sctp_assoc_id()}.

C: struct sctp_sndinfo

sctp_snd_rcv_info()

(since OTP 22.0)

-type sctp_snd_rcv_info() ::
          #{stream := uint16(),
            ssn => uint16(),
            flags => sctp_snd_rcv_info_flags(),
            ppid => uint32(),
            context => uint32(),
            time_to_live => uint32(),
            tsn => uint32(),
            cum_tsn => uint32(),
            assoc_id := sctp_assoc_id()}.

SCTP options for sendmsg() and SCTP header information about a received message through recvmsg().

When sending, only the stream and assoc_id fields needs to be assigned. When receiving all values will be assigned.

C: struct sctp_sndrcvinfo

sctp_snd_rcv_info_flags()

(not exported) (since OTP 22.0)

-type sctp_snd_rcv_info_flags() :: [unordered | addr_over | abort | eof].

sctp_status()

(since OTP 22.0)

-type sctp_status() ::
          #{assoc_id := sctp_assoc_id(),
            state := sctp_peer_address_state(),
            rwnd := uint32(),
            unacked_data := uint16(),
            pending_data := uint16(),
            in_streams := uint16(),
            out_streams := uint16(),
            fragmentation_point := uint32(),
            primary := sctp_peer_address_info()}.

C: struct sctp_status.

sctp_stream_change_event()

(not exported) (since OTP 22.0)

-type sctp_stream_change_event() ::
          #{type := stream_change,
            flags := [denied | failed],
            assoc_id := sctp_assoc_id(),
            inbound_streams := uint16(),
            outbound_streams := uint16()}.

C: struct sctp_stream_change_event

sctp_stream_reset_event()

(not exported) (since OTP 22.0)

-type sctp_stream_reset_event() ::
          #{type := stream_reset,
            flags := [incoming_ssn | outgoing_ssn | denied | failed],
            assoc_id := sctp_assoc_id(),
            stream_list := [uint16()]}.

C: struct sctp_stream_reset_event

select_handle()

(since OTP 22.0)

-type select_handle() :: reference().

Select operation handle.

A reference/0 that uniquely identifies the (select) operation, contained in the returned select_info/0.

select_info()

(since OTP 22.0)

-type select_info() :: {select_info, SelectTag :: select_tag(), SelectHandle :: select_handle()}.

Select operation info.

Returned by an operation that requires the caller to wait for a select message containing the SelectHandle.

On select systems, if the option {otp, select_read} is set, {select_read, {select_info(), _}} is returned instead of {ok, _} to indicate that a new asynchronous receive operation has been initiated and the caller should wait for a select message containing the SelectHandle.

select_tag()

(since OTP 22.0)

-type select_tag() ::
          accept | connect |
          recv | recvfrom | recvmsg | recvmmsg | send | sendv | sendto | sendmsg | sendmmsg | sendfile |
          {recv | recvfrom | recvmsg | recvmmsg | send | sendv | sendto | sendmsg | sendmmsg | sendfile,
           ContData :: term()}.

Select operation tag.

A tag that describes the (select) operation (= function name), contained in the returned select_info/0.

sockaddr()

(since OTP 22.0)

-type sockaddr() ::
          sockaddr_in() |
          sockaddr_in6() |
          sockaddr_un() |
          sockaddr_ll() |
          sockaddr_dl() |
          sockaddr_unspec() |
          sockaddr_native().

sockaddr_dl()

(since OTP 22.0)

-type sockaddr_dl() ::
          #{family := link,
            index := non_neg_integer(),
            type := interface_type(),
            nlen := non_neg_integer(),
            alen := non_neg_integer(),
            slen := non_neg_integer(),
            data := binary()}.

C: struct sockaddr_dl

Link level address (PF_LINK) on BSD:s.

sockaddr_in6()

(since OTP 22.0)

-type sockaddr_in6() ::
          #{family := inet6,
            port := port_number(),
            addr := any | loopback | in6_addr(),
            flowinfo := in6_flow_info(),
            scope_id := in6_scope_id()}.

C: struct sockaddr_in6

Domain inet6 (IPv6) address.

sockaddr_in()

(since OTP 22.0)

-type sockaddr_in() ::
          #{family := inet, port := port_number(), addr := any | broadcast | loopback | in_addr()}.

C: struct sockaddr_in

Domain inet (IPv4) address.

sockaddr_ll()

(since OTP 22.0)

-type sockaddr_ll() ::
          #{family := packet,
            protocol := non_neg_integer(),
            ifindex := integer(),
            pkttype := packet_type(),
            hatype := hatype(),
            addr := binary()}.

C: struct sockaddr_ll

Domain packet, type raw (link level) address.

sockaddr_native()

(since OTP 22.0)

-type sockaddr_native() :: #{family := integer(), addr := binary()}.

C: struct sockaddr

In C, a struct sockaddr with the integer value of sa_family in the map/0 key family, and the content of sa_data in the map/0 key addr.

sockaddr_recv()

(since OTP 22.0)

-type sockaddr_recv() :: sockaddr() | binary().

sockaddr_un()

(since OTP 22.0)

-type sockaddr_un() :: #{family := local, path := binary() | string()}.

C: struct sockaddr_un.

A Unix Domain socket address, a.k.a local address (AF_LOCAL).

The path element will always be a binary when returned from this module. When supplied to an API function in this module it may be a string/0, which will be encoded into a binary according to the native file name encoding on the platform.

A terminating zero character will be appended before the address path is given to the OS, and the terminating zero will be stripped before giving the address path to the caller.

Linux's non-portable abstract socket address extension is handled by not doing any terminating zero processing in either direction, if the first byte of the address is zero.

sockaddr_unspec()

(since OTP 22.0)

-type sockaddr_unspec() :: #{family := unspec, addr := binary()}.

C: struct sockaddr of AF_UNSPEC

In C, a struct sockaddr with sa_family = AF_UNSPEC and the content of sa_data in the map/0 key addr.

socket()

(since OTP 22.0)

-type socket() :: {'$socket', socket_handle()}.

A socket, according to this module.

Created and returned by open/1,2,3,4 and accept/1,2.

socket_counters()

(since OTP 22.0)

-type socket_counters() ::
          #{read_byte := non_neg_integer(),
            read_fails := non_neg_integer(),
            read_pkg := non_neg_integer(),
            read_pkg_max := non_neg_integer(),
            read_tries := non_neg_integer(),
            read_waits := non_neg_integer(),
            write_byte := non_neg_integer(),
            write_fails := non_neg_integer(),
            write_pkg := non_neg_integer(),
            write_pkg_max := non_neg_integer(),
            write_tries := non_neg_integer(),
            write_waits := non_neg_integer(),
            sendfile => non_neg_integer(),
            sendfile_byte => non_neg_integer(),
            sendfile_fails => non_neg_integer(),
            sendfile_max => non_neg_integer(),
            sendfile_pkg => non_neg_integer(),
            sendfile_pkg_max => non_neg_integer(),
            sendfile_tries => non_neg_integer(),
            sendfile_waits => non_neg_integer(),
            acc_success := non_neg_integer(),
            acc_fails := non_neg_integer(),
            acc_tries := non_neg_integer(),
            acc_waits := non_neg_integer()}.

A map/0 of Name := Counter associations.

socket_handle()

(since OTP 22.0)

-opaque socket_handle()

Opaque socket handle unique for the socket.

socket_info()

(since OTP 22.0)

-type socket_info() ::
          #{domain := domain() | integer(),
            type := type() | integer(),
            protocol := protocol() | integer(),
            owner := pid(),
            ctype := normal | fromfd | {fromfd, integer()},
            counters := socket_counters(),
            num_readers := non_neg_integer(),
            num_writers := non_neg_integer(),
            num_acceptors := non_neg_integer(),
            writable := boolean(),
            readable := boolean(),
            rstates := [atom()],
            wstates := [atom()]}.

socket_option()

(since OTP 22.0)

-type socket_option() ::
          {Level :: socket,
           Opt ::
               acceptconn | acceptfilter | bindtodevice | broadcast | bsp_state | busy_poll | debug |
               domain | dontroute | error | exclusiveaddruse | keepalive | linger | mark | maxdg |
               max_msg_size | oobinline | passcred | peek_off | peercred | priority | protocol |
               rcvbuf | rcvbufforce | rcvlowat | rcvtimeo | reuseaddr | reuseport | rxq_ovfl | setfib |
               sndbuf | sndbufforce | sndlowat | sndtimeo | timestamp | timestampns | type} |
          {Level :: ip,
           Opt ::
               add_membership | add_source_membership | block_source | dontfrag | drop_membership |
               drop_source_membership | freebind | hdrincl | minttl | msfilter | mtu | mtu_discover |
               multicast_all | multicast_if | multicast_loop | multicast_ttl | nodefrag | options |
               pktinfo | recvdstaddr | recverr | recvif | recvopts | recvorigdstaddr | recvtos |
               recvttl | retopts | router_alert | sndsrcaddr | tos | transparent | ttl | unblock_source} |
          {Level :: ipv6,
           Opt ::
               addrform | add_membership | authhdr | auth_level | checksum | drop_membership | dstopts |
               esp_trans_level | esp_network_level | faith | flowinfo | hopopts | ipcomp_level |
               join_group | leave_group | mtu | mtu_discover | multicast_hops | multicast_if |
               multicast_loop | portrange | pktoptions | recverr | recvhoplimit | hoplimit |
               recvpktinfo | pktinfo | recvtclass | router_alert | rthdr | tclass | unicast_hops |
               use_min_mtu | v6only} |
          {Level :: tcp,
           Opt ::
               congestion | cork | info | keepcnt | keepidle | keepintvl | maxseg | md5sig | nodelay |
               noopt | nopush | syncnt | user_timeout} |
          {Level :: udp, Opt :: cork} |
          {Level :: sctp,
           Opt ::
               adaption_layer | associnfo | auth_active_key | auth_asconf | auth_chunk | auth_key |
               auth_delete_key | autoclose | context | default_send_param | delayed_ack_time |
               disable_fragments | hmac_ident | events | explicit_eor | fragment_interleave |
               get_peer_addr_info | initmsg | i_want_mapped_v4_addr | local_auth_chunks | maxseg |
               maxburst | nodelay | partial_delivery_point | peer_addr_params | peer_auth_chunks |
               primary_addr | reset_streams | rtoinfo | set_peer_primary_addr | status |
               use_ext_recvinfo}.

Socket option.

Socket options of the form {Level, Opt} where the OS protocol Level = level/0 and Opt is a socket option on that protocol level.

The OS name for an options is, except where otherwise noted, the Opt atom, in capitals, with prefix according to level/0.

Note

The IPv6 option pktoptions is a special (barf) case. It is intended for backward compatibility usage only.

Do not use this option.

Note

See the OS documentation for every socket option.

An option below that has the value type boolean/0 will translate the value false to a C int with value 0, and the value true to !!0 (not (not false)).

An option with value type integer/0 will be translated to a C int that may have a restricted range, for example byte: 0..255. See the OS documentation.

The calls supports(options), supports(options, Level) and is_supported(options, {Level, Opt}) can be used to find out which socket options that are supported by the platform.

Options for protocol level socket:

{socket, acceptconn} - Value = boolean()

{socket, bindtodevice} - Value = string()

{socket, broadcast} - Value = boolean()

{socket, debug} - Value = integer()

{socket, domain} - Value = domain/0

Only valid to get.

The socket's protocol domain. Does not work on for instance FreeBSD.

{socket, dontroute} - Value = boolean()

{socket, keepalive} - Value = boolean()

{socket, linger} - Value = abort | linger/0

The value abort is shorthand for #{onoff => true, linger => 0}, and only valid to set.

{socket, oobinline} - Value = boolean()

{socket, passcred} - Value = boolean()

{socket, peek_off} - Value = integer()

Currently disabled due to a possible infinite loop when calling recv/1-4 with peek in Flags.

{socket, priority} - Value = integer()

{socket, protocol} - Value = protocol/0

Only valid to get.

The socket's protocol. Does not work on for instance Darwin.

{socket, rcvbuf} - Value = integer()

{socket, rcvlowat} - Value = integer()

{socket, rcvtimeo} - Value = timeval/0

This option is unsupported per default; OTP has to be explicitly built with the --enable-esock-rcvsndtimeo configure option for this to be available.

Since our implementation uses non-blocking sockets, it is unknown if and how this option works, or even if it may cause malfunction. Therefore, we do not recommend setting this option.

Instead, use the Timeout argument to, for instance, the recv/3 function.

{socket, reuseaddr} - Value = boolean()

{socket, reuseport} - Value = boolean()

{socket, sndbuf} - Value = integer()

{socket, sndlowat} - Value = integer()

{socket, sndtimeo} - Value = timeval/0

This option is unsupported per default; OTP has to be explicitly built with the --enable-esock-rcvsndtimeo configure option for this to be available.

Since our implementation uses non-blocking sockets, it is unknown if and how this option works, or even if it may cause malfunction. Therefore, we do not recommend setting this option.

Instead, use the Timeout argument to, for instance, the send/3 function.

{socket, timestamp} - Value = boolean()

Enable or disable the SO_TIMESTAMP socket option. When enabled, the socket will receive timestamps in control messages for received packets.

{socket, timestampns} - Value = boolean()

Enable or disable the SO_TIMESTAMPNS socket option. When enabled, the socket will receive nanosecond-precision timestamps in control messages for received packets.

{socket, type} - Value = type/0

Only valid to get.

The socket's type.

Options for protocol level ip:

{ip, add_membership} - Value = ip_mreq/0

Only valid to set.

{ip, add_source_membership} - Value = ip_mreq_source/0

Only valid to set.

{ip, block_source} - Value = ip_mreq_source/0

Only valid to set.

{ip, drop_membership} - Value = ip_mreq/0

Only valid to set.

{ip, drop_source_membership} - Value = ip_mreq_source/0

Only valid to set.

{ip, freebind} - Value = boolean()

{ip, hdrincl} - Value = boolean()

{ip, minttl} - Value = integer()

{ip, msfilter} - Value = null | ip_msfilter/0

Only valid to set.

The value null passes a NULL pointer and size 0 to the C library call.

{ip, mtu} - Value = integer()

Only valid to get.

{ip, mtu_discover} - Value = ip_pmtudisc() | integer()

An integer/0 value according to the platform's header files.

{ip, multicast_all} - Value = boolean()

{ip, multicast_if} - Value = any | in_addr/0

{ip, multicast_loop} - Value = boolean()

{ip, multicast_ttl} - Value = integer()

{ip, nodefrag} - Value = boolean()

{ip, pktinfo} - Value = boolean()

{ip, recvdstaddr} - Value = boolean()

{ip, recverr} - Value = boolean()

Enable extended reliable error message passing.

Warning! When this option is enabled, error messages may arrive on the socket's error queue, which should be read using the message flag errqueue, and using recvmsg/1,2,3,4,5 to get all error information in the message's ctrl field as a control message #{level := ip, type := recverr}.

A working strategy should be to first poll the error queue using recvmsg/2,3,4 with Timeout =:= 0 and Flags containing errqueue (ignore the return value {error, timeout}) before reading the actual data to ensure that the error queue gets cleared. And read the data using one of the nowait | select_handle() recv functions: recv/3,4, recvfrom/3,4 or recvmsg/3,4,5. Otherwise you might accidentally cause a busy loop in and out of 'select' for the socket.

{ip, recvif} - Value = boolean()

{ip, recvopts} - Value = boolean()

{ip, recvorigdstaddr} - Value = boolean()

{ip, recvtos} - Value = boolean()

{ip, recvttl} - Value = boolean()

{ip, retopts} - Value = boolean()

{ip, router_alert} - Value = integer()

{ip, sendsrcaddr} - Value = boolean()

{ip, tos} - Value = ip_tos() | integer()

An integer/0 value is according to the platform's header files.

{ip, transparent} - Value = boolean()

{ip, ttl} - Value = integer()

{ip, unblock_source} - Value = ip_mreq_source/0

Only valid to set.

Options for protocol level ipv6:

{ipv6, addrform} - Value = domain/0

As far as we know the only valid value is inet and it is only allowed for an IPv6 socket that is connected and bound to an IPv4-mapped IPv6 address.

{ipv6, add_membership} - Value = ipv6_mreq/0

Only valid to set.

{ipv6, authhdr} - Value = boolean()

{ipv6, drop_membership} - Value = ipv6_mreq/0

Only valid to set.

{ipv6, dstopts} - Value = boolean()

{ipv6, flowinfo} - Value = boolean()

{ipv6, hoplimit} - Value = boolean()

{ipv6, hopopts} - Value = boolean()

{ipv6, mtu} - Value = integer()

{ipv6, mtu_discover} - Value = ipv6_pmtudisc() | integer()

An integer/0 value is according to the platform's header files.

{ipv6, multicast_hops} - Value = ipv6_hops/0

{ipv6, multicast_if} - Value = integer()

{ipv6, multicast_loop} - Value = boolean()

{ipv6, recverr} - Value = boolean()

Warning! See the socket option {ip, recverr} regarding the socket's error queue. The same warning applies for this option.

{ipv6, recvhoplimit} - Value = boolean()

{ipv6, recvpktinfo} - Value = boolean()

{ipv6, recvtclass} - Value = boolean()

{ipv6, router_alert} - Value = integer()

{ipv6, rthdr} - Value = boolean()

{ipv6, tclass} - Value = boolean()

{ipv6, unicast_hops} - Value = ipv6_hops/0

{ipv6, v6only} - Value = boolean()

Options for protocol level sctp. See also RFC 6458.

{sctp, associnfo} - Value = sctp_assocparams/0

{sctp, autoclose} - Value = integer()

{sctp, disable_fragments} - Value = boolean()

{sctp, events} - Value = sctp_event_subscribe/0

Only valid to set.

{sctp, initmsg} - Value = sctp_initmsg/0

{sctp, maxseg} - Value = integer()

{sctp, nodelay} - Value = boolean()

{sctp, rtoinfo} - Value = sctp_rtoinfo/0

{sctp, get_peer_addr_info} - Value = sctp_peer_address_info/0

Only valid for get. Also, requires an OptValue (containing sctp_assoc_id/0 and sockaddr/0) specifying the peer. See getopt/3 for more info.

{sctp, status} - Value = sctp_status/0

Only valid for get. Also, requires an OptValue (containing sctp_assoc_id/0) specifying the association. See getopt/3 for more info.

Options for protocol level tcp:

{tcp, congestion} - Value = string()

{tcp, cork} - Value = boolean()

{tcp, keepcnt} - Value = integer()

{tcp, keepidle} - Value = integer()

{tcp, keepintvl} - Value = integer()

{tcp, maxseg} - Value = integer()

{tcp, nodelay} - Value = boolean()

{tcp, nopush} - Value = boolean()

{tcp, user_timeout} - Value = non_neg_integer()

Options for protocol level udp:

{udp, cork} - Value = boolean()

timespec()

(since OTP 22.0)

-type timespec() :: #{sec := integer(), nsec := integer()}.

C: struct timespec

Corresponds to the C struct timespec. The field sec holds seconds, and nsec nanoseconds.

timeval()

(since OTP 22.0)

-type timeval() :: #{sec := integer(), usec := integer()}.

C: struct timeval

Corresponds to the C struct timeval. The field sec holds seconds, and usec microseconds.

type()

(since OTP 22.0)

-type type() :: stream | dgram | raw | rdm | seqpacket.

Protocol type.

A lowercase atom/0 representing a protocol type on the platform named SOCK_*. For example stream corresponds to SOCK_STREAM.

uint8()

(not exported) (since OTP 22.0)

-type uint8() :: 0..255.

uint16()

(not exported) (since OTP 22.0)

-type uint16() :: 0..65535.

uint32()

(not exported) (since OTP 22.0)

-type uint32() :: 0..4294967295.

uint64()

(not exported) (since OTP 22.0)

-type uint64() :: 0..18446744073709551615.

Functions

accept(ListenSocket)

(since OTP 22.0)

-spec accept(ListenSocket) -> Result
                when
                    Result :: {ok, Socket} | {error, Reason},
                    ListenSocket :: socket(),
                    Socket :: socket(),
                    Reason :: dynamic().

Equivalent to accept(ListenSocket, infinity).

accept/2

(since OTP 22.0)

-spec accept(ListenSocket, Timeout :: infinity) -> {ok, Socket} | {error, Reason}
                when
                    ListenSocket :: socket(),
                    Socket :: socket(),
                    Reason ::
                        posix() |
                        closed |
                        invalid() |
                        {create_accept_socket, posix()} |
                        {add_socket, posix()} |
                        {update_accept_context, posix()};
            (ListenSocket, Timeout :: non_neg_integer()) -> {ok, Socket} | {error, Reason}
                when
                    ListenSocket :: socket(),
                    Socket :: socket(),
                    Reason ::
                        posix() |
                        closed |
                        invalid() |
                        timeout |
                        {create_accept_socket, posix()} |
                        {add_socket, posix()} |
                        {update_accept_context, posix()};
            (ListenSocket, nowait | (Handle :: select_handle() | completion_handle())) ->
                {ok, Socket} | {select, SelectInfo} | {completion, CompletionInfo} | {error, Reason}
                when
                    ListenSocket :: socket(),
                    Socket :: socket(),
                    SelectInfo :: select_info(),
                    CompletionInfo :: completion_info(),
                    Reason ::
                        posix() |
                        closed |
                        invalid() |
                        {create_accept_socket, posix()} |
                        {add_accept_socket, posix()} |
                        {update_accept_context, posix()}.

Accept a connection on a listening socket.

ListenSocket has to be of a connection oriented type (types stream or seqpacket, see open/1), and set to listen (see listen/1).

If the Timeout argument is infinity; accepts the first pending incoming connection for the listen socket or wait for one to arrive, and return the new connection socket.

If the Timeout argument is a time-out value (non_neg_integer/0); returns {error, timeout} if no connection has arrived after Timeout milliseconds.

If the Handle argument nowait (since OTP 22.1), starts an asynchronous call if the operation couldn't be completed immediately.

If the Handle argument is a select_handle/0, (since OTP 24.0), or on Windows, the equivalent completion_handle/0 (since OTP 26.0), starts an asynchronous call like for nowait.

The possible values for CompletionStatus in the completion message are:

{ok, NewSocket} - Success; A connection has been accepted.

{error, Reason} - An error occured and no connection was established.

See the note Asynchronous Calls at the start of this module reference manual page.

bind(Socket, Addr)

(since OTP 22.0)

-spec bind(Socket, Addr) -> ok | {error, Reason}
              when
                  Socket :: socket(),
                  Addr :: sockaddr() | any | broadcast | loopback,
                  Reason :: posix() | closed | invalid().

Bind a name to a socket.

When a socket is created (with open), it has no address assigned to it. bind assigns the address specified by the Addr argument.

The rules used for name binding vary between domains.

If you bind a socket to an address in for example the inet or inet6 address families, with an ephemeral port number (0), and want to know which port that was chosen, you can find out using something like: {ok, #{port := Port}} =socket:sockname(Socket)

bind(Socket, Addrs, Action)

(since OTP @OTP-19834@)

-spec bind(Socket, Addrs, Action) -> ok | {error, Reason}
              when
                  Socket :: socket(),
                  Addrs :: [sockaddr_in()] | [sockaddr_in() | sockaddr_in6()],
                  Action :: add | remove,
                  Reason :: posix() | closed.

Bind a list of socket addreses to a socket.

When a socket is created (with open), it has no address assigned to it. This bind assigns the address specified by the Addr argument.

Calling this function is only valid if the socket is type = seqpacket and protocol = sctp.

If the domain is inet, then all addresses must be IPv4. If the domain is inet6, the addresses can be either IPv4 or IPv6.

cancel/2

(since OTP 22.1)

-spec cancel(Socket, SelectInfo | CompletionInfo) -> ok | {error, Reason}
                when
                    Socket :: socket(),
                    SelectInfo :: select_info(),
                    CompletionInfo :: completion_info(),
                    Reason :: closed | invalid().

Cancel an asynchronous call in progress.

Call this function to cancel an asynchronous call in progress, that is; it returned a value containing a completion_info/0 or select_info/0.

See the note Asynchronous Calls at the start of this module reference manual page.

If another process tries an operation of the same basic type (accept/1 | send/2 | recv/2) it will be enqueued and notified through a select or completion message when the current operation and all enqueued before it has been completed. If the current operation is canceled by this function it is treated as a completed operation; the process first in queue is notified.

If SelectInfo | CompletionInfo does not match an operation in progress for the calling process, this function returns {error, {invalid, SelectInfo | CompletionInfo}}.

cancel_monitor(MRef)

(since OTP 24.0)

-spec cancel_monitor(MRef :: reference()) -> boolean().

Cancel a socket monitor.

If MRef is a reference that the calling process obtained by calling monitor/1, this monitor is removed. If there is no such monitor for the calling process (or MRef doesn't correspond to a monitor), nothing happens.

The returned value is one of the following:

true - The monitor was found and removed. In this case, no 'DOWN' message corresponding to this monitor has been delivered and will not be delivered.

false - The monitor was not found so it couldn't be removed. This might be because the monitor has already triggered and there is a 'DOWN' message from this monitor in the caller message queue.

close(Socket)

(since OTP 22.0)

-spec close(Socket) -> ok | {error, Reason}
               when Socket :: socket(), Reason :: posix() | closed | timeout.

Close a socket.

Note

Note that for Protocol = tcp (see open/3), although TCP guarantees that when the other side sees the stream close all data that we sent before closing has been delivered, there is no way for us to know that the other side got all data and the stream close. All kinds of network and OS issues may obliterate that.

To get such a guarantee we need to implement an in-band acknowledge protocol on the connection, or we can use the shutdown function to signal that no more data will be sent and then wait for the other end to close the socket. Then we will see our read side getting a socket close. In this way we implement a small acknowledge protocol using shutdown/2. The other side cannot know that we ever saw the socket close, but in a client/server scenario that is often not relevant.

connect(Socket)

(since OTP 24.0)

-spec connect(Socket :: socket()) -> ok | {error, Reason} when Reason :: posix() | closed | invalid().

Finalize a connect/3 operation.

See the note Asynchronous Calls at the start of this module reference manual page.

On select systems this function finalizes a connection setup on a socket, after receiving a select message {'$socket', Socket, select,SelectHandle}, and returns whether the connection setup was successful or not.

Instead of calling this function, for backwards compatibility, it is allowed to call connect/2,3 again, but that incurs more overhead since the connect address and time-out argument are processed in vain.

The call that completes the connect operation, the second call, cannot return a select return value.

connect(Socket, SockAddr)

(since OTP 22.0)

-spec connect(Socket :: socket(), SockAddr :: sockaddr() | [SockAddr :: term()]) ->
                 ok | {error, Reason :: dynamic()}.

Equivalent to connect(Socket, SockAddr, infinity) or connect(Socket, SockAddrs, undefined, infinity).

connect/3

(since OTP 22.0)

-spec connect(Socket, SockAddrs, TimeoutOrHandle) -> {ok, AssocId} | {error, Reason}
                 when
                     Socket :: socket(),
                     SockAddrs :: [sockaddr_in()] | [sockaddr_in6()],
                     TimeoutOrHandle :: infinity | Timeout | nowait | Handle,
                     Timeout :: non_neg_integer(),
                     Handle :: select_handle(),
                     AssocId :: sctp_assoc_id(),
                     Reason :: posix() | closed | invalid() | already;
             (Socket, SockAddr, Timeout :: infinity) -> ok | {error, Reason}
                 when
                     Socket :: socket(),
                     SockAddr :: sockaddr(),
                     Reason ::
                         posix() |
                         closed |
                         invalid() |
                         already | not_bound |
                         {add_socket, posix()} |
                         {update_connect_context, posix()};
             (Socket, SockAddr, Timeout :: non_neg_integer()) -> ok | {error, Reason}
                 when
                     Socket :: socket(),
                     SockAddr :: sockaddr(),
                     Reason ::
                         posix() |
                         closed |
                         invalid() |
                         already | not_bound | timeout |
                         {add_socket, posix()} |
                         {update_connect_context, posix()};
             (Socket, SockAddr, nowait | Handle) ->
                 ok | {select, SelectInfo} | {completion, CompletionInfo} | {error, Reason}
                 when
                     Socket :: socket(),
                     SockAddr :: sockaddr(),
                     Handle :: select_handle() | completion_handle(),
                     SelectInfo :: select_info(),
                     CompletionInfo :: completion_info(),
                     Reason ::
                         posix() |
                         closed |
                         invalid() |
                         already | not_bound |
                         {add_socket, posix()} |
                         {update_connect_context, posix()}.

Connect the socket to the given address(s).

This function connects the socket to the address(s) specified by the SockAddr|SockAddrs argument.

If a connection attempt is already in progress (by another process), {error, already} is returned.

Note

On Windows the socket has to be bound.

If the time-out argument (argument 3) is infinity it is up to the OS implementation to decide when the connection attempt failed and then what to return; probably {error, etimedout}. The OS time-out may be very long.

If the time-out argument (argument 3) is a time-out value (non_neg_integer/0); return {error, timeout} if the connection hasn't been established within Timeout milliseconds.

Note

Note that when this call has returned {error, timeout} the connection state of the socket is uncertain since the platform's network stack may complete the connection at any time, up to some platform specific time-out.

Repeating a connection attempt towards the same address would be ok, but towards a different address could end up with a connection to either address.

The safe play is to close the socket and start over.

Also note that this applies to cancelling a nowait connect call described below.

If the time-out argument (argument 2) is nowait (since OTP 22.1), start an asynchronous call if the operation couldn't be completed immediately.

If the time-out argument (argument 2) is a Handle :: select_handle/0, (since OTP 24.0), or on Windows, the equivalent Handle :: completion_handle/0 (since OTP 26.0), start an asynchronous call like for nowait.

See the note Asynchronous Calls at the start of this module reference manual page.

After receiving a select message; call connect/1 to complete the operation.

If cancelling the operation with cancel/2 see the note above about connection time-out.

The possible values for CompletionStatus in the completion message are:

ok - Complete success; A connection has been established.

{error, Reason} - An error occured and no connection was established.

Note

Note that calling with a list of socket addresses only works for SCTP sockets (type = seqpacket). And that the family of all addresses in the list is either IPv4 (inet) or IPv6 (inet6).

getopt/2

(since OTP 24.0)

-spec getopt(socket(), SocketOption :: {Level :: otp, Opt :: otp_socket_option()}) ->
                {ok, Value :: term()} | {error, invalid() | closed};
            (socket(), SocketOption :: socket_option()) ->
                {ok, Value :: term()} | {error, posix() | invalid() | closed}.

Get the value of a socket option.

Gets the value of an OS protocol level socket option, or from the otp pseudo protocol level, which is this module's implementation level above the OS protocol levels.

See the type otp_socket_option() for a description of the otp protocol level.

See the type socket_option/0 for which OS protocol level options that this implementation knows about, how they are related to OS option names, and if there are known peculiarities with any of them.

What options that are valid depends on the OS, and on the kind of socket (domain/0,type/0 and protocol/0). See the type t:socket_option() and the socket options chapter in the User's Guide for more info.

Note

Not all options are valid, nor possible to get, on all platforms. That is, even if this socket implementation support an option; it doesn't mean that the underlying OS does.

getopt/3

(since OTP 22.0)

-spec getopt(Socket :: socket(),
             SocketOption :: {sctp, get_peer_addr_info},
             OptValue :: #{assoc_id := sctp_assoc_id(), addr := sockaddr()}) ->
                {ok, Value :: sctp_peer_address_info()} | {error, posix() | invalid() | closed};
            (Socket :: socket(),
             SocketOption :: {sctp, status},
             OptValue :: #{assoc_id := sctp_assoc_id()}) ->
                {ok, Value :: sctp_status()} | {error, posix() | invalid() | closed};
            (Socket :: socket(), Level :: level(), Opt :: term()) ->
                {ok, Value :: term()} | {error, posix() | invalid() | closed}.

Get a socket option, with a specifier (extra input) OptValue.

This function is used when the option takes an input 'value' argument. We only support this for a limited set of options: {sctp, get_peer_addr_info} and {sctp, status}.

Some uses of this function is for backwards compatibility reasons.

For instance, getopt(Socket, Level, Opt) is equivalent to getopt(Socket, {Level, Opt}), or as a special case if Opt = {NativeOpt ::integer/0, ValueSpec} equivalent to getopt_native(Socket, {Level, NativeOpt}, ValueSpec).

Use getopt/2 or getopt_native/3 instead to handle the option level and name as a single term, and to make the difference between known options and native options clear.

getopt_native/3

(since OTP 24.0)

-spec getopt_native(socket(),
                    SocketOption ::
                        socket_option() |
                        {Level :: level() | (NativeLevel :: integer()), NativeOpt :: integer()},
                    ValueType :: integer) ->
                       {ok, Value :: integer()} | {error, posix() | invalid() | closed};
                   (socket(),
                    SocketOption ::
                        socket_option() |
                        {Level :: level() | (NativeLevel :: integer()), NativeOpt :: integer()},
                    ValueType :: boolean) ->
                       {ok, Value :: boolean()} | {error, posix() | invalid() | closed};
                   (socket(),
                    SocketOption ::
                        socket_option() |
                        {Level :: level() | (NativeLevel :: integer()), NativeOpt :: integer()},
                    ValueSize :: non_neg_integer()) ->
                       {ok, Value :: binary()} | {error, posix() | invalid() | closed};
                   (socket(),
                    SocketOption ::
                        socket_option() |
                        {Level :: level() | (NativeLevel :: integer()), NativeOpt :: integer()},
                    ValueSpec :: binary()) ->
                       {ok, Value :: binary()} | {error, posix() | invalid() | closed}.

Get a "native" socket option.

Gets a socket option that may be unknown to our implementation, or that has a type not compatible with our implementation, that is; in "native mode".

The socket option may be specified with an ordinary socket_option() tuple, with a known Level = level() and an integer NativeOpt, or with both an integer NativeLevel and NativeOpt.

How to decode the option value has to be specified either with ValueType, by specifying the ValueSize for a binary/0 that will contain the fetched option value, or by specifying a binary/0 ValueSpec that will be copied to a buffer for the getsockopt() call to write the value in which will be returned as a new binary/0.

If ValueType is integer a C type (int) will be fetched, if it is boolean a C type (int) will be fetched and converted into a boolean/0 according to the C implementation's notion about true and false.

If an option is valid depends both on the platform and on what kind of socket it is (domain/0, type/0 and protocol/0).

The integer values for NativeLevel and NativeOpt as well as the Value encoding has to be deduced from the header files for the running system.

i()

(since OTP 24.1)

-spec i() -> ok.

Print information to the erlang shell in table format for all sockets.

The information printed for each socket is specified by the default set of info_keys/0 (all keys).

The sockets that are printed are all sockets created by this socket module's implementation.

i/1

(since OTP 24.1)

-spec i(InfoKeys :: info_keys()) -> ok;
       (Domain :: inet | inet6 | local) -> ok;
       (Proto :: sctp | tcp | udp) -> ok;
       (Type :: dgram | seqpacket | stream) -> ok.

Print information to the erlang shell in table format for all sockets.

If the argument is a list of info_keys/0, print the specified information for all sockets. See i/0.

Otherwise the same as i/2 with the same first argument and the default information (see i/0).

i/2

(since OTP 24.1)

-spec i(Domain :: inet | inet6 | local, InfoKeys) -> ok when InfoKeys :: info_keys();
       (Proto :: sctp | tcp | udp, InfoKeys) -> ok when InfoKeys :: info_keys();
       (Type :: dgram | seqpacket | stream, InfoKeys) -> ok when InfoKeys :: info_keys().

Print information to the erlang shell in table format for a selection of sockets.

The argument InfoKeys specifies which information is printed for each socket.

If the first argument is Domain print information for all sockets of that specific domain/0.

If the first argument is Proto print information for all sockets of that specific protocol/0.

If the first argument is Type print information for all sockets of that specific type/0.

info()

(since OTP 24.0)

-spec info() -> info().

Get miscellaneous information about this socket library.

The function returns a map with each information item as a key-value pair.

Note

In order to ensure data integrity, mutexes are taken when needed. So, don't call this function often.

info(Socket)

(since OTP 22.1)

-spec info(Socket) -> socket_info() when Socket :: socket().

Get miscellaneous info about a socket.

The function returns a map with each information item as a key-value pair reflecting the "current" state of the socket (such as counter values).

Note

In order to ensure data integrity, mutexes are taken when needed. So, don't call this function often.

ioctl/2

(since OTP 24.2)

-spec ioctl(Socket, GetRequest :: gifconf) ->
               {ok, IFConf :: [#{name := string, addr := sockaddr()}]} | {error, Reason}
               when Socket :: socket(), Reason :: posix() | closed;
           (Socket, GetRequest :: nread | nwrite | nspace) ->
               {ok, NumBytes :: non_neg_integer()} | {error, Reason}
               when Socket :: socket(), Reason :: posix() | closed;
           (Socket, GetRequest :: atmark) -> {ok, Available :: boolean()} | {error, Reason}
               when Socket :: socket(), Reason :: posix() | closed;
           (Socket, GetRequest :: tcp_info) -> {ok, Info :: map()} | {error, Reason}
               when Socket :: socket(), Reason :: posix() | closed.

Set socket (device) parameters.

This function retrieves a specific parameter, according to the GetRequest argument.

gifconf - Get a list of interface (transport layer) addresses.

Result; a list of map/0s, one for each interface, with its name and address.

nread - Get the number of bytes immediately available for reading (since OTP 26.1).

Result; the number of bytes, integer/0.

nwrite - Get the number of bytes in the send queue (since OTP 26.1).

Result; the number of bytes, integer/0.

nspace - Get the free space in the send queue (since OTP 26.1).

Result; the number of bytes, integer/0.

atmark - Test if there is OOB (out-of-bound) data waiting to be read (since OTP 26.1).

Result; a boolean/0.

tcp_info - Get miscellaneous TCP related information for a connected socket (since OTP 26.1).

Result; a map/0 with information items as key-value pairs.

Note

Not all requests are supported by all platforms. To see if a ioctl request is supported on the current platform:

      Request = nread,
      true = socket:is_supported(ioctl_requests, Request),
      :

ioctl/3

(since OTP 24.2)

-spec ioctl(Socket, GetRequest, NameOrIndex) -> {ok, Result} | {error, Reason}
               when
                   Socket :: socket(),
                   GetRequest ::
                       gifname | gifindex | gifaddr | gifdstaddr | gifbrdaddr | gifnetmask | gifhwaddr |
                       genaddr | gifmtu | giftxqlen | gifflags | tcp_info,
                   NameOrIndex :: string() | integer(),
                   Result :: dynamic(),
                   Reason :: posix() | closed;
           (Socket, SetRequest, Value) -> ok | {error, Reason}
               when
                   Socket :: socket(),
                   SetRequest :: rcvall,
                   Value :: off | on | iplevel,
                   Reason :: posix() | closed;
           (Socket, SetRequest, Value) -> ok | {error, Reason}
               when
                   Socket :: socket(),
                   SetRequest :: rcvall_igmpmcast | rcvall_mcast,
                   Value :: off | on,
                   Reason :: posix() | closed.

Get or set socket (device) parameters.

This function retrieves a specific parameter, according to one of the following GetRequest arguments. The third argument is the (lookup) "key", identifying the interface, for most requests the name of the interface as a string/0. Also, see the note above.

gifname - Get the name of the interface with the specified index (integer/0).

Result; the name of the interface, string/0.

gifindex - Get the index of the interface with the specified name.

Result; the interface index, integer/0.

gifaddr - Get the address of the interface with the specified name.

Result; the address of the interface, sockaddr/0.

gifdstaddr - Get the destination address of the point-to-point interface with the specified name.

Result; the destination address of the interface, sockaddr/0.

gifbrdaddr - Get the broadcast address of the interface with the specified name.

Result; broadcast address of the interface, sockaddr/0.

gifnetmask - Get the network mask of the interface with the specified name.

Result; the network mask of the interface, sockaddr/0.

gifhwaddr | genaddr - Get the hardware address for the interface with the specified name.

Result; the hardware address of the interface, sockaddr/0 | binary/0. The family field contains the 'ARPHRD' device type (or an integer).

gifmtu - Get the MTU (Maximum Transfer Unit) for the interface with the specified name.

Result; MTU of the interface, integer/0.

giftxqlen - Get the transmit queue length of the interface with the specified name.

Result; transmit queue length of the interface, integer/0.

gifflags - Get the active flag word of the interface with the specified name.

Result; the active flag word of the interface, is a list of ioctl_device_flag/0 | t:integer( ).

With the following SetRequest argument this function sets the Value for the request parameter (since OTP 26.1).

rcvall - Enables (or disables) a socket to receive all IPv4 or IPv6 packages passing through a network interface.

The Socket has to be one of:

An IPv4 socket - Created with the address domain inet, socket type raw and protocol ip.

An IPv6 socket - Created with the address domain inet6, socket type raw and protocol ipv6.

The socket must also be bound to an (explicit) local IPv4 or IPv6 interface (any isn't allowed).

Setting this IOCTL requires elevated privileges.

With the following SetRequest arguments this function sets the Value for the request parameter (since OTP 26.1).

rcvall_igmpmcall - Enables (or disables) a socket to receive IGMP multicast IP traffic, without receiving any other IP traffic.

The socket has to be created with the address domain inet, socket type raw and protocol igmp.

The socket must also be bound to an (explicit) local interface (any isn't allowed).

The receive buffer must be sufficiently large.

Setting this IOCTL requires elevated privileges.

rcvall_mcall - Enables (or disables) a socket to receive all multicast IP traffic (as in; all IP packets destined for IP addresses in the range 224.0.0.0 to 239.255.255.255).

The socket has to be created with the address domain inet, socket type raw and protocol udp.

The socket must also be bound to an (explicit) local interface (any isn't allowed), And bound to port 0.

The receive buffer must be sufficiently large.

Setting this IOCTL requires elevated privileges.

ioctl(Socket, SetRequest, Name, Value)

(since OTP 24.2)

-spec ioctl(Socket, SetRequest, Name, Value) -> ok | {error, Reason}
               when
                   Socket :: socket(),
                   SetRequest ::
                       sifflags | sifaddr | sifdstaddr | sifbrdaddr | sifnetmask | sifhwaddr | sifmtu |
                       siftxqlen,
                   Name :: string(),
                   Value :: dynamic(),
                   Reason :: posix() | closed.

Set socket (device) parameters.

This function sets a specific parameter, according to the SetRequest argument. The Name argument is the name of the interface, and the Value argument is the value to set.

These operations require elevated privileges.

sifflags - Set the the active flag word, #{Flag => boolean()}, of the interface with the specified name.

Each flag to be changed should be added to the value map/0, with the value true if the Flag should be set and false if the flag should be cleared.

sifaddr - Set the address, sockaddr/0, of the interface with the specified name.

sifdstaddr - Set the destination address, sockaddr/0, of a point-to-point interface with the specified name.

sifbrdaddr - Set the broadcast address, sockaddr/0, of the interface with the specified name.

sifnetmask - Set the network mask, sockaddr/0, of the interface with the specified name.

sifhwaddr - Set the hardware address, sockaddr/0, of the interface with the specified name.

sifmtu - Set the MTU (Maximum Transfer Unit), integer/0, for the interface with the specified name.

siftxqlen - Set the transmit queue length, integer/0, of the interface with the specified name.

is_supported(Key1)

(since OTP 23.0)

-spec is_supported(Key1 :: term()) -> boolean().

Check if a socket feature is supported.

Returns true if supports/0 has a {Key1, true} tuple or a {Key1, list()} tuple in its returned list, otherwise false (also for unknown keys).

Example:

true = socket:is_supported(local),

is_supported(Key1, Key2)

(since OTP 23.0)

-spec is_supported(Key1 :: term(), Key2 :: term()) -> boolean().

Check if a socket feature is supported.

Returns true if supports(Key1) has a {Key2, true} tuple in its returned list, otherwise false (also for unknown keys).

Example:

true = socket:is_supported(msg_flags, errqueue),

listen(Socket)

(since OTP 22.0)

-spec listen(Socket :: socket()) -> ok | {error, Reason :: posix() | closed}.

Make a socket listen for connections.

Equivalent to listen(Socket, Backlog) with a default value for Backlog (currently 5).

listen/2

(since OTP 22.0)

-spec listen(Socket, IsServer) -> ok | {error, Reason}
                when Socket :: socket(), IsServer :: boolean(), Reason :: posix() | closed;
            (Socket, Backlog) -> ok | {error, Reason}
                when Socket :: socket(), Backlog :: pos_integer(), Reason :: posix() | closed.

Make a socket listen for connections.

The IsServer clauses are intended to be used for SCTP sockets. The Backlog argument states the length of the queue for incoming not yet accepted connections. Exactly how that number is interpreted is up to the OS' protocol stack, but the resulting effective queue length will most probably be perceived as at least that long.

Note

On Windows the socket has to be bound.

monitor(Socket)

(since OTP 24.0)

-spec monitor(Socket :: socket()) -> MonitorRef :: reference().

Start a socket monitor.

If the Socket doesn't exist or when later the monitor is triggered, a 'DOWN' message is sent to the process that called monitor/1 with the following pattern:

	    {'DOWN', MonitorRef, socket, Socket, Info}

Info is the termination reason of the socket or nosock if Socket did not exist when the monitor was started.

Making several calls to socket:monitor/1 for the same Socket is not an error; each call creates an independent monitor instance.

number_of()

(since OTP 22.3)

-spec number_of() -> non_neg_integer().

Return the number of active sockets.

open(FD)

(since OTP 23.0)

-spec open(FD :: integer()) -> dynamic().

Equivalent to open(FD, #{}).

open/2

(since OTP 22.0)

-spec open(FD, Opts) -> {ok, Socket} | {error, Reason}
              when
                  FD :: integer(),
                  Opts ::
                      #{domain => domain() | integer(),
                        type => type() | integer(),
                        protocol => default | protocol() | integer(),
                        dup => boolean(),
                        debug => boolean(),
                        use_registry => boolean()},
                  Socket :: socket(),
                  Reason :: posix() | domain | type | protocol;
          (Domain, Type) -> {ok, Socket} | {error, Reason}
              when
                  Domain :: domain(),
                  Type :: type() | integer(),
                  Socket :: socket(),
                  Reason :: posix() | protocol.

Create a socket.

With arguments Domain and Type

Equivalent to open(Domain, Type, default, #{}).

With arguments FD and Opts (since OTP 23.0)

Creates an endpoint for communication (socket) based on an already existing file descriptor that must be a socket. This function attempts to retrieve the file descriptor's domain, type and protocol from the system. This is however not possible on all platforms; in that case they should be specified in Opts.

The Opts argument can provide extra information:

domain - The file descriptor's communication domain. See also

open/2,3,4.

type - The file descriptor's socket type.

See also open/2,3,4.

protocol - The file descriptor's protocol. The atom default is equivalent to the integer protocol number 0 which means the default protocol for a given domain and type.

If the protocol can not be retrieved from the platform for the socket, and protocol is not specified, the default protocol is used, which may or may not be correct.

See also open/2,3,4.

dup - If false don't duplicate the provided file descriptor.

Defaults to true; do duplicate the file descriptor.

debug - If true enable socket debug logging.

Defaults to false; don't enable socket debug logging.

use_registry - Enable or disable use of the socket registry for this socket. This overrides the global setting.

Defaults to the global setting, see use_registry/1.

Note

This function should be used with care!

On some platforms it is necessary to provide domain, type and protocol since they cannot be retrieved from the platform.

On some platforms it is not easy to get hold of a file descriptor to use in this function.

open/3

(since OTP 22.0)

-spec open(Domain, Type, Opts | Protocol) -> {ok, Socket} | {error, Reason}
              when
                  Domain :: domain() | integer(),
                  Type :: type() | integer(),
                  Opts :: map(),
                  Protocol :: default | protocol() | integer(),
                  Socket :: socket(),
                  Reason :: posix() | protocol.

Create a socket.

With arguments Domain, Type and Protocol

Equivalent to open(Domain, Type, Protocol, #{}).

With arguments Domain, Type and Opts (since OTP 24.0)

Equivalent to open(Domain, Type, default, #{}).

open(Domain, Type, Protocol, Opts)

(since OTP 22.0)

-spec open(Domain, Type, Protocol, Opts) -> {ok, Socket} | {error, Reason}
              when
                  Domain :: domain() | integer(),
                  Type :: type() | integer(),
                  Protocol :: default | protocol() | integer(),
                  Opts :: #{netns => string(), debug => boolean(), use_registry => boolean()},
                  Socket :: socket(),
                  Reason :: posix() | protocol.

Create a socket.

Creates an endpoint for communication (socket).

Domain and Type may be integer/0s, as defined in the platform's header files. The same goes for Protocol as defined in the platform's services(5) database. See also the OS man page for the library call socket(2).

Note

For some combinations of Domain and Type the platform has got a default protocol that can be selected with Protocol = default, and the platform may allow or require selecting the default protocol, or a specific protocol.

Examples:

socket:open(inet, stream, tcp) - It is common that for protocol domain and type inet,stream it is allowed to select the tcp protocol although that mostly is the default.

socket:open(local, dgram) - It is common that for the protocol domain local it is mandatory to not select a protocol, that is; to select the default protocol.

The Opts argument is intended for "other" options. The supported option(s) are described below:

netns: string() - Used to set the network namespace during the open call. Only supported on Linux.

debug: boolean() - Enable or disable debug logging.

Defaults to false.

use_registry: boolean() - Enable or disable use of the socket registry for this socket. This overrides the global value.

Defaults to the global value, see use_registry/1.

peeloff(Socket, AssocId)

(since OTP @OTP-19834@)

-spec peeloff(Socket, AssocId) -> {ok, NewSock} | {ok, NewSock, InheritErrs} | {error, Reason}
                 when
                     Socket :: socket(),
                     AssocId :: sctp_assoc_id(),
                     NewSock :: socket(),
                     InheritErrs :: [{SockOpt, get | set, Reason}],
                     SockOpt :: socket_option(),
                     Reason :: posix() | closed.

Branch off an association into a separate socket.

Equivalent to peeloff(Socket, AssocId, [])

peeloff(Socket, AssocId, InheritOpts)

(since OTP @OTP-19834@)

-spec peeloff(Socket, AssocId, InheritOpts) ->
                 {ok, NewSock} | {ok, NewSock, InheritErrs} | {error, Reason}
                 when
                     Socket :: socket(),
                     AssocId :: sctp_assoc_id(),
                     InheritOpts :: [socket_option()],
                     NewSock :: socket(),
                     InheritErrs :: [{SockOpt, get | set, Reason}],
                     SockOpt :: socket_option(),
                     Reason :: posix() | closed.

Branch off an association into a separate socket.

Create a new one-to-one socket from an existing one-to-many socket. The specified InheritOpts will be inherited by the new socket (get from existing socket and then set on the new socket).

If the peeloff operation is successful but some (or all) of the InheritOpts failed to transfer to the new socket, {'ok', NewSock, InheritErrs} is returned. It is then up to the caller to decide if this is acceptable.

peername(Socket)

(since OTP 22.0)

-spec peername(Socket :: socket()) -> {ok, SockAddr} | {error, Reason}
                  when SockAddr :: sockaddr_recv(), Reason :: posix() | closed.

Return the remote address of a socket.

Returns the address of the connected peer, that is, the remote end of the socket.

peernames(Socket, AssocId)

(since OTP @OTP-19834@)

-spec peernames(Socket :: socket(), AssocId :: sctp_assoc_id()) -> {ok, [SockAddr]} | {error, Reason}
                   when SockAddr :: sockaddr_recv(), Reason :: posix() | closed.

Return the remote (peer) address(s) of an association of a socket.

If the socket is IPv4 then all returned addresess will be IPv4. If the socket is IPv6, then the returned addresess can be a mix of IPv4 and IPv6.

For a one-to-many socket, AssocId specifies the association. For a one-to-one socket, AssocId is ignored.

The behaviour if AssocId is 0 (zero), is undefined for one-to-many sockets.

recv(Socket)

(since OTP 22.0)

-spec recv(Socket :: socket()) -> dynamic().

Equivalent to recv(Socket, 0, [], infinity).

recv/2

(since OTP 22.0)

-spec recv(Socket :: socket(), Flags :: [msg_flag() | integer()]) -> dynamic();
          (Socket :: socket(), Length :: non_neg_integer()) -> dynamic().

Receive data on a connected socket.

With argument Length; equivalent to recv(Socket, Length, [], infinity).

With argument Flags; equivalent to recv(Socket, 0, Flags, infinity) (since OTP 24.0).

recv/3

(since OTP 22.0)

-spec recv(Socket, Flags, TimeoutOrHandle) -> dynamic()
              when
                  Socket :: socket(),
                  Flags :: [msg_flag() | integer()],
                  TimeoutOrHandle :: timeout() | nowait | select_handle() | completion_handle();
          (Socket :: socket(), Length :: non_neg_integer(), Flags :: [msg_flag() | integer()]) ->
              dynamic();
          (Socket :: socket(), Length :: non_neg_integer(), TimeoutOrHandle) -> dynamic()
              when TimeoutOrHandle :: timeout() | nowait | select_handle() | completion_handle().

Receive data on a connected socket.

With arguments Length and Flags; equivalent to recv(Socket, Length, Flags, infinity).

With arguments Length and TimeoutOrHandle; equivalent to recv(Socket, Length, [], TimeoutOrHandle). TimeoutOrHandle :: nowait has been allowed since OTP 22.1. TimeoutOrHandle :: Handle has been allowed since OTP 24.0.

With arguments Flags and TimeoutOrHandle; equivalent to recv(Socket, 0, Flags, TimeoutOrHandle) (since OTP 24.0).

recv/4

(since OTP 22.0)

-spec recv(Socket, Length, Flags, Timeout :: infinity) ->
              {ok, Data} | {error, Reason} | {error, {Reason, Data}}
              when
                  Socket :: socket(),
                  Length :: non_neg_integer(),
                  Flags :: [msg_flag() | integer()],
                  Data :: binary(),
                  Reason :: posix() | closed | invalid();
          (Socket, Length, Flags, Timeout :: non_neg_integer()) ->
              {ok, Data} | {error, Reason} | {error, {Reason, Data}}
              when
                  Socket :: socket(),
                  Length :: non_neg_integer(),
                  Flags :: [msg_flag() | integer()],
                  Data :: binary(),
                  Reason :: posix() | closed | invalid() | timeout;
          (Socket, Length, Flags, nowait | Handle) ->
              {ok, Data} |
              {select, SelectInfo} |
              {select, {SelectInfo, Data}} |
              {select_read, {SelectInfo, Data}} |
              {completion, CompletionInfo} |
              {error, Reason}
              when
                  Socket :: socket(),
                  Length :: non_neg_integer(),
                  Flags :: [msg_flag() | integer()],
                  Handle :: select_handle() | completion_handle(),
                  Data :: binary(),
                  SelectInfo :: select_info(),
                  CompletionInfo :: completion_info(),
                  Reason :: posix() | closed | invalid().

Receive data on a connected socket.

The argument Length specifies the size of the receive buffer. Packet oriented sockets truncate the packet if the size is too small.

If Length == 0; a default buffer size is used, which can be set by socket:setopt(Socket, {otp,recvbuf}, BufSz).

For a socket of type stream, when a Timeout argument is used, the operation iterates until Length bytes has been received, or the operation times out. If Length == 0 all readily available data is returned.

On a select system, when the default receive buffer size option {otp,recvbuf} special value {N,BufSize} is used, N limits how many BufSize buffers that may be received in a tight loop before the receive operation returns. The option value {1,BufSize} is equivalent to just specifying a size value BufSize.

The message Flags may be symbolic msg_flag/0s and/or integer/0s as in the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

When there is a socket error this function returns {error, Reason}, or if some data arrived before the error; {error, {Reason, Data}} (can only happen for a socket of type stream).

If the Timeout argument is infinity; waits for the data to arrive. For a socket of type stream this call won't return until all requested data can be delivered, or if "all available" was requested when the first data chunk arrives, or if the OS reports an error for the operation.

If the Timeout argument is a time-out value (non_neg_integer/0); return {error, timeout} if no data has arrived after Timeout milliseconds, or {error, {timeout, Data}} if some but not enough data has been received on a socket of type stream with Length > 0. It can also return directly with {ok, Data} (type dgram).

Timeout = 0 only polls the OS receive call and doesn't engage the Asynchronous Calls mechanisms. If no data is immediately available {error, timeout} is returned.On a socket of type stream, {error, {timeout, Data}} is returned if there is an insufficient amount of data immediately available.

If the Handle argument is nowait (since OTP 22.1), starts an asynchronous call if the operation couldn't be completed immediately.

If the Handle argument is a select_handle/0, (since OTP 24.0), or on Windows, the equivalent completion_handle/0 (since OTP 26.0), starts an asynchronous call like for nowait.

See the note Asynchronous Calls at the start of this module reference manual page.

The possible values for CompletionStatus in the completion message are:

{ok, Data} - Complete success; All requested data was read.

{more, Data} - Partial success; Some, but not all, data was read.

{error, Reason} - An error occured and no data was read.

On select systems, for a socket of type stream, if Length > 0 and there is some but not enough data available, this function will return {select, {SelectInfo, Data}} with partial Data. A repeated call to complete the operation may need an updated Length argument.

On select systems, if the option {otp, select_read} is set, {select_read, {SelectInfo, Data}} is returned instead of {ok, Data} and a new asynchronous receive operation has been initiated, which can be seen as an automatic nowait call whenever a receive operation is completed.

recvfrom(Socket)

(since OTP 22.0)

-spec recvfrom(Socket :: socket()) -> dynamic().

Equivalent to recvfrom(Socket, 0, [], infinity).

recvfrom/2

(since OTP 22.0)

-spec recvfrom(Socket :: socket(), Flags :: list()) -> dynamic();
              (Socket :: socket(), BufSz :: non_neg_integer()) -> dynamic().

Receive a message on a socket.

With argument BufSz; equivalent to recvfrom(Socket, BufSz, [], infinity).

With argument Flags; equivalent to recvfrom(Socket, 0, Flags, infinity) (since OTP 24.0).

recvfrom/3

(since OTP 22.0)

-spec recvfrom(Socket :: socket(), Flags :: [msg_flag() | integer()], TimeoutOrHandle :: dynamic()) ->
                  dynamic();
              (Socket :: socket(), BufSz :: non_neg_integer(), Flags :: [msg_flag() | integer()]) ->
                  dynamic();
              (Socket :: socket(), BufSz :: non_neg_integer(), TimeoutOrHandle) -> dynamic()
                  when TimeoutOrHandle :: timeout() | nowait | select_handle() | completion_handle().

Receive a message on a socket.

With arguments BufSz and Flags; equivalent to recvfrom(Socket, BufSz, Flags, infinity).

With arguments BufSz and TimeoutOrHandle; equivalent to recvfrom(Socket, BufSz, [], TimeoutOrHandle).

With arguments Flags and TimeoutOrHandle; equivalent to recvfrom(Socket, 0, Flags, TimeoutOrHandle)

TimeoutOrHandle :: 'nowait' has been allowed since OTP 22.1.

TimeoutOrHandle :: Handle has been allowed since OTP 24.0.

recvfrom/4

(since OTP 22.0)

-spec recvfrom(Socket, BufSz, Flags, Timeout :: infinity) -> {ok, {Source, Data}} | {error, Reason}
                  when
                      Socket :: socket(),
                      BufSz :: non_neg_integer(),
                      Flags :: [msg_flag() | integer()],
                      Source :: sockaddr_recv(),
                      Data :: binary(),
                      Reason :: posix() | closed | invalid();
              (Socket, BufSz, Flags, Timeout :: non_neg_integer()) ->
                  {ok, {Source, Data}} | {error, Reason}
                  when
                      Socket :: socket(),
                      BufSz :: non_neg_integer(),
                      Flags :: [msg_flag() | integer()],
                      Source :: sockaddr_recv(),
                      Data :: binary(),
                      Reason :: posix() | closed | invalid() | timeout;
              (Socket, BufSz, Flags, nowait | Handle) ->
                  {ok, {Source, Data}} |
                  {select, SelectInfo} |
                  {select_read, {SelectInfo, {Source, Data}}} |
                  {completion, CompletionInfo} |
                  {error, Reason}
                  when
                      Socket :: socket(),
                      BufSz :: non_neg_integer(),
                      Flags :: [msg_flag() | integer()],
                      Handle :: select_handle() | completion_handle(),
                      Source :: sockaddr_recv(),
                      Data :: binary(),
                      SelectInfo :: select_info(),
                      CompletionInfo :: completion_info(),
                      Reason :: posix() | closed | invalid().

Receive a message on a socket.

This function is intended primarily for sockets that are not connection oriented such as type dgram or seqpacket where messages may arrive from different source addresses.

Argument BufSz specifies the number of bytes for the receive buffer. If the buffer size is too small, the message will be truncated.

If BufSz is 0, a default buffer size is used, which can be set by socket:setopt(Socket, {otp,recvbuf}, BufSz).

If there is no known appropriate buffer size, it may be possible to use the receive message flag peek. When this flag is used, the message is not "consumed" from the underlying buffers, so another recvfrom/1,2,3,4 call is needed, possibly with an adjusted buffer size.

The message Flags may be symbolic msg_flag/0s and/or integer/0s, as in the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

If the Timeout argument is infinity; waits for a message to arrive, or for a socket error.

If the Timeout argument is a time-out value (non_neg_integer/0); returns {error, timeout} if no message has arrived after Timeout milliseconds.

Timeout = 0 only polls the OS receive call and doesn't engage the Asynchronous Calls mechanisms. If no message is immediately available {error, timeout} is returned.

If the Handle argument is nowait (since OTP 22.1), starts an asynchronous call if the operation couldn't be completed immediately.

If the 'Handle' argument is a select_handle/0, (since OTP 24.0), or on Windows, the equivalent completion_handle/0 (since OTP 26.0), starts an asynchronous call like for nowait.

See the note Asynchronous Calls at the start of this module reference manual page.

The possible values for CompletionStatus in the completion message are:

{ok, {Source, Data}} - Success.

{error, Reason} - An error occured and no data was read.

recvmmsg/6

(since OTP 29.0)

-spec recvmmsg(Socket, VLen, BufSz, CtrlSz, Flags, Timeout :: infinity) -> {ok, Msgs} | {error, Reason}
                  when
                      Socket :: socket(),
                      VLen :: non_neg_integer(),
                      BufSz :: non_neg_integer(),
                      CtrlSz :: non_neg_integer(),
                      Flags :: [msg_flag() | integer()],
                      Msgs :: [msg_recv()],
                      Reason :: posix() | closed | invalid();
              (Socket, VLen, BufSz, CtrlSz, Flags, Timeout :: non_neg_integer()) ->
                  {ok, Msgs} | {error, Reason}
                  when
                      Socket :: socket(),
                      VLen :: non_neg_integer(),
                      BufSz :: non_neg_integer(),
                      CtrlSz :: non_neg_integer(),
                      Flags :: [msg_flag() | integer()],
                      Msgs :: [msg_recv()],
                      Reason :: posix() | closed | invalid() | timeout;
              (Socket, VLen, BufSz, CtrlSz, Flags, nowait | Handle) ->
                  {ok, Msgs} |
                  {select, SelectInfo} |
                  {select_read, {SelectInfo, Msgs}} |
                  {completion, CompletionInfo} |
                  {error, Reason}
                  when
                      Socket :: socket(),
                      VLen :: non_neg_integer(),
                      BufSz :: non_neg_integer(),
                      CtrlSz :: non_neg_integer(),
                      Handle :: select_handle() | completion_handle(),
                      Flags :: [msg_flag() | integer()],
                      Msgs :: [msg_recv()],
                      SelectInfo :: select_info(),
                      CompletionInfo :: completion_info(),
                      Reason :: posix() | closed | invalid().

Receive multiple messages on a socket.

This function is equivalent to calling recvmsg/5 multiple times, but uses the platform's recvmmsg syscall for better performance when receiving multiple datagrams.

Note

This function is only available on Linux and BSD systems (not macOS/Darwin or Windows). On unsupported platforms, it will return {error, notsup}.

Arguments:

VLen - Maximum number of messages to receive (must be >= 1).

BufSz - Buffer size for each message (0 uses default).

CtrlSz - Control message buffer size for each message (0 uses default).

Flags - Receive flags (same as recvmsg/5).

Timeout - Timeout or nowait or infinity.

Returns a list of message maps, one per received message. The list length indicates how many messages were actually received.

recvmsg(Socket)

(since OTP 22.0)

-spec recvmsg(Socket :: socket()) -> dynamic().

Equivalent to recvmsg(Socket, 0, 0, [], infinity).

recvmsg/2

(since OTP 22.0)

-spec recvmsg(Socket :: socket(), Flags :: list()) -> dynamic();
             (Socket :: socket(), TimeoutOrHandle) -> dynamic()
                 when
                     TimeoutOrHandle :: timeout() | nowait | Handle,
                     Handle :: select_handle() | completion_handle().

Receive a message on a socket.

With argument Flags; equivalent to recvmsg(Socket, 0, 0, Flags, infinity).

With argument TimeoutOrHandle; equivalent to recvmsg(Socket, 0, 0, [], TimeoutOrHandle).

TimeoutOrHandle :: nowait has been allowed since OTP 22.1.

TimeoutOrHandle :: Handle has been allowed since OTP 24.0.

recvmsg/3

(since OTP 22.0)

-spec recvmsg(Socket :: dynamic(), Flags :: list(), TimeoutOrHandle :: dynamic()) -> dynamic();
             (Socket :: dynamic(), BufSz :: integer(), CtrlSz :: integer()) -> dynamic().

Receive a message on a socket.

With arguments Flags; equivalent to recvmsg(Socket, 0, 0, Flags, infinity).

With argument TimeoutOrHandle; equivalent to recvmsg(Socket, 0, 0, [], TimeoutOrHandle).

TimeoutOrHandle :: nowait has been allowed since OTP 22.1.

TimeoutOrHandle :: Handle has been allowed since OTP 24.0.

recvmsg(Socket, BufSz, CtrlSz, TimeoutOrHandle)

(since OTP 24.0)

-spec recvmsg(Socket :: socket(),
              BufSz :: non_neg_integer(),
              CtrlSz :: non_neg_integer(),
              TimeoutOrHandle :: dynamic()) ->
                 dynamic().

Equivalent to recvmsg(Socket, BufSz, CtrlSz, [], TimeoutOrHandle).

recvmsg/5

(since OTP 22.0)

-spec recvmsg(Socket, BufSz, CtrlSz, Flags, Timeout :: infinity) -> {ok, Msg} | {error, Reason}
                 when
                     Socket :: socket(),
                     BufSz :: non_neg_integer(),
                     CtrlSz :: non_neg_integer(),
                     Flags :: [msg_flag() | integer()],
                     Msg :: msg_recv(),
                     Reason :: posix() | closed | invalid();
             (Socket, BufSz, CtrlSz, Flags, Timeout :: non_neg_integer()) -> {ok, Msg} | {error, Reason}
                 when
                     Socket :: socket(),
                     BufSz :: non_neg_integer(),
                     CtrlSz :: non_neg_integer(),
                     Flags :: [msg_flag() | integer()],
                     Msg :: msg_recv(),
                     Reason :: posix() | closed | invalid() | timeout;
             (Socket, BufSz, CtrlSz, Flags, nowait | Handle) ->
                 {ok, Msg} |
                 {select, SelectInfo} |
                 {select_read, {SelectInfo, Msg}} |
                 {completion, CompletionInfo} |
                 {error, Reason}
                 when
                     Socket :: socket(),
                     BufSz :: non_neg_integer(),
                     CtrlSz :: non_neg_integer(),
                     Handle :: select_handle() | completion_handle(),
                     Flags :: [msg_flag() | integer()],
                     Msg :: msg_recv(),
                     SelectInfo :: select_info(),
                     CompletionInfo :: completion_info(),
                     Reason :: posix() | closed | invalid().

Receive a message on a socket.

This function receives a data message with control messages as well as its source address.

Arguments BufSz and CtrlSz specifies the number of bytes for the receive buffer and the control message buffer. If the buffer size(s) is(are) too small, the message and/or control message list will be truncated.

If BufSz is 0, a default buffer size is used, which can be set by socket:setopt(Socket, {otp,recvbuf}, BufSz). The same applies to CtrlSz and socket:setopt(Socket, {otp,recvctrlbuf}, CtrlSz).

If there is no known appropriate buffer size, it may be possible to use the receive message flag peek. When this flag is used, the message is not "consumed" from the underlying buffers, so another recvfrom/1,2,3,4 call is needed, possibly with an adjusted buffer size.

The message Flags may be symbolic msg_flag/0s and/or integer/0s, as in the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

If the Timeout argument is infinity; waits for the message to arrive, or for a socket error.

If the Timeout argument is a time-out value (non_neg_integer/0); return {error, timeout} if no message has arrived after Timeout milliseconds.

Timeout = 0 only polls the OS receive call and doesn't engage the Asynchronous Calls mechanisms. If no message is immediately available {error, timeout} is returned.

If the Handle argument is nowait (since OTP 22.1), starts an asynchronous call if the operation couldn't be completed immediately.

If the 'Handle' argument is a select_handle/0, (since OTP 24.0), or on Windows, the equivalent completion_handle/0 (since OTP 26.0), starts an asynchronous call like for nowait.

See the note Asynchronous Calls at the start of this module reference manual page.

The possible values for CompletionStatus in the completion message are:

{ok, Msg} - Success.

{error, Reason} - An error occured and no data was read.

rest_iov(Written, IOV)

(since OTP 28.0.2)

-spec rest_iov(Written, IOV) -> RestIOV
                  when Written :: non_neg_integer(), IOV :: erlang:iovec(), RestIOV :: erlang:iovec().

Calculate the rest I/O vector after a partially successful sendv (CompletionStatus was {ok, Written}).

send(Socket, Data)

(since OTP 22.0)

-spec send(Socket, Data) -> Result
              when
                  Socket :: socket(),
                  Data :: iodata(),
                  Result ::
                      ok |
                      {ok, RestData :: binary()} |
                      {select, SelectInfo :: dynamic()} |
                      {completion, CompletionInfo :: dynamic()} |
                      {error, Reason :: dynamic()}.

Equivalent to send(Socket, Data, [], infinity).

send/3

(since OTP 22.0)

-spec send(Socket :: term(), Data :: term(), Cont :: tuple()) -> _;
          (Socket :: term(), Data :: term(), Flags :: list()) -> _;
          (Socket :: term(), Data :: term(), Timeout :: timeout()) -> _.

Send data on a connected socket.

With argument Timeout; equivalent to send(Socket, Data, [], Timeout).

With argument Flags; equivalent to send(Socket, Data, Flags, infinity).

With argument Cont; equivalent to send(Socket, Data, Cont, infinity) (since OTP 24.0).

send/4

(since OTP 22.0)

-spec send(Socket, Data, Flags | Cont, Timeout :: infinity) ->
              ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}}
              when
                  Socket :: socket(),
                  Data :: iodata(),
                  Flags :: [msg_flag() | integer()],
                  Cont :: select_info(),
                  RestData :: binary(),
                  Reason :: posix() | closed | invalid() | netname_deleted | too_many_cmds | eei();
          (Socket, Data, Flags | Cont, Timeout :: non_neg_integer()) ->
              ok | {ok, RestData} | {error, Reason | timeout} | {error, {Reason | timeout, RestData}}
              when
                  Socket :: socket(),
                  Data :: iodata(),
                  Flags :: [msg_flag() | integer()],
                  Cont :: select_info(),
                  RestData :: binary(),
                  Reason :: posix() | closed | invalid() | netname_deleted | too_many_cmds | eei();
          (Socket, Data, Flags | Cont, nowait | Handle) ->
              ok |
              {ok, RestData} |
              {select, SelectInfo} |
              {select, {SelectInfo, RestData}} |
              {completion, CompletionInfo} |
              {error, Reason}
              when
                  Socket :: socket(),
                  Data :: iodata(),
                  Flags :: [msg_flag() | integer()],
                  Cont :: select_info(),
                  Handle :: select_handle() | completion_handle(),
                  RestData :: binary(),
                  SelectInfo :: select_info(),
                  CompletionInfo :: completion_info(),
                  Reason :: posix() | closed | invalid() | netname_deleted | too_many_cmds | eei().

Send data on a connected socket.

The message Flags may be symbolic msg_flag/0s and/or integer/0s as in the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

The Data, if it is not a binary/0, is copied into one before calling the platform network API, because a single buffer is required. A returned RestData is a sub binary of it.

The return value indicates the result from the platform's network layer:

ok - All data was accepted by the OS for delivery

{ok, RestData} - Some but not all data was accepted, but no error was reported (partially successful send). RestData is the tail of Data that wasn't accepted.

This cannot happen for a socket of type stream where such a partially successful send is retried until the data is either accepted for delivery or there is an error.

For a socket of type dgram this should probably also not happen since a message that cannot be passed atomically should render an error.

It is nevertheless possible for the platform's network layer to return this, surely more possible for a socket of type seqpacket.

{error, Reason} - An error has been reported and no data was accepted for delivery. Reason :: posix/0 is what the platform's network layer reported. closed means that this socket library was informed that the socket was closed, and invalid/0 means that this socket library found an argument to be invalid.

{error, {Reason, RestData}} - An error was reported but before that some data was accepted for delivery. RestData is the tail of Data that wasn't accepted. See {error, Reason} above.

This can only happen for a socket of type stream when a partially successful send is retried until there is an error.

If the Timeout argument is infinity; wait for the OS to complete the send operation (take responsibility for the data), or return an error.

If the Timeout argument is a time-out value (non_neg_integer/0); return {error, timeout} if no data has been sent within Timeout millisecond, or {error, {timeout, RestData}} if some data was sent (accepted by the OS for delivery). RestData is the tail of the data that hasn't been sent.

If the Handle argument is nowait (since OTP 22.1), starts an asynchronous call if the operation couldn't be completed immediately.

If the Handle argument is a select_handle/0, (since OTP 24.0), or on Windows, the equivalent completion_handle/0 (since OTP 26.0), starts an asynchronous call like for nowait.

See the note Asynchronous Calls at the start of this module reference manual page.

The possible values for CompletionStatus in the completion message are:

ok - Complete success; The data was written in its entirety.

{ok, Written} - Partial success; Some but not all data was written, but no error was reported. Written is the number of bytes that was written.

{error, Reason} - An error occured and no data was sent.

If the function is called with a Cont argument, that is; the SelectInfo from the previous send/3,4 call; the send is continued with preprocessed send parameters in the SelectInfo. Using this argument variant avoids for example having to validate and encode message flags in every call but the first.

sendfile(Socket, FileHandle_Cont)

(since OTP 24.0)

-spec sendfile(Socket, FileHandle | Continuation) -> dynamic()
                  when Socket :: socket(), FileHandle :: file:fd(), Continuation :: select_info().

Send a file on a socket.

Equivalent to sendfile(Socket, FileHandle_or_Continuation, 0, 0, infinity).

sendfile(Socket, FileHandle_Cont, Timeout_Handle)

(since OTP 24.0)

-spec sendfile(Socket, FileHandle | Continuation, Timeout | Handle) -> dynamic()
                  when
                      Socket :: socket(),
                      FileHandle :: file:fd(),
                      Continuation :: select_info(),
                      Timeout :: infinity | non_neg_integer(),
                      Handle :: nowait | select_handle().

Send a file on a socket.

Equivalent to sendfile(Socket, FileHandle_or_Continuation, 0, 0, Timeout_or_Handle).

sendfile(Socket, FileHandle_Cont, Offset, Count)

(since OTP 24.0)

-spec sendfile(Socket, FileHandle | Continuation, Offset, Count) -> dynamic()
                  when
                      Socket :: socket(),
                      FileHandle :: file:fd(),
                      Continuation :: select_info(),
                      Offset :: integer(),
                      Count :: non_neg_integer().

Send a file on a socket.

Equivalent to sendfile(Socket, FileHandle_or_Continuation, Offset, Count, infinity).

sendfile/5

(since OTP 24.0)

-spec sendfile(Socket, FileHandle | Continuation, Offset, Count, Timeout :: infinity) ->
                  {ok, BytesSent} | {error, Reason} | {error, {Reason, BytesSent}}
                  when
                      Socket :: socket(),
                      FileHandle :: file:fd(),
                      Continuation :: select_info(),
                      Offset :: integer(),
                      Count :: non_neg_integer(),
                      BytesSent :: non_neg_integer(),
                      Reason :: posix() | closed | invalid();
              (Socket, FileHandle | Continuation, Offset, Count, Timeout :: non_neg_integer()) ->
                  {ok, BytesSent} | {error, Reason} | {error, {Reason, BytesSent}}
                  when
                      Socket :: socket(),
                      FileHandle :: file:fd(),
                      Continuation :: select_info(),
                      Offset :: integer(),
                      Count :: non_neg_integer(),
                      BytesSent :: non_neg_integer(),
                      Reason :: posix() | closed | invalid() | timeout;
              (Socket,
               FileHandle | Continuation,
               Offset, Count,
               nowait | (SelectHandle :: select_handle())) ->
                  {ok, BytesSent} |
                  {select, SelectInfo} |
                  {select, {SelectInfo, BytesSent}} |
                  {error, Reason}
                  when
                      Socket :: socket(),
                      FileHandle :: file:fd(),
                      Continuation :: select_info(),
                      Offset :: integer(),
                      Count :: non_neg_integer(),
                      BytesSent :: non_neg_integer(),
                      SelectInfo :: select_info(),
                      Reason :: posix() | closed | invalid().

Send a file on a socket.

Note

This function unsupported on Windows.

The FileHandle argument must refer to an open raw file as described in file:open/2.

The Offset argument is the file offset to start reading from. The default offset is 0.

The Count argument is the number of bytes to transfer from FileHandle to Socket. If Count = 0 (the default) the transfer stops at the end of file.

The return value indicates the result from the platform's network layer:

{ok, BytesSent} - The transfer completed successfully after BytesSent bytes of data.

{error, Reason} - An error has been reported and no data was transferred. Reason :: posix/0 is what the platform's network layer reported. closed means that this socket library was informed that the socket was closed, and invalid/0 means that this socket library found an argument to be invalid.

{error, {Reason, BytesSent}} - An error has been reported but before that some data was transferred. See {error, Reason} and {ok, BytesSent} above.

If the Timeout argument is infinity; wait for the OS to complete the send operation (take responsibility for the data), or return an error.

If the Timeout argument is a time-out value (non_neg_integer/0); return {error, timeout} if no data has been sent within Timeout millisecond, or {error, {timeout, BytesSent}} if some but not all data was sent (accepted by the OS for delivery).

If the Handle argument is nowait, starts an asynchronous call if the operation couldn't be completed immediately.

If the Handle argument is a select_handle/0, starts an asynchronous call like for nowait.

See the note Asynchronous Calls at the start of this module reference manual page.

After receiving a select message; call sendfile/2,3,4,5 with SelectInfo as the Continuation argument, to complete the operation.

If the function is called with a Continuation argument, that is; the SelectInfo from the previous sendfile/5 call; the transfer is continued with preprocessed parameters in the SelectInfo.

The Offset and maybe Count arguments will probably need to be updated between continuation calls.

sendmmsg/4

(since OTP 29.0)

-spec sendmmsg(Socket, Msgs, Flags, Timeout :: infinity) -> ok | {ok, Rest} | {error, Reason}
                  when
                      Socket :: socket(),
                      Msgs :: [msg_send()],
                      Flags :: [msg_flag() | integer()],
                      Rest :: [erlang:iovec()],
                      Reason :: posix() | closed | invalid();
              (Socket, Msgs, Flags, Timeout :: non_neg_integer()) ->
                  ok | {ok, Rest} | {error, Reason | timeout}
                  when
                      Socket :: socket(),
                      Msgs :: [msg_send()],
                      Flags :: [msg_flag() | integer()],
                      Rest :: [erlang:iovec()],
                      Reason :: posix() | closed | invalid();
              (Socket, Msgs, Flags, nowait | Handle) ->
                  ok |
                  {ok, Rest} |
                  {select_write, {SelectInfo, SentCount}} |
                  {select, SelectInfo} |
                  {completion, CompletionInfo} |
                  {error, Reason}
                  when
                      Socket :: socket(),
                      Msgs :: [msg_send()],
                      Flags :: [msg_flag() | integer()],
                      Handle :: select_handle() | completion_handle(),
                      Rest :: [erlang:iovec()],
                      SentCount :: non_neg_integer(),
                      SelectInfo :: select_info(),
                      CompletionInfo :: completion_info(),
                      Reason :: posix() | closed | invalid().

Send multiple messages on a socket.

This function is equivalent to calling sendmsg/4 multiple times, but uses the platform's sendmmsg syscall for better performance when sending multiple datagrams.

Note

This function is only available on Linux and BSD systems (not macOS/Darwin or Windows). On unsupported platforms, it will return {error, notsup}.

On success, returns either:

ok – when all messages were sent in full (or there were zero messages).

{ok, Rest} – when one or more messages had a partial write. Rest is a list with one element per message that was not fully sent, in message order. Each element is the remaining data for that message in the same form as sendmsg/4's rest data (erlang:iovec/0), so you can retry with sendmsg for each.

On error returns {error, Reason}.

sendmsg(Socket, Msg)

(since OTP 22.0)

-spec sendmsg(Socket, Msg) -> Result
                 when Socket :: socket(), Msg :: msg_send() | erlang:iovec(), Result :: dynamic().

Equivalent to sendmsg(Socket, Msg, [], infinity).

sendmsg/3

(since OTP 22.0)

-spec sendmsg(Socket :: socket(), Msg :: msg_send(), Flags :: list()) -> dynamic();
             (Socket :: socket(), Data :: msg_send() | erlang:iovec(), Cont :: select_info()) ->
                 dynamic();
             (Socket :: socket(), Msg :: msg_send(), Timeout :: infinity) -> dynamic().

Send data and control messages on a socket.

With arguments Msg and Timeout; equivalent to sendmsg(Socket, Msg, [], Timeout).

With arguments Msg and Flags; equivalent to sendmsg(Socket, Msg, Flags, infinity).

With arguments Data and Cont; equivalent to sendmsg(Socket, Data, Cont, infinity) since OTP 24.0.

sendmsg/4

(since OTP 22.0)

-spec sendmsg(Socket, Msg, Flags, Timeout :: infinity) ->
                 ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}}
                 when
                     Socket :: socket(),
                     Msg :: msg_send(),
                     Flags :: [msg_flag() | integer()],
                     RestData :: erlang:iovec(),
                     Reason :: posix() | closed | invalid();
             (Socket, Msg, Flags, Timeout :: non_neg_integer()) ->
                 ok | {ok, RestData} | {error, Reason | timeout} | {error, {Reason | timeout, RestData}}
                 when
                     Socket :: socket(),
                     Msg :: msg_send(),
                     Flags :: [msg_flag() | integer()],
                     RestData :: erlang:iovec(),
                     Reason :: posix() | closed | invalid();
             (Socket, Msg, Flags, nowait | Handle) ->
                 ok |
                 {ok, RestData} |
                 {select, SelectInfo} |
                 {select, {SelectInfo, RestData}} |
                 {completion, CompletionInfo} |
                 {error, Reason} |
                 {error, {Reason, RestData}}
                 when
                     Socket :: socket(),
                     Msg :: msg_send(),
                     Flags :: [msg_flag() | integer()],
                     Handle :: select_handle() | completion_handle(),
                     RestData :: erlang:iovec(),
                     SelectInfo :: select_info(),
                     CompletionInfo :: completion_info(),
                     Reason :: posix() | closed | invalid();
             (Socket, Data, Cont, Timeout :: infinity) ->
                 ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}}
                 when
                     Socket :: socket(),
                     Data :: msg_send() | erlang:iovec(),
                     Cont :: select_info(),
                     RestData :: erlang:iovec(),
                     Reason :: posix() | closed | invalid();
             (Socket, Data, Cont, Timeout :: non_neg_integer()) ->
                 ok | {ok, RestData} | {error, Reason | timeout} | {error, {Reason | timeout, RestData}}
                 when
                     Socket :: socket(),
                     Data :: msg_send() | erlang:iovec(),
                     Cont :: select_info(),
                     RestData :: erlang:iovec(),
                     Reason :: posix() | closed | invalid();
             (Socket, Data, Cont, nowait | Handle) ->
                 ok |
                 {ok, RestData} |
                 {select, SelectInfo} |
                 {select, {SelectInfo, RestData}} |
                 {completion, CompletionInfo} |
                 {error, Reason} |
                 {error, {Reason, RestData}}
                 when
                     Socket :: socket(),
                     Data :: msg_send() | erlang:iovec(),
                     Cont :: select_info(),
                     Handle :: select_handle(),
                     RestData :: erlang:iovec(),
                     SelectInfo :: select_info(),
                     CompletionInfo :: completion_info(),
                     Reason :: posix() | closed | invalid().

Send data and control messages on a socket.

The argument Msg is a map that contains the data to be sent under the key iov as anerlang:iovec/0 (list of binary/0). It may also contain the destination address under the key addr, which is mandatory if the socket isn't connected. If the socket is connected it is best to not have an addr key since the platform may regard that as an error (or ignore it). Under the key ctrl there may be a list of protocol and platform dependent control messages (a.k.a ancillary data, a.k.a control information) to send.

The message data is given to the platform's network layer as an I/O vector without copying the content. If the number of elements in the I/O vector is larger than allowed on the platform (reported in the iov_max field from info/0), on a socket of type stream the send is iterated over all elements, but for other socket types the call fails.

See send/4 for a description of the Flags argument and the return values.

Note

On Windows, this function can only be used with datagram and raw sockets.

If the Timeout argument is infinity; wait for the OS to complete the send operation (take responsibility for the data), or return an error.

If the Timeout argument is a time-out value (non_neg_integer/0); return {error, timeout} if no data has been sent within Timeout millisecond, or {error, {timeout, RestData}} if some data was sent (accepted by the OS for delivery). RestData is the tail of the data that hasn't been sent.

If the Handle argument is nowait (since OTP 22.1), starts an asynchronous call if the operation couldn't be completed immediately.

If the Handle argument is a select_handle/0, (since OTP 24.0), or on Windows, the equivalent completion_handle/0 (since OTP 26.0), starts an asynchronous call like for nowait.

See the note Asynchronous Calls at the start of this module reference manual page.

The possible values for CompletionStatus in the completion message are:

ok - Complete success; The data was written in its entirety.

{ok, Written} - Partial success; Some but not all data was written, but no error was reported. Written is the number of bytes that was written.

{error, Reason} - An error occured and no data was sent.

After receiving a select message; call sendmsg/3,4 with SelectInfo as the Cont argument, to complete the operation.

With the arguments Data and Cont, continues the send operation. Cont should be the SelectInfo returned from the previous sendmsg/2,3,4 call.

Data can be a Msg map/0 where only the key iov is used, or an erlang:iovec/0.

sendto/3

(since OTP 22.0)

-spec sendto(Socket :: socket(), Data :: iodata(), Cont | Dest) -> Result
                when
                    Cont :: select_info(),
                    Dest :: sockaddr(),
                    Result :: ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}},
                    RestData :: binary(),
                    Reason :: posix() | closed | invalid().

Send data on a socket.

With argument Dest; equivalent to sendto(Socket, Data, Dest, [], infinity).

With argument Cont; equivalent to sendto(Socket, Data, Cont, infinity) since OTP 24.0.

sendto/4

(since OTP 22.0)

-spec sendto(Socket :: socket(),
             Data :: iodata(),
             Dest :: sockaddr(),
             Flags :: [msg_flag() | integer()]) ->
                dynamic();
            (Socket :: socket(),
             Data :: iodata(),
             Cont :: select_info(),
             Timeout :: timeout() | nowait | (Handle :: select_handle())) ->
                dynamic();
            (Socket :: socket(),
             Data :: iodata(),
             Dest :: sockaddr(),
             Timeout :: timeout() | nowait | (Handle :: select_handle() | completion_handle())) ->
                dynamic().

Send data on a socket.

With arguments Dest and TimeoutOrHandle; equivalent to sendto(Socket, Data, Dest, [], TimeoutOrHandle).

With arguments Dest and Flags; equivalent to sendto(Socket, Data, Dest, Flags, infinity).

With arguments Cont and TimeoutOrHandle; Cont must be the SelectInfo from the previous sendto/3,4,5 call and the send is continued with preprocessed send parameters in the SelectInfo. Using this argument variant avoids for example having o validate and encode message flags in every call but the first. (Since OTP 24.0)

See the last argument (argument 5) of sendto/5 for an explanation of TimeoutOrHandle.

sendto/5

(since OTP 22.0)

-spec sendto(Socket, Data, Dest, Flags, Timeout :: infinity) ->
                ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}}
                when
                    Socket :: socket(),
                    Data :: iodata(),
                    Dest :: sockaddr(),
                    Flags :: [msg_flag() | integer()],
                    RestData :: binary(),
                    Reason :: posix() | closed | invalid();
            (Socket, Data, Dest, Flags, Timeout :: non_neg_integer()) ->
                ok | {ok, RestData} | {error, Reason | timeout} | {error, {Reason | timeout, RestData}}
                when
                    Socket :: socket(),
                    Data :: iodata(),
                    Dest :: sockaddr(),
                    Flags :: [msg_flag() | integer()],
                    RestData :: binary(),
                    Reason :: posix() | closed | invalid();
            (Socket, Data, Dest, Flags, nowait | Handle) ->
                ok |
                {ok, RestData} |
                {select, SelectInfo} |
                {select, {SelectInfo, RestData}} |
                {completion, CompletionInfo} |
                {error, Reason}
                when
                    Socket :: socket(),
                    Data :: iodata(),
                    Dest :: sockaddr(),
                    Flags :: [msg_flag() | integer()],
                    Handle :: select_handle() | completion_handle(),
                    RestData :: binary(),
                    SelectInfo :: select_info(),
                    CompletionInfo :: completion_info(),
                    Reason :: posix() | closed | invalid().

Send data on a socket.

The To argument is the destination address where to send the data. For a connected socket this argument is still passed to the OS call that may ignore the address or return an error.

See send/4 for a description of the Flags and Data arguments, and the return values.

If the Timeout argument is infinity; wait for the OS to complete the send operation (take responsibility for the data), or return an error.

If the Timeout argument is a time-out value (non_neg_integer/0); return {error, timeout} if no data has been sent within Timeout millisecond, or {error, {timeout, RestData}} if some data was sent (accepted by the OS for delivery). RestData is the tail of the data that hasn't been sent.

If the Handle argument is nowait (since OTP 22.1), starts an asynchronous call if the operation couldn't be completed immediately.

If the Handle argument is a select_handle/0, (since OTP 24.0), or on Windows, the equivalent completion_handle/0 (since OTP 26.0), starts an asynchronous call like for nowait.

See the note Asynchronous Calls at the start of this module reference manual page.

The possible values for CompletionStatus in the completion message are:

ok - Complete success; The data was written in its entirety.

{ok, Written} - Partial success; Some but not all data was written, but no error was reported. Written is the number of bytes that was written.

{error, Reason} - An error occured and no data was sent.

After receiving a select message; call sendto/3,4 with SelectInfo as the Cont argument, to complete the operation.

sendv(Socket, IOV)

(since OTP 27.0)

-spec sendv(Socket, IOV) -> ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}}
               when
                   Socket :: socket(),
                   IOV :: erlang:iovec(),
                   RestIOV :: erlang:iovec(),
                   Reason :: posix() | closed | invalid().

Equivalent to sendv(Socket, IOV, infinity).

sendv/3

(since OTP 27.0)

-spec sendv(Socket, IOV, Timeout :: infinity) ->
               ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}}
               when
                   Socket :: socket(),
                   IOV :: erlang:iovec(),
                   RestIOV :: erlang:iovec(),
                   Reason :: posix() | closed | invalid();
           (Socket, IOV, Timeout :: non_neg_integer()) ->
               ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}}
               when
                   Socket :: socket(),
                   IOV :: erlang:iovec(),
                   RestIOV :: erlang:iovec(),
                   Reason :: posix() | closed | invalid() | timeout;
           (Socket, IOV, nowait | Handle) ->
               ok |
               {ok, RestIOV} |
               {select, SelectInfo} |
               {select, {SelectInfo, RestIOV}} |
               {completion, CompletionInfo} |
               {completion, {CompletionInfo, RestIOV}} |
               {error, Reason} |
               {error, {Reason, RestIOV}}
               when
                   Socket :: socket(),
                   IOV :: erlang:iovec(),
                   Handle :: select_handle() | completion_handle(),
                   RestIOV :: erlang:iovec(),
                   SelectInfo :: select_info(),
                   CompletionInfo :: completion_info(),
                   Reason :: posix() | closed | invalid();
           (Socket, IOV, Cont) -> ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}}
               when
                   Socket :: socket(),
                   IOV :: erlang:iovec(),
                   Cont :: select_info(),
                   RestIOV :: erlang:iovec(),
                   Reason :: posix() | closed | invalid().

Send erlang:iovec/0 data on a connected socket.

See sendmsg/4 about how the IOV data is handled towards the platform's network layer.

The return value indicates the result from the platform's network layer:

ok - All data has been accepted by the OS for delivery.

{ok, RestIOV} - Some but not all data was accepted, but no error was reported (partially successful send). RestIOV is the tail of IOV that wasn't accepted.

{error, Reason} - An error has been reported and no data was accepted for delivery. Reason :: posix/0 is what the platform's network layer reported. closed means that this socket library was informed that the socket was closed, and invalid/0 means that this socket library found an argument to be invalid.

{error, {Reason, RestIOV}} - - An error was reported but before that some data was accepted for delivery. RestIOV is the tail of IOV that wasn't accepted. See {error, Reason} above.

If the Timeout argument is infinity; wait for the OS to complete the send operation (take responsibility for the data), or return an error.

If the Timeout argument is a time-out value (non_neg_integer/0); return {error, timeout} if no data has been sent within Timeout millisecond, or {error, {timeout, RestIOV}} if some data was sent (accepted by the OS for delivery). RestIOV is the tail of the data that hasn't been sent.

If the Handle argument is nowait, starts an asynchronous call if the operation couldn't be completed immediately.

If the Handle argument is a select_handle/0, or on Windows, the equivalent completion_handle/0, starts an asynchronous call like for nowait.

See the note Asynchronous Calls at the start of this module reference manual page.

The possible values for CompletionStatus in the completion message are:

ok - Complete success; The I/O vector was written in its entirety.

{ok, Written} - Partial success; Some but not all data was written, but no error was reported. Written is the number of bytes that was written. rest_iov(Written, IOV) can be used to calculate the rest I/O vector (from the original IOV).

{error, Reason} - An error occured and no data was sent.

With the argument Cont, equivalent to sendv(Socket, IOV, Cont, infinity).

sendv/4

(since OTP 27.0)

-spec sendv(Socket, IOV, Cont, Timeout :: infinity) ->
               ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}}
               when
                   Socket :: socket(),
                   IOV :: erlang:iovec(),
                   Cont :: select_info(),
                   RestIOV :: erlang:iovec(),
                   Reason :: posix() | closed | invalid();
           (Socket, IOV, Cont, Timeout :: non_neg_integer()) ->
               ok | {ok, RestIOV} | {error, Reason} | {error, {Reason | RestIOV}}
               when
                   Socket :: socket(),
                   IOV :: erlang:iovec(),
                   Cont :: select_info(),
                   RestIOV :: erlang:iovec(),
                   Reason :: posix() | closed | invalid() | timeout;
           (Socket, IOV, Cont, nowait | SelectHandle) ->
               ok |
               {ok, RestIOV} |
               {select, SelectInfo} |
               {select, {SelectInfo, RestIOV}} |
               {error, Reason} |
               {error, {Reason, RestIOV}}
               when
                   Socket :: socket(),
                   IOV :: erlang:iovec(),
                   Cont :: select_info(),
                   SelectHandle :: select_handle(),
                   RestIOV :: erlang:iovec(),
                   SelectInfo :: select_info(),
                   Reason :: posix() | closed | invalid().

Send data on a connected socket, continuation.

Continues sending data on a connected socket. Cont is the SelectInfo returned from the previous sendv/2,3 call. IOV should be the rest data that wasn't sent.

See asynchronous calls about continuing unfinished calls.

See sendv/3 about the return values.

setopt/3

(since OTP 24.0)

-spec setopt(Socket, SocketOption, Value) -> ok | {error, invalid() | closed}
                when
                    Socket :: socket(),
                    SocketOption :: {Level :: otp, Opt :: otp_socket_option()},
                    Value :: dynamic();
            (Socket, SocketOption, Value) -> ok | {error, posix() | invalid() | closed}
                when Socket :: socket(), SocketOption :: socket_option(), Value :: dynamic().

Set a socket option.

Set an OS protocol level option, or an otp pseudo protocol level option. The latter level is this module's implementation level above the OS protocol levels.

See the type otp_socket_option() for a description of the otp protocol level.

See the type socket_option/0 for which OS protocol level options that this implementation knows about, how they are related to OS option names, and if there are known peculiarities with any of them.

What options that are valid depends on the OS, and on the kind of socket (domain/0,type/0 and protocol/0). See the type t:socket_option() and the socket options chapter in the User's Guide for more info.

Note

Not all options are valid, nor possible to set, on all platforms. That is, even if this socket implementation support an option; it doesn't mean that the underlying OS does.

setopt/4

(since OTP 22.0)

-spec setopt(socket(), Level :: term(), Opt :: term(), Value :: term()) -> _.

Set a socket option (backwards compatibility function).

Equivalent to setopt(Socket, {Level, Opt}, Value), or as a special case if Opt = NativeOpt :: integer/0 and Value = binary/0 equivalent to setopt_native(Socket, {Level, NativeOpt}, ValueSpec).

Use setopt/3 or setopt_native/3 instead to handle the option level and name as a single term, and to make the difference between known options and native options clear.

setopt_native(Socket, Option, Value)

(since OTP 24.0)

-spec setopt_native(Socket, Option, Value) -> ok | {error, posix() | invalid() | closed}
                       when
                           Socket :: socket(),
                           Option :: socket_option() | {Level, NativeOpt} | {NativeLevel, NativeOpt},
                           Value :: native_value(),
                           Level :: level(),
                           NativeLevel :: integer(),
                           NativeOpt :: integer().

Set a "native" socket option.

Sets a socket option that may be unknown to our implementation, or that has a type not compatible with our implementation, that is; in "native mode".

If Value is an integer/0 it will be used as a C type (int), if it is a boolean/0 it will be used as a C type (int) with the C implementations values for false or true, and if it is a binary/0 its content and size will be used as the option value.

The socket option may be specified with an ordinary socket_option/0 tuple, with a symbolic Level as {Level :: level/0,NativeOpt :: integer/0}, or with integers for both NativeLevel and NativeOpt as {NativeLevel :: integer/0,NativeOpt :: integer/0}.

If an option is valid depends both on the platform and on what kind of socket it is (domain/0, type/0 and protocol/0).

The integer values for NativeLevel and NativeOpt as well as the Value encoding has to be deduced from the header files for the running system.

shutdown(Socket, How)

(since OTP 22.0)

-spec shutdown(Socket, How) -> ok | {error, Reason}
                  when Socket :: socket(), How :: read | write | read_write, Reason :: posix() | closed.

Shut down all or part of a full-duplex connection.

sockname(Socket)

(since OTP 22.0)

-spec sockname(Socket :: socket()) -> {ok, SockAddr} | {error, Reason}
                  when SockAddr :: sockaddr_recv(), Reason :: posix() | closed.

Get the socket's address.

Returns the address to which the socket is currently bound. If the bind address had the wildcard port 0, the address returned by this function contains the ephemeral port selected by the OS.

socknames(Socket, AssocId)

(since OTP @OTP-19834@)

-spec socknames(Socket :: socket(), AssocId :: sctp_assoc_id()) -> {ok, [SockAddr]} | {error, Reason}
                   when SockAddr :: sockaddr_recv(), Reason :: posix() | closed.

Get the socket's address.

Returns all the locally bound addresses to which the socket is currently bound.

If the socket is IPv4 then all returned addresess will be IPv4. If the socket is IPv6, then the returned addresess can be a mix of IPv4 and IPv6.

For a one-to-many socket, AssocId specifies the association. For a one-to-one socket, AssocId is ignored.

If AssocId is 0 (zero), then the returned addresses are without any particular association.

supports()

(since OTP 22.0)

-spec supports() ->
                  [{Key1 :: term(),
                    boolean() | [{Key2 :: term(), boolean() | [{Key3 :: term(), boolean()}]}]}].

Retrieve information about what socket features the module and the platform supports.

Returns a list of, in no particular order, {Key1,supports(Key1)} tuples for every Key1 described in supports/1, and {Key, boolean()} tuples for each of the following keys:

sctp - SCTP support

ipv6 - IPv6 support

local - Unix Domain sockets support (AF_UNIX | AF_LOCAL)

netns - Network Namespaces support (Linux, setns(2))

sendfile - Sendfile support (sendfile(2))

supports(Key1)

(since OTP 22.0)

-spec supports(Key1 :: term()) -> [{Key2 :: term(), boolean() | [{Key3 :: term(), boolean()}]}].

Retrieve information about what socket features the module and the platform supports.

If Key1 = msg_flags returns a list of {Flag, boolean()} tuples for every Flag in msg_flag/0 with the boolean/0 indicating if the flag is supported on this platform.

If Key1 = protocols returns a list of {Name, boolean()} tuples for every Name inprotocol/0 with the boolean/0 indicating if the protocol is supported on this platform.

If Key1 = options returns a list of {SocketOption, boolean()} tuples for every SocketOption in socket_option/0 with the boolean/0 indicating if the socket option is supported on this platform.

There is no particular order of any of the returned lists.

For other values of Key1 returns []. Note that in future versions of this module or on different platforms, there might be more supported keys.

supports(Key1, Key2)

(since OTP 22.0)

-spec supports(Key1 :: term(), Key2 :: term()) -> [{Key3 :: term(), boolean()}].

Retrieve information about what socket features the module and the platform supports.

If Key1 = options, for a Key2 in level/0 returns a list of {Opt, boolean()} tuples for all known socket options Opt on that Level = Key2 with the boolean/0 indicating if the socket option is supported on this platform. See setopt/3 and getopt/2.

There is no particular order of any of the returned lists.

For other values of Key1 or Key2 returns []. Note that in future versions of this module or on different platforms, there might be more supported keys.

use_registry(D)

(since OTP 23.1)

-spec use_registry(D :: boolean()) -> ok.

Set the global use_registry option default value.

Globally change if the socket registry is to be used or not. Note that its still possible to override this explicitly when creating an individual sockets, see open/2,3,4 for more info (the Opts :: map/0).

which_sockets()

(since OTP 22.3)

-spec which_sockets() -> [socket()].

Return a list of all known sockets.

Equivalent to which_sockets(fun (_) -> true end).

which_sockets(FilterRule)

(since OTP 22.3)

-spec which_sockets(FilterRule) -> [socket()]
                       when
                           FilterRule ::
                               inet | inet6 | local | stream | dgram | seqpacket | sctp | tcp | udp |
                               pid() |
                               fun((socket_info()) -> boolean()).

Return a filtered list of known sockets.

There are several predefined FilterRules and one general:

inet | inet6 - Only the sockets with matching domain/0 are returned.

stream | dgram | seqpacket - Only the sockets with matching type/0 are returned.

sctp | tcp | udp - Only the sockets with matching protocol/0 are returned.

pid/0 - Only the sockets with matching Controlling Process are returned. See the OTP socket option controlling_process.

fun((socket_info()) -> boolean()) - The general filter rule. A fun that takes the socket info and returns a boolean/0 indicating if the socket should be returned or not.

disk_log

disk_log is a disk-based term logger that enables efficient logging of items on files.

Three types of logs are supported:

halt logs - Appends items to a single file, which size can be limited by the disk_log module.

wrap logs - Uses a sequence of wrap log files of limited size. As a wrap log file is filled up, further items are logged on to the next file in the sequence, starting all over with the first file when the last file is filled up.

rotate logs - Uses a sequence of rotate log files of limited size. As a log file is filled up, it is rotated and then compressed. There is one active log file and upto the configured number of compressed log files. Only externally formatted logs are supported. It follows the same naming convention as the handler logger_std_h for Logger. For more details about the naming convention check the file parameter for open/1.

It follows the same naming convention as that for the compressed files for Linux's logrotate and BSD's newsyslog.

For efficiency reasons, items are always written to files as binaries.

Two formats of the log files are supported:

internal format - Supports automatic repair of log files that are not properly closed and enables efficient reading of logged items in chunks using a set of functions defined in this module. This is the only way to read internally formatted logs. An item logged to an internally formatted log must not occupy more than 4 GB of disk space (the size must fit in 4 bytes).

external format - Leaves it up to the user to read and interpret the logged data. The disk_log module cannot repair externally formatted logs.

For each open disk log, one process handles requests made to the disk log. This process is created when open/1 is called, provided there exists no process handling the disk log. A process that opens a disk log can be an owner or an anonymous user of the disk log. Each owner is linked to the disk log process, and an owner can close the disk log either explicitly (by calling close/1) or by terminating.

Owners can subscribe to notifications, messages of the form {disk_log, Node, Log, Info}, which are sent from the disk log process when certain events occur, see the functions and in particular the open/1 option notify. A log can have many owners, but a process cannot own a log more than once. However, the same process can open the log as a user more than once.

For a disk log process to close its file properly and terminate, it must be closed by its owners and once by some non-owner process for each time the log was used anonymously. The users are counted and there must not be any users left when the disk log process terminates.

Items can be logged synchronously by using functions log/2, blog/2, log_terms/2, and blog_terms/2. For each of these functions, the caller is put on hold until the items are logged (but not necessarily written, use sync/1 to ensure that). By adding an a to each of the mentioned function names, we get functions that log items asynchronously. Asynchronous functions do not wait for the disk log process to write the items to the file, but return the control to the caller more or less immediately.

When using the internal format for logs, use functions log/2, log_terms/2, alog/2, and alog_terms/2. These functions log one or more Erlang terms. By prefixing each of the functions with a b (for "binary"), we get the corresponding blog() functions for the external format. These functions log one or more chunks of bytes. For example, to log the string "hello" in ASCII format, you can use disk_log:blog(Log, "hello"), or disk_log:blog(Log, list_to_binary("hello")). The two alternatives are equally efficient.

The blog() functions can also be used for internally formatted logs, but in this case they must be called with binaries constructed with calls to term_to_binary/1. There is no check to ensure this, it is entirely the responsibility of the caller. If these functions are called with binaries that do not correspond to Erlang terms, the chunk/2,3 and automatic repair functions fail. The corresponding terms (not the binaries) are returned when chunk/2,3 is called.

An open disk log is only accessible from the node where the disk log process runs. All processes on the node where the disk log process runs can log items or otherwise change, inspect, or close the log.

Errors are reported differently for asynchronous log attempts and other uses of the disk_log module. When used synchronously, this module replies with an error message, but when called asynchronously, this module does not know where to send the error message. Instead, owners subscribing to notifications receive an error_status message.

The disk_log module does not report errors to the error_logger module. It is up to the caller to decide whether to employ the error logger. Function format_error/1 can be used to produce readable messages from error replies. However, information events are sent to the error logger in two situations, namely when a log is repaired, or when a file is missing while reading chunks.

Error message no_such_log means that the specified disk log is not open. Nothing is said about whether the disk log files exist or not.

Note

If an attempt to reopen or truncate a log fails (see reopen/2,3 and truncate/1,2) the disk log process terminates immediately. Before the process terminates, links to owners and blocking processes (see block/1,2) are removed. The effect is that the links work in one direction only. Any process using a disk log must check for error message no_such_log if some other process truncates or reopens the log simultaneously.

See Also

file, wrap_log_reader

Summary

Types

bchunk_ret()

block_error_rsn()

chunk_error_rsn()

chunk_ret()

close_error_rsn()

continuation()

Chunk continuation returned by chunk/2,3, bchunk/2,3, or chunk_step/3.

dlog_format()

dlog_head_opt()

dlog_info()

dlog_mode()

dlog_optattr()

dlog_option()

dlog_options()

dlog_size()

dlog_type()

file_error()

inc_wrap_error_rsn()

invalid_header()

log()

log_error_rsn()

next_file_error_rsn()

notify_ret()

open_error_rsn()

open_ret()

reopen_error_rsn()

sync_error_rsn()

trunc_error_rsn()

unblock_error_rsn()

Functions

all()

Returns the names of the disk logs accessible on the current node.

alog(Log, Term)

Asynchronously version of log/2.

alog_terms(Log, TermList)

Asynchronously version of log_terms/2.

balog(Log, Bytes)

Asynchronously version of blog/2.

balog_terms(Log, ByteList)

Asynchronously version of blog_terms/2.

bchunk(Log, Continuation)

Equivalent to bchunk(Log, Cont, infinity).

bchunk(Log, Continuation, N)

Equivalent to chunk(Log, Continuation, N) except that it returns the binaries read from the file, that is it does not call binary_to_term/1.

block(Log)

Equivalent to block(Log, true).

block(Log, QueueLogRecords)

With a call to block/2 a process can block a log.

blog(Log, Bytes)

Equivalent to log/2 except that it is used for externally formatted logs.

blog_terms(Log, BytesList)

Equivalent to log_terms/2 except that it is used for externally formatted logs.

breopen(Log, File, BHead)

Equivalent to reopen except that it is used for externally formatted logs.

btruncate(Log, BHead)

Equivalent to truncate/2 for externally formatted logs.

change_header(Log, Header)

Changes the value of option head or head_func for an owner of a disk log.

change_notify(Log, Owner, Notify)

Changes the value of option notify for an owner of a disk log.

change_size(Log, Size)

Changes the size of an open log. For a halt log, the size can always be increased, but it cannot be decreased to something less than the current file size.

chunk(Log, Continuation)

Equivalent to chunk(Log, Continuation, infinity).

chunk(Log, Continuation, N)

Efficiently reads the terms that are appended to an internally formatted log.

chunk_info(Continuation)

Returns the pair {node, Node}, describing the chunk continuation returned by chunk/2,3, bchunk/2,3, or chunk_step/3.

chunk_step(Log, Continuation, Step)

Can be used with chunk/2,3 and bchunk/2,3 to search through an internally formatted wrap log.

close(Log)

Closes a disk log properly.

format_error(Error)

Given the error returned by any function in this module, this function returns a descriptive string of the error in English.

inc_wrap_file(Log) deprecated

Forces the internally formatted disk log to start logging to the next log file. It can be used, for example, with change_size/2 to reduce the amount of disk space allocated by the disk log.

info(Log)

Returns a list of {Tag, Value} pairs describing a log running on the node.

log(Log, Term)

Synchronously appends a term to a internally formatted disk log. Returns ok or {error, Reason} when the term is written to disk.

log_terms(Log, TermList)

Synchronously appends a list of items to an internally formatted log.

next_file(Log)

For wrap logs, it forces the disk log to start logging to the next log file. It can be used, for example, with change_size/2 to reduce the amount of disk space allocated by the disk log.

open(ArgL)

Open a new disk_log file for reading or writing.

pid2name(Pid)

Returns the log name given the pid of a disk log process on the current node, or undefined if the specified pid is not a disk log process.

reopen(Log, File)

Equivalent to reopen(Log, File, Head) where Head is the Head specified in open/1.

reopen(Log, File, Head)

Renames an internally formatted log file to File and then recreates a new log file. If a wrap/rotate log exists, File is used as the base name of the renamed files.

sync(Log)

Ensures that the contents of the log are written to the disk. This is usually a rather expensive operation.

truncate(Log)

Equivalent to truncate(Log, Head) where Head is the Head specified in open/1.

truncate(Log, Head)

Removes all items from an internally formatted disk log. The argument Head or is written first in the newly truncated log.

unblock(Log)

Unblocks a log. A log can only be unblocked by the blocking process.

Types

bchunk_ret()

(not exported)

-type bchunk_ret() ::
          {Continuation2 :: continuation(), Binaries :: [binary()]} |
          {Continuation2 :: continuation(), Binaries :: [binary()], Badbytes :: non_neg_integer()} |
          eof |
          {error, Reason :: chunk_error_rsn()}.

block_error_rsn()

(not exported)

-type block_error_rsn() :: no_such_log | nonode | {blocked_log, log()}.

chunk_error_rsn()

(not exported)

-type chunk_error_rsn() ::
          no_such_log |
          {format_external, log()} |
          {blocked_log, log()} |
          {badarg, continuation} |
          {not_internal_wrap, log()} |
          {corrupt_log_file, FileName :: file:filename()} |
          {file_error, file:filename(), file_error()}.

chunk_ret()

(not exported)

-type chunk_ret() ::
          {Continuation2 :: continuation(), Terms :: [term()]} |
          {Continuation2 :: continuation(), Terms :: [term()], Badbytes :: non_neg_integer()} |
          eof |
          {error, Reason :: chunk_error_rsn()}.

close_error_rsn()

(not exported)

-type close_error_rsn() :: no_such_log | nonode | {file_error, file:filename(), file_error()}.

continuation()

-opaque continuation()

Chunk continuation returned by chunk/2,3, bchunk/2,3, or chunk_step/3.

dlog_format()

(not exported)

-type dlog_format() :: external | internal.

dlog_head_opt()

(not exported)

-type dlog_head_opt() :: none | term() | iodata().

dlog_info()

(not exported)

-type dlog_info() ::
          {name, Log :: log()} |
          {file, File :: file:filename()} |
          {type, Type :: dlog_type()} |
          {format, Format :: dlog_format()} |
          {size, Size :: dlog_size()} |
          {mode, Mode :: dlog_mode()} |
          {owners, [{pid(), Notify :: boolean()}]} |
          {users, Users :: non_neg_integer()} |
          {status, Status :: ok | {blocked, QueueLogRecords :: boolean()}} |
          {node, Node :: node()} |
          {head, Head :: none | {head, binary()} | (MFA :: {atom(), atom(), list()})} |
          {no_written_items, NoWrittenItems :: non_neg_integer()} |
          {full, Full :: boolean} |
          {no_current_bytes, non_neg_integer()} |
          {no_current_items, non_neg_integer()} |
          {no_items, non_neg_integer()} |
          {current_file, pos_integer()} |
          {no_overflows, {SinceLogWasOpened :: non_neg_integer(), SinceLastInfo :: non_neg_integer()}}.

dlog_mode()

(not exported)

-type dlog_mode() :: read_only | read_write.

dlog_optattr()

(not exported)

-type dlog_optattr() ::
          name | file | linkto | repair | type | format | size | notify | head | head_func | mode.

dlog_option()

(not exported)

-type dlog_option() ::
          {name, Log :: log()} |
          {file, FileName :: file:filename()} |
          {linkto, LinkTo :: none | pid()} |
          {repair, Repair :: true | false | truncate} |
          {type, Type :: dlog_type()} |
          {format, Format :: dlog_format()} |
          {size, Size :: dlog_size()} |
          {notify, boolean()} |
          {head, Head :: dlog_head_opt()} |
          {head_func, MFA :: {atom(), atom(), list()}} |
          {quiet, boolean()} |
          {mode, Mode :: dlog_mode()}.

dlog_options()

(not exported)

-type dlog_options() :: [dlog_option()].

dlog_size()

(not exported)

-type dlog_size() ::
          infinity | pos_integer() | {MaxNoBytes :: pos_integer(), MaxNoFiles :: pos_integer()}.

dlog_type()

(not exported)

-type dlog_type() :: halt | wrap | rotate.

file_error()

(not exported)

-type file_error() :: term().

inc_wrap_error_rsn()

(not exported)

-type inc_wrap_error_rsn() :: next_file_error_rsn().

invalid_header()

(not exported)

-type invalid_header() :: term().

log()

(not exported)

-type log() :: term().

log_error_rsn()

(not exported)

-type log_error_rsn() ::
          no_such_log | nonode |
          {read_only_mode, log()} |
          {format_external, log()} |
          {blocked_log, log()} |
          {full, log()} |
          {invalid_header, invalid_header()} |
          {file_error, file:filename(), file_error()}.

next_file_error_rsn()

(not exported)

-type next_file_error_rsn() ::
          no_such_log | nonode |
          {read_only_mode, log()} |
          {blocked_log, log()} |
          {halt_log, log()} |
          {rotate_log, log()} |
          {invalid_header, invalid_header()} |
          {file_error, file:filename(), file_error()}.

notify_ret()

(not exported)

-type notify_ret() :: ok | {error, no_such_log}.

open_error_rsn()

(not exported)

-type open_error_rsn() ::
          no_such_log |
          {badarg, term()} |
          {size_mismatch, CurrentSize :: dlog_size(), NewSize :: dlog_size()} |
          {arg_mismatch, OptionName :: dlog_optattr(), CurrentValue :: term(), Value :: term()} |
          {name_already_open, Log :: log()} |
          {open_read_write, Log :: log()} |
          {open_read_only, Log :: log()} |
          {need_repair, Log :: log()} |
          {not_a_log_file, FileName :: file:filename()} |
          {invalid_index_file, FileName :: file:filename()} |
          {invalid_header, invalid_header()} |
          {file_error, file:filename(), file_error()} |
          {node_already_open, Log :: log()}.

open_ret()

(not exported)

-type open_ret() ::
          {ok, Log :: log()} |
          {repaired,
           Log :: log(),
           {recovered, Rec :: non_neg_integer()},
           {badbytes, Bad :: non_neg_integer()}} |
          {error, open_error_rsn()}.

reopen_error_rsn()

(not exported)

-type reopen_error_rsn() ::
          no_such_log | nonode |
          {read_only_mode, log()} |
          {blocked_log, log()} |
          {same_file_name, log()} |
          {invalid_index_file, file:filename()} |
          {invalid_header, invalid_header()} |
          {file_error, file:filename(), file_error()}.

sync_error_rsn()

(not exported)

-type sync_error_rsn() ::
          no_such_log | nonode |
          {read_only_mode, log()} |
          {blocked_log, log()} |
          {file_error, file:filename(), file_error()}.

trunc_error_rsn()

(not exported)

-type trunc_error_rsn() ::
          no_such_log | nonode |
          {read_only_mode, log()} |
          {blocked_log, log()} |
          {invalid_header, invalid_header()} |
          {file_error, file:filename(), file_error()}.

unblock_error_rsn()

(not exported)

-type unblock_error_rsn() :: no_such_log | nonode | {not_blocked, log()} | {not_blocked_by_pid, log()}.

Functions

all()

(since OTP 24.0)

-spec all() -> [Log] when Log :: log().

Returns the names of the disk logs accessible on the current node.

alog(Log, Term)

-spec alog(Log, Term) -> notify_ret() when Log :: log(), Term :: term().

Asynchronously version of log/2.

Owners subscribing to notifications receive message read_only, blocked_log, or format_external if the item cannot be written on the log, and possibly one of the messages wrap, full, or error_status if an item is written on the log. Message error_status is sent if something is wrong with the header function or if a file error occurs.

alog_terms(Log, TermList)

-spec alog_terms(Log, TermList) -> notify_ret() when Log :: log(), TermList :: [term()].

Asynchronously version of log_terms/2.

Owners subscribing to notifications receive message read_only, blocked_log, or format_external if the items cannot be written on the log, and possibly one or more of the messages wrap, full, and error_status if items are written on the log. Message error_status is sent if something is wrong with the header function or if a file error occurs.

balog(Log, Bytes)

-spec balog(Log, Bytes) -> notify_ret() when Log :: log(), Bytes :: iodata().

Asynchronously version of blog/2.

Owners subscribing to notifications receive message read_only, blocked_log, or format_external if the item cannot be written on the log, and possibly one of the messages wrap, full, or error_status if an item is written on the log. Message error_status is sent if something is wrong with the header function or if a file error occurs.

balog_terms(Log, ByteList)

-spec balog_terms(Log, ByteList) -> notify_ret() when Log :: log(), ByteList :: [iodata()].

Asynchronously version of blog_terms/2.

Owners subscribing to notifications receive message read_only, blocked_log, or format_external if the items cannot be written on the log, and possibly one or more of the messages wrap, full, and error_status if items are written on the log. Message error_status is sent if something is wrong with the header function or if a file error occurs.

bchunk(Log, Continuation)

-spec bchunk(Log, Continuation) -> bchunk_ret()
                when Log :: log(), Continuation :: start | continuation().

Equivalent to bchunk(Log, Cont, infinity).

bchunk(Log, Continuation, N)

-spec bchunk(Log, Continuation, N) -> bchunk_ret()
                when Log :: log(), Continuation :: start | continuation(), N :: pos_integer() | infinity.

Equivalent to chunk(Log, Continuation, N) except that it returns the binaries read from the file, that is it does not call binary_to_term/1.

block(Log)

-spec block(Log) -> ok | {error, block_error_rsn()} when Log :: log().

Equivalent to block(Log, true).

block(Log, QueueLogRecords)

-spec block(Log, QueueLogRecords) -> ok | {error, block_error_rsn()}
               when Log :: log(), QueueLogRecords :: boolean().

With a call to block/2 a process can block a log.

If the blocking process is not an owner of the log, a temporary link is created between the disk log process and the blocking process. The link ensures that the disk log is unblocked if the blocking process terminates without first closing or unblocking the log.

Any process can probe a blocked log with info/1 or close it with close/1. The blocking process can also use functions chunk/2,3, bchunk/2,3, chunk_step/3, and unblock/1 without being affected by the block. Any other attempt than those mentioned so far to update or read a blocked log suspends the calling process until the log is unblocked or returns error message {blocked_log, Log}, depending on whether the value of QueueLogRecords is true or false.

blog(Log, Bytes)

-spec blog(Log, Bytes) -> ok | {error, Reason :: log_error_rsn()} when Log :: log(), Bytes :: iodata().

Equivalent to log/2 except that it is used for externally formatted logs.

blog/2 can also be used for internally formatted logs if the binaries are constructed with calls to term_to_binary/1.

blog_terms(Log, BytesList)

-spec blog_terms(Log, BytesList) -> ok | {error, Reason :: log_error_rsn()}
                    when Log :: log(), BytesList :: [iodata()].

Equivalent to log_terms/2 except that it is used for externally formatted logs.

blog_terms/2 can also be used for internally formatted logs if the binaries are constructed with calls to term_to_binary/1.

breopen(Log, File, BHead)

-spec breopen(Log, File, BHead) -> ok | {error, reopen_error_rsn()}
                 when Log :: log(), File :: file:filename(), BHead :: iodata().

Equivalent to reopen except that it is used for externally formatted logs.

btruncate(Log, BHead)

-spec btruncate(Log, BHead) -> ok | {error, trunc_error_rsn()} when Log :: log(), BHead :: iodata().

Equivalent to truncate/2 for externally formatted logs.

change_header(Log, Header)

-spec change_header(Log, Header) -> ok | {error, Reason}
                       when
                           Log :: log(),
                           Header ::
                               {head, dlog_head_opt()} | {head_func, MFA :: {atom(), atom(), list()}},
                           Reason ::
                               no_such_log | nonode |
                               {read_only_mode, Log} |
                               {blocked_log, Log} |
                               {badarg, head}.

Changes the value of option head or head_func for an owner of a disk log.

change_notify(Log, Owner, Notify)

-spec change_notify(Log, Owner, Notify) -> ok | {error, Reason}
                       when
                           Log :: log(),
                           Owner :: pid(),
                           Notify :: boolean(),
                           Reason ::
                               no_such_log | nonode |
                               {blocked_log, Log} |
                               {badarg, notify} |
                               {not_owner, Owner}.

Changes the value of option notify for an owner of a disk log.

change_size(Log, Size)

-spec change_size(Log, Size) -> ok | {error, Reason}
                     when
                         Log :: log(),
                         Size :: dlog_size(),
                         Reason ::
                             no_such_log | nonode |
                             {read_only_mode, Log} |
                             {blocked_log, Log} |
                             {new_size_too_small, Log, CurrentSize :: pos_integer()} |
                             {badarg, size} |
                             {file_error, file:filename(), file_error()}.

Changes the size of an open log. For a halt log, the size can always be increased, but it cannot be decreased to something less than the current file size.

For a wrap or rotate log, both the size and the number of files can always be increased, as long as the number of files does not exceed 65000. For wrap logs, if the maximum number of files is decreased, the change is not valid until the current file is full and the log wraps to the next file. The redundant files are removed the next time the log wraps around, that is, starts to log to file number 1.

As an example, assume that the old maximum number of files is 10 and that the new maximum number of files is 6. If the current file number is not greater than the new maximum number of files, files 7-10 are removed when file 6 is full and the log starts to write to file number 1 again. Otherwise, the files greater than the current file are removed when the current file is full (for example, if the current file is 8, files 9 and 10 are removed). The files between the new maximum number of files and the current file (that is, files 7 and 8) are removed the next time file 6 is full.

For rotate logs, if the maximum number of files is decreased, the redundant files are deleted instantly.

If the size of the files is decreased, the change immediately affects the current log. It does not change the size of log files already full until the next time they are used.

If the log size is decreased, for example, to save space, function next_file/1, can be used to force the log to wrap.

chunk(Log, Continuation)

-spec chunk(Log, Continuation) -> chunk_ret() when Log :: log(), Continuation :: start | continuation().

Equivalent to chunk(Log, Continuation, infinity).

chunk(Log, Continuation, N)

-spec chunk(Log, Continuation, N) -> chunk_ret()
               when Log :: log(), Continuation :: start | continuation(), N :: pos_integer() | infinity.

Efficiently reads the terms that are appended to an internally formatted log.

It minimizes disk I/O by reading 64 kilobyte chunks from the file.

The first time chunk() is called, an initial continuation, the atom start, must be provided.

When chunk/3 is called, N controls the maximum number of terms that are read from the log in each chunk. infinity means that all the terms contained in the 64 kilobyte chunk are read. If less than N terms are returned, this does not necessarily mean that the end of the file is reached.

chunk/3 returns a tuple {Continuation2, Terms}, where Terms is a list of terms found in the log. Continuation2 is yet another continuation, which must be passed on to any subsequent calls to chunk(). With a series of calls to chunk(), all terms from a log can be extracted.

chunk/3 returns a tuple {Continuation2, Terms, Badbytes} if the log is opened in read-only mode and the read chunk is corrupt. Badbytes is the number of bytes in the file found not to be Erlang terms in the chunk. Notice that the log is not repaired. When trying to read chunks from a log opened in read-write mode, tuple {corrupt_log_file, FileName} is returned if the read chunk is corrupt.

chunk/3 returns eof when the end of the log is reached, or {error, Reason} if an error occurs. If a wrap log file is missing, a message is output on the error log.

When chunk/2,3 is used with wrap logs, the returned continuation might not be valid in the next call to chunk/3. This is because the log can wrap and delete the file into which the continuation points. To prevent this, the log can be blocked during the search.

chunk_info(Continuation)

-spec chunk_info(Continuation) -> InfoList | {error, Reason}
                    when
                        Continuation :: continuation(),
                        InfoList :: [{node, Node :: node()}, ...],
                        Reason :: {no_continuation, Continuation}.

Returns the pair {node, Node}, describing the chunk continuation returned by chunk/2,3, bchunk/2,3, or chunk_step/3.

Terms are read from the disk log running on Node.

chunk_step(Log, Continuation, Step)

-spec chunk_step(Log, Continuation, Step) -> {ok, any()} | {error, Reason}
                    when
                        Log :: log(),
                        Continuation :: start | continuation(),
                        Step :: integer(),
                        Reason ::
                            no_such_log | end_of_log |
                            {format_external, Log} |
                            {blocked_log, Log} |
                            {badarg, continuation} |
                            {file_error, file:filename(), file_error()}.

Can be used with chunk/2,3 and bchunk/2,3 to search through an internally formatted wrap log.

It takes as argument a continuation as returned by chunk/2,3, bchunk/2,3, or chunk_step/3, and steps forward (or backward) Step files in the wrap log. The continuation returned, points to the first log item in the new current file.

If atom start is specified as continuation, the first file of the wrap log is chosen as the new current file.

If the wrap log is not full because all files are not yet used, {error, end_of_log} is returned if trying to step outside the log.

close(Log)

-spec close(Log) -> ok | {error, close_error_rsn()} when Log :: log().

Closes a disk log properly.

An internally formatted log must be closed before the Erlang system is stopped. Otherwise, the log is regarded as unclosed and the automatic repair procedure is activated next time the log is opened.

The disk log process is not terminated as long as there are owners or users of the log. All owners must close the log, possibly by terminating. Also, any other process, not only the processes that have opened the log anonymously, can decrement the users counter by closing the log. Attempts to close a log by a process that is not an owner are ignored if there are no users.

If the log is blocked by the closing process, the log is also unblocked.

format_error(Error)

-spec format_error(Error) -> io_lib:chars() when Error :: term().

Given the error returned by any function in this module, this function returns a descriptive string of the error in English.

For file errors, function format_error/1 in module file is called.

inc_wrap_file(Log)

This function is deprecated. disk_log:inc_wrap_file/1 is deprecated; use disk_log:next_file/1 instead.

-spec inc_wrap_file(Log) -> ok | {error, inc_wrap_error_rsn()} when Log :: log().

Forces the internally formatted disk log to start logging to the next log file. It can be used, for example, with change_size/2 to reduce the amount of disk space allocated by the disk log.

Owners subscribing to notifications normally receive a wrap message, but if an error occurs with a reason tag of invalid_header or file_error, an error_status message is sent.

info(Log)

-spec info(Log) -> InfoList | {error, no_such_log} when Log :: log(), InfoList :: [dlog_info()].

Returns a list of {Tag, Value} pairs describing a log running on the node.

The following pairs are returned for all logs:

{name, Log} - Log is the log name as specified by the open/1 option name.

{file, File} - For halt logs File is the filename, and for wrap logs File is the base name.

{type, Type} - Type is the log type as specified by the open/1 option type.

{format, Format} - Format is the log format as specified by the open/1 option format.

{size, Size} - Size is the log size as specified by the open/1 option size, or the size set by change_size/2. The value set by change_size/2 is reflected immediately.

{mode, Mode} - Mode is the log mode as specified by the open/1 option mode.

{owners, [{pid(), Notify}]} - Notify is the value set by the open/1 option notify or function change_notify/3 for the owners of the log.

{users, Users} - Users is the number of anonymous users of the log, see the open/1 option linkto.

{status, Status} - Status is ok or {blocked, QueueLogRecords} as set by functions block/1,2 and unblock/1.

{node, Node} - The information returned by the current invocation of function info/1 is gathered from the disk log process running on Node.

The following pairs are returned for all logs opened in read_write mode:

{head, Head} - Depending on the value of the open/1 options head and head_func, or set by function change_header/2, the value of Head is none (default), {head, H} (head option), or {M,F,A} (head_func option).

{no_written_items, NoWrittenItems} - NoWrittenItems is the number of items written to the log since the disk log process was created.

The following pair is returned for halt logs opened in read_write mode:

{full, Full} - Full is true or false depending on whether the halt log is full or not.

The following pairs are returned for wrap logs opened in read_write mode:

{no_current_bytes, integer() >= 0} - The number of bytes written to the current wrap log file.

{no_current_items, integer() >= 0} - The number of items written to the current wrap log file, header inclusive.

{no_items, integer() >= 0} - The total number of items in all wrap log files.

{current_file, integer()} - The ordinal for the current wrap log file in the range 1..MaxNoFiles, where MaxNoFiles is specified by the open/1 option size or set by change_size/2.

{no_overflows, {SinceLogWasOpened, SinceLastInfo}} - SinceLogWasOpened (SinceLastInfo) is the number of times a wrap log file has been filled up and a new one is opened or inc_wrap_file/1 has been called since the disk log was last opened (info/1 was last called). The first time info/2 is called after a log was (re)opened or truncated, the two values are equal.

Notice that functions chunk/2,3, bchunk/2,3, and chunk_step/3 do not affect any value returned by info/1.

log(Log, Term)

-spec log(Log, Term) -> ok | {error, Reason :: log_error_rsn()} when Log :: log(), Term :: term().

Synchronously appends a term to a internally formatted disk log. Returns ok or {error, Reason} when the term is written to disk.

Terms are written by the ordinary write() function of the operating system. Hence, it is not guaranteed that the term is written to disk, it can linger in the operating system kernel for a while. To ensure that the item is written to disk, function sync/1 must be called.

Owners subscribing to notifications are notified of an error with an error_status message if the error reason tag is invalid_header or file_error.

log_terms(Log, TermList)

-spec log_terms(Log, TermList) -> ok | {error, Reason :: log_error_rsn()}
                   when Log :: log(), TermList :: [term()].

Synchronously appends a list of items to an internally formatted log.

It is more efficient to use this functions instead of log/2. The specified list is split into as large sublists as possible (limited by the size of wrap log files), and each sublist is logged as one single item, which reduces the overhead.

Owners subscribing to notifications are notified of an error with an error_status message if the error reason tag is invalid_header or file_error.

next_file(Log)

(since OTP 26.0)

-spec next_file(Log) -> ok | {error, next_file_error_rsn()} when Log :: log().

For wrap logs, it forces the disk log to start logging to the next log file. It can be used, for example, with change_size/2 to reduce the amount of disk space allocated by the disk log.

Owners subscribing to notifications normally receive a wrap message, but if an error occurs with a reason tag of invalid_header or file_error, an error_status message is sent.

For rotate logs, it forces rotation of the currently active log file, compresses it and opens a new active file for logging.

open(ArgL)

-spec open(ArgL) -> open_ret() when ArgL :: dlog_options().

Open a new disk_log file for reading or writing.

Parameter ArgL is a list of the following options:

{name, Log} - Specifies the log name. This name must be passed on as a parameter in all subsequent logging operations. A name must always be supplied.

{file, FileName} - Specifies the name of the file to be used for logged terms. If this value is omitted and the log name is an atom or a string, the filename defaults to lists:concat([Log, ".LOG"]) for halt logs.

For wrap logs, this is the base name of the files. Each file in a wrap log is called <FileName>.N, where N is an integer. Each wrap log also has two files called <FileName>.idx and <FileName>.siz.

For rotate logs, this is the name of the active log file. The compressed files are named as <FileName>.N.gz, where N is an integer and <FileName>.0.gz is the latest compressed log file. All the compressed files are renamed at each rotation so that the latest files have the smallest index. The maximum value for N is the value of MaxNoFiles minus 1.

{linkto, LinkTo}
If LinkTo is a pid, it becomes an owner of the log. If LinkTo is none, the log records that it is used anonymously by some process by incrementing the users counter. By default, the process that calls open/1 owns the log.

{repair, Repair} - If Repair is true, the current log file is repaired, if needed. As the restoration is initiated, a message is output on the error log. If false is specified, no automatic repair is attempted. Instead, the tuple {error, {need_repair, Log}} is returned if an attempt is made to open a corrupt log file. If truncate is specified, the log file becomes truncated, creating an empty log, regardless of previous content. Defaults to true, which has no effect on logs opened in read-only mode.

{type, Type} - The log type. Defaults to halt.

{format, Format} - Disk log format. Defaults to internal.

{size, Size} - Log size.

When a halt log has reached its maximum size, all attempts to log more items are rejected. Defaults to infinity, which for halt implies that there is no maximum size.

For wrap and rotate logs, parameter Size can be a pair {MaxNoBytes, MaxNoFiles}. For wrap logs it can also be infinity. In the latter case, if the files of an existing wrap log with the same name can be found, the size is read from the existing wrap log, otherwise an error is returned.

Wrap logs write at most MaxNoBytes bytes on each file and use MaxNoFiles files before starting all over with the first wrap log file. Regardless of MaxNoBytes, at least the header (if there is one) and one item are written on each wrap log file before wrapping to the next file.

The first time an existing wrap log is opened, that is, when the disk log process is created, the value of the option size is allowed to differ from the current log size, and the size of the disk log is changed as per change_size/2.

When opening an existing wrap log, it is not necessary to supply a value for option size, but if the log is already open, that is, the disk log process exists, the supplied value must equal the current log size, otherwise the tuple {error, {size_mismatch, CurrentSize, NewSize}} is returned.

Note

Before Erlang/OTP 24.0, the supplied value of option size was to be equal to the current log size when opening an existing wrap log for the first time, that is, when creating the disk log process.

Rotate logs write at most MaxNoBytes bytes on the active log file and keep the latest MaxNoFiles compressed files. Regardless of MaxNoBytes, at least the header (if there is one) and one item are written on each rotate log file before rotation.

When opening an already open halt log, option size is ignored.

{notify, boolean()} - If true, the log owners are notified when certain log events occur. Defaults to false. The owners are sent one of the following messages when an event occurs:

{disk_log, Node, Log, {wrap, NoLostItems}} - Sent when a wrap log has filled up one of its files and a new file is opened. NoLostItems is the number of previously logged items that were lost when truncating existing files.

{disk_log, Node, Log, {truncated, NoLostItems}} - Sent when a log is truncated or reopened. For halt logs NoLostItems is the number of items written on the log since the disk log process was created. For wrap logs NoLostItems is the number of items on all wrap log files.

{disk_log, Node, Log, {read_only, Items}} - Sent when an asynchronous log attempt is made to a log file opened in read-only mode. Items is the items from the log attempt.

{disk_log, Node, Log, {blocked_log, Items}} - Sent when an asynchronous log attempt is made to a blocked log that does not queue log attempts. Items is the items from the log attempt.

{disk_log, Node, Log, {format_external, Items}} - Sent when function alog/2 or alog_terms/2 is used for internally formatted logs. Items is the items from the log attempt.

{disk_log, Node, Log, full} - Sent when an attempt to log items to a wrap log would write more bytes than the limit set by option size.

{disk_log, Node, Log, {error_status, Status}} - Sent when the error status changes. The error status is defined by the outcome of the last attempt to log items to the log, or to truncate the log, or the last use of function sync/1, inc_wrap_file/1, or change_size/2. Status is either ok or {error, Error}, the former is the initial value.

{head, Head} - Specifies a header to be written first on the log file. If the log is a wrap or rotate log, the item Head is written first in each new file. Head is to be a term if the format is internal, otherwise an iodata/0. Defaults to none, which means that no header is written first on the file.

{head_func, {M,F,A}} - Specifies a function to be called each time a new log file is opened. The call M:F(A) is assumed to return {ok, Head}. The item Head is written first in each file. Head is to be a term if the format is internal, otherwise an iodata/0.

{mode, Mode} - Specifies if the log is to be opened in read-only or read-write mode. Defaults to read_write.

{quiet, Boolean} - Specifies if messages will be sent to error_logger on recoverable errors with the log files. Defaults to false.

open/1 returns {ok, Log} if the log file is successfully opened. If the file is successfully repaired, the tuple {repaired, Log, {recovered, Rec}, {badbytes, Bad}} is returned, where Rec is the number of whole Erlang terms found in the file and Bad is the number of bytes in the file that are non-Erlang terms.

When a disk log is opened in read-write mode, any existing log file is checked for. If there is none, a new empty log is created, otherwise the existing file is opened at the position after the last logged item, and the logging of items starts from there. If the format is internal and the existing file is not recognized as an internally formatted log, a tuple {error, {not_a_log_file, FileName}} is returned.

open/1 cannot be used for changing the values of options of an open log. When there are prior owners or users of a log, all option values except name, linkto, and notify are only checked against the values supplied before as option values to function open/1, change_header/2, change_notify/3, or change_size/2. Thus, none of the options except name is mandatory. If some specified value differs from the current value, a tuple {error, {arg_mismatch, OptionName, CurrentValue, Value}} is returned.

Note

If an owner attempts to open a log as owner once again, it is acknowledged with the return value {ok, Log}, but the state of the disk log is not affected.

A log file can be opened more than once by giving different values to option name or by using the same file when opening a log on different nodes. It is up to the user of module disk_log to ensure that not more than one disk log process has write access to any file, otherwise the file can be corrupted.

If an attempt to open a log file for the first time fails, the disk log process terminates with the EXIT message {{failed,Reason},[{disk_log,open,1}]}. The function returns {error, Reason} for all other errors.

pid2name(Pid)

-spec pid2name(Pid) -> {ok, Log} | undefined when Pid :: pid(), Log :: log().

Returns the log name given the pid of a disk log process on the current node, or undefined if the specified pid is not a disk log process.

This function is meant to be used for debugging only.

reopen(Log, File)

-spec reopen(Log, File) -> ok | {error, reopen_error_rsn()} when Log :: log(), File :: file:filename().

Equivalent to reopen(Log, File, Head) where Head is the Head specified in open/1.

reopen(Log, File, Head)

-spec reopen(Log, File, Head) -> ok | {error, reopen_error_rsn()}
                when Log :: log(), File :: file:filename(), Head :: term().

Renames an internally formatted log file to File and then recreates a new log file. If a wrap/rotate log exists, File is used as the base name of the renamed files.

Writes the value of Head first in the newly opened log file. The header argument is used only once. Next time a wrap/rotate log file is opened, the header given to open/1 is used.

Owners subscribing to notifications receive a truncate message.

Upon failure to reopen the log, the disk log process terminates with the EXIT message {{failed,Error},[{disk_log,Fun,Arity}]}. Other processes having requests queued receive the message {disk_log, Node, {error, disk_log_stopped}}.

sync(Log)

-spec sync(Log) -> ok | {error, sync_error_rsn()} when Log :: log().

Ensures that the contents of the log are written to the disk. This is usually a rather expensive operation.

truncate(Log)

-spec truncate(Log) -> ok | {error, trunc_error_rsn()} when Log :: log().

Equivalent to truncate(Log, Head) where Head is the Head specified in open/1.

This function can be used for both internally and externally formatted logs.

truncate(Log, Head)

-spec truncate(Log, Head) -> ok | {error, trunc_error_rsn()} when Log :: log(), Head :: term().

Removes all items from an internally formatted disk log. The argument Head or is written first in the newly truncated log.

The header argument is used only once. Next time a wrap/rotate log file is opened, the header given to open/1 is used.

Owners subscribing to notifications receive a truncate message.

If the attempt to truncate the log fails, the disk log process terminates with the EXIT message {{failed,Reason},[{disk_log,Fun,Arity}]}. Other processes having requests queued receive the message {disk_log, Node, {error, disk_log_stopped}}.

unblock(Log)

-spec unblock(Log) -> ok | {error, unblock_error_rsn()} when Log :: log().

Unblocks a log. A log can only be unblocked by the blocking process.

error_logger

Erlang error logger.

Note

In Erlang/OTP 21.0, a new API for logging was added. The old error_logger module can still be used by legacy code, but log events are redirected to the new Logger API. New code should use the Logger API directly.

error_logger is no longer started by default, but is automatically started when an event handler is added with error_logger:add_report_handler/1,2. The error_logger module is then also added as a handler to the new logger.

See logger and the Logging chapter in the User's Guide for more information.

The Erlang error logger is an event manager (see OTP Design Principles and gen_event), registered as error_logger.

Error logger is no longer started by default, but is automatically started when an event handler is added with add_report_handler/1,2. The error_logger module is then also added as a handler to the new logger, causing log events to be forwarded from logger to error logger, and consequently to all installed error logger event handlers.

User-defined event handlers can be added to handle application-specific events.

Existing event handlers provided by STDLIB and SASL are still available, but are no longer used by OTP.

Warning events were introduced in Erlang/OTP R9C and are enabled by default as from Erlang/OTP 18.0. To retain backwards compatibility with existing user-defined event handlers, the warning events can be tagged as errors or info using command-line flag +W <e | i | w>, thus showing up as ERROR REPORT or INFO REPORT in the logs.

Events

All event handlers added to the error logger must handle the following events. Gleader is the group leader pid of the process that sent the event, and Pid is the process that sent the event.

{error, Gleader, {Pid, Format, Data}} - Generated when error_msg/1,2 or format/2 is called.

{error_report, Gleader, {Pid, std_error, Report}} - Generated when error_report/1 is called.

{error_report, Gleader, {Pid, Type, Report}} - Generated when error_report/2 is called.

{warning_msg, Gleader, {Pid, Format, Data}} - Generated when warning_msg/1,2 is called if warnings are set to be tagged as warnings.

{warning_report, Gleader, {Pid, std_warning, Report}} - Generated when warning_report/1 is called if warnings are set to be tagged as warnings.

{warning_report, Gleader, {Pid, Type, Report}} - Generated when warning_report/2 is called if warnings are set to be tagged as warnings.

{info_msg, Gleader, {Pid, Format, Data}} - Generated when info_msg/1,2 is called.

{info_report, Gleader, {Pid, std_info, Report}} - Generated when info_report/1 is called.

{info_report, Gleader, {Pid, Type, Report}} - Generated when info_report/2 is called.

Notice that some system-internal events can also be received. Therefore a catch-all clause last in the definition of the event handler callback function gen_event:handle_event/2 is necessary. This also applies for gen_event:handle_info/2, as the event handler must also take care of some system-internal messages.

See Also

gen_event, logger, log_mf_h, kernel, sasl

Summary

Types

open_error()

report()

Functions

add_report_handler(Handler)

Equivalent to add_report_handler(Handler, []).

add_report_handler(Handler, Args)

Adds a new event handler to the error logger. The event handler must be implemented as a gen_event callback module.

delete_report_handler(Handler)

Deletes an event handler from the error logger by calling gen_event:delete_handler(error_logger, Handler, []).

error_msg(Format)

Equivalent to error_msg(Format, []).

error_msg(Format, Data)

Log a standard error event. The Format and Data arguments are the same as the arguments of io:format/2 in STDLIB.

error_report(Report)

Log a standard error event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

error_report(Type, Report)

Log a user-defined error event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

format(Format, Data)

Equivalent to error_msg(Format, Data).

get_format_depth()

Returns max(10, Depth), where Depth is the value of error_logger_format_depth in the Kernel application, if Depth is an integer. Otherwise, unlimited is returned.

info_msg(Format)

Equivalent to info_msg(Format, []).

info_msg(Format, Data)

Log a standard information event. The Format and Data arguments are the same as the arguments of io:format/2 in STDLIB.

info_report(Report)

Log a standard information event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

info_report(Type, Report)

Log a user-defined information event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

logfile/1

Enables or disables printout of standard events to a file.

tty(Flag)

Enables (Flag == true) or disables (Flag == false) printout of standard events to the terminal.

warning_map()

Returns the current mapping for warning events.

warning_msg(Format)

Equivalent to warning_msg(Format, []).

warning_msg(Format, Data)

Log a standard warning event. The Format and Data arguments are the same as the arguments of io:format/2 in STDLIB.

warning_report(Report)

Log a standard warning event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

warning_report(Type, Report)

Log a user-defined warning event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

Types

open_error()

(not exported)

-type open_error() :: file:posix() | badarg | system_limit.

report()

(not exported)

-type report() :: [{Tag :: term(), Data :: term()} | term()] | string() | term().

Functions

add_report_handler(Handler)

-spec add_report_handler(Handler) -> any() when Handler :: module().

Equivalent to add_report_handler(Handler, []).

add_report_handler(Handler, Args)

-spec add_report_handler(Handler, Args) -> Result
                            when
                                Handler :: module(),
                                Args :: gen_event:handler_args(),
                                Result :: gen_event:add_handler_ret().

Adds a new event handler to the error logger. The event handler must be implemented as a gen_event callback module.

Handler is typically the name of the callback module and Args is an optional term (defaults to []) passed to the initialization callback function gen_event:init/1. The function returns ok if successful.

The event handler must be able to handle the events in this module, see section Events.

The first time this function is called, error_logger is added as a Logger handler, and the error_logger process is started.

delete_report_handler(Handler)

-spec delete_report_handler(Handler) -> Result
                               when Handler :: module(), Result :: gen_event:del_handler_ret().

Deletes an event handler from the error logger by calling gen_event:delete_handler(error_logger, Handler, []).

If no more event handlers exist after the deletion, error_logger is removed as a Logger handler, and the error_logger process is stopped.

error_msg(Format)

-spec error_msg(Format) -> ok when Format :: string().

Equivalent to error_msg(Format, []).

error_msg(Format, Data)

-spec error_msg(Format, Data) -> ok when Format :: string(), Data :: list().

Log a standard error event. The Format and Data arguments are the same as the arguments of io:format/2 in STDLIB.

Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

The event is handled by the default Logger handler.

This function is kept for backwards compatibility and must not be used by new code. Use the ?LOG_ERROR macro or logger:error/1,2,3 instead.

Example:

1> error_logger:error_msg("An error occurred in ~p", [a_module]).
=ERROR REPORT==== 22-May-2018::11:18:43.376917 ===
An error occurred in a_module
ok

Warning

If the Unicode translation modifier (t) is used in the format string, all event handlers must ensure that the formatted output is correctly encoded for the I/O device.

error_report(Report)

-spec error_report(Report) -> ok when Report :: report().

Log a standard error event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

The event is handled by the default Logger handler.

This functions is kept for backwards compatibility and must not be used by new code. Use the ?LOG_ERROR macro or logger:error/1,2,3 instead.

Example:

2> error_logger:error_report([{tag1,data1},a_term,{tag2,data}]).
=ERROR REPORT==== 22-May-2018::11:24:23.699306 ===
    tag1: data1
    a_term
    tag2: data
ok
3> error_logger:error_report("Serious error in my module").
=ERROR REPORT==== 22-May-2018::11:24:45.972445 ===
Serious error in my module
ok

error_report(Type, Report)

-spec error_report(Type, Report) -> ok when Type :: term(), Report :: report().

Log a user-defined error event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

Error logger also adds a domain field with value [Type] to this event's metadata, causing the filters of the default Logger handler to discard the event. A different Logger handler, or an error logger event handler, must be added to handle this event.

It is recommended that Report follows the same structure as for error_report/1.

This functions is kept for backwards compatibility and must not be used by new code. Use the ?LOG_ERROR macro or logger:error/1,2,3 instead.

format(Format, Data)

-spec format(Format, Data) -> ok when Format :: string(), Data :: list().

Equivalent to error_msg(Format, Data).

get_format_depth()

(since OTP 20.0)

-spec get_format_depth() -> unlimited | pos_integer().

Returns max(10, Depth), where Depth is the value of error_logger_format_depth in the Kernel application, if Depth is an integer. Otherwise, unlimited is returned.

Note

The error_logger_format_depth variable is deprecated since the Logger API was introduced in Erlang/OTP 21.0. The variable, and this function, are kept for backwards compatibility since they still might be used by legacy report handlers.

info_msg(Format)

-spec info_msg(Format) -> ok when Format :: string().

Equivalent to info_msg(Format, []).

info_msg(Format, Data)

-spec info_msg(Format, Data) -> ok when Format :: string(), Data :: list().

Log a standard information event. The Format and Data arguments are the same as the arguments of io:format/2 in STDLIB.

Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

The event is handled by the default Logger handler.

These functions are kept for backwards compatibility and must not be used by new code. Use the ?LOG_INFO macro or logger:info/1,2,3 instead.

Example:

1> error_logger:info_msg("Something happened in ~p", [a_module]).
=INFO REPORT==== 22-May-2018::12:03:32.612462 ===
Something happened in a_module
ok

Warning

If the Unicode translation modifier (t) is used in the format string, all event handlers must ensure that the formatted output is correctly encoded for the I/O device.

info_report(Report)

-spec info_report(Report) -> ok when Report :: report().

Log a standard information event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

The event is handled by the default Logger handler.

This functions is kept for backwards compatibility and must not be used by new code. Use the ?LOG_INFO macro or logger:info/1,2,3 instead.

Example:

2> error_logger:info_report([{tag1,data1},a_term,{tag2,data}]).
=INFO REPORT==== 22-May-2018::12:06:35.994440 ===
    tag1: data1
    a_term
    tag2: data
ok
3> error_logger:info_report("Something strange happened").
=INFO REPORT==== 22-May-2018::12:06:49.066872 ===
Something strange happened
ok

info_report(Type, Report)

-spec info_report(Type, Report) -> ok when Type :: any(), Report :: report().

Log a user-defined information event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

Error logger also adds a domain field with value [Type] to this event's metadata, causing the filters of the default Logger handler to discard the event. A different Logger handler, or an error logger event handler, must be added to handle this event.

It is recommended that Report follows the same structure as for info_report/1.

This functions is kept for backwards compatibility and must not be used by new code. Use the ?LOG_INFO macro or logger:info/1,2,3 instead.

logfile/1

-spec logfile(Request :: {open, Filename}) -> ok | {error, OpenReason}
                 when Filename :: file:name(), OpenReason :: allready_have_logfile | open_error();
             (Request :: close) -> ok | {error, CloseReason} when CloseReason :: module_not_found;
             (Request :: filename) -> Filename | {error, FilenameReason}
                 when Filename :: file:name(), FilenameReason :: no_log_file.

Enables or disables printout of standard events to a file.

This is done by adding or deleting the error_logger_file_h event handler, and thus indirectly adding error_logger as a Logger handler.

Notice that this function does not manipulate the Logger configuration directly, meaning that if the default Logger handler is already logging to a file, this function can potentially cause logging to a second file.

This function is useful as a shortcut during development and testing, but must not be used in a production system. See section Logging in the Kernel User's Guide, and the logger manual page for information about how to configure Logger for live systems.

Request is one of the following:

{open, Filename} - Opens log file Filename. Returns ok if successful, or {error, allready_have_logfile} if logging to file is already enabled, or an error tuple if another error occurred (for example, if Filename cannot be opened). The file is opened with encoding UTF-8.

close - Closes the current log file. Returns ok, or {error, module_not_found}.

filename - Returns the name of the log file Filename, or {error, no_log_file} if logging to file is not enabled.

tty(Flag)

-spec tty(Flag) -> ok when Flag :: boolean().

Enables (Flag == true) or disables (Flag == false) printout of standard events to the terminal.

This is done by manipulating the Logger configuration. The function is useful as a shortcut during development and testing, but must not be used in a production system. See section Logging in the Kernel User's Guide, and the logger manual page for information about how to configure Logger for live systems.

warning_map()

-spec warning_map() -> Tag when Tag :: error | warning | info.

Returns the current mapping for warning events.

Events sent using warning_msg/1,2 or warning_report/1,2 are tagged as errors, warnings (default), or info, depending on the value of command-line flag +W.

Example:

os$ erl
Erlang (BEAM) emulator version 5.4.8 [hipe] [threads:0] [kernel-poll]

Eshell V5.4.8  (abort with ^G)
1> error_logger:warning_map().
warning
2> error_logger:warning_msg("Warnings tagged as: ~p~n", [warning]).

=WARNING REPORT==== 11-Aug-2005::15:31:55 ===
Warnings tagged as: warning
ok
3>
User switch command
 --> q
os$ erl +W e
Erlang (BEAM) emulator version 5.4.8 [hipe] [threads:0] [kernel-poll]

Eshell V5.4.8  (abort with ^G)
1> error_logger:warning_map().
error
2> error_logger:warning_msg("Warnings tagged as: ~p~n", [error]).

=ERROR REPORT==== 11-Aug-2005::15:31:23 ===
Warnings tagged as: error
ok

warning_msg(Format)

-spec warning_msg(Format) -> ok when Format :: string().

Equivalent to warning_msg(Format, []).

warning_msg(Format, Data)

-spec warning_msg(Format, Data) -> ok when Format :: string(), Data :: list().

Log a standard warning event. The Format and Data arguments are the same as the arguments of io:format/2 in STDLIB.

Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

The event is handled by the default Logger handler. The log level can be changed to error or info, see warning_map/0.

These functions are kept for backwards compatibility and must not be used by new code. Use the ?LOG_WARNING macro or logger:warning/1,2,3 instead.

Warning

If the Unicode translation modifier (t) is used in the format string, all event handlers must ensure that the formatted output is correctly encoded for the I/O device.

warning_report(Report)

-spec warning_report(Report) -> ok when Report :: report().

Log a standard warning event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

The event is handled by the default Logger handler. The log level can be changed to error or info, see warning_map/0.

This functions is kept for backwards compatibility and must not be used by new code. Use the ?LOG_WARNING macro or logger:warning/1,2,3 instead.

warning_report(Type, Report)

-spec warning_report(Type, Report) -> ok when Type :: any(), Report :: report().

Log a user-defined warning event. Error logger forwards the event to Logger, including metadata that allows backwards compatibility with legacy error logger event handlers.

Error logger also adds a domain field with value [Type] to this event's metadata, causing the filters of the default Logger handler to discard the event. A different Logger handler, or an error logger event handler, must be added to handle this event.

The log level can be changed to error or info, see warning_map/0.

It is recommended that Report follows the same structure as for warning_report/1.

This functions is kept for backwards compatibility and must not be used by new code. Use the ?LOG_WARNING macro or logger:warning/1,2,3 instead.

logger

API module for Logger, the standard logging facility in Erlang/OTP.

This module implements the main API for logging in Erlang/OTP. To create a log event, use the API functions or the log macros, for example:

?LOG_ERROR("error happened because: ~p", [Reason]).   % With macro
logger:error("error happened because: ~p", [Reason]). % Without macro

To configure the Logger backend, use Kernel configuration parameters or configuration functions in the logger API.

By default, the Kernel application installs one log handler at system start. This handler is named default. It receives and processes standard log events produced by the Erlang runtime system, standard behaviours and different Erlang/OTP applications. The log events are by default printed to the terminal.

If you want your systems logs to be printed to a file instead, you must configure the default handler to do so. The simplest way is to include the following in your sys.config:

[{kernel,
  [{logger,
    [{handler, default, logger_std_h,
      #{config => #{file => "path/to/file.log"}}}]}]}].

For more information about:

the Logger facility in general, see the User's Guide.

how to configure Logger, see the Configuration section in the User's Guide.

the built-in handlers, see logger_std_h and logger_disk_log_h.

the built-in formatter, see logger_formatter.

built-in filters, see logger_filters.

Macros

The following macros are defined in logger.hrl, which is included in a module with the directive

    -include_lib("kernel/include/logger.hrl").

?LOG_EMERGENCY(StringOrReport[,Metadata])

?LOG_EMERGENCY(FunOrFormat,Args[,Metadata])

?LOG_ALERT(StringOrReport[,Metadata])

?LOG_ALERT(FunOrFormat,Args[,Metadata])

?LOG_CRITICAL(StringOrReport[,Metadata])

?LOG_CRITICAL(FunOrFormat,Args[,Metadata])

?LOG_ERROR(StringOrReport[,Metadata])

?LOG_ERROR(FunOrFormat,Args[,Metadata])

?LOG_WARNING(StringOrReport[,Metadata])

?LOG_WARNING(FunOrFormat,Args[,Metadata])

?LOG_NOTICE(StringOrReport[,Metadata])

?LOG_NOTICE(FunOrFormat,Args[,Metadata])

?LOG_INFO(StringOrReport[,Metadata])

?LOG_INFO(FunOrFormat,Args[,Metadata])

?LOG_DEBUG(StringOrReport[,Metadata])

?LOG_DEBUG(FunOrFormat,Args[,Metadata])

?LOG(Level,StringOrReport[,Metadata])

?LOG(Level,FunOrFormat,Args[,Metadata])

All macros expand to a call to Logger, where Level is taken from the macro name, or from the first argument in the case of the ?LOG macro. Location data is added to the metadata as described under the metadata/0 type definition.

The call is wrapped in a case statement and will be evaluated only if Level is equal to or below the configured log level.

See Also

config, erlang, io, logger_disk_log_h, logger_filters, logger_handler, logger_formatter, logger_std_h, unicode

Summary

Types

config_handler()

Configuration used when adding or updating a handler.

filter()

A filter which can be installed as a handler filter, or as a primary filter in Logger.

filter_arg()

The second argument to the filter fun.

filter_id()

A unique identifier for a filter.

filter_return()

The return value from the filter fun.

formatter_config()

Configuration data for the formatter. See logger_formatter for an example of a formatter implementation.

handler_config()

Handler configuration data for Logger.

handler_id()

A unique identifier for a handler instance.

level()

The severity level for the message to be logged.

log_event()

A log event passed to filters and handlers

metadata()

Metadata for the log event.

msg_fun()

msg_fun_return()

olp_config()

Overload protection configuration.

primary_config()

Primary configuration data for Logger. The following default values apply

report()

A log report.

report_cb()

A fun which converts a report() to a format string and arguments, or directly to a string.

report_cb_config()

timestamp()

A timestamp produced with logger:timestamp().

Logging API functions

alert(StringOrReport)

Equivalent to alert(StringOrReport, #{}).

alert(FormatOrFun, Args)

Create a alert log event.

alert(FormatOrFun, Args, Metadata)

Equivalent to log(alert, FormatOrFun, Args, Metadata).

critical(StringOrReport)

Equivalent to critical(StringOrReport, #{}).

critical(FormatOrFun, Args)

Create a critical log event.

critical(FormatOrFun, Args, Metadata)

Equivalent to log(critical, FormatOrFun, Args, Metadata).

debug(StringOrReport)

Equivalent to debug(StringOrReport, #{}).

debug(FormatOrFun, Args)

Create a debug log event.

debug(FormatOrFun, Args, Metadata)

Equivalent to log(debug, FormatOrFun, Args, Metadata).

emergency(StringOrReport)

Equivalent to emergency(StringOrReport, #{}).

emergency(FormatOrFun, Args)

Create a emergency log event.

emergency(FormatOrFun, Args, Metadata)

Equivalent to log(emergency, FormatOrFun, Args, Metadata).

error(StringOrReport)

Equivalent to error(StringOrReport, #{}).

error(FormatOrFun, Args)

Create a error log event.

error(FormatOrFun, Args, Metadata)

Equivalent to log(error, FormatOrFun, Args, Metadata).

info(StringOrReport)

Equivalent to info(StringOrReport, #{}).

info(FormatOrFun, Args)

Create a info log event.

info(FormatOrFun, Args, Metadata)

Equivalent to log(info, FormatOrFun, Args, Metadata).

log(Level, StringOrReport)

Equivalent to log(Level, StringOrReport, #{}).

log/3

Create a log event at the given log level, with the given message to be logged and metadata.

log(Level, FunOrFormat, Args, Metadata)

Create a log event at the given log level, with the given message to be logged and metadata.

notice(StringOrReport)

Equivalent to notice(StringOrReport, #{}).

notice(FormatOrFun, Args)

Create a notice log event.

notice(FormatOrFun, Args, Metadata)

Equivalent to log(notice, FormatOrFun, Args, Metadata).

warning(StringOrReport)

Equivalent to warning(StringOrReport, #{}).

warning(FormatOrFun, Args)

Create a warning log event.

warning(FormatOrFun, Args, Metadata)

Equivalent to log(warning, FormatOrFun, Args, Metadata).

Functions

add_handler(HandlerId, Module, Config)

Add a handler with the given configuration.

add_handler_filter(HandlerId, FilterId, Filter)

Add a filter to the specified handler.

add_handlers/1

Reads the application configuration parameter logger and calls add_handlers/1 with its contents.

add_primary_filter(FilterId, Filter)

Add a primary filter to Logger.

compare_levels(Level1, Level2)

Compare the severity of two log levels. Returns gt if Level1 is more severe than Level2, lt if Level1 is less severe, and eq if the levels are equal.

format_report(Report)

Convert a log message on report form to {Format, Args}. This is the default report callback used by logger_formatter when no custom report callback is found. See section Log Message in the Kernel User's Guide for information about report callbacks and valid forms of log messages.

get_config()

Look up all current Logger configuration, including primary, handler, and proxy configuration, and module level settings.

get_handler_config()

Look up the current configuration for all handlers.

get_handler_config(HandlerId)

Look up the current configuration for the given handler.

get_handler_ids()

Look up the identities for all installed handlers.

get_module_level()

Look up all current module levels. Returns a list containing one {Module,Level} element for each module for which the module level was previously set with set_module_level/2.

get_module_level(Modules)

Look up the current level for the given modules. Returns a list containing one {Module,Level} element for each of the given modules for which the module level was previously set with set_module_level/2.

get_primary_config()

Look up the current primary configuration for Logger.

get_process_metadata()

Retrieve data set with set_process_metadata/1 or update_process_metadata/1.

get_proxy_config()

Look up the current configuration for the Logger proxy.

i()

Pretty print all Logger configuration.

i(What)

Pretty print the Logger configuration.

reconfigure()

Reconfigure Logger using updated kernel configuration that was set after kernel application was loaded.

remove_handler(HandlerId)

Remove the handler identified by HandlerId.

remove_handler_filter(HandlerId, FilterId)

Remove the filter identified by FilterId from the handler identified by HandlerId.

remove_primary_filter(FilterId)

Remove the primary filter identified by FilterId from Logger.

set_application_level(Application, Level)

Set the log level for all the modules of the specified application.

set_handler_config(HandlerId, Config)

Set configuration data for the specified handler. This overwrites the current handler configuration.

set_handler_config(HandlerId, Key, Value)

Add or update configuration data for the specified handler. If the given Key already exists, its associated value will be changed to the given value. If it does not exist, it will be added.

set_module_level(Modules, Level)

Set the log level for the specified modules.

set_primary_config(Config)

Set primary configuration data for Logger. This overwrites the current configuration.

set_primary_config(Key, Value)

Add or update primary configuration data for Logger. If the given Key already exists, its associated value will be changed to the given value. If it does not exist, it will be added.

set_process_metadata(Meta)

Set metadata which Logger shall automatically insert in all log events produced on the current process.

set_proxy_config(Config)

Set configuration data for the Logger proxy. This overwrites the current proxy configuration. Keys that are not specified in the Config map gets default values.

timestamp()

Return a timestamp that can be inserted as the time field in the meta data for a log event. It is produced with os:system_time(microsecond).

unset_application_level(Application)

Unset the log level for all the modules of the specified application.

unset_module_level()

Remove module specific log settings. After this, the primary log level is used for all modules.

unset_module_level(Modules)

Remove module specific log settings. After this, the primary log level is used for the specified modules.

unset_process_metadata()

Delete data set with set_process_metadata/1 or update_process_metadata/1.

update_formatter_config(HandlerId, FormatterConfig)

Update the formatter configuration for the specified handler.

update_formatter_config(HandlerId, Key, Value)

Equivalent to update_formatter_config(HandlerId, #{Key => Value}).

update_handler_config(HandlerId, Config)

Update configuration data for the specified handler. This function behaves as if it was implemented as follows

update_handler_config(HandlerId, Key, Value)

Add or update configuration data for the specified handler. If the given Key already exists, its associated value will be changed to the given value. If it does not exist, it will be added.

update_primary_config(Config)

Update primary configuration data for Logger. This function behaves as if it was implemented as follows

update_process_metadata(Meta)

Set or update metadata to use when logging from current process

update_proxy_config(Config)

Update configuration data for the Logger proxy. This function behaves as if it was implemented as follows

Types

config_handler()

(since OTP 21.0)

-type config_handler() :: {handler, logger_handler:id(), module(), logger_handler:config()}.

Configuration used when adding or updating a handler.

filter()

(since OTP 21.0)

-type filter() :: {fun((log_event(), filter_arg()) -> filter_return()), filter_arg()}.

A filter which can be installed as a handler filter, or as a primary filter in Logger.

filter_arg()

(since OTP 21.0)

-type filter_arg() :: term().

The second argument to the filter fun.

filter_id()

(since OTP 21.0)

-type filter_id() :: atom().

A unique identifier for a filter.

filter_return()

(since OTP 21.0)

-type filter_return() :: stop | ignore | log_event().

The return value from the filter fun.

formatter_config()

(since OTP 21.0)

-type formatter_config() :: #{atom() => term()}.

Configuration data for the formatter. See logger_formatter for an example of a formatter implementation.

handler_config()

(since OTP 21.0)

-type handler_config() :: logger_handler:config().

Handler configuration data for Logger.

Note

DEPRECATED: Use logger_handler:config/0 instead.

handler_id()

(since OTP 21.0)

-type handler_id() :: logger_handler:id().

A unique identifier for a handler instance.

Note

DEPRECATED: Use logger_handler:id/0 instead.

level()

(since OTP 21.0)

-type level() :: emergency | alert | critical | error | warning | notice | info | debug.

The severity level for the message to be logged.

log_event()

(since OTP 21.0)

-type log_event() ::
          #{level := level(),
            msg := {io:format(), [term()]} | {report, report()} | {string, unicode:chardata()},
            meta := metadata()}.

A log event passed to filters and handlers

metadata()

(since OTP 21.0)

-type metadata() ::
          #{pid => pid(),
            gl => pid(),
            time => timestamp(),
            mfa => {module(), atom(), non_neg_integer()},
            file => file:filename(),
            line => non_neg_integer(),
            domain => [atom()],
            report_cb => report_cb(),
            atom() => term()}.

Metadata for the log event.

Logger adds the following metadata to each log event:

pid => self()

gl => group_leader()

time => logger:timestamp()

When a log macro is used, Logger also inserts location information:

mfa => {?MODULE, ?FUNCTION_NAME, ?FUNCTION_ARITY}

file => ?FILE

line => ?LINE

You can add custom metadata, either by:

specifying a map as the last parameter to any of the log macros or the logger API functions.

setting process metadata with set_process_metadata/1 or update_process_metadata/1.

setting primary metadata with set_primary_config/1 or through the kernel configuration parameter logger_metadata

Note

When adding custom metadata, make sure not to use any of the keys mentioned above as that may cause a lot of confusion about the log events.

Logger merges all the metadata maps before forwarding the log event to the handlers. If the same keys occur, values from the log call overwrite process metadata, which overwrites the primary metadata, which in turn overwrite values set by Logger.

The following custom metadata keys have special meaning:

domain - The value associated with this key is used by filters for grouping log events originating from, for example, specific functional areas. See logger_filters:domain/2 for a description of how this field can be used.

report_cb - If the log message is specified as a report/0, the report_cb key can be associated with a fun (report callback) that converts the report to a format string and arguments, or directly to a string. See the type definition of report_cb/0, and section Log Message in the User's Guide for more information about report callbacks.

msg_fun()

(since OTP 21.0)

-type msg_fun() :: fun((term()) -> msg_fun_return() | {msg_fun_return(), metadata()}).

msg_fun_return()

(not exported) (since OTP 21.0)

-type msg_fun_return() :: {io:format(), [term()]} | report() | unicode:chardata() | ignore.

olp_config()

(since OTP 21.0)

-type olp_config() :: logger_handler:olp_config().

Overload protection configuration.

Note

DEPRECATED: Use logger_handler:olp_config/0 instead.

primary_config()

(since OTP 21.0)

-type primary_config() ::
          #{level => level() | all | none,
            metadata => metadata(),
            filter_default => log | stop,
            filters => [{filter_id(), filter()}]}.

Primary configuration data for Logger. The following default values apply:

level => info

filter_default => log

filters => []

report()

(since OTP 21.0)

-type report() :: map() | [{atom(), term()}, ...].

A log report.

report_cb()

(since OTP 21.0)

-type report_cb() ::
          fun((report()) -> {io:format(), [term()]}) |
          fun((report(), report_cb_config()) -> unicode:chardata()).

A fun which converts a report() to a format string and arguments, or directly to a string.

See section Log Message in the User's Guide for more information.

report_cb_config()

(since OTP 21.0)

-type report_cb_config() ::
          #{depth := pos_integer() | unlimited,
            chars_limit := pos_integer() | unlimited,
            single_line := boolean()}.

timestamp()

(since OTP 21.0)

-type timestamp() :: integer().

A timestamp produced with logger:timestamp().

Logging API functions

alert(StringOrReport)

(since OTP 21.0)

-spec alert(String :: unicode:chardata()) -> ok;
           (Report :: report()) -> ok.

Equivalent to alert(StringOrReport, #{}).

alert(FormatOrFun, Args)

(since OTP 21.0)

-spec alert(String :: unicode:chardata(), Metadata :: metadata()) -> ok;
           (Report :: report(), Metadata :: metadata()) -> ok;
           (Format :: io:format(), Args :: [term()]) -> ok;
           (Fun :: msg_fun(), FunArgs :: term()) -> ok.

Create a alert log event.

Equivalent to log(alert, StringOrReport, Metadata) if called as alert(StringOrReport, Metadata).

Equivalent to alert(FormatOrFun, Args, #{}) if called as alert(FormatOrFun, Args).

alert(FormatOrFun, Args, Metadata)

(since OTP 21.0)

-spec alert(Format :: io:format(), Args :: [term()], Metadata :: metadata()) -> ok;
           (Fun :: msg_fun(), FunArgs :: term(), Metadata :: metadata()) -> ok.

Equivalent to log(alert, FormatOrFun, Args, Metadata).

critical(StringOrReport)

(since OTP 21.0)

-spec critical(String :: unicode:chardata()) -> ok;
              (Report :: report()) -> ok.

Equivalent to critical(StringOrReport, #{}).

critical(FormatOrFun, Args)

(since OTP 21.0)

-spec critical(String :: unicode:chardata(), Metadata :: metadata()) -> ok;
              (Report :: report(), Metadata :: metadata()) -> ok;
              (Format :: io:format(), Args :: [term()]) -> ok;
              (Fun :: msg_fun(), FunArgs :: term()) -> ok.

Create a critical log event.

Equivalent to log(critical, StringOrReport, Metadata) if called as critical(StringOrReport, Metadata).

Equivalent to critical(FormatOrFun, Args, #{}) if called as critical(FormatOrFun, Args).

critical(FormatOrFun, Args, Metadata)

(since OTP 21.0)

-spec critical(Format :: io:format(), Args :: [term()], Metadata :: metadata()) -> ok;
              (Fun :: msg_fun(), FunArgs :: term(), Metadata :: metadata()) -> ok.

Equivalent to log(critical, FormatOrFun, Args, Metadata).

debug(StringOrReport)

(since OTP 21.0)

-spec debug(String :: unicode:chardata()) -> ok;
           (Report :: report()) -> ok.

Equivalent to debug(StringOrReport, #{}).

debug(FormatOrFun, Args)

(since OTP 21.0)

-spec debug(String :: unicode:chardata(), Metadata :: metadata()) -> ok;
           (Report :: report(), Metadata :: metadata()) -> ok;
           (Format :: io:format(), Args :: [term()]) -> ok;
           (Fun :: msg_fun(), FunArgs :: term()) -> ok.

Create a debug log event.

Equivalent to log(debug, StringOrReport, Metadata) if called as debug(StringOrReport, Metadata).

Equivalent to debug(FormatOrFun, Args, #{}) if called as debug(FormatOrFun, Args).

debug(FormatOrFun, Args, Metadata)

(since OTP 21.0)

-spec debug(Format :: io:format(), Args :: [term()], Metadata :: metadata()) -> ok;
           (Fun :: msg_fun(), FunArgs :: term(), Metadata :: metadata()) -> ok.

Equivalent to log(debug, FormatOrFun, Args, Metadata).

emergency(StringOrReport)

(since OTP 21.0)

-spec emergency(String :: unicode:chardata()) -> ok;
               (Report :: report()) -> ok.

Equivalent to emergency(StringOrReport, #{}).

emergency(FormatOrFun, Args)

(since OTP 21.0)

-spec emergency(String :: unicode:chardata(), Metadata :: metadata()) -> ok;
               (Report :: report(), Metadata :: metadata()) -> ok;
               (Format :: io:format(), Args :: [term()]) -> ok;
               (Fun :: msg_fun(), FunArgs :: term()) -> ok.

Create a emergency log event.

Equivalent to log(emergency, StringOrReport, Metadata) if called as emergency(StringOrReport, Metadata).

Equivalent to emergency(FormatOrFun, Args, #{}) if called as emergency(FormatOrFun, Args).

emergency(FormatOrFun, Args, Metadata)

(since OTP 21.0)

-spec emergency(Format :: io:format(), Args :: [term()], Metadata :: metadata()) -> ok;
               (Fun :: msg_fun(), FunArgs :: term(), Metadata :: metadata()) -> ok.

Equivalent to log(emergency, FormatOrFun, Args, Metadata).

error(StringOrReport)

(since OTP 21.0)

-spec error(String :: unicode:chardata()) -> ok;
           (Report :: report()) -> ok.

Equivalent to error(StringOrReport, #{}).

error(FormatOrFun, Args)

(since OTP 21.0)

-spec error(String :: unicode:chardata(), Metadata :: metadata()) -> ok;
           (Report :: report(), Metadata :: metadata()) -> ok;
           (Format :: io:format(), Args :: [term()]) -> ok;
           (Fun :: msg_fun(), FunArgs :: term()) -> ok.

Create a error log event.

Equivalent to log(error, StringOrReport, Metadata) if called as error(StringOrReport, Metadata).

Equivalent to error(FormatOrFun, Args, #{}) if called as error(FormatOrFun, Args).

error(FormatOrFun, Args, Metadata)

(since OTP 21.0)

-spec error(Format :: io:format(), Args :: [term()], Metadata :: metadata()) -> ok;
           (Fun :: msg_fun(), FunArgs :: term(), Metadata :: metadata()) -> ok.

Equivalent to log(error, FormatOrFun, Args, Metadata).

info(StringOrReport)

(since OTP 21.0)

-spec info(String :: unicode:chardata()) -> ok;
          (Report :: report()) -> ok.

Equivalent to info(StringOrReport, #{}).

info(FormatOrFun, Args)

(since OTP 21.0)

-spec info(String :: unicode:chardata(), Metadata :: metadata()) -> ok;
          (Report :: report(), Metadata :: metadata()) -> ok;
          (Format :: io:format(), Args :: [term()]) -> ok;
          (Fun :: msg_fun(), FunArgs :: term()) -> ok.

Create a info log event.

Equivalent to log(info, StringOrReport, Metadata) if called as info(StringOrReport, Metadata).

Equivalent to info(FormatOrFun, Args, #{}) if called as info(FormatOrFun, Args).

info(FormatOrFun, Args, Metadata)

(since OTP 21.0)

-spec info(Format :: io:format(), Args :: [term()], Metadata :: metadata()) -> ok;
          (Fun :: msg_fun(), FunArgs :: term(), Metadata :: metadata()) -> ok.

Equivalent to log(info, FormatOrFun, Args, Metadata).

log(Level, StringOrReport)

(since OTP 21.0)

-spec log(Level :: level(), String :: unicode:chardata()) -> ok;
         (Level :: level(), Report :: report()) -> ok.

Equivalent to log(Level, StringOrReport, #{}).

log/3

(since OTP 21.0)

-spec log(Level :: level(), String :: unicode:chardata(), Metadata :: metadata()) -> ok;
         (Level :: level(), Report :: report(), Metadata :: metadata()) -> ok;
         (Level :: level(), Format :: io:format(), Args :: [term()]) -> ok;
         (Level :: level(), Fun :: msg_fun(), FunArgs :: term()) -> ok.

Create a log event at the given log level, with the given message to be logged and metadata.

Example:

%% A plain string
1> logger:log(info, "Hello World").
%% A plain string with metadata
2> logger:log(debug, "Hello World", #{ meta => data }).
%% A format string with arguments
3> logger:log(warning, "The roof is on ~ts",[Cause]).
%% A report
4> logger:log(warning, #{ what => roof, cause => Cause }).

Equivalent to log(Level, FormatOrFun, Args, #{}) if called as log(Level, FormatOrFun, Args).

log(Level, FunOrFormat, Args, Metadata)

(since OTP 21.0)

-spec log(Level :: level(), Format :: io:format(), Args :: [term()], Metadata :: metadata()) -> ok;
         (Level :: level(), Fun :: msg_fun(), FunArgs :: term(), Metadata :: metadata()) -> ok.

Create a log event at the given log level, with the given message to be logged and metadata.

The message and metadata can either be given directly in the arguments, or returned from a fun. Passing a fun instead of the message/metadata directly is useful in scenarios when the message/metadata is very expensive to compute. This is because the fun is only evaluated when the message/metadata is actually needed, which may be not at all if the log event is not to be logged. Examples:

%% A plain string with expensive metadata
1> logger:info(fun([]) -> {"Hello World", #{ meta => expensive() }} end,[]).
%% An expensive report
2> logger:debug(fun(What) -> #{ what => What, cause => expensive() } end,roof).
%% A plain string with expensive metadata and normal metadata
3> logger:debug(fun([]) -> {"Hello World", #{ meta => expensive() }} end,[],
               #{ meta => data }).

When metadata is given both as an argument and returned from the fun they are merged. If equal keys exists the values are taken from the metadata returned by the fun.

notice(StringOrReport)

(since OTP 21.0)

-spec notice(String :: unicode:chardata()) -> ok;
            (Report :: report()) -> ok.

Equivalent to notice(StringOrReport, #{}).

notice(FormatOrFun, Args)

(since OTP 21.0)

-spec notice(String :: unicode:chardata(), Metadata :: metadata()) -> ok;
            (Report :: report(), Metadata :: metadata()) -> ok;
            (Format :: io:format(), Args :: [term()]) -> ok;
            (Fun :: msg_fun(), FunArgs :: term()) -> ok.

Create a notice log event.

Equivalent to log(notice, StringOrReport, Metadata) if called as notice(StringOrReport, Metadata).

Equivalent to notice(FormatOrFun, Args, #{}) if called as notice(FormatOrFun, Args).

notice(FormatOrFun, Args, Metadata)

(since OTP 21.0)

-spec notice(Format :: io:format(), Args :: [term()], Metadata :: metadata()) -> ok;
            (Fun :: msg_fun(), FunArgs :: term(), Metadata :: metadata()) -> ok.

Equivalent to log(notice, FormatOrFun, Args, Metadata).

warning(StringOrReport)

(since OTP 21.0)

-spec warning(String :: unicode:chardata()) -> ok;
             (Report :: report()) -> ok.

Equivalent to warning(StringOrReport, #{}).

warning(FormatOrFun, Args)

(since OTP 21.0)

-spec warning(String :: unicode:chardata(), Metadata :: metadata()) -> ok;
             (Report :: report(), Metadata :: metadata()) -> ok;
             (Format :: io:format(), Args :: [term()]) -> ok;
             (Fun :: msg_fun(), FunArgs :: term()) -> ok.

Create a warning log event.

Equivalent to log(warning, StringOrReport, Metadata) if called as warning(StringOrReport, Metadata).

Equivalent to warning(FormatOrFun, Args, #{}) if called as warning(FormatOrFun, Args).

warning(FormatOrFun, Args, Metadata)

(since OTP 21.0)

-spec warning(Format :: io:format(), Args :: [term()], Metadata :: metadata()) -> ok;
             (Fun :: msg_fun(), FunArgs :: term(), Metadata :: metadata()) -> ok.

Equivalent to log(warning, FormatOrFun, Args, Metadata).

Functions

add_handler(HandlerId, Module, Config)

(since OTP 21.0)

-spec add_handler(HandlerId, Module, Config) -> ok | {error, term()}
                     when
                         HandlerId :: logger_handler:id(),
                         Module :: module(),
                         Config :: logger_handler:config().

Add a handler with the given configuration.

HandlerId is a unique identifier which must be used in all subsequent calls referring to this handler.

add_handler_filter(HandlerId, FilterId, Filter)

(since OTP 21.0)

-spec add_handler_filter(HandlerId, FilterId, Filter) -> ok | {error, term()}
                            when
                                HandlerId :: logger_handler:id(),
                                FilterId :: filter_id(),
                                Filter :: filter().

Add a filter to the specified handler.

The filter fun is called with the log event as the first parameter, and the specified filter_args() as the second parameter.

The return value of the fun specifies if a log event is to be discarded or forwarded to the handler callback:

log_event/0 - The filter passed. The next handler filter, if any, is applied. If no more filters exist for this handler, the log event is forwarded to the handler callback.

stop - The filter did not pass, and the log event is immediately discarded.

ignore - The filter has no knowledge of the log event. The next handler filter, if any, is applied. If no more filters exist for this handler, the value of the filter_default configuration parameter for the handler specifies if the log event shall be discarded or forwarded to the handler callback.

See section Filters in the User's Guide for more information about filters.

Some built-in filters exist. These are defined in logger_filters.

add_handlers/1

(since OTP 21.0)

-spec add_handlers(Application) -> ok | {error, term()} when Application :: atom();
                  (HandlerConfig) -> ok | {error, term()} when HandlerConfig :: [config_handler()].

Reads the application configuration parameter logger and calls add_handlers/1 with its contents.

This function should be used by custom Logger handlers to make configuration consistent no matter which handler the system uses. Normal usage is to add a call to logger:add_handlers/1 just after the processes that the handler needs are started, and pass the application's logger configuration as the argument. For example:

-behaviour(application).
start(_, []) ->
    case supervisor:start_link({local, my_sup}, my_sup, []) of
        {ok, Pid} ->
            ok = logger:add_handlers(my_app),
            {ok, Pid, []};
        Error -> Error
     end.

This reads the logger configuration parameter from the my_app application and starts the configured handlers. The contents of the configuration use the same rules as the logger handler configuration.

If the handler is meant to replace the default handler, the Kernel's default handler have to be disabled before the new handler is added. A sys.config file that disables the Kernel handler and adds a custom handler could look like this:

[{kernel,
  [{logger,
    %% Disable the default Kernel handler
    [{handler, default, undefined}]}]},
 {my_app,
  [{logger,
    %% Enable this handler as the default
    [{handler, default, my_handler, #{}}]}]}].

add_primary_filter(FilterId, Filter)

(since OTP 21.0)

-spec add_primary_filter(FilterId, Filter) -> ok | {error, term()}
                            when FilterId :: filter_id(), Filter :: filter().

Add a primary filter to Logger.

The filter fun is called with the log event as the first parameter, and the specified filter_args() as the second parameter.

The return value of the fun specifies if a log event is to be discarded or forwarded to the handlers:

log_event/0 - The filter passed. The next primary filter, if any, is applied. If no more primary filters exist, the log event is forwarded to the handler part of Logger, where handler filters are applied.

stop - The filter did not pass, and the log event is immediately discarded.

ignore - The filter has no knowledge of the log event. The next primary filter, if any, is applied. If no more primary filters exist, the value of the primary filter_default configuration parameter specifies if the log event shall be discarded or forwarded to the handler part.

See section Filters in the User's Guide for more information about filters.

Some built-in filters exist. These are defined in logger_filters.

compare_levels(Level1, Level2)

(since OTP 21.0)

-spec compare_levels(Level1, Level2) -> eq | gt | lt
                        when Level1 :: level() | all | none, Level2 :: level() | all | none.

Compare the severity of two log levels. Returns gt if Level1 is more severe than Level2, lt if Level1 is less severe, and eq if the levels are equal.

format_report(Report)

(since OTP 21.0)

-spec format_report(Report) -> FormatArgs when Report :: report(), FormatArgs :: {io:format(), [term()]}.

Convert a log message on report form to {Format, Args}. This is the default report callback used by logger_formatter when no custom report callback is found. See section Log Message in the Kernel User's Guide for information about report callbacks and valid forms of log messages.

The function produces lines of Key: Value from key-value lists. Strings are printed with ~ts and other terms with ~tp.

If Report is a map, it is converted to a key-value list before formatting as such.

get_config()

(since OTP 21.0)

-spec get_config() ->
                    #{primary => primary_config(),
                      handlers => [logger_handler:config()],
                      proxy => olp_config(),
                      module_levels => [{module(), level() | all | none}]}.

Look up all current Logger configuration, including primary, handler, and proxy configuration, and module level settings.

get_handler_config()

(since OTP 21.0)

-spec get_handler_config() -> [Config] when Config :: logger_handler:config().

Look up the current configuration for all handlers.

get_handler_config(HandlerId)

(since OTP 21.0)

-spec get_handler_config(HandlerId) -> {ok, Config} | {error, term()}
                            when HandlerId :: logger_handler:id(), Config :: logger_handler:config().

Look up the current configuration for the given handler.

get_handler_ids()

(since OTP 21.0)

-spec get_handler_ids() -> [HandlerId] when HandlerId :: logger_handler:id().

Look up the identities for all installed handlers.

get_module_level()

(since OTP 21.0)

-spec get_module_level() -> [{Module, Level}] when Module :: module(), Level :: level() | all | none.

Look up all current module levels. Returns a list containing one {Module,Level} element for each module for which the module level was previously set with set_module_level/2.

get_module_level(Modules)

(since OTP 21.0)

-spec get_module_level(Modules) -> [{Module, Level}]
                          when
                              Modules :: [Module] | Module,
                              Module :: module(),
                              Level :: level() | all | none.

Look up the current level for the given modules. Returns a list containing one {Module,Level} element for each of the given modules for which the module level was previously set with set_module_level/2.

get_primary_config()

(since OTP 21.0)

-spec get_primary_config() -> Config when Config :: primary_config().

Look up the current primary configuration for Logger.

get_process_metadata()

(since OTP 21.0)

-spec get_process_metadata() -> Meta | undefined when Meta :: metadata().

Retrieve data set with set_process_metadata/1 or update_process_metadata/1.

get_proxy_config()

(since OTP 21.3)

-spec get_proxy_config() -> Config when Config :: olp_config().

Look up the current configuration for the Logger proxy.

For more information about the proxy, see section Logger Proxy in the Kernel User's Guide.

i()

(since OTP 21.3)

-spec i() -> ok.

Pretty print all Logger configuration.

i(What)

(since OTP 21.3)

-spec i(What) -> ok when What :: primary | handlers | proxy | modules | logger_handler:id().

Pretty print the Logger configuration.

reconfigure()

(since OTP 24.2)

-spec reconfigure() -> ok | {error, term()}.

Reconfigure Logger using updated kernel configuration that was set after kernel application was loaded.

Beware, that this is meant to be run only by the build tools, not manually during application lifetime, as this may cause missing log entries.

Before reconfiguration, simple logger handler is added to capture log events before the logging infrastructure is started and prints them to standard output. After the default handler is added again, all log events captured by the simple handler are replayed to the default handler, and the simple handler is removed. Notice that if you don't add the default handler, simple handler will persist.

remove_handler(HandlerId)

(since OTP 21.0)

-spec remove_handler(HandlerId) -> ok | {error, term()} when HandlerId :: logger_handler:id().

Remove the handler identified by HandlerId.

remove_handler_filter(HandlerId, FilterId)

(since OTP 21.0)

-spec remove_handler_filter(HandlerId, FilterId) -> ok | {error, term()}
                               when HandlerId :: logger_handler:id(), FilterId :: filter_id().

Remove the filter identified by FilterId from the handler identified by HandlerId.

remove_primary_filter(FilterId)

(since OTP 21.0)

-spec remove_primary_filter(FilterId) -> ok | {error, term()} when FilterId :: filter_id().

Remove the primary filter identified by FilterId from Logger.

set_application_level(Application, Level)

(since OTP 21.1)

-spec set_application_level(Application, Level) -> ok | {error, not_loaded}
                               when Application :: atom(), Level :: level() | all | none.

Set the log level for all the modules of the specified application.

This function is a convenience function that calls logger:set_module_level/2 for each module associated with an application.

set_handler_config(HandlerId, Config)

(since OTP 21.0)

-spec set_handler_config(HandlerId, Config) -> ok | {error, term()}
                            when HandlerId :: logger_handler:id(), Config :: logger_handler:config().

Set configuration data for the specified handler. This overwrites the current handler configuration.

To modify the existing configuration, use update_handler_config/2, or, if a more complex merge is needed, read the current configuration with get_handler_config/1 , then do the merge before writing the new configuration back with this function.

If a key is removed compared to the current configuration, and the key is known by Logger, the default value is used. If it is a custom key, then it is up to the handler implementation if the value is removed or a default value is inserted.

set_handler_config(HandlerId, Key, Value)

(since OTP 21.0)

-spec set_handler_config(HandlerId, level, Level) -> Return
                            when
                                HandlerId :: logger_handler:id(),
                                Level :: level() | all | none,
                                Return :: ok | {error, term()};
                        (HandlerId, filter_default, FilterDefault) -> Return
                            when
                                HandlerId :: logger_handler:id(),
                                FilterDefault :: log | stop,
                                Return :: ok | {error, term()};
                        (HandlerId, filters, Filters) -> Return
                            when
                                HandlerId :: logger_handler:id(),
                                Filters :: [{filter_id(), filter()}],
                                Return :: ok | {error, term()};
                        (HandlerId, formatter, Formatter) -> Return
                            when
                                HandlerId :: logger_handler:id(),
                                Formatter :: {module(), formatter_config()},
                                Return :: ok | {error, term()};
                        (HandlerId, config, Config) -> Return
                            when
                                HandlerId :: logger_handler:id(),
                                Config :: term(),
                                Return :: ok | {error, term()}.

Add or update configuration data for the specified handler. If the given Key already exists, its associated value will be changed to the given value. If it does not exist, it will be added.

If the value is incomplete, which for example can be the case for the config key, it is up to the handler implementation how the unspecified parts are set. For all handlers in the Kernel application, unspecified data for the config key is set to default values. To update only specified data, and keep the existing configuration for the rest, use update_handler_config/3.

See the definition of the logger_handler:config/0 type for more information about the different parameters.

set_module_level(Modules, Level)

(since OTP 21.0)

-spec set_module_level(Modules, Level) -> ok | {error, term()}
                          when Modules :: [module()] | module(), Level :: level() | all | none.

Set the log level for the specified modules.

The log level for a module overrides the primary log level of Logger for log events originating from the module in question. Notice, however, that it does not override the level configuration for any handler.

For example: Assume that the primary log level for Logger is info, and there is one handler, h1, with level info and one handler, h2, with level debug.

With this configuration, no debug messages will be logged, since they are all stopped by the primary log level.

If the level for mymodule is now set to debug, then debug events from this module will be logged by the handler h2, but not by handler h1.

Debug events from other modules are still not logged.

To change the primary log level for Logger, use set_primary_config(level, Level).

To change the log level for a handler, use set_handler_config(HandlerId, level, Level) .

Note

The originating module for a log event is only detected if the key mfa exists in the metadata, and is associated with {Module, Function, Arity}. When log macros are used, this association is automatically added to all log events. If an API function is called directly, without using a macro, the logging client must explicitly add this information if module levels shall have any effect.

set_primary_config(Config)

(since OTP 21.0)

-spec set_primary_config(Config) -> ok | {error, term()} when Config :: primary_config().

Set primary configuration data for Logger. This overwrites the current configuration.

To modify the existing configuration, use update_primary_config/1, or, if a more complex merge is needed, read the current configuration with get_primary_config/0 , then do the merge before writing the new configuration back with this function.

If a key is removed compared to the current configuration, the default value is used.

set_primary_config(Key, Value)

(since OTP 21.0)

-spec set_primary_config(level, Level) -> ok | {error, term()} when Level :: level() | all | none;
                        (filter_default, FilterDefault) -> ok | {error, term()}
                            when FilterDefault :: log | stop;
                        (filters, Filters) -> ok | {error, term()}
                            when Filters :: [{filter_id(), filter()}];
                        (metadata, Meta) -> ok | {error, term()} when Meta :: metadata().

Add or update primary configuration data for Logger. If the given Key already exists, its associated value will be changed to the given value. If it does not exist, it will be added.

The metadata key was added in OTP 24.0.

set_process_metadata(Meta)

(since OTP 21.0)

-spec set_process_metadata(Meta) -> ok when Meta :: metadata().

Set metadata which Logger shall automatically insert in all log events produced on the current process.

Location data produced by the log macros, and/or metadata given as argument to the log call (API function or macro), are merged with the process metadata. If the same keys occur, values from the metadata argument to the log call overwrite values from the process metadata, which in turn overwrite values from the location data.

Subsequent calls to this function overwrites previous data set. To update existing data instead of overwriting it, see update_process_metadata/1.

set_proxy_config(Config)

(since OTP 21.3)

-spec set_proxy_config(Config) -> ok | {error, term()} when Config :: olp_config().

Set configuration data for the Logger proxy. This overwrites the current proxy configuration. Keys that are not specified in the Config map gets default values.

To modify the existing configuration, use update_proxy_config/1, or, if a more complex merge is needed, read the current configuration with get_proxy_config/0 , then do the merge before writing the new configuration back with this function.

For more information about the proxy, see section Logger Proxy in the Kernel User's Guide.

timestamp()

(since OTP 21.3)

-spec timestamp() -> timestamp().

Return a timestamp that can be inserted as the time field in the meta data for a log event. It is produced with os:system_time(microsecond).

Notice that Logger automatically inserts a timestamp in the meta data unless it already exists. This function is exported for the rare case when the timestamp must be taken at a different point in time than when the log event is issued.

unset_application_level(Application)

(since OTP 21.1)

-spec unset_application_level(Application) -> ok | {error, {not_loaded, Application}}
                                 when Application :: atom().

Unset the log level for all the modules of the specified application.

This function is a utility function that calls logger:unset_module_level/2 for each module associated with an application.

unset_module_level()

(since OTP 21.0)

-spec unset_module_level() -> ok.

Remove module specific log settings. After this, the primary log level is used for all modules.

unset_module_level(Modules)

(since OTP 21.0)

-spec unset_module_level(Modules) -> ok when Modules :: [module()] | module().

Remove module specific log settings. After this, the primary log level is used for the specified modules.

unset_process_metadata()

(since OTP 21.0)

-spec unset_process_metadata() -> ok.

Delete data set with set_process_metadata/1 or update_process_metadata/1.

update_formatter_config(HandlerId, FormatterConfig)

(since OTP 21.0)

-spec update_formatter_config(HandlerId, FormatterConfig) -> ok | {error, term()}
                                 when
                                     HandlerId :: logger_handler:id(),
                                     FormatterConfig :: formatter_config().

Update the formatter configuration for the specified handler.

The new configuration is merged with the existing formatter configuration.

To overwrite the existing configuration without any merge, use

set_handler_config(HandlerId, formatter,
	      {FormatterModule, FormatterConfig}).

update_formatter_config(HandlerId, Key, Value)

(since OTP 21.0)

-spec update_formatter_config(HandlerId, Key, Value) -> ok | {error, term()}
                                 when HandlerId :: logger_handler:id(), Key :: atom(), Value :: term().

Equivalent to update_formatter_config(HandlerId, #{Key => Value}).

update_handler_config(HandlerId, Config)

(since OTP 21.0)

-spec update_handler_config(HandlerId, Config) -> ok | {error, term()}
                               when HandlerId :: logger_handler:id(), Config :: logger_handler:config().

Update configuration data for the specified handler. This function behaves as if it was implemented as follows:

{ok, {_, Old}} = logger:get_handler_config(HandlerId),
logger:set_handler_config(HandlerId, maps:merge(Old, Config)).

To overwrite the existing configuration without any merge, use set_handler_config/2 .

update_handler_config(HandlerId, Key, Value)

(since OTP 21.2)

-spec update_handler_config(HandlerId, level, Level) -> Return
                               when
                                   HandlerId :: logger_handler:id(),
                                   Level :: level() | all | none,
                                   Return :: ok | {error, term()};
                           (HandlerId, filter_default, FilterDefault) -> Return
                               when
                                   HandlerId :: logger_handler:id(),
                                   FilterDefault :: log | stop,
                                   Return :: ok | {error, term()};
                           (HandlerId, filters, Filters) -> Return
                               when
                                   HandlerId :: logger_handler:id(),
                                   Filters :: [{filter_id(), filter()}],
                                   Return :: ok | {error, term()};
                           (HandlerId, formatter, Formatter) -> Return
                               when
                                   HandlerId :: logger_handler:id(),
                                   Formatter :: {module(), formatter_config()},
                                   Return :: ok | {error, term()};
                           (HandlerId, config, Config) -> Return
                               when
                                   HandlerId :: logger_handler:id(),
                                   Config :: term(),
                                   Return :: ok | {error, term()}.

Add or update configuration data for the specified handler. If the given Key already exists, its associated value will be changed to the given value. If it does not exist, it will be added.

If the value is incomplete, which for example can be the case for the config key, it is up to the handler implementation how the unspecified parts are set. For all handlers in the Kernel application, unspecified data for the config key is not changed. To reset unspecified data to default values, use set_handler_config/3.

See the definition of the logger_handler:config/0 type for more information about the different parameters.

update_primary_config(Config)

(since OTP 21.0)

-spec update_primary_config(Config) -> ok | {error, term()} when Config :: primary_config().

Update primary configuration data for Logger. This function behaves as if it was implemented as follows:

Old = logger:get_primary_config(),
logger:set_primary_config(maps:merge(Old, Config)).

To overwrite the existing configuration without any merge, use set_primary_config/1 .

update_process_metadata(Meta)

(since OTP 21.0)

-spec update_process_metadata(Meta) -> ok when Meta :: metadata().

Set or update metadata to use when logging from current process

If process metadata exists for the current process, this function behaves as if it was implemented as follows:

logger:set_process_metadata(maps:merge(logger:get_process_metadata(), Meta)).

If no process metadata exists, the function behaves as set_process_metadata/1 .

update_proxy_config(Config)

(since OTP 21.3)

-spec update_proxy_config(Config) -> ok | {error, term()} when Config :: olp_config().

Update configuration data for the Logger proxy. This function behaves as if it was implemented as follows:

Old = logger:get_proxy_config(),
logger:set_proxy_config(maps:merge(Old, Config)).

To overwrite the existing configuration without any merge, use set_proxy_config/1 .

For more information about the proxy, see section Logger Proxy in the Kernel User's Guide.

logger_disk_log_h

A disk_log based handler for Logger

This is a handler for Logger that offers circular (wrapped) logs by using disk_log. Multiple instances of this handler can be added to Logger, and each instance prints to its own disk log file, created with the name and settings specified in the handler configuration.

The default standard handler, logger_std_h, can be replaced by a disk_log handler at startup of the Kernel application. See an example of this below.

The handler has an overload protection mechanism that keeps the handler process and the Kernel application alive during high loads of log events. How overload protection works, and how to configure it, is described in the User's Guide.

To add a new instance of the disk_log handler, use logger:add_handler/3. The handler configuration argument is a map which can contain general configuration parameters, as documented in the User's Guide, and handler specific parameters. The specific data is stored in a sub map with the key config, and can contain the following parameters:

file - This is the full name of the disk log file. The option corresponds to the name property in the dlog_option() datatype.

The value is set when the handler is added, and it cannot be changed in runtime.

Defaults to the same name as the handler identity, in the current directory.

type - This is the disk log type, wrap or halt. The option corresponds to the type property in the dlog_option() datatype.

The value is set when the handler is added, and it cannot be changed in runtime.

Defaults to wrap.

max_no_files - This is the maximum number of files that disk_log uses for its circular logging. The option corresponds to the MaxNoFiles element in the size property in the dlog_option() datatype.

The value is set when the handler is added, and it cannot be changed in runtime.

Defaults to 10.

The setting has no effect on a halt log.

max_no_bytes - This is the maximum number of bytes that is written to a log file before disk_log proceeds with the next file in order, or generates an error in case of a full halt log. The option corresponds to the MaxNoBytes element in the size property in the dlog_option() datatype.

The value is set when the handler is added, and it cannot be changed in runtime.

Defaults to 1048576 bytes for a wrap log, and infinity for a halt log.

filesync_repeat_interval - This value, in milliseconds, specifies how often the handler does a disk_log sync operation to write buffered data to disk. The handler attempts the operation repeatedly, but only performs a new sync if something has actually been logged.

Defaults to 5000 milliseconds.

If no_repeat is set as value, the repeated sync operation is disabled. The user can also call the filesync/1 function to perform a disk_log sync.

Other configuration parameters exist, to be used for customizing the overload protection behaviour. The same parameters are used both in the standard handler and the disk_log handler, and are documented in the User's Guide.

Notice that when changing the configuration of the handler in runtime, the disk_log options (file, type, max_no_files, max_no_bytes) must not be modified.

Example of adding a disk_log handler:

logger:add_handler(my_disk_log_h, logger_disk_log_h,
                   #{config => #{file => "./my_disk_log",
                                 type => wrap,
                                 max_no_files => 4,
                                 max_no_bytes => 10000,
                                 filesync_repeat_interval => 1000}}).

To use the disk_log handler instead of the default standard handler when starting an Erlang node, change the Kernel default logger to use logger_disk_log_h. Example:

erl -kernel logger '[{handler,default,logger_disk_log_h,
                      #{config => #{file => "./system_disk_log"}}}]'

See Also

logger, logger_std_h, disk_log

Summary

Functions

filesync(Name)

Write buffered data to disk.

Functions

filesync(Name)

(since OTP 21.0)

-spec filesync(Name) -> ok | {error, Reason}
                  when Name :: atom(), Reason :: handler_busy | {badarg, term()}.

Write buffered data to disk.

logger_filters

Filters to use with Logger.

All functions exported from this module can be used as primary or handler filters. See logger:add_primary_filter/2 and logger:add_handler_filter/3 for more information about how filters are added.

Filters are removed with logger:remove_primary_filter/1 and logger:remove_handler_filter/2.

See Also

logger

Summary

Functions

domain(LogEvent, Extra)

This filter provides a way of filtering log events based on a domain field in Metadata. This field is optional, and the purpose of using it is to group log events from, for example, a specific functional area. This allows filtering or other specialized treatment in a Logger handler.

level(LogEvent, Extra)

This filter provides a way of filtering log events based on the log level. It matches log events by comparing the log level with a specified MatchLevel

progress(LogEvent, Extra)

This filter matches all progress reports from supervisor and application_controller.

remote_gl(LogEvent, Extra)

This filter matches all events originating from a process that has its group leader on a remote node.

Functions

domain(LogEvent, Extra)

(since OTP 21.0)

-spec domain(LogEvent, Extra) -> logger:filter_return()
                when
                    LogEvent :: logger:log_event(),
                    Extra :: {Action, Compare, MatchDomain},
                    Action :: log | stop,
                    Compare :: super | sub | equal | not_equal | undefined,
                    MatchDomain :: [atom()].

This filter provides a way of filtering log events based on a domain field in Metadata. This field is optional, and the purpose of using it is to group log events from, for example, a specific functional area. This allows filtering or other specialized treatment in a Logger handler.

A domain field must be a list of atoms, creating smaller and more specialized domains as the list grows longer. The greatest domain is [], which comprises all possible domains.

For example, consider the following domains:

D1 = [otp]
D2 = [otp, sasl]

D1 is the greatest of the two, and is said to be a super-domain of D2. D2 is a sub-domain D1. Both D1 and D2 are sub-domains of [].

The above domains are used for logs originating from Erlang/OTP. D1 specifies that the log event comes from Erlang/OTP in general, and D2 indicates that the log event is a so called SASL report.

The Extra parameter to the domain/2 function is specified when adding the filter via logger:add_primary_filter/2 or logger:add_handler_filter/3.

The filter compares the value of the domain field in the log event's metadata (Domain) against MatchDomain. The filter matches if the value of Compare is:

sub - and Domain is equal to or a sub-domain of MatchDomain, that is, if MatchDomain is a prefix of Domain.

super - and Domain is equal to or a super-domain of MatchDomain, that is, if Domain is a prefix of MatchDomain.

equal - and Domain is equal to MatchDomain.

not_equal - and Domain differs from MatchDomain, or if there is no domain field in metadata.

undefined - and there is no domain field in metadata. In this case MatchDomain must be set to [].

If the filter matches and Action is log, the log event is allowed. If the filter matches and Action is stop, the log event is stopped.

If the filter does not match, it returns ignore, meaning that other filters, or the value of the configuration parameter filter_default, decide if the event is allowed or not.

Log events that do not contain any domain field, match only when Compare is equal to undefined or not_equal.

Example: stop all events with domain [otp, sasl | _]

1> logger:set_handler_config(h1, filter_default, log). % this is the default
ok
2> Filter = {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}.
...
3> logger:add_handler_filter(h1, no_sasl, Filter).
ok

level(LogEvent, Extra)

(since OTP 21.0)

-spec level(LogEvent, Extra) -> logger:filter_return()
               when
                   LogEvent :: logger:log_event(),
                   Extra :: {Action, Operator, MatchLevel},
                   Action :: log | stop,
                   Operator :: neq | eq | lt | gt | lteq | gteq,
                   MatchLevel :: logger:level().

This filter provides a way of filtering log events based on the log level. It matches log events by comparing the log level with a specified MatchLevel

The Extra parameter is specified when adding the filter via logger:add_primary_filter/2 or logger:add_handler_filter/3.

The filter compares the value of the event's log level (Level) to MatchLevel by calling logger:compare_levels(Level, MatchLevel). The filter matches if the value of Operator is:

neq - and the compare function returns lt or gt.

eq - and the compare function returns eq.

lt - and the compare function returns lt.

gt - and the compare function returns gt.

lteq - and the compare function returns lt or eq.

gteq - and the compare function returns gt or eq.

If the filter matches and Action is log, the log event is allowed. If the filter matches and Action is stop, the log event is stopped.

If the filter does not match, it returns ignore, meaning that other filters, or the value of the configuration parameter filter_default, will decide if the event is allowed or not.

Example: only allow debug level log events

logger:set_handler_config(h1, filter_default, stop).
Filter = {fun logger_filters:level/2, {log, eq, debug}}.
logger:add_handler_filter(h1, debug_only, Filter).
ok

progress(LogEvent, Extra)

(since OTP 21.0)

-spec progress(LogEvent, Extra) -> logger:filter_return()
                  when LogEvent :: logger:log_event(), Extra :: log | stop.

This filter matches all progress reports from supervisor and application_controller.

If Extra is log, the progress reports are allowed. If Extra is stop, the progress reports are stopped.

The filter returns ignore for all other log events.

remote_gl(LogEvent, Extra)

(since OTP 21.0)

-spec remote_gl(LogEvent, Extra) -> logger:filter_return()
                   when LogEvent :: logger:log_event(), Extra :: log | stop.

This filter matches all events originating from a process that has its group leader on a remote node.

If Extra is log, the matching events are allowed. If Extra is stop, the matching events are stopped.

The filter returns ignore for all other log events.

logger_formatter behaviour

Default formatter for Logger.

Each Logger handler has a configured formatter specified as a module and a configuration term. The purpose of the formatter is to translate the log events to a final printable string (unicode:chardata()) which can be written to the output device of the handler. See sections Handlers and Formatters in the Kernel User's Guide for more information.

logger_formatter is the default formatter used by Logger.

See Also

calendar, error_logger, io, io_lib, logger, maps, sasl(6), unicode

Summary

Types

config()

The configuration term for logger_formatter is a map, and the following keys can be set as configuration parameters

metakey()

template()

The template to be used by a logger formatter.

Callbacks: Formatter Callback Functions

check_config(Config)

The function is called by a Logger when formatter configuration is set or modified. The formatter must validate the given configuration and return ok if it is correct, and {error,Reason} if it is faulty.

format(LogEvent, Config)

The function can be called by a log handler to convert a log event term to a printable string. The returned value can, for example, be printed as a log entry to the console or a file using io:put_chars/1,2.

Functions

check_config(Config)

The function is called by Logger when the formatter configuration for a handler is set or modified. It returns ok if the configuration is valid, and {error,term()} if it is faulty.

format(LogEvent, Config)

This the formatter callback function to be called from handlers.

Types

config()

(not exported) (since OTP 21.0)

-type config() ::
          #{chars_limit => pos_integer() | unlimited,
            depth => pos_integer() | unlimited,
            legacy_header => boolean(),
            max_size => pos_integer() | unlimited,
            report_cb => logger:report_cb(),
            single_line => boolean(),
            template => template(),
            time_designator => byte(),
            time_offset => integer() | [byte()]}.

The configuration term for logger_formatter is a map, and the following keys can be set as configuration parameters:

chars_limit = integer() > 0 | unlimited - A positive integer representing the value of the option with the same name to be used when calling io_lib:format/3. This value limits the total number of characters printed for each log event. Notice that this is a soft limit. For a hard truncation limit, see option max_size.

Defaults to unlimited.

depth = integer() > 0 | unlimited - A positive integer representing the maximum depth to which terms shall be printed by this formatter. Format strings passed to this formatter are rewritten. The format controls ~p and ~w are replaced with ~P and ~W, respectively, and the value is used as the depth parameter. For details, see io:format/2,3 in STDLIB.

Defaults to unlimited.

legacy_header = boolean() - If set to true a header field is added to logger_formatter's part of Metadata. The value of this field is a string similar to the header created by the old error_logger event handlers. It can be included in the log event by adding the list [logger_formatter,header] to the template. See the description of the template/0 type for more information.

Defaults to false.

max_size = integer() > 0 | unlimited - A positive integer representing the absolute maximum size a string returned from this formatter can have. If the formatted string is longer, after possibly being limited by chars_limit or depth, it is truncated.

Defaults to unlimited.

report_cb = logger:report_cb/0 - A report callback is used by the formatter to transform log messages on report form to a format string and arguments. The report callback can be specified in the metadata for the log event. If no report callback exists in metadata, logger_formatter will use logger:format_report/1 as default callback.

If this configuration parameter is set, it replaces both the default report callback, and any report callback found in metadata. That is, all reports are converted by this configured function.

single_line = boolean() - If set to true, each log event is printed as a single line. To achieve this, logger_formatter sets the field width to 0 for all ~p and ~P control sequences in the format a string (see io:format/2), and replaces all newlines in the message with ", ". White spaces following directly after newlines are removed. Notice that newlines added by the template parameter are not replaced.

Defaults to true.

template =template/0 - The template describes how the formatted string is composed by combining different data values from the log event. See the description of the template/0 type for more information about this.

time_designator = byte() - Timestamps are formatted according to RFC3339, and the time designator is the character used as date and time separator.

Defaults to $T.

The value of this parameter is used as the time_designator option to calendar:system_time_to_rfc3339/2.

time_offset = integer() | [byte()] - The time offset, either a string or an integer, to be used when formatting the timestamp.

An empty string is interpreted as local time. The values "Z", "z" or 0 are interpreted as Universal Coordinated Time (UTC).

Strings, other than "Z", "z", or "", must be of the form ±[hh]:[mm], for example "-02:00" or "+00:00".

Integers must be in microseconds, meaning that the offset 7200000000 is equivalent to "+02:00".

Defaults to an empty string, meaning that timestamps are displayed in local time. However, for backwards compatibility, if the SASL configuration parameter utc_log=true, the default is changed to "Z", meaning that timestamps are displayed in UTC.

The value of this parameter is used as the offset option to calendar:system_time_to_rfc3339/2.

metakey()

(not exported) (since OTP 21.0)

-type metakey() :: atom() | [atom()].

template()

(not exported) (since OTP 21.0)

-type template() :: [metakey() | {metakey(), template(), template()} | unicode:chardata()].

The template to be used by a logger formatter.

The template is a list of atoms, atom lists, tuples and strings. The atoms level or msg, are treated as placeholders for the severity level and the log message, respectively. Other atoms or atom lists are interpreted as placeholders for metadata, where atoms are expected to match top level keys, and atom lists represent paths to sub keys when the metadata is a nested map. For example the list [key1,key2] is replaced by the value of the key2 field in the nested map below. The atom key1 on its own is replaced by the complete value of the key1 field. The values are converted to strings.

#{key1 => #{key2 => my_value,
            ...}
  ...}

Tuples in the template express if-exist tests for metadata keys. For example, the following tuple says that if key1 exists in the metadata map, print "key1=Value", where Value is the value that key1 is associated with in the metadata map. If key1 does not exist, print nothing.

{key1, ["key1=",key1], []}

Strings in the template are printed literally.

The default value for the template configuration parameter depends on the value of the single_line and legacy_header configuration parameters as follows.

The log event used in the examples is:

?LOG_ERROR("name: ~p~nexit_reason: ~p", [my_name, "It crashed"])

legacy_header = true, single_line = false - Default template: [[logger_formatter,header],"\n",msg,"\n"]

Example log entry:

=ERROR REPORT==== 17-May-2018::18:30:19.453447 ===
name: my_name
exit_reason: "It crashed"

Notice that all eight levels can occur in the heading, not only ERROR, WARNING or INFO as error_logger produces. And microseconds are added at the end of the timestamp.

legacy_header = true, single_line = true - Default template: [[logger_formatter,header],"\n",msg,"\n"]

Notice that the template is here the same as for single_line=false, but the resulting log entry differs in that there is only one line after the heading:

=ERROR REPORT==== 17-May-2018::18:31:06.952665 ===
name: my_name, exit_reason: "It crashed"

legacy_header = false, single_line = true - Default template: [time," ",level,": ",msg,"\n"]

Example log entry:

2018-05-17T18:31:31.152864+02:00 error: name: my_name, exit_reason: "It crashed"

legacy_header = false, single_line = false - Default template: [time," ",level,":\n",msg,"\n"]

Example log entry:

2018-05-17T18:32:20.105422+02:00 error:
name: my_name
exit_reason: "It crashed"

Callbacks: Formatter Callback Functions

check_config(Config)

(since OTP 21.0)

-callback check_config(FConfig) -> ok | {error, Reason}
                          when FConfig :: logger:formatter_config(), Reason :: term().

The function is called by a Logger when formatter configuration is set or modified. The formatter must validate the given configuration and return ok if it is correct, and {error,Reason} if it is faulty.

The following Logger API functions can trigger this callback:

logger:add_handler/3

logger:set_handler_config/2,3

logger:update_handler_config/2,3

logger:update_formatter_config/2

See logger_formatter for an example implementation. logger_formatter is the default formatter used by Logger.

format(LogEvent, Config)

(since OTP 21.0)

-callback format(LogEvent, FConfig) -> FormattedLogEntry
                    when
                        LogEvent :: logger:log_event(),
                        FConfig :: logger:formatter_config(),
                        FormattedLogEntry :: unicode:chardata().

The function can be called by a log handler to convert a log event term to a printable string. The returned value can, for example, be printed as a log entry to the console or a file using io:put_chars/1,2.

See logger_formatter for an example implementation. logger_formatter is the default formatter used by Logger.

Functions

check_config(Config)

(since OTP 21.0)

-spec check_config(Config) -> ok | {error, term()} when Config :: config().

The function is called by Logger when the formatter configuration for a handler is set or modified. It returns ok if the configuration is valid, and {error,term()} if it is faulty.

The following Logger API functions can trigger this callback:

logger:add_handler/3

logger:set_handler_config/2,3

logger:update_handler_config/2

logger:update_formatter_config/2

format(LogEvent, Config)

(since OTP 21.0)

-spec format(LogEvent, Config) -> unicode:chardata()
                when LogEvent :: logger:log_event(), Config :: config().

This the formatter callback function to be called from handlers.

The log event is processed as follows:

If the message is on report form, it is converted to {Format,Args} by calling the report callback. See section Log Message in the Kernel User's Guide for more information about report callbacks and valid forms of log messages.

The message size is limited according to the values of configuration parameters chars_limit and depth.

The full log entry is composed according to the template.

If the final string is too long, it is truncated according to the value of configuration parameter max_size.

logger_handler behaviour

logger_handler behavior module.

The behaviour module for logger handlers. A logger handler is a callback module that is called when a log event has passed all filters and is ready to be logged somewhere. For more information see Handlers in the Users Guide.

See Also

logger_filters, logger_formatter, logger

Summary

Types

config()

Handler configuration data for Logger. The following default values apply

id()

A unique identifier for a handler instance.

olp_config()

Overload protection configuration.

Callbacks

adding_handler(Config1)

The function is called on a temporary process when a new handler is about to be added. The purpose is to verify the configuration and initiate all resources needed by the handler.

changing_config(SetOrUpdate, OldConfig, NewConfig)

The function is called on a temporary process when the configuration for a handler is about to change. The purpose is to verify and act on the new configuration.

filter_config(Config)

The function is called when one of the Logger API functions for fetching the handler configuration is called, for example logger:get_handler_config/1.

log(LogEvent, Config)

The function is called when all primary filters and all handler filters for the handler in question have passed for the given log event. It is called on the client process, that is, the process that issued the log event.

removing_handler(Config)

The function is called on a temporary process when a handler is about to be removed. The purpose is to release all resources used by the handler.

Types

config()

(since OTP 27.0)

-type config() ::
          #{id => id(),
            config => term(),
            level => logger:level() | all | none,
            module => module(),
            filter_default => log | stop,
            filters => [{logger:filter_id(), logger:filter()}],
            formatter => {module(), logger:formatter_config()}}.

Handler configuration data for Logger. The following default values apply:

level => all

filter_default => log

filters => []

formatter => {logger_formatter, DefaultFormatterConfig}

In addition to these, the following fields are automatically inserted by Logger, values taken from the two first parameters to logger:add_handler/3:

id => HandlerId

module => Module

These are read-only and cannot be changed in runtime.

Handler specific configuration data is inserted by the handler callback itself, in a sub structure associated with the field named config. See the logger_std_h and logger_disk_log_h manual pages for information about the specific configuration for these handlers.

See the logger_formatter manual page for information about the default configuration for this formatter.

id()

(since OTP 27.0)

-type id() :: atom().

A unique identifier for a handler instance.

olp_config()

(since OTP 27.0)

-type olp_config() ::
          #{sync_mode_qlen => non_neg_integer(),
            drop_mode_qlen => pos_integer(),
            flush_qlen => pos_integer(),
            burst_limit_enable => boolean(),
            burst_limit_max_count => pos_integer(),
            burst_limit_window_time => pos_integer(),
            overload_kill_enable => boolean(),
            overload_kill_qlen => pos_integer(),
            overload_kill_mem_size => pos_integer(),
            overload_kill_restart_after => non_neg_integer() | infinity}.

Overload protection configuration.

See Protecting the Handler from Overload for more details.

Callbacks

adding_handler(Config1)

(since OTP 21.0) (optional)

-callback adding_handler(Config1) -> {ok, Config2} | {error, Reason}
                            when Config1 :: config(), Config2 :: config(), Reason :: term().

The function is called on a temporary process when a new handler is about to be added. The purpose is to verify the configuration and initiate all resources needed by the handler.

The handler identity is associated with the id key in Config1.

If everything succeeds, the callback function can add possible default values or internal state values to the configuration, and return the adjusted map in {ok,Config2}.

If the configuration is faulty, or if the initiation fails, the callback function must return {error,Reason}.

changing_config(SetOrUpdate, OldConfig, NewConfig)

(since OTP 21.2) (optional)

-callback changing_config(SetOrUpdate, OldConfig, NewConfig) -> {ok, Config} | {error, Reason}
                             when
                                 SetOrUpdate :: set | update,
                                 OldConfig :: config(),
                                 NewConfig :: config(),
                                 Config :: config(),
                                 Reason :: term().

The function is called on a temporary process when the configuration for a handler is about to change. The purpose is to verify and act on the new configuration.

OldConfig is the existing configuration and NewConfig is the new configuration.

The handler identity is associated with the id key in OldConfig.

SetOrUpdate has the value set if the configuration change originates from a call to logger:set_handler_config/2,3, and update if it originates from logger:update_handler_config/2,3. The handler can use this parameter to decide how to update the value of the config field, that is, the handler specific configuration data. Typically, if SetOrUpdate equals set, values that are not specified must be given their default values. If SetOrUpdate equals update, the values found in OldConfig must be used instead.

If everything succeeds, the callback function must return a possibly adjusted configuration in {ok,Config}.

If the configuration is faulty, the callback function must return {error,Reason}.

filter_config(Config)

(since OTP 21.2) (optional)

-callback filter_config(Config) -> FilteredConfig when Config :: config(), FilteredConfig :: config().

The function is called when one of the Logger API functions for fetching the handler configuration is called, for example logger:get_handler_config/1.

It allows the handler to remove internal data fields from its configuration data before it is returned to the caller.

log(LogEvent, Config)

(since OTP 21.0)

-callback log(LogEvent, Config) -> term() when LogEvent :: logger:log_event(), Config :: config().

The function is called when all primary filters and all handler filters for the handler in question have passed for the given log event. It is called on the client process, that is, the process that issued the log event.

The handler identity is associated with the id key in Config.

The handler must log the event.

The return value from this function is ignored by Logger.

removing_handler(Config)

(since OTP 21.0) (optional)

-callback removing_handler(Config) -> ok when Config :: config().

The function is called on a temporary process when a handler is about to be removed. The purpose is to release all resources used by the handler.

The handler identity is associated with the id key in Config.

The return value is ignored by Logger.

logger_std_h

Standard handler for Logger.

This is the standard handler for Logger. Multiple instances of this handler can be added to Logger, and each instance prints logs to standard_io, standard_error, or to file.

The handler has an overload protection mechanism that keeps the handler process and the Kernel application alive during high loads of log events. How overload protection works, and how to configure it, is described in the User's Guide.

To add a new instance of the standard handler, use logger:add_handler/3. The handler configuration argument is a map which can contain general configuration parameters, as documented in the User's Guide, and handler specific parameters. The specific data is stored in a sub map with the key config, and can contain the following parameters:

type = io:standard_io/0 | io:standard_error/0 | file | {device, io:device/0 } - Specifies the log destination.

The value is set when the handler is added, and it cannot be changed in runtime.

Defaults to standard_io, unless parameter file is given, in which case it defaults to file.

file = file:filename/0 - This specifies the name of the log file when the handler is of type file.

The value is set when the handler is added, and it cannot be changed in runtime.

Defaults to the same name as the handler identity, in the current directory.

modes = [ file:mode/0 ] - This specifies the file modes to use when opening the log file, see file:open/2. If modes are not specified, the default list used is [raw,append,delayed_write]. If modes are specified, the list replaces the default modes list with the following adjustments:

If raw is not found in the list, it is added.

If none of write, append or exclusive is found in the list, append is added.

If none of delayed_write or {delayed_write,Size,Delay} is found in the list, delayed_write is added.

Log files are always UTF-8 encoded. The encoding cannot be changed by setting the mode {encoding,Encoding}.

The value is set when the handler is added, and it cannot be changed in runtime.

Defaults to [raw,append,delayed_write].

max_no_bytes = pos_integer/0 | infinity - This parameter specifies if the log file should be rotated or not. The value infinity means the log file will grow indefinitely, while an integer value specifies at which file size (bytes) the file is rotated.

Defaults to infinity.

max_no_files = non_neg_integer/0 - This parameter specifies the number of rotated log file archives to keep. This has meaning only if max_no_bytes is set to an integer value.

The log archives are named FileName.0, FileName.1, ... FileName.N, where FileName is the name of the current log file. FileName.0 is the newest of the archives. The maximum value for N is the value of max_no_files minus 1.

Notice that setting this value to 0 does not turn off rotation. It only specifies that no archives are kept.

Defaults to 0.

compress_on_rotate = boolean/0 - This parameter specifies if the rotated log file archives shall be compressed or not. If set to true, all archives are compressed with gzip, and renamed to FileName.N.gz

compress_on_rotate has no meaning if max_no_bytes has the value infinity.

Defaults to false.

file_check = non_neg_integer/0 - When logger_std_h logs to a file, it reads the file information of the log file prior to each write operation. This is to make sure the file still exists and has the same inode as when it was opened. This implies some performance loss, but ensures that no log events are lost in the case when the file has been removed or renamed by an external actor.

In order to allow minimizing the performance loss, the file_check parameter can be set to a positive integer value, N. The handler will then skip reading the file information prior to writing, as long as no more than N milliseconds have passed since it was last read.

Notice that the risk of losing log events grows when the file_check value grows.

Defaults to 0.

filesync_repeat_interval = pos_integer/0 | no_repeat - This value, in milliseconds, specifies how often the handler does a file sync operation to write buffered data to disk. The handler attempts the operation repeatedly, but only performs a new sync if something has actually been logged.

If no_repeat is set as value, the repeated file sync operation is disabled, and it is the operating system settings that determine how quickly or slowly data is written to disk. The user can also call the filesync/1 function to perform a file sync.

Defaults to 5000 milliseconds.

Other configuration parameters exist, to be used for customizing the overload protection behaviour. The same parameters are used both in the standard handler and the disk_log handler, and are documented in the User's Guide.

Notice that if changing the configuration of the handler in runtime, the type, file, or modes parameters must not be modified.

Example of adding a standard handler:

logger:add_handler(my_standard_h, logger_std_h,
                   #{config => #{file => "./system_info.log",
                                 filesync_repeat_interval => 1000}}).

To set the default handler, that starts initially with the Kernel application, to log to file instead of standard_io, change the Kernel default logger configuration. Example:

erl -kernel logger '[{handler,default,logger_std_h,
                      #{config => #{file => "./log.log"}}}]'

An example of how to replace the standard handler with a disk_log handler at startup is found in the logger_disk_log_h manual.

See Also

logger, logger_disk_log_h

Summary

Functions

filesync(Name)

Write buffered data to disk.

Functions

filesync(Name)

(since OTP 21.0)

-spec filesync(Name) -> ok | {error, Reason}
                  when Name :: atom(), Reason :: handler_busy | {badarg, term()}.

Write buffered data to disk.

wrap_log_reader

A service to read internally formatted wrap disk logs.

This module makes it possible to read internally formatted wrap disk logs, see disk_log. wrap_log_reader does not interfere with disk_log activities; there is however a bug in this version of the wrap_log_reader, see section Known Limitations.

A wrap disk log file consists of many files, called index files. A log file can be opened and closed. Also, a single index file can be opened separately. If a non-existent or non-internally formatted file is opened, an error message is returned. If the file is corrupt, no attempt is made to repair it, but an error message is returned.

If a log is configured to be distributed, it is possible that all items are not logged on all nodes. wrap_log_reader only reads the log on the called node; it is up to the user to be sure that all items are read.

Known Limitations

This version of wrap_log_reader does not detect if disk_log wraps to a new index file between a call to wrap_log_reader:open/1 and the first call to wrap_log_reader:chunk/1. If this occurs, the call to chunk/1 reads the last logged items in the log file, as the opened index file was truncated by disk_log.

Summary

Types

chunk_ret()

continuation()

Continuation returned by open/1,2 or chunk/1,2.

open_ret()

Functions

chunk(Continuation)

Equivalent to chunk(Continuation, infinity).

chunk(Continuation, N)

Enables to efficiently read the terms that are appended to a log. Minimises disk I/O by reading 64 kilobyte chunks from the file.

close(Continuation)

Closes a log file properly.

open(Filename)

Equivalent to open(Filename, ...) except that the whole wrap log file is read.

open(Filename, N)

Filename specifies the name of the file to be read.

Types

chunk_ret()

(not exported)

-type chunk_ret() ::
          {Continuation2 :: term(), Terms :: [term()]} |
          {Continuation2 :: term(), Terms :: [term()], Badbytes :: non_neg_integer()} |
          {Continuation2 :: term(), eof} |
          {error, Reason :: term()}.

continuation()

-opaque continuation()

Continuation returned by open/1,2 or chunk/1,2.

open_ret()

(not exported)

-type open_ret() :: {ok, Continuation :: continuation()} | {error, Reason :: tuple()}.

Functions

chunk(Continuation)

-spec chunk(Continuation) -> chunk_ret() when Continuation :: continuation().

Equivalent to chunk(Continuation, infinity).

chunk(Continuation, N)

-spec chunk(Continuation, N) -> chunk_ret()
               when Continuation :: continuation(), N :: infinity | pos_integer().

Enables to efficiently read the terms that are appended to a log. Minimises disk I/O by reading 64 kilobyte chunks from the file.

The first time chunk/2 is called, an initial continuation returned from open/1 or open/2 must be provided.

When chunk/2 is called, N controls the maximum number of terms that are read from the log in each chunk. infinity means that all the terms contained in the 8K chunk are read. If less than N terms are returned, this does not necessarily mean that end of file is reached.

Returns a tuple {Continuation2, Terms}, where Terms is a list of terms found in the log. Continuation2 is yet another continuation that must be passed on to any subsequent calls to chunk(). With a series of calls to chunk(), it is then possible to extract all terms from a log.

Returns a tuple {Continuation2, Terms, Badbytes} if the log is opened in read only mode and the read chunk is corrupt. Badbytes indicates the number of non-Erlang terms found in the chunk. Notice that the log is not repaired.

Returns {Continuation2, eof} when the end of the log is reached, and {error, Reason} if an error occurs.

The returned continuation either is or is not valid in the next call to this function. This is because the log can wrap and delete the file into which the continuation points. To ensure this does not occur, the log can be blocked during the search.

close(Continuation)

-spec close(Continuation) -> ok | {error, Reason}
               when Continuation :: continuation(), Reason :: file:posix().

Closes a log file properly.

open(Filename)

-spec open(Filename) -> open_ret() when Filename :: string() | atom().

Equivalent to open(Filename, ...) except that the whole wrap log file is read.

open(Filename, N)

-spec open(Filename, N) -> open_ret() when Filename :: string() | atom(), N :: integer().

Filename specifies the name of the file to be read.

N specifies the index of the file to be read. Use open/1 to read the entire wrap log.

Returns {ok, Continuation} if the log/index file is opened successfully. Continuation is to be used when chunking or closing the file.

Returns {error, Reason} for all errors.

auth

This module is deprecated. See each function for what to use instead.

Erlang network authentication server.

For a description of the Magic Cookie system, refer to Distributed Erlang in the Erlang Reference Manual.

Summary

Types

cookie()

Functions

cookie() deprecated

Use erlang:get_cookie() in ERTS instead.

cookie(TheCookie) deprecated

Use erlang:set_cookie(node(), Cookie) in ERTS instead.

is_auth(Node) deprecated

Returns yes if communication with Node is authorized.

node_cookie([Node, Cookie]) deprecated

Equivalent to node_cookie(Node, Cookie).

node_cookie(Node, Cookie) deprecated

Sets the magic cookie of Node to Cookie and verifies the status of the authorization.

Types

cookie()

(not exported)

-type cookie() :: atom().

Functions

cookie()

This function is deprecated. auth:cookie/0 is deprecated; use erlang:get_cookie/0 instead.

-spec cookie() -> Cookie when Cookie :: cookie().

Use erlang:get_cookie() in ERTS instead.

cookie(TheCookie)

This function is deprecated. auth:cookie/1 is deprecated; use erlang:set_cookie/2 instead.

-spec cookie(TheCookie) -> true when TheCookie :: Cookie | [Cookie], Cookie :: cookie().

Use erlang:set_cookie(node(), Cookie) in ERTS instead.

is_auth(Node)

This function is deprecated. auth:is_auth/1 is deprecated; use net_adm:ping/1 instead.

-spec is_auth(Node) -> yes | no when Node :: node().

Returns yes if communication with Node is authorized.

Use net_adm:ping(Node) instead.

Notice that a connection to Node is established in this case. Returns no if Node does not exist or communication is not authorized (it has another cookie than auth thinks it has).

node_cookie([Node, Cookie])

This function is deprecated. auth:node_cookie/1 is deprecated; use erlang:set_cookie/2 and net_adm:ping/1 instead.

-spec node_cookie(Cookies :: [node() | cookie(), ...]) -> yes | no.

Equivalent to node_cookie(Node, Cookie).

node_cookie(Node, Cookie)

This function is deprecated. auth:node_cookie/2 is deprecated; use erlang:set_cookie/2 and net_adm:ping/1 instead.

-spec node_cookie(Node, Cookie) -> yes | no when Node :: node(), Cookie :: cookie().

Sets the magic cookie of Node to Cookie and verifies the status of the authorization.

Equivalent to calling erlang:set_cookie(Node, Cookie), followed by auth:is_auth(Node).

erl_boot_server

Boot server for other Erlang machines.

This server is used to assist diskless Erlang nodes that fetch all Erlang code from another machine.

This server is used to fetch all code, including the start script, if an Erlang runtime system is started with command-line flag -loader inet. All hosts specified with command-line flag -hosts Host must have one instance of this server running.

This server can be started with the Kernel configuration parameter start_boot_server.

The erl_boot_server can read regular files and files in archives. See code and erl_prim_loader in ERTS.

Warning

The support for loading code from archive files is experimental. It is released before it is ready to obtain early feedback. The file format, semantics, interfaces, and so on, can be changed in a future release.

SEE ALSO

erts:init, erts:erl_prim_loader

Summary

Functions

add_slave(Slave)

Adds a Slave node to the list of allowed slave hosts.

delete_slave(Slave)

Deletes a Slave node from the list of allowed slave hosts.

start(Slaves)

The same as start(Slaves, #{}).

start(Slaves, Options)

Starts the boot server. Slaves is a list of IP addresses for hosts, which are allowed to use this server as a boot server. Options is a map with configuration options.

start_link(Slaves)

The same as start_link(Slaves, #{}).

start_link(Slaves, Options)

The same as start(Slaves, Options), but it also links to the caller.

which_slaves()

Returns the current list of allowed slave hosts.

Functions

add_slave(Slave)

-spec add_slave(Slave) -> ok | {error, Reason}
                   when
                       Slave :: Host,
                       Host :: inet:ip_address() | inet:hostname(),
                       Reason :: {badarg, Slave}.

Adds a Slave node to the list of allowed slave hosts.

delete_slave(Slave)

-spec delete_slave(Slave) -> ok | {error, Reason}
                      when
                          Slave :: Host,
                          Host :: inet:ip_address() | inet:hostname(),
                          Reason :: {badarg, Slave}.

Deletes a Slave node from the list of allowed slave hosts.

start(Slaves)

-spec start(Slaves) -> {ok, Pid} | {error, Reason}
               when
                   Slaves :: [Host],
                   Host :: inet:ip_address() | inet:hostname(),
                   Pid :: pid(),
                   Reason :: any().

The same as start(Slaves, #{}).

start(Slaves, Options)

(since OTP @OTP-19944@)

-spec start(Slaves, Options) -> {ok, Pid} | {error, Reason}
               when
                   Slaves :: [Host],
                   Host :: inet:ip_address() | inet:hostname(),
                   Options :: #{listen_port => inet:port_number()},
                   Pid :: pid(),
                   Reason :: any().

Starts the boot server. Slaves is a list of IP addresses for hosts, which are allowed to use this server as a boot server. Options is a map with configuration options.

The boot server listening port can be configured with listen_port. If an empty map is provided, or listen_port is zero, then an ephemeral port is used.

start_link(Slaves)

-spec start_link(Slaves) -> {ok, Pid} | {error, Reason}
                    when
                        Slaves :: [Host],
                        Host :: inet:ip_address() | inet:hostname(),
                        Pid :: pid(),
                        Reason :: any().

The same as start_link(Slaves, #{}).

start_link(Slaves, Options)

(since OTP @OTP-19944@)

-spec start_link(Slaves, Options) -> {ok, Pid} | {error, Reason}
                    when
                        Slaves :: [Host],
                        Host :: inet:ip_address() | inet:hostname(),
                        Options :: #{listen_port => inet:port_number()},
                        Pid :: pid(),
                        Reason :: any().

The same as start(Slaves, Options), but it also links to the caller.

which_slaves()

-spec which_slaves() -> Slaves
                      when
                          Slaves :: [Slave],
                          Slave :: {Netmask :: inet:ip_address(), Address :: inet:ip_address()}.

Returns the current list of allowed slave hosts.

erl_epmd

Erlang interface towards epmd

This module communicates with the EPMD daemon, see epmd. To implement your own epmd module please see ERTS User's Guide: How to Implement an Alternative Node Discovery for Erlang Distribution

Summary

Functions

address_please(Name, Host, AddressFamily)

Called by the distribution module to resolves the Host to an IP address of a remote node.

listen_port_please(Name, Host)

Called by the distribution module to get which port the local node should listen to when accepting new distribution requests.

names(Host)

Called by net_adm:names/0. Host defaults to the localhost. Returns the names and associated port numbers of the Erlang nodes that epmd registered at the specified host. Returns {error, address} if epmd is not operational.

port_please(Name, Host)

Equivalent to port_please(Name, Host, infinity).

port_please(Name, Host, Timeout)

Requests the distribution port for the given node of an EPMD instance. Together with the port it returns a distribution protocol version which has been 5 since Erlang/OTP R6.

register_node(Name, Port)

Equivalent to register_node(Name, Port, inet).

register_node(Name, Port, Driver)

Registers the node with epmd and tells epmd what port will be used for the current node. It returns a creation number. This number is incremented on each register to help differentiate a new node instance connecting to epmd with the same name.

start_link()

This function is invoked as this module is added as a child of the erl_distribution supervisor.

Functions

address_please(Name, Host, AddressFamily)

(since OTP 21.0)

-spec address_please(Name, Host, AddressFamily) -> Success | {error, term()}
                        when
                            Name :: string(),
                            Host :: string() | inet:ip_address(),
                            AddressFamily :: inet | inet6,
                            Port :: non_neg_integer(),
                            Version :: non_neg_integer(),
                            Success :: {ok, inet:ip_address()} | {ok, inet:ip_address(), Port, Version}.

Called by the distribution module to resolves the Host to an IP address of a remote node.

As an optimization this function may also return the port and version of the remote node. If port and version are returned port_please/3 will not be called.

listen_port_please(Name, Host)

(since OTP 23.0)

-spec listen_port_please(Name, Host) -> {ok, Port}
                            when
                                Name :: atom() | string(),
                                Host :: atom() | string() | inet:ip_address(),
                                Port :: non_neg_integer().

Called by the distribution module to get which port the local node should listen to when accepting new distribution requests.

names(Host)

(since OTP 21.0)

-spec names(Host) -> {ok, [{Name, Port}]} | {error, Reason}
               when
                   Host :: atom() | string() | inet:ip_address(),
                   Name :: string(),
                   Port :: non_neg_integer(),
                   Reason :: address | file:posix().

Called by net_adm:names/0. Host defaults to the localhost. Returns the names and associated port numbers of the Erlang nodes that epmd registered at the specified host. Returns {error, address} if epmd is not operational.

Example:

(arne@dunn)1> erl_epmd:names(localhost).
{ok,[{"arne",40262}]}

port_please(Name, Host)

(since OTP 21.0)

-spec port_please(Name, Host) -> {port, Port, Version} | noport | closed | {error, term()}
                     when
                         Name :: atom() | string(),
                         Host :: atom() | string() | inet:ip_address(),
                         Port :: non_neg_integer(),
                         Version :: non_neg_integer().

Equivalent to port_please(Name, Host, infinity).

port_please(Name, Host, Timeout)

(since OTP 21.0)

-spec port_please(Name, Host, Timeout) -> {port, Port, Version} | noport | closed | {error, term()}
                     when
                         Name :: atom() | string(),
                         Host :: atom() | string() | inet:ip_address(),
                         Timeout :: non_neg_integer() | infinity,
                         Port :: non_neg_integer(),
                         Version :: non_neg_integer().

Requests the distribution port for the given node of an EPMD instance. Together with the port it returns a distribution protocol version which has been 5 since Erlang/OTP R6.

register_node(Name, Port)

(since OTP 21.0)

-spec register_node(Name, Port) -> Result
                       when
                           Name :: string(),
                           Port :: non_neg_integer(),
                           Creation :: non_neg_integer(),
                           Result :: {ok, Creation} | {error, already_registered} | term().

Equivalent to register_node(Name, Port, inet).

register_node(Name, Port, Driver)

(since OTP 21.0)

-spec register_node(Name, Port, Driver) -> Result
                       when
                           Name :: string(),
                           Port :: non_neg_integer(),
                           Driver :: inet_tcp | inet6_tcp | inet | inet6,
                           Creation :: non_neg_integer() | -1,
                           Result :: {ok, Creation} | {error, already_registered} | term().

Registers the node with epmd and tells epmd what port will be used for the current node. It returns a creation number. This number is incremented on each register to help differentiate a new node instance connecting to epmd with the same name.

After the node has successfully registered with epmd it will automatically attempt reconnect to the daemon if the connection is broken.

start_link()

(since OTP 21.0)

-spec start_link() -> {ok, pid()} | ignore | {error, term()}.

This function is invoked as this module is added as a child of the erl_distribution supervisor.

erpc

Enhanced Remote Procedure Call

This module provide services similar to Remote Procedure Calls. A remote procedure call is a method to call a function on a remote node and collect the answer. It is used for collecting information on a remote node, or for running a function with some specific side effects on the remote node.

This is an enhanced subset of the operations provided by the rpc module. Enhanced in the sense that it makes it possible to distinguish between returned value, raised exceptions, and other errors. erpc also has better performance and scalability than the original rpc implementation. However, current rpc module will utilize erpc in order to also provide these properties when possible.

In order for an erpc operation to succeed, the remote node also needs to support erpc. Typically only ordinary Erlang nodes as of OTP 23 have erpc support.

Note that it is up to the user to ensure that correct code to execute via erpc is available on the involved nodes.

Note

For some important information about distributed signals, see the Blocking Signaling Over Distribution section in the Processes chapter of the Erlang Reference Manual. Blocking signaling can, for example, cause timeouts in erpc to be significantly delayed.

Summary

Types

call_options()

Options to be used in call/3,5 and multicall/3,5 functions.

caught_call_exception()

request_id()

An opaque request identifier. For more information see send_request/4.

request_id_collection()

An opaque collection of request identifiers (request_id/0) where each request identifier can be associated with a label chosen by the user. For more information see reqids_new/0.

stack_item()

timeout_time()

The timeout time used by erpc functions.

Functions

call(Node, Fun)

Equivalent to call(Node, Fun, #{timeout => infinity}).

call(Node, Fun, TimeoutOrOptions)

Equivalent to erpc:call(Node, erlang, apply, [Fun,[]], #{timeout => Timeout}).

call(Node, Module, Function, Args)

Equivalent to call(Node, Module, Function, Args, #{timeout => infinity}).

call(Node, Module, Function, Args, TimeoutOrOptions)

Evaluates apply(Module, Function, Args) on node Node and returns the corresponding value Result.

cast(Node, Fun)

Equivalent to erpc:cast(Node,erlang,apply,[Fun,[]]).

cast(Node, Module, Function, Args)

Evaluates apply(Module, Function, Args) on node Node. No response is delivered to the calling process. cast() returns immediately after the cast request has been sent. Any failures beside bad arguments are silently ignored.

check_response(Message, RequestId)

Check if a message is a response to a call request previously made by the calling process using send_request/4.

check_response(Message, RequestIdCollection, Delete)

Check if a message is a response to a call request corresponding to a request identifier saved in RequestIdCollection. All request identifiers of RequestIdCollection must correspond to requests that have been made using send_request/4 or send_request/6, and all requests must have been made by the process calling this function.

multicall(Nodes, Fun)

Equivalent to multicall(Nodes, Fun, #{timeout => infinity}).

multicall(Nodes, Fun, TimeoutOrOptions)

Equivalent to erpc:multicall(Nodes, erlang, apply, [Fun,[]], #{timeout => Timeout}).

multicall(Nodes, Module, Function, Args)

Equivalent to multicall(Nodes, Module, Function, Args, #{timeout => infinity}).

multicall(Nodes, Module, Function, Args, TimeoutOrOptions)

Performs multiple call operations in parallel on multiple nodes.

multicast(Nodes, Fun)

Equivalent to erpc:multicast(Nodes,erlang,apply,[Fun,[]]).

multicast(Nodes, Module, Function, Args)

Evaluates apply(Module, Function, Args) on the nodes Nodes. No response is delivered to the calling process. multicast() returns immediately after the cast requests have been sent. Any failures beside bad arguments are silently ignored.

receive_response(RequestId)

Equivalent to receive_response(RequestId, infinity).

receive_response(RequestId, Timeout)

Receive a response to a call request previously made by the calling process using send_request/4.

receive_response(RequestIdCollection, Timeout, Delete)

Receive a response to a call request corresponding to a request identifier saved in RequestIdCollection. All request identifiers of RequestIdCollection must correspond to requests that have been made using send_request/4 or send_request/6, and all requests must have been made by the process calling this function.

reqids_add(RequestId, Label, RequestIdCollection)

Saves RequestId and associates a Label with the request identifier by adding this information to RequestIdCollection and returning the resulting request identifier collection.

reqids_new()

Returns a new empty request identifier collection. A request identifier collection can be utilized in order the handle multiple outstanding requests.

reqids_size(RequestIdCollection)

Returns the amount of request identifiers saved in RequestIdCollection.

reqids_to_list(RequestIdCollection)

Returns a list of {RequestId, Label} tuples which corresponds to all request identifiers with their associated labels present in the RequestIdCollection collection.

send_request(Node, Fun)

Equivalent to erpc:send_request(Node, erlang, apply, [Fun, []]).

send_request/4

Send an asynchronous call request to the node Node.

send_request(Node, Module, Function, Args, Label, RequestIdCollection)

Send an asynchronous call request to the node Node. The Label will be associated with the request identifier of the operation and added to the returned request identifier collection NewRequestIdCollection. The collection can later be used in order to get one response corresponding to a request in the collection by passing the collection as argument to receive_response/3, wait_response/3, or, check_response/3.

wait_response(RequestId)

Equivalent to erpc:wait_response(RequestId, 0). That is, poll for a response message to a call request previously made by the calling process.

wait_response(RequestId, WaitTime)

Wait or poll for a response message to a call request previously made by the calling process using send_request/4.

wait_response(RequestIdCollection, WaitTime, Delete)

Wait or poll for a response to a call request corresponding to a request identifier saved in RequestIdCollection. All request identifiers of RequestIdCollection must correspond to requests that have been made using send_request/4 or send_request/6, and all requests must have been made by the process calling this function.

Types

call_options()

(since OTP 28.0)

-type call_options() ::
          #{timeout => Timeout :: timeout_time(), always_spawn => AlwaysSpawn :: boolean()}.

Options to be used in call/3,5 and multicall/3,5 functions.

timeout - Upper time limit for call operations to complete, see timeout_time/0. Default: infinity.

always_spawn - If true, the apply() will always be performed in a freshly spawned process. If false, the calling process may be used instead, if possible. Default: false.

caught_call_exception()

(not exported) (since OTP 23.0)

-type caught_call_exception() ::
          {throw, Throw :: term()} |
          {exit, {exception, Reason :: term()}} |
          {error, {exception, Reason :: term(), StackTrace :: [stack_item()]}} |
          {exit, {signal, Reason :: term()}} |
          {error, {erpc, Reason :: term()}}.

request_id()

(since OTP 23.0)

-opaque request_id()

An opaque request identifier. For more information see send_request/4.

request_id_collection()

(since OTP 23.0)

-opaque request_id_collection()

An opaque collection of request identifiers (request_id/0) where each request identifier can be associated with a label chosen by the user. For more information see reqids_new/0.

stack_item()

(not exported) (since OTP 23.0)

-type stack_item() ::
          {Module :: atom(),
           Function :: atom(),
           Arity :: arity() | (Args :: [term()]),
           Location :: [{file, Filename :: string()} | {line, Line :: pos_integer()}]}.

timeout_time()

(since OTP 23.0)

-type timeout_time() :: 0..4294967295 | infinity | {abs, integer()}.

The timeout time used by erpc functions.

The value can be:

0..4294967295 - Timeout relative to current time in milliseconds.

infinity - Infinite timeout. That is, the operation will never time out.

{abs, Timeout} - An absolute Erlang monotonic time timeout in milliseconds. That is, the operation will time out when erlang:monotonic_time(millisecond) returns a value larger than or equal to Timeout. Timeout is not allowed to identify a time further into the future than 4294967295 milliseconds. Identifying the timeout using an absolute timeout value is especially handy when you have a deadline for responses corresponding to a complete collection of requests (request_id_collection/0), since you do not have to recalculate the relative time until the deadline over and over again.

Functions

call(Node, Fun)

(since OTP 23.0)

-spec call(Node, Fun) -> Result when Node :: node(), Fun :: function(), Result :: term().

Equivalent to call(Node, Fun, #{timeout => infinity}).

call(Node, Fun, TimeoutOrOptions)

(since OTP 23.0)

-spec call(Node, Fun, TimeoutOrOptions) -> Result
              when
                  Node :: node(),
                  Fun :: function(),
                  TimeoutOrOptions :: timeout_time() | call_options(),
                  Result :: term().

Equivalent to erpc:call(Node, erlang, apply, [Fun,[]], #{timeout => Timeout}).

May raise all the same exceptions as call/5 plus an {erpc, badarg} error exception if Fun is not a fun of zero arity.

call(Node, Module, Function, Args)

(since OTP 23.0)

-spec call(Node, Module, Function, Args) -> Result
              when
                  Node :: node(),
                  Module :: atom(),
                  Function :: atom(),
                  Args :: [term()],
                  Result :: term().

Equivalent to call(Node, Module, Function, Args, #{timeout => infinity}).

call(Node, Module, Function, Args, TimeoutOrOptions)

(since OTP 23.0)

-spec call(Node, Module, Function, Args, TimeoutOrOptions) -> Result
              when
                  Node :: node(),
                  Module :: atom(),
                  Function :: atom(),
                  Args :: [term()],
                  TimeoutOrOptions :: timeout_time() | call_options(),
                  Result :: term().

Evaluates apply(Module, Function, Args) on node Node and returns the corresponding value Result.

TimeoutOrOptions can be either a timeout time or a call options map (since OTP 28.0).

The call() function only returns if the applied function successfully returned without raising any uncaught exceptions, the operation did not time out, and no failures occurred. In all other cases an exception is raised. The following exceptions, listed by exception class, can currently be raised by call():

throw - The applied function called throw(Value) and did not catch this exception. The exception reason Value equals the argument passed to throw/1.

exit - Exception reason:

{exception, ExitReason} - The applied function called exit(ExitReason) and did not catch this exception. The exit reason ExitReason equals the argument passed to exit/1.

{signal, ExitReason} - The process that applied the function received an exit signal and terminated due to this signal. The process terminated with exit reason ExitReason.

error - Exception reason:

{exception, ErrorReason, StackTrace} - A runtime error occurred which raised an error exception while applying the function, and the applied function did not catch the exception. The error reason ErrorReason indicates the type of error that occurred. StackTrace is formatted as when caught in a try/catch construct. The StackTrace is limited to the applied function and functions called by it.

{erpc, ERpcErrorReason} - The erpc operation failed. The following ERpcErrorReasons are the most common ones:

badarg - If any one of these are true:

Node is not an atom.

Module is not an atom.

Function is not an atom.

Args is not a list. Note that the list is not verified to be a proper list at the client side.

Timeout is invalid.

noconnection - The connection to Node was lost or could not be established. The function may or may not be applied.

system_limit - The erpc operation failed due to some system limit being reached. This typically due to failure to create a process on the remote node Node, but can be other things as well.

timeout - The erpc operation timed out. The function may or may not be applied.

notsup - The remote node Node does not support this erpc operation.

If the erpc operation fails, but it is unknown if the function is/will be applied (that is, a timeout or a connection loss), the caller will not receive any further information about the result if/when the applied function completes. If the applied function explicitly communicates with the calling process, such communication may, of course, reach the calling process.

Note

If the always_spawn option is false (which is the default), you cannot make any assumptions about the process that will perform the apply(). It may be the calling process itself, or a freshly spawned process.

cast(Node, Fun)

(since OTP 23.0)

-spec cast(Node, Fun) -> ok when Node :: node(), Fun :: function().

Equivalent to erpc:cast(Node,erlang,apply,[Fun,[]]).

cast/2 fails with an {erpc, badarg} error exception if:

Node is not an atom.

Fun is not a a fun of zero arity.

cast(Node, Module, Function, Args)

(since OTP 23.0)

-spec cast(Node, Module, Function, Args) -> ok
              when Node :: node(), Module :: atom(), Function :: atom(), Args :: [term()].

Evaluates apply(Module, Function, Args) on node Node. No response is delivered to the calling process. cast() returns immediately after the cast request has been sent. Any failures beside bad arguments are silently ignored.

cast/4 fails with an {erpc, badarg} error exception if:

Node is not an atom.

Module is not an atom.

Function is not an atom.

Args is not a list. Note that the list is not verified to be a proper list at the client side.

check_response(Message, RequestId)

(since OTP 23.0)

-spec check_response(Message, RequestId) -> {response, Result} | no_response
                        when Message :: term(), RequestId :: request_id(), Result :: term().

Check if a message is a response to a call request previously made by the calling process using send_request/4.

RequestId should be the value returned from the previously made send_request/4 call, and the corresponding response should not already have been received and handled to completion by check_response/2, receive_response/2, or wait_response/2. Message is the message to check.

If Message does not correspond to the response, the atom no_response is returned. If Message corresponds to the response, the call operation is completed and either the result is returned as {response, Result} where Result corresponds to the value returned from the applied function or an exception is raised. The exceptions that can be raised corresponds to the same exceptions as can be raised by call/4. That is, no {erpc, timeout} error exception can be raised. check_response() will fail with an {erpc, badarg} exception if/when an invalid RequestId is detected.

If the erpc operation fails, but it is unknown if the function is/will be applied (that is, a connection loss), the caller will not receive any further information about the result if/when the applied function completes. If the applied function explicitly communicates with the calling process, such communication may, of course, reach the calling process.

check_response(Message, RequestIdCollection, Delete)

(since OTP 25.0)

-spec check_response(Message, RequestIdCollection, Delete) ->
                        {{response, Result}, Label, NewRequestIdCollection} | no_response | no_request
                        when
                            Message :: term(),
                            RequestIdCollection :: request_id_collection(),
                            Delete :: boolean(),
                            Result :: term(),
                            Label :: term(),
                            NewRequestIdCollection :: request_id_collection().

Check if a message is a response to a call request corresponding to a request identifier saved in RequestIdCollection. All request identifiers of RequestIdCollection must correspond to requests that have been made using send_request/4 or send_request/6, and all requests must have been made by the process calling this function.

Label is the label associated with the request identifier of the request that the response corresponds to. A request identifier is associated with a label when adding a request identifier in a request identifier collection, or when sending the request using send_request/6.

Compared to check_response/2, the returned result associated with a specific request identifier or an exception associated with a specific request identifier will be wrapped in a 3-tuple. The first element of this tuple equals the value that would have been produced by check_response/2, the second element equals the Label associated with the specific request identifier, and the third element NewRequestIdCollection is a possibly modified request identifier collection. The error exception {erpc, badarg} is not associated with any specific request identifier, and will hence not be wrapped.

If RequestIdCollection is empty, the atom no_request will be returned. If Message does not correspond to any of the request identifiers in RequestIdCollection, the atom no_response is returned.

If Delete equals true, the association with Label will have been deleted from RequestIdCollection in the resulting NewRequestIdCollection. If Delete equals false, NewRequestIdCollection will equal RequestIdCollection. Note that deleting an association is not for free and that a collection containing already handled requests can still be used by subsequent calls to check_response/3, receive_response/3, and wait_response/3. However, without deleting handled associations, the above calls will not be able to detect when there are no more outstanding requests to handle, so you will have to keep track of this some other way than relying on a no_request return. Note that if you pass a collection only containing associations of already handled or abandoned requests to check_response/3, it will always return no_response.

Note that a response might have been consumed uppon an {erpc, badarg} exception and if so, will be lost for ever.

multicall(Nodes, Fun)

(since OTP 23.0)

-spec multicall(Nodes, Fun) -> Result when Nodes :: [atom()], Fun :: function(), Result :: term().

Equivalent to multicall(Nodes, Fun, #{timeout => infinity}).

multicall(Nodes, Fun, TimeoutOrOptions)

(since OTP 23.0)

-spec multicall(Nodes, Fun, TimeoutOrOptions) -> Result
                   when
                       Nodes :: [atom()],
                       Fun :: function(),
                       TimeoutOrOptions :: timeout_time() | call_options(),
                       Result :: term().

Equivalent to erpc:multicall(Nodes, erlang, apply, [Fun,[]], #{timeout => Timeout}).

May raise all the same exceptions as multicall/5 plus an {erpc, badarg} error exception if Fun is not a fun of zero arity.

multicall(Nodes, Module, Function, Args)

(since OTP 23.0)

-spec multicall(Nodes, Module, Function, Args) -> Result
                   when
                       Nodes :: [atom()],
                       Module :: atom(),
                       Function :: atom(),
                       Args :: [term()],
                       Result :: [{ok, ReturnValue :: term()} | caught_call_exception()].

Equivalent to multicall(Nodes, Module, Function, Args, #{timeout => infinity}).

multicall(Nodes, Module, Function, Args, TimeoutOrOptions)

(since OTP 23.0)

-spec multicall(Nodes, Module, Function, Args, TimeoutOrOptions) -> Result
                   when
                       Nodes :: [atom()],
                       Module :: atom(),
                       Function :: atom(),
                       Args :: [term()],
                       TimeoutOrOptions :: timeout_time() | call_options(),
                       Result :: [{ok, ReturnValue :: term()} | caught_call_exception()].

Performs multiple call operations in parallel on multiple nodes.

That is, evaluates apply(Module, Function, Args) on the nodes Nodes in parallel.

TimeoutOrOptions can be either a timeout time or a call options map (since OTP 28.0).

The result is returned as a list where the result from each node is placed at the same position as the node name is placed in Nodes. Each item in the resulting list is formatted as either:

{ok, Result} - The call operation for this specific node returned Result.

{Class, ExceptionReason} - The call operation for this specific node raised an exception of class Class with exception reason ExceptionReason. These correspond to the exceptions that call/5 can raise.

multicall/5 fails with an {erpc, badarg} error exception if:

Nodes is not a proper list of atoms. Note that some requests may already have been sent when the failure occurs. That is, the function may or may not be applied on some nodes.

Module is not an atom.

Function is not an atom.

Args is not a list. Note that the list is not verified to be a proper list at the client side.

The call erpc:multicall(Nodes, Module, Function, Args) is equivalent to the call erpc:multicall(Nodes, Module, Function, Args, infinity). These calls are also equivalent to calling my_multicall(Nodes, Module, Function, Args) below if one disregard performance and failure behavior. multicall() can utilize a selective receive optimization which removes the need to scan the message queue from the beginning in order to find a matching message. The send_request()/receive_response() combination can, however, not utilize this optimization.

my_multicall(Nodes, Module, Function, Args) ->
  ReqIds = lists:map(fun (Node) ->
                       erpc:send_request(Node, Module, Function, Args)
                     end,
                     Nodes),
  lists:map(fun (ReqId) ->
              try
                {ok, erpc:receive_response(ReqId, infinity)}
              catch
                Class:Reason ->
                  {Class, Reason}
              end
            end,
            ReqIds).

If an erpc operation fails, but it is unknown if the function is/will be applied (that is, a timeout, connection loss, or an improper Nodes list), the caller will not receive any further information about the result if/when the applied function completes. If the applied function communicates with the calling process, such communication may, of course, reach the calling process.

Note

If the always_spawn option is false (which is the default), you cannot make any assumptions about the processes that will perform the apply()s. It may be the calling process itself, or freshly spawned processes, or a mix of both.

multicast(Nodes, Fun)

(since OTP 23.0)

-spec multicast(Nodes, Fun) -> ok when Nodes :: [node()], Fun :: function().

Equivalent to erpc:multicast(Nodes,erlang,apply,[Fun,[]]).

multicast/2 fails with an {erpc, badarg} error exception if:

Nodes is not a proper list of atoms.

Fun is not a a fun of zero arity.

multicast(Nodes, Module, Function, Args)

(since OTP 23.0)

-spec multicast(Nodes, Module, Function, Args) -> ok
                   when Nodes :: [node()], Module :: atom(), Function :: atom(), Args :: [term()].

Evaluates apply(Module, Function, Args) on the nodes Nodes. No response is delivered to the calling process. multicast() returns immediately after the cast requests have been sent. Any failures beside bad arguments are silently ignored.

multicast/4 fails with an {erpc, badarg} error exception if:

Nodes is not a proper list of atoms. Note that some requests may already have been sent when the failure occurs. That is, the function may or may not be applied on some nodes.

Module is not an atom.

Function is not an atom.

Args is not a list. Note that the list is not verified to be a proper list at the client side.

receive_response(RequestId)

(since OTP 23.0)

-spec receive_response(RequestId) -> Result when RequestId :: request_id(), Result :: term().

Equivalent to receive_response(RequestId, infinity).

receive_response(RequestId, Timeout)

(since OTP 23.0)

-spec receive_response(RequestId, Timeout) -> Result
                          when RequestId :: request_id(), Timeout :: timeout_time(), Result :: term().

Receive a response to a call request previously made by the calling process using send_request/4.

RequestId should be the value returned from the previously made send_request/4 call, and the corresponding response should not already have been received and handled to completion by receive_response(), check_response/4, or wait_response/4.

Timeout sets an upper time limit on how long to wait for a response. If the operation times out, the request identified by RequestId will be abandoned, then an {erpc, timeout} error exception will be raised. That is, no response corresponding to the request will ever be received after a timeout. If a response is received, the call operation is completed and either the result is returned or an exception is raised. The exceptions that can be raised corresponds to the same exceptions as can be raised by call/5. receive_response/2 will fail with an {erpc, badarg} exception if/when an invalid RequestId is detected or if an invalid Timeout is passed.

A call to the function my_call(Node, Module, Function, Args, Timeout) below is equivalent to the call erpc:call(Node, Module, Function, Args, Timeout) if one disregards performance. call() can utilize a selective receive optimization which removes the need to scan the message queue from the beginning in order to find a matching message. The send_request()/receive_response() combination can, however, not utilize this optimization.

my_call(Node, Module, Function, Args, Timeout) ->
  RequestId = erpc:send_request(Node, Module, Function, Args),
  erpc:receive_response(RequestId, Timeout).

If the erpc operation fails, but it is unknown if the function is/will be applied (that is, a timeout, or a connection loss), the caller will not receive any further information about the result if/when the applied function completes. If the applied function explicitly communicates with the calling process, such communication may, of course, reach the calling process.

receive_response(RequestIdCollection, Timeout, Delete)

(since OTP 25.0)

-spec receive_response(RequestIdCollection, Timeout, Delete) ->
                          {Result, Label, NewRequestIdCollection} | no_request
                          when
                              RequestIdCollection :: request_id_collection(),
                              Timeout :: timeout_time(),
                              Delete :: boolean(),
                              Result :: term(),
                              Label :: term(),
                              NewRequestIdCollection :: request_id_collection().

Receive a response to a call request corresponding to a request identifier saved in RequestIdCollection. All request identifiers of RequestIdCollection must correspond to requests that have been made using send_request/4 or send_request/6, and all requests must have been made by the process calling this function.

Label is the label associated with the request identifier of the request that the response corresponds to. A request identifier is associated with a label when adding a request identifier in a request identifier collection, or when sending the request using send_request/6.

Compared to receive_response/2, the returned result associated with a specific request identifier or an exception associated with a specific request identifier will be wrapped in a 3-tuple. The first element of this tuple equals the value that would have been produced by receive_response/2, the second element equals the Label associated with the specific request identifier, and the third element NewRequestIdCollection is a possibly modified request identifier collection. The error exceptions {erpc, badarg} and {erpc, timeout} are not associated with any specific request identifiers, and will hence not be wrapped.

If RequestIdCollection is empty, the atom no_request will be returned.

If the operation times out, all requests identified by RequestIdCollection will be abandoned, then an {erpc, timeout} error exception will be raised. That is, no responses corresponding to any of the request identifiers in RequestIdCollection will ever be received after a timeout. The difference between receive_response/3 and wait_response/3 is that receive_response/3 abandons the requests at timeout so that any potential future responses are ignored, while wait_response/3 does not.

If Delete equals true, the association with Label will have been deleted from RequestIdCollection in the resulting NewRequestIdCollection. If Delete equals false, NewRequestIdCollection will equal RequestIdCollection. Note that deleting an association is not for free and that a collection containing already handled requests can still be used by subsequent calls to receive_response/3, check_response/3, and wait_response/3. However, without deleting handled associations, the above calls will not be able to detect when there are no more outstanding requests to handle, so you will have to keep track of this some other way than relying on a no_request return. Note that if you pass a collection only containing associations of already handled or abandoned requests to receive_response/3, it will always block until a timeout determined by Timeout is triggered.

Note that a response might have been consumed uppon an {erpc, badarg} exception and if so, will be lost for ever.

reqids_add(RequestId, Label, RequestIdCollection)

(since OTP 25.0)

-spec reqids_add(RequestId :: request_id(),
                 Label :: term(),
                 RequestIdCollection :: request_id_collection()) ->
                    NewRequestIdCollection :: request_id_collection().

Saves RequestId and associates a Label with the request identifier by adding this information to RequestIdCollection and returning the resulting request identifier collection.

reqids_new()

(since OTP 25.0)

-spec reqids_new() -> NewRequestIdCollection :: request_id_collection().

Returns a new empty request identifier collection. A request identifier collection can be utilized in order the handle multiple outstanding requests.

Request identifiers of requests made by send_request/4 can be saved in a request identifier collection using reqids_add/3. Such a collection of request identifiers can later be used in order to get one response corresponding to a request in the collection by passing the collection as argument to check_response/3, receive_response/3, and wait_response/3.

reqids_size/1 can be used to determine the amount of request identifiers in a request identifier collection.

reqids_size(RequestIdCollection)

(since OTP 25.0)

-spec reqids_size(RequestIdCollection :: request_id_collection()) -> non_neg_integer().

Returns the amount of request identifiers saved in RequestIdCollection.

reqids_to_list(RequestIdCollection)

(since OTP 25.0)

-spec reqids_to_list(RequestIdCollection :: request_id_collection()) ->
                        [{RequestId :: request_id(), Label :: term()}].

Returns a list of {RequestId, Label} tuples which corresponds to all request identifiers with their associated labels present in the RequestIdCollection collection.

send_request(Node, Fun)

(since OTP 23.0)

-spec send_request(Node, Fun) -> RequestId
                      when Node :: node(), Fun :: function(), RequestId :: request_id().

Equivalent to erpc:send_request(Node, erlang, apply, [Fun, []]).

Fails with an {erpc, badarg} error exception if:

Node is not an atom.

Fun is not a fun of zero arity.

send_request/4

(since OTP 23.0)

-spec send_request(Node, Module, Function, Args) -> RequestId
                      when
                          Node :: node(),
                          Module :: atom(),
                          Function :: atom(),
                          Args :: [term()],
                          RequestId :: request_id();
                  (Node, Fun, Label, RequestIdCollection) -> NewRequestIdCollection
                      when
                          Node :: node(),
                          Fun :: function(),
                          Label :: term(),
                          RequestIdCollection :: request_id_collection(),
                          NewRequestIdCollection :: request_id_collection().

Send an asynchronous call request to the node Node.

send_request/4 returns a request identifier that later is to be passed to either receive_response/2, wait_response/2, or, check_response/2 in order to get the response of the call request. Besides passing the request identifier directly to these functions, it can also be added in a request identifier collection using reqids_add/3. Such a collection of request identifiers can later be used in order to get one response corresponding to a request in the collection by passing the collection as argument to receive_response/3, wait_response/3, or, check_response/3. If you are about to save the request identifier in a request identifier collection, you may want to consider using send_request/6 instead.

A call to the function my_call(Node, Module, Function, Args, Timeout) below is equivalent to the call erpc:call(Node, Module, Function, Args, Timeout) if one disregards performance. call() can utilize a selective receive optimization which removes the need to scan the message queue from the beginning in order to find a matching message. The send_request()/receive_response() combination can, however, not utilize this optimization.

my_call(Node, Module, Function, Args, Timeout) ->
  RequestId = erpc:send_request(Node, Module, Function, Args),
  erpc:receive_response(RequestId, Timeout).

Fails with an {erpc, badarg} error exception if:

Node is not an atom.

Module is not an atom.

Function is not an atom.

Args is not a list. Note that the list is not verified to be a proper list at the client side.

Equivalent to erpc:send_request(Node, erlang, apply, [Fun,[]]), Label, RequestIdCollection).

Fails with an {erpc, badarg} error exception if:

Node is not an atom.

Fun is not a fun of zero arity.

RequestIdCollection is detected not to be request identifier collection.

send_request(Node, Module, Function, Args, Label, RequestIdCollection)

(since OTP 25.0)

-spec send_request(Node, Module, Function, Args, Label, RequestIdCollection) -> NewRequestIdCollection
                      when
                          Node :: node(),
                          Module :: atom(),
                          Function :: atom(),
                          Args :: [term()],
                          Label :: term(),
                          RequestIdCollection :: request_id_collection(),
                          NewRequestIdCollection :: request_id_collection().

Send an asynchronous call request to the node Node. The Label will be associated with the request identifier of the operation and added to the returned request identifier collection NewRequestIdCollection. The collection can later be used in order to get one response corresponding to a request in the collection by passing the collection as argument to receive_response/3, wait_response/3, or, check_response/3.

Equivalent to erpc:reqids_add(erpc:send_request(Node, Module, Function, Args), Label, RequestIdCollection), but calling send_request/6 is slightly more efficient.

Fails with an {erpc, badarg} error exception if:

Node is not an atom.

Module is not an atom.

Function is not an atom.

Args is not a list. Note that the list is not verified to be a proper list at the client side.

RequestIdCollection is detected not to be request identifier collection.

wait_response(RequestId)

(since OTP 23.0)

-spec wait_response(RequestId) -> {response, Result} | no_response
                       when RequestId :: request_id(), Result :: term().

Equivalent to erpc:wait_response(RequestId, 0). That is, poll for a response message to a call request previously made by the calling process.

wait_response(RequestId, WaitTime)

(since OTP 23.0)

-spec wait_response(RequestId, WaitTime) -> {response, Result} | no_response
                       when RequestId :: request_id(), WaitTime :: timeout_time(), Result :: term().

Wait or poll for a response message to a call request previously made by the calling process using send_request/4.

RequestId should be the value returned from the previously made send_request() call, and the corresponding response should not already have been received and handled to completion by check_response/2, receive_response/2, or wait_response().

WaitTime sets an upper time limit on how long to wait for a response. If no response is received before the WaitTime timeout has triggered, the atom no_response is returned. It is valid to continue waiting for a response as many times as needed up until a response has been received and completed by check_response(), receive_response(), or wait_response(). If a response is received, the call operation is completed and either the result is returned as {response, Result} where Result corresponds to the value returned from the applied function or an exception is raised. The exceptions that can be raised corresponds to the same exceptions as can be raised by call/4. That is, no {erpc, timeout} error exception can be raised. wait_response/2 will fail with an {erpc, badarg} exception if/when an invalid RequestId is detected or if an invalid WaitTime is passed.

If the erpc operation fails, but it is unknown if the function is/will be applied (that is, a too large wait time value, or a connection loss), the caller will not receive any further information about the result if/when the applied function completes. If the applied function explicitly communicates with the calling process, such communication may, of course, reach the calling process.

wait_response(RequestIdCollection, WaitTime, Delete)

(since OTP 25.0)

-spec wait_response(RequestIdCollection, WaitTime, Delete) ->
                       {{response, Result}, Label, NewRequestIdCollection} | no_response | no_request
                       when
                           RequestIdCollection :: request_id_collection(),
                           WaitTime :: timeout_time(),
                           Delete :: boolean(),
                           Label :: term(),
                           NewRequestIdCollection :: request_id_collection(),
                           Result :: term().

Wait or poll for a response to a call request corresponding to a request identifier saved in RequestIdCollection. All request identifiers of RequestIdCollection must correspond to requests that have been made using send_request/4 or send_request/6, and all requests must have been made by the process calling this function.

Label is the label associated with the request identifier of the request that the response corresponds to. A request identifier is associated with a label when adding a request identifier in a request identifier collection, or when sending the request using send_request/6.

Compared to wait_response/2, the returned result associated with a specific request identifier or an exception associated with a specific request identifier will be wrapped in a 3-tuple. The first element of this tuple equals the value that would have been produced by wait_response/2, the second element equals the Label associated with the specific request identifier, and the third element NewRequestIdCollection is a possibly modified request identifier collection. The error exception {erpc, badarg} is not associated with any specific request identifier, and will hence not be wrapped.

If RequestIdCollection is empty, no_request will be returned. If no response is received before the WaitTime timeout has triggered, the atom no_response is returned. It is valid to continue waiting for a response as many times as needed up until a response has been received and completed by check_response(), receive_response(), or wait_response(). The difference between receive_response/3 and wait_response/3 is that receive_response/3 abandons requests at timeout so that any potential future responses are ignored, while wait_response/3 does not.

If Delete equals true, the association with Label will have been deleted from RequestIdCollection in the resulting NewRequestIdCollection. If Delete equals false, NewRequestIdCollection will equal RequestIdCollection. Note that deleting an association is not for free and that a collection containing already handled requests can still be used by subsequent calls to wait_response/3, check_response/3, and receive_response/3. However, without deleting handled associations, the above calls will not be able to detect when there are no more outstanding requests to handle, so you will have to keep track of this some other way than relying on a no_request return. Note that if you pass a collection only containing associations of already handled or abandoned requests to wait_response/3, it will always block until a timeout determined by WaitTime is triggered and then return no_response.

Note that a response might have been consumed uppon an {erpc, badarg} exception and if so, will be lost for ever.

global

A global name registration facility.

This module consists of the following services:

Registration of global names

Global locks

Maintenance of the fully connected network

As of OTP 25, global will by default prevent overlapping partitions due to network issues by actively disconnecting from nodes that reports that they have lost connections to other nodes. This will cause fully connected partitions to form instead of leaving the network in a state with overlapping partitions.

Warning

Prevention of overlapping partitions can be disabled using the prevent_overlapping_partitions Kernel parameter, making global behave like it used to do. This is, however, problematic for all applications expecting a fully connected network to be provided, such as for example mnesia, but also for global itself. A network of overlapping partitions might cause the internal state of global to become inconsistent. Such an inconsistency can remain even after such partitions have been brought together to form a fully connected network again. The effect on other applications that expects that a fully connected network is maintained may vary, but they might misbehave in very subtle hard to detect ways during such a partitioning. Since you might get hard to detect issues without this fix, you are strongly advised not to disable this fix. Also note that this fix has to be enabled on all nodes in the network in order to work properly.

Note

None of the above services will be reliably delivered unless both of the kernel parameters connect_all and prevent_overlapping_partitions are enabled. Calls to the global API will, however, not fail even though one or both of them are disabled. You will just get unreliable results.

These services are controlled through the process global_name_server that exists on every node. The global name server starts automatically when a node is started. With the term global is meant over a system consisting of many Erlang nodes.

The ability to globally register names is a central concept in the programming of distributed Erlang systems. In this module, the equivalent of the register/2 and whereis/1 BIFs (for local name registration) are provided, but for a network of Erlang nodes. A registered name is an alias for a process identifier (pid). The global name server monitors globally registered pids. If a process terminates, the name is also globally unregistered.

The registered names are stored in replica global name tables on every node. There is no central storage point. Thus, the translation of a name to a pid is fast, as it is always done locally. For any action resulting in a change to the global name table, all tables on other nodes are automatically updated.

Global locks have lock identities and are set on a specific resource. For example, the specified resource can be a pid. When a global lock is set, access to the locked resource is denied for all resources other than the lock requester.

Both the registration and lock services are atomic. All nodes involved in these actions have the same view of the information.

The global name server also performs the critical task of continuously monitoring changes in node configuration. If a node that runs a globally registered process goes down, the name is globally unregistered. To this end, the global name server subscribes to nodeup and nodedown messages sent from module net_kernel. Relevant Kernel application variables in this context are net_setuptime, net_ticktime, and dist_auto_connect.

The name server also maintains a fully connected network. For example, if node N1 connects to node N2 (which is already connected to N3), the global name servers on the nodes N1 and N3 ensure that also N1 and N3 are connected. In this case, the name registration service cannot be used, but the lock mechanism still works.

If the global name server fails to connect nodes (N1 and N3 in the example), a warning event is sent to the error logger. The presence of such an event does not exclude the nodes to connect later (you can, for example, try command rpc:call(N1, net_adm, ping, [N2]) in the Erlang shell), but it indicates a network problem.

Note

If the fully connected network is not set up properly, try first to increase the value of net_setuptime.

See Also

global_group, net_kernel

Summary

Types

id()

A lock id used to set or delete lock ResourceId on behalf of LockRequesterId.

method()

retries()

trans_fun()

Functions

del_lock(Id)

Equivalent to del_lock(Id, [node() | nodes()]).

del_lock(Id, Nodes)

Deletes the lock Id synchronously.

disconnect()

Disconnect from all other nodes known to global.

notify_all_name(Name, Pid1, Pid2)

The function unregisters both pids and sends the message {global_name_conflict, Name, OtherPid} to both processes.

random_exit_name(Name, Pid1, Pid2)

The function randomly selects one of the pids for registration and kills the other one.

random_notify_name(Name, Pid1, Pid2)

The function randomly selects one of the pids for registration, and sends the message {global_name_conflict, Name} to the other pid.

re_register_name(Name, Pid)

Equivalent to re_register_name(Name, Pid, fun random_exit_name/3).

re_register_name(Name, Pid, Resolve)

Atomically changes the registered name Name on all nodes to refer to Pid.

register_name(Name, Pid)

Equivalent to register_name(Name, Pid, fun random_exit_name/3).

register_name(Name, Pid, Resolve)

Globally associates name Name with a pid, that is, globally notifies all nodes of a new global name in a network of Erlang nodes.

registered_names()

Returns a list of all globally registered names.

send(Name, Msg)

Sends message Msg to the pid globally registered as Name.

set_lock(Id)

Equivalent to set_lock(Id, [node() | nodes()], infinity).

set_lock(Id, Nodes)

Equivalent to set_lock(Id, Nodes, infinity).

set_lock(Id, Nodes, Retries)

Sets a lock on the specified nodes on using id/0.

sync()

Synchronizes the global name server with all nodes known to this node.

trans(Id, Fun)

Equivalent to trans(Id, Fun, [node() | nodes()], infinity).

trans(Id, Fun, Nodes)

Equivalent to trans(Id, Fun, Nodes, infinity).

trans(Id, Fun, Nodes, Retries)

Sets a lock on Id (using set_lock/3).

unregister_name(Name)

Removes the globally registered name Name from the network of Erlang nodes.

whereis_name(Name)

Returns the pid with the globally registered name Name. Returns undefined if the name is not globally registered.

Types

id()

(not exported)

-type id() :: {ResourceId :: term(), LockRequesterId :: term()}.

A lock id used to set or delete lock ResourceId on behalf of LockRequesterId.

method()

(not exported)

-type method() :: fun((Name :: term(), Pid :: pid(), Pid2 :: pid()) -> pid() | none).

retries()

(not exported)

-type retries() :: non_neg_integer() | infinity.

trans_fun()

(not exported)

-type trans_fun() :: function() | {module(), atom()}.

Functions

del_lock(Id)

-spec del_lock(Id) -> true when Id :: id().

Equivalent to del_lock(Id, [node() | nodes()]).

del_lock(Id, Nodes)

-spec del_lock(Id, Nodes) -> true when Id :: id(), Nodes :: [node()].

Deletes the lock Id synchronously.

disconnect()

(since OTP 25.1)

-spec disconnect() -> [node()].

Disconnect from all other nodes known to global.

A list of node names (in an unspecified order) is returned which corresponds to the nodes that were disconnected. All disconnect operations performed have completed when global:disconnect/0 returns.

The disconnects will be made in such a way that only the current node will be removed from the cluster of global nodes. If prevent_overlapping_partitions is enabled and you disconnect, from other nodes in the cluster of global nodes, by other means, global on the other nodes may partition the remaining nodes in order to ensure that no overlapping partitions appear. Even if prevent_overlapping_partitions is disabled, you should preferably use global:disconnect/0 in order to remove current node from a cluster of global nodes, since you otherwise likely will create overlapping partitions which might cause problems.

Note that if the node is going to be halted, there is no need to remove it from a cluster of global nodes explicitly by calling global:disconnect/0 before halting it. The removal from the cluster is taken care of automatically when the node halts regardless of whether prevent_overlapping_partitions is enabled or not.

If current node has been configured to be part of a global group, only connected and/or synchronized nodes in that group are known to global, so global:disconnect/0 will only disconnect from those nodes. If current node is not part of a global group, all connected visible nodes will be known to global, so global:disconnect/0 will disconnect from all those nodes.

Note that information about connected nodes does not instantaneously reach global, so the caller might see a node part of the result returned by nodes() while it still is not known to global. The disconnect operation will, however, still not cause any overlapping partitions when prevent_overlapping_partitions is enabled. If prevent_overlapping_partitions is disabled, overlapping partitions might form in this case.

Note that when prevent_overlapping_partitions is enabled, you may see warning reports on other nodes when they detect that current node has disconnected. These are in this case completely harmless and can be ignored.

notify_all_name(Name, Pid1, Pid2)

-spec notify_all_name(Name, Pid1, Pid2) -> none when Name :: term(), Pid1 :: pid(), Pid2 :: pid().

The function unregisters both pids and sends the message {global_name_conflict, Name, OtherPid} to both processes.

Can be used as a name resolving function for register_name/3 and re_register_name/3.

random_exit_name(Name, Pid1, Pid2)

-spec random_exit_name(Name, Pid1, Pid2) -> pid() when Name :: term(), Pid1 :: pid(), Pid2 :: pid().

The function randomly selects one of the pids for registration and kills the other one.

Can be used as a name resolving function for register_name/3 and re_register_name/3.

random_notify_name(Name, Pid1, Pid2)

-spec random_notify_name(Name, Pid1, Pid2) -> pid() when Name :: term(), Pid1 :: pid(), Pid2 :: pid().

The function randomly selects one of the pids for registration, and sends the message {global_name_conflict, Name} to the other pid.

Can be used as a name resolving function for register_name/3 and re_register_name/3.

re_register_name(Name, Pid)

-spec re_register_name(Name, Pid) -> yes when Name :: term(), Pid :: pid().

Equivalent to re_register_name(Name, Pid, fun random_exit_name/3).

re_register_name(Name, Pid, Resolve)

-spec re_register_name(Name, Pid, Resolve) -> yes when Name :: term(), Pid :: pid(), Resolve :: method().

Atomically changes the registered name Name on all nodes to refer to Pid.

Function Resolve has the same behavior as in register_name/2,3.

register_name(Name, Pid)

-spec register_name(Name, Pid) -> yes | no when Name :: term(), Pid :: pid().

Equivalent to register_name(Name, Pid, fun random_exit_name/3).

register_name(Name, Pid, Resolve)

-spec register_name(Name, Pid, Resolve) -> yes | no
                       when Name :: term(), Pid :: pid(), Resolve :: method().

Globally associates name Name with a pid, that is, globally notifies all nodes of a new global name in a network of Erlang nodes.

When new nodes are added to the network, they are informed of the globally registered names that already exist. The network is also informed of any global names in newly connected nodes. If any name clashes are discovered, function Resolve is called. Its purpose is to decide which pid is correct. If the function crashes, or returns anything other than one of the pids, the name is unregistered. This function is called once for each name clash.

Warning

If you plan to change code without restarting your system, you must use an external fun (fun Module:Function/Arity) as function Resolve. If you use a local fun, you can never replace the code for the module that the fun belongs to.

Three predefined resolve functions exist: random_exit_name/3, random_notify_name/3, and notify_all_name/3.

This function is completely synchronous, that is, when this function returns, the name is either registered on all nodes or none.

The function returns yes if successful, no if it fails. For example, no is returned if an attempt is made to register an already registered process or to register a process with a name that is already in use.

Note

Releases up to and including Erlang/OTP R10 did not check if the process was already registered. The global name table could therefore become inconsistent. The old (buggy) behavior can be chosen by giving the Kernel application variable global_multi_name_action the value allow.

If a process with a registered name dies, or the node goes down, the name is unregistered on all nodes.

registered_names()

-spec registered_names() -> [Name] when Name :: term().

Returns a list of all globally registered names.

send(Name, Msg)

-spec send(Name, Msg) -> Pid when Name :: term(), Msg :: term(), Pid :: pid().

Sends message Msg to the pid globally registered as Name.

If Name is not a globally registered name, the calling function exits with reason {badarg, {Name, Msg}}.

set_lock(Id)

-spec set_lock(Id) -> boolean() when Id :: id().

Equivalent to set_lock(Id, [node() | nodes()], infinity).

set_lock(Id, Nodes)

-spec set_lock(Id, Nodes) -> boolean() when Id :: id(), Nodes :: [node()].

Equivalent to set_lock(Id, Nodes, infinity).

set_lock(Id, Nodes, Retries)

-spec set_lock(Id, Nodes, Retries) -> boolean() when Id :: id(), Nodes :: [node()], Retries :: retries().

Sets a lock on the specified nodes on using id/0.

If a lock already exists on ResourceId for another requester than LockRequesterId, and Retries is not equal to 0, the process sleeps for a while and tries to execute the action later. When Retries attempts have been made, false is returned, otherwise true. If Retries is infinity, true is eventually returned (unless the lock is never released).

This function is completely synchronous.

If a process that holds a lock dies, or the node goes down, the locks held by the process are deleted.

The global name server keeps track of all processes sharing the same lock, that is, if two processes set the same lock, both processes must delete the lock.

This function does not address the problem of a deadlock. A deadlock can never occur as long as processes only lock one resource at a time. A deadlock can occur if some processes try to lock two or more resources. It is up to the application to detect and rectify a deadlock.

Note

Avoid the following values of ResourceId, otherwise Erlang/OTP does not work properly:

dist_ac

global

mnesia_adjust_log_writes

mnesia_table_lock

sync()

-spec sync() -> ok | {error, Reason :: term()}.

Synchronizes the global name server with all nodes known to this node.

These are the nodes that are returned from nodes(). When this function returns, the global name server receives global information from all nodes. This function can be called when new nodes are added to the network.

The only possible error reason Reason is {"global_groups definition error", Error}.

trans(Id, Fun)

-spec trans(Id, Fun) -> Res | aborted when Id :: id(), Fun :: trans_fun(), Res :: term().

Equivalent to trans(Id, Fun, [node() | nodes()], infinity).

trans(Id, Fun, Nodes)

-spec trans(Id, Fun, Nodes) -> Res | aborted
               when Id :: id(), Fun :: trans_fun(), Nodes :: [node()], Res :: term().

Equivalent to trans(Id, Fun, Nodes, infinity).

trans(Id, Fun, Nodes, Retries)

-spec trans(Id, Fun, Nodes, Retries) -> Res | aborted
               when
                   Id :: id(),
                   Fun :: trans_fun(),
                   Nodes :: [node()],
                   Retries :: retries(),
                   Res :: term().

Sets a lock on Id (using set_lock/3).

If this succeeds, Fun() is evaluated and the result Res is returned. Returns aborted if the lock attempt fails. If Retries is set to infinity, the transaction does not abort.

infinity is the default setting and is used if no value is specified for Retries.

unregister_name(Name)

-spec unregister_name(Name) -> _ when Name :: term().

Removes the globally registered name Name from the network of Erlang nodes.

whereis_name(Name)

-spec whereis_name(Name) -> pid() | undefined when Name :: term().

Returns the pid with the globally registered name Name. Returns undefined if the name is not globally registered.

global_group

Grouping nodes to global name registration groups.

This module makes it possible to partition the nodes of a system into global groups. Each global group has its own global namespace, see global.

The main advantage of dividing systems into global groups is that the background load decreases while the number of nodes to be updated is reduced when manipulating globally registered names.

The Kernel configuration parameter global_groups defines the global groups:

{global_groups, [GroupTuple :: group_tuple()]}

For the processes and nodes to run smoothly using the global group functionality, the following criteria must be met:

An instance of the global group server, global_group, must be running on each node. The processes are automatically started and synchronized when a node is started.

All involved nodes must agree on the global group definition, otherwise the behavior of the system is undefined.

All nodes in the system must belong to exactly one global group.

In the following descriptions, a group node is a node belonging to the same global group as the local node.

Notes

In the situation where a node has lost its connections to other nodes in its global group, but has connections to nodes in other global groups, a request from another global group can produce an incorrect or misleading result. For example, the isolated node can have inaccurate information about registered names in its global group.

Function send/2,3 is not secure.

Distribution of applications is highly dependent of the global group definitions. It is not recommended that an application is distributed over many global groups, as the registered names can be moved to another global group at failover/takeover. Nothing prevents this to be done, but the application code must then handle the situation.

See Also

global, erl

Summary

Types

group_name()

group_tuple()

A GroupTuple without PublishType is the same as a GroupTuple with PublishType equal to normal.

info_item()

name()

A registered name.

publish_type()

A node started with command-line flag -hidden (see erl) is said to be a hidden node. A hidden node establishes hidden connections to nodes not part of the same global group, but normal (visible) connections to nodes part of the same global group.

sync_state()

where()

Functions

global_groups()

Returns a tuple containing the name of the global group that the local node belongs to, and the list of all other known group names.

info()

Returns a list containing information about the global groups. Each list element is a tuple. The order of the tuples is undefined.

monitor_nodes(Flag)

Alter the calling process' subscription of node status change messages.

own_nodes()

Returns the names of all group nodes, regardless of their current status.

registered_names(Where)

Returns a list of all names that are globally registered on the specified node or in the specified global group.

send(Name, Msg)

Sends Msg to the pid represented by the globally registered name Name.

send(Where, Name, Msg)

Equivalent to send(Name, Msg) except that he search is limited to the node or global group specified by Where.

sync()

Synchronizes the group nodes, that is, the global name servers on the group nodes. Also checks the names globally registered in the current global group and unregisters them on any known node not part of the group.

whereis_name(Name)

Searched for Name in any global group.

whereis_name(Where, Name)

Equivalent to whereis_name(Name) except that he search is limited to the node or global group specified by Where.

Types

group_name()

(not exported)

-type group_name() :: atom().

group_tuple()

(not exported)

-type group_tuple() ::
          {GroupName :: group_name(), [node()]} |
          {GroupName :: group_name(), PublishType :: publish_type(), [node()]}.

A GroupTuple without PublishType is the same as a GroupTuple with PublishType equal to normal.

info_item()

(not exported)

-type info_item() ::
          {state, State :: sync_state()} |
          {own_group_name, GroupName :: group_name()} |
          {own_group_nodes, Nodes :: [node()]} |
          {synched_nodes, Nodes :: [node()]} |
          {sync_error, Nodes :: [node()]} |
          {no_contact, Nodes :: [node()]} |
          {other_groups, Groups :: [group_tuple()]} |
          {monitoring, Pids :: [pid()]}.

name()

(not exported)

-type name() :: atom().

A registered name.

publish_type()

(not exported)

-type publish_type() :: hidden | normal.

A node started with command-line flag -hidden (see erl) is said to be a hidden node. A hidden node establishes hidden connections to nodes not part of the same global group, but normal (visible) connections to nodes part of the same global group.

A global group defined with PublishType equal to hidden is said to be a hidden global group. All nodes in a hidden global group are hidden nodes, whether they are started with command-line flag -hidden or not.

sync_state()

(not exported)

-type sync_state() :: no_conf | synced.

where()

(not exported)

-type where() :: {node, node()} | {group, group_name()}.

Functions

global_groups()

-spec global_groups() -> {GroupName, GroupNames} | undefined
                       when GroupName :: group_name(), GroupNames :: [GroupName].

Returns a tuple containing the name of the global group that the local node belongs to, and the list of all other known group names.

Returns undefined if no global groups are defined.

info()

-spec info() -> [info_item()].

Returns a list containing information about the global groups. Each list element is a tuple. The order of the tuples is undefined.

{state, State} - If the local node is part of a global group, State is equal to synced. If no global groups are defined, State is equal to no_conf.

{own_group_name, GroupName} - The name (atom) of the group that the local node belongs to.

{own_group_nodes, Nodes} - A list of node names (atoms), the group nodes.

{synced_nodes, Nodes} - A list of node names, the group nodes currently synchronized with the local node.

{sync_error, Nodes} - A list of node names, the group nodes with which the local node has failed to synchronize.

{no_contact, Nodes} - A list of node names, the group nodes to which there are currently no connections.

{other_groups, Groups} - Groups is a list of tuples {GroupName, Nodes}, specifying the name and nodes of the other global groups.

{monitoring, Pids} - A list of pids, specifying the processes that have subscribed to nodeup and nodedown messages.

monitor_nodes(Flag)

-spec monitor_nodes(Flag) -> ok when Flag :: boolean().

Alter the calling process' subscription of node status change messages.

If Flag is equal to true the calling process starts subscribing to node status change messages. If equal to false it stops subscribing.

A process that has subscribed receives the messages {nodeup, Node} and {nodedown, Node} when a group node connects or disconnects, respectively.

own_nodes()

-spec own_nodes() -> Nodes when Nodes :: [Node :: node()].

Returns the names of all group nodes, regardless of their current status.

registered_names(Where)

-spec registered_names(Where) -> Names when Where :: where(), Names :: [Name :: name()].

Returns a list of all names that are globally registered on the specified node or in the specified global group.

send(Name, Msg)

-spec send(Name, Msg) -> pid() | {badarg, {Name, Msg}} when Name :: name(), Msg :: term().

Sends Msg to the pid represented by the globally registered name Name.

send/2 searches for Name any any global group. The global groups are searched in the order that they appear in the value of configuration parameter global_groups.

If Name is found, message Msg is sent to the corresponding pid. The pid is also the return value of the function. If the name is not found, the function returns {badarg, {Name, Msg}}.

send(Where, Name, Msg)

-spec send(Where, Name, Msg) -> pid() | {badarg, {Name, Msg}}
              when Where :: where(), Name :: name(), Msg :: term().

Equivalent to send(Name, Msg) except that he search is limited to the node or global group specified by Where.

sync()

-spec sync() -> ok.

Synchronizes the group nodes, that is, the global name servers on the group nodes. Also checks the names globally registered in the current global group and unregisters them on any known node not part of the group.

If synchronization is not possible, an error report is sent to the error logger (see also error_logger.

Returns {error, {'invalid global_groups definition', Bad}} if configuration parameter global_groups has an invalid value Bad.

whereis_name(Name)

-spec whereis_name(Name) -> pid() | undefined when Name :: name().

Searched for Name in any global group.

The global groups are searched in the order that they appear in the value of configuration parameter global_groups.

If Name is found, the corresponding pid is returned. If the name is not found, the function returns undefined.

whereis_name(Where, Name)

-spec whereis_name(Where, Name) -> pid() | undefined when Where :: where(), Name :: name().

Equivalent to whereis_name(Name) except that he search is limited to the node or global group specified by Where.

net_adm

Various Erlang net administration routines.

This module contains various network utility functions.

Files

File .hosts.erlang consists of a number of host names written as Erlang terms. It is looked for in the current work directory, the user's home directory, and $OTPROOT (the root directory of Erlang/OTP), in that order.

The format of file .hosts.erlang must be one host name per line. The host names must be within quotes.

Example:

'super.eua.ericsson.se'.
'renat.eua.ericsson.se'.
'grouse.eua.ericsson.se'.
'gauffin1.eua.ericsson.se'.
^ (new line)

Summary

Types

verbosity()

Functions

dns_hostname(Host)

Returns the official name of Host, or {error, Host} if no such name is found. See also inet.

host_file()

Reads file .hosts.erlang, see section Files. Returns the hosts in this file as a list. Returns {error, Reason} if the file cannot be read or the Erlang terms on the file cannot be interpreted.

localhost()

Returns the name of the local host. If Erlang was started with command-line flag -name, Name is the fully qualified name.

names()

Equivalent to names(net_adm:localhost()).

names(Host)

Returns the names and associated port numbers of the Erlang nodes that epmd registered at the specified host.

ping(Node)

Sets up a connection to Node. Returns pong if it is successful, otherwise pang.

world()

Equivalent to world(silent).

world(Arg)

Calls names(Host) for all hosts that are specified in the Erlang host file .hosts.erlang, collects the replies, and then evaluates ping(Node) on all those nodes. Returns the list of all nodes that are successfully pinged.

world_list(Hosts)

Equivalent to world_list(Hosts, silent).

world_list(Hosts, Arg)

Same as world/0,1, but the hosts are specified as argument instead of being read from .hosts.erlang.

Types

verbosity()

(not exported)

-type verbosity() :: silent | verbose.

Functions

dns_hostname(Host)

-spec dns_hostname(Host) -> {ok, Name} | {error, Host} when Host :: atom() | string(), Name :: string().

Returns the official name of Host, or {error, Host} if no such name is found. See also inet.

host_file()

-spec host_file() -> Hosts | {error, Reason}
                   when
                       Hosts :: [Host :: atom()],
                       Reason ::
                           file:posix() |
                           badarg | terminated | system_limit |
                           {Line :: integer(), Mod :: module(), Term :: term()}.

Reads file .hosts.erlang, see section Files. Returns the hosts in this file as a list. Returns {error, Reason} if the file cannot be read or the Erlang terms on the file cannot be interpreted.

localhost()

-spec localhost() -> Name when Name :: string().

Returns the name of the local host. If Erlang was started with command-line flag -name, Name is the fully qualified name.

names()

-spec names() -> {ok, [{Name, Port}]} | {error, Reason}
               when Name :: string(), Port :: non_neg_integer(), Reason :: address | file:posix().

Equivalent to names(net_adm:localhost()).

names(Host)

-spec names(Host) -> {ok, [{Name, Port}]} | {error, Reason}
               when
                   Host :: atom() | string() | inet:ip_address(),
                   Name :: string(),
                   Port :: non_neg_integer(),
                   Reason :: address | file:posix().

Returns the names and associated port numbers of the Erlang nodes that epmd registered at the specified host.

Similar to epmd -names, see erts:epmd.

Returns {error, address} if epmd is not operational.

Example:

(arne@dunn)1> net_adm:names().
{ok,[{"arne",40262}]}

ping(Node)

-spec ping(Node) -> pong | pang when Node :: atom().

Sets up a connection to Node. Returns pong if it is successful, otherwise pang.

world()

-spec world() -> [node()].

Equivalent to world(silent).

world(Arg)

-spec world(Arg) -> [node()] when Arg :: verbosity().

Calls names(Host) for all hosts that are specified in the Erlang host file .hosts.erlang, collects the replies, and then evaluates ping(Node) on all those nodes. Returns the list of all nodes that are successfully pinged.

If Arg == verbose, the function writes information about which nodes it is pinging to stdout.

This function can be useful when a node is started, and the names of the other network nodes are not initially known.

Returns {error, Reason} if host_file/0 returns {error, Reason}.

world_list(Hosts)

-spec world_list(Hosts) -> [node()] when Hosts :: [atom()].

Equivalent to world_list(Hosts, silent).

world_list(Hosts, Arg)

-spec world_list(Hosts, Arg) -> [node()] when Hosts :: [atom()], Arg :: verbosity().

Same as world/0,1, but the hosts are specified as argument instead of being read from .hosts.erlang.

net_kernel

Erlang networking kernel.

The net kernel is a system process, registered as net_kernel, which must be operational for distributed Erlang to work. The purpose of this process is to implement parts of the BIFs spawn/4 and spawn_link/4, and to provide monitoring of the network.

An Erlang node is started using command-line flag -name or -sname:

$ erl -sname foobar

It is also possible to call net_kernel:start(foobar, #{}) directly from the normal Erlang shell prompt:

1> net_kernel:start(foobar, #{name_domain => shortnames}).
{ok,<0.64.0>}
(foobar@gringotts)2>

If the node is started with command-line flag -sname, the node name is foobar@Host, where Host is the short name of the host (not the fully qualified domain name). If started with flag -name, the node name is foobar@Host, where Host is the fully qualified domain name. For more information, see erl.

Normally, connections are established automatically when another node is referenced. This functionality can be disabled by setting Kernel configuration parameter dist_auto_connect to never, see kernel(6). In this case, connections must be established explicitly by calling connect_node/1.

Which nodes that are allowed to communicate with each other is handled by the magic cookie system, see section Distributed Erlang in the Erlang Reference Manual.

Warning

Starting a distributed node without also specifying -proto_dist inet_tls will expose the node to attacks that may give the attacker complete access to the node and in extension the cluster. When using un-secure distributed nodes, make sure that the network is configured to keep potential attackers out. See the Using SSL for Erlang Distribution User's Guide for details on how to setup a secure distributed node.

Summary

Types

connection_state()

connection_type()

Functions

allow(Nodes)

Permits access to the specified set of nodes.

allowed()

Returns a list of nodes that are explicitly allowed to connect to the node by calling allow/1. If empty list is returned, it means that any node using the same cookie will be able to connect.

connect_node(Node)

Establishes a connection to Node.

get_net_ticktime()

Returns currently used net tick time in seconds.

get_state()

Get the current state of the distribution for the local node.

getopts(Node, Options)

Get one or more options for the distribution socket connected to Node.

monitor_nodes(Flag)

Equivalent to monitor_nodes(Flag, []).

monitor_nodes(Flag, Options)

The calling process subscribes or unsubscribes to node status change messages. A nodeup message is delivered to all subscribing processes when a new node is connected, and a nodedown message is delivered when a node is disconnected.

set_net_ticktime(NetTicktime)

Equivalent to set_net_ticktime(NetTicktime, 60).

set_net_ticktime(NetTicktime, TransitionPeriod)

Sets net_ticktime (see kernel(6)) to NetTicktime seconds. TransitionPeriod defaults to 60.

setopts(Node, Options)

Set one or more options for distribution sockets. Argument Node can be either one node name or the atom new to affect the distribution sockets of all future connected nodes.

start(Options) deprecated

Turns a non-distributed node into a distributed node by starting net_kernel and other necessary processes.

start(Name, Options)

Turns a non-distributed node into a distributed node by starting net_kernel and other necessary processes.

stop()

Turns a distributed node into a non-distributed node.

Types

connection_state()

(not exported)

-type connection_state() :: check_pending | pending | up | up_pending.

connection_type()

(not exported)

-type connection_type() :: normal | hidden.

Functions

allow(Nodes)

-spec allow(Nodes) -> ok | error | ignored when Nodes :: [node()].

Permits access to the specified set of nodes.

Before the first call to allow/1, any node with the correct cookie can be connected. When allow/1 is called, a list of allowed nodes is established. Any access attempts made from (or to) nodes not in that list will be rejected.

Subsequent calls to allow/1 will add the specified nodes to the list of allowed nodes. It is not possible to remove nodes from the list.

Disallowing an already connected node will not cause it to be disconnected. It will, however, prevent any future reconnection attempts.

Passing Nodes as an empty list has never any affect at all.

Returns error if any element in Nodes is not an atom, and ignored if the local node is not alive.

allowed()

(since OTP 28.0)

-spec allowed() -> {ok, Nodes} | ignored when Nodes :: [node()].

Returns a list of nodes that are explicitly allowed to connect to the node by calling allow/1. If empty list is returned, it means that any node using the same cookie will be able to connect.

connect_node(Node)

-spec connect_node(Node) -> boolean() | ignored when Node :: node().

Establishes a connection to Node.

Returns true if a connection was established or was already established or if Node is the local node itself. Returns false if the connection attempt failed, and ignored if the local node is not alive.

get_net_ticktime()

-spec get_net_ticktime() -> Res
                          when
                              Res :: NetTicktime | {ongoing_change_to, NetTicktime} | ignored,
                              NetTicktime :: pos_integer().

Returns currently used net tick time in seconds.

For more information see the net_ticktime Kernel parameter.

Defined return values (Res):

NetTicktime - net_ticktime is NetTicktime seconds.

{ongoing_change_to, NetTicktime} - net_kernel is currently changing net_ticktime to NetTicktime seconds.

ignored - The local node is not alive.

get_state()

(since OTP 25.0)

-spec get_state() ->
                   #{started => no | static | dynamic,
                     name => atom(),
                     name_type => static | dynamic,
                     name_domain => shortnames | longnames}.

Get the current state of the distribution for the local node.

Returns a map with (at least) the following key-value pairs:

started => Started - Valid values for Started:

no - The distribution is not started. In this state none of the other keys below are present in the map.

static - The distribution was started with command line arguments -name or -sname.

dynamic - The distribution was started with net_kernel:start/1 and can be stopped with net_kernel:stop/0.

name => Name - The name of the node. Same as returned by erlang:node/0 except when name_type is dynamic in which case Name may be undefined (instead of nonode@nohost).

name_type => NameType - Valid values for NameType:

static - The node has a static node name set by the node itself.

dynamic - The distribution was started in dynamic node name mode, and will get its node name assigned from the first node it connects to. If key name has value undefined that has not happened yet.

name_domain => NameDomain - Valid values for NameDomain:

shortnames - The distribution was started to use node names with a short host portion (not fully qualified).

longnames - The distribution was started to use node names with a long fully qualified host portion.

getopts(Node, Options)

(since OTP 19.1)

-spec getopts(Node, Options) -> {ok, OptionValues} | {error, Reason} | ignored
                 when
                     Node :: node(),
                     Options :: [inet:socket_getopt()],
                     OptionValues :: [inet:socket_setopt()],
                     Reason :: inet:posix() | noconnection.

Get one or more options for the distribution socket connected to Node.

If Node is a connected node the return value is the same as from inet:getopts(Sock, Options) where Sock is the distribution socket for Node.

Returns ignored if the local node is not alive or {error, noconnection} if Node is not connected.

monitor_nodes(Flag)

-spec monitor_nodes(Flag) -> ok | Error when Flag :: boolean(), Error :: error | {error, term()}.

Equivalent to monitor_nodes(Flag, []).

monitor_nodes(Flag, Options)

-spec monitor_nodes(Flag, Options) -> ok | Error
                       when
                           Flag :: boolean(),
                           Options :: OptionsList | OptionsMap,
                           OptionsList :: [ListOption],
                           ListOption :: connection_id | {node_type, NodeType} | nodedown_reason,
                           OptionsMap ::
                               #{connection_id => boolean(),
                                 node_type => NodeType,
                                 nodedown_reason => boolean()},
                           NodeType :: visible | hidden | all,
                           Error :: error | {error, term()}.

The calling process subscribes or unsubscribes to node status change messages. A nodeup message is delivered to all subscribing processes when a new node is connected, and a nodedown message is delivered when a node is disconnected.

If Flag is true, a new subscription is started. If Flag is false, all previous subscriptions started with the same Options are stopped. Two option lists are considered the same if they contain the same set of options.

Delivery guarantees of nodeup/nodedown messages:

nodeup messages are delivered before delivery of any signals from the remote node through the newly established connection.

nodedown messages are delivered after all the signals from the remote node over the connection have been delivered.

nodeup messages are delivered after the corresponding node appears in results from erlang:nodes().

nodedown messages are delivered after the corresponding node has disappeared in results from erlang:nodes().

As of OTP 23.0, a nodedown message for a connection being taken down will be delivered before a nodeup message due to a new connection to the same node. Prior to OTP 23.0, this was not guaranteed to be the case.

The format of the node status change messages depends on Options. If Options is the empty list or if net_kernel:monitor_nodes/1 is called, the format is as follows:

{nodeup, Node} | {nodedown, Node}
  Node = node()

When Options is the empty map or empty list, the caller will only subscribe for status change messages for visible nodes. That is, only nodes that appear in the result of erlang:nodes/0.

If Options equals anything other than the empty list, the format of the status change messages is as follows:

{nodeup, Node, Info} | {nodedown, Node, Info}
  Node = node()
  Info = #{Tag => Val} | [{Tag, Val}]

Info is either a map or a list of 2-tuples. Its content depends on Options. If Options is a map, Info will also be a map. If Options is a list, Info will also be a list.

When Options is a map, currently the following associations are allowed:

connection_id => boolean() - If the value of the association equals true, a connection_id => ConnectionId association will be included in the Info map where ConnectionId is the connection identifier of the connection coming up or going down. For more info about this connection identifier see the documentation of erlang:nodes/2.

node_type => NodeType - Valid values for NodeType:

visible - Subscribe to node status change messages for visible nodes only. The association node_type => visible will be included in the Info map.

hidden - Subscribe to node status change messages for hidden nodes only. The association node_type => hidden will be included in the Info map.

all - Subscribe to node status change messages for both visible and hidden nodes. The association node_type => visible | hidden will be included in the Info map.

If no node_type => NodeType association is included in the Options map, the caller will subscribe for status change messages for visible nodes only, but no node_type => visible association will be included in the Info map.

nodedown_reason => boolean() - If the value of the association equals true, a nodedown_reason => Reason association will be included in the Info map for nodedown messages.

Reason can, depending on which distribution module or process that is used, be any term, but for the standard TCP distribution module it is one of the following:

connection_setup_failed - The connection setup failed (after nodeup messages were sent).

no_network - No network is available.

net_kernel_terminated - The net_kernel process terminated.

shutdown - Unspecified connection shutdown.

connection_closed - The connection was closed.

disconnect - The connection was disconnected (forced from the current node).

net_tick_timeout - Net tick time-out.

send_net_tick_failed - Failed to send net tick over the connection.

get_status_failed - Status information retrieval from the Port holding the connection failed.

When Options is a list, currently ListOption can be one of the following:

connection_id - A {connection_id, ConnectionId} tuple will be included in Info where ConnectionId is the connection identifier of the connection coming up or going down. For more info about this connection identifier see the documentation of erlang:nodes/2.

{node_type, NodeType} - Valid values for NodeType:

visible - Subscribe to node status change messages for visible nodes only. The tuple {node_type, visible} will be included in the Info list.

hidden - Subscribe to node status change messages for hidden nodes only. The tuple {node_type, hidden} will be included in the Info list.

all - Subscribe to node status change messages for both visible and hidden nodes. The tuple {node_type, visible | hidden} will be included in the Info list.

If no {node_type, NodeType} option has been given. The caller will subscribe for status change messages for visible nodes only, but no {node_type, visible} tuple will be included in the Info list.

nodedown_reason - The tuple {nodedown_reason, Reason} will be included in the Info list for nodedown messages.

See the documentation of the nodedown_reason => boolean() association above for information about possible Reason values.

Example:

(a@localhost)1> net_kernel:monitor_nodes(true, #{connection_id=>true, node_type=>all, nodedown_reason=>true}).
ok
(a@localhost)2> flush().
Shell got {nodeup,b@localhost,
                  #{connection_id => 3067552,node_type => visible}}
Shell got {nodeup,c@localhost,
                  #{connection_id => 13892107,node_type => hidden}}
Shell got {nodedown,b@localhost,
                    #{connection_id => 3067552,node_type => visible,
                      nodedown_reason => connection_closed}}
Shell got {nodedown,c@localhost,
                    #{connection_id => 13892107,node_type => hidden,
                      nodedown_reason => net_tick_timeout}}
Shell got {nodeup,b@localhost,
                  #{connection_id => 3067553,node_type => visible}}
ok
(a@localhost)3>

set_net_ticktime(NetTicktime)

-spec set_net_ticktime(NetTicktime) -> Res
                          when
                              NetTicktime :: pos_integer(),
                              Res :: unchanged | change_initiated | {ongoing_change_to, NewNetTicktime},
                              NewNetTicktime :: pos_integer().

Equivalent to set_net_ticktime(NetTicktime, 60).

set_net_ticktime(NetTicktime, TransitionPeriod)

-spec set_net_ticktime(NetTicktime, TransitionPeriod) -> Res
                          when
                              NetTicktime :: pos_integer(),
                              TransitionPeriod :: non_neg_integer(),
                              Res :: unchanged | change_initiated | {ongoing_change_to, NewNetTicktime},
                              NewNetTicktime :: pos_integer().

Sets net_ticktime (see kernel(6)) to NetTicktime seconds. TransitionPeriod defaults to 60.

Some definitions:

Minimum transition traffic interval (MTTI) - minimum(NetTicktime, PreviousNetTicktime)*1000 div 4 milliseconds.

Transition period - The time of the least number of consecutive MTTIs to cover TransitionPeriod seconds following the call to set_net_ticktime/2 (that is, ((TransitionPeriod*1000 - 1) div MTTI + 1)*MTTI milliseconds).

If NetTicktime < PreviousNetTicktime, the net_ticktime change is done at the end of the transition period; otherwise at the beginning. During the transition period, net_kernel ensures that there is outgoing traffic on all connections at least every MTTI millisecond.

Note

The net_ticktime changes must be initiated on all nodes in the network (with the same NetTicktime) before the end of any transition period on any node; otherwise connections can erroneously be disconnected.

Returns one of the following:

unchanged - net_ticktime already has the value of NetTicktime and is left unchanged.

change_initiated - net_kernel initiated the change of net_ticktime to NetTicktime seconds.

{ongoing_change_to, NewNetTicktime} - The request is ignored because net_kernel is busy changing net_ticktime to NewNetTicktime seconds.

setopts(Node, Options)

(since OTP 19.1)

-spec setopts(Node, Options) -> ok | {error, Reason} | ignored
                 when
                     Node :: node() | new,
                     Options :: [inet:socket_setopt()],
                     Reason :: inet:posix() | noconnection.

Set one or more options for distribution sockets. Argument Node can be either one node name or the atom new to affect the distribution sockets of all future connected nodes.

The return value is the same as from inet:setopts/2 or {error, noconnection} if Node is not a connected node or new.

If Node is new the Options will then also be added to kernel configuration parameters inet_dist_listen_options and inet_dist_connect_options.

Returns ignored if the local node is not alive.

start(Options)

This function is deprecated. Use start/2 instead.

-spec start(Options) -> {ok, pid()} | {error, Reason}
               when
                   Options :: [Name | NameDomain | TickTime, ...],
                   Name :: atom(),
                   NameDomain :: shortnames | longnames,
                   TickTime :: pos_integer(),
                   Reason :: {already_started, pid()} | term().

Turns a non-distributed node into a distributed node by starting net_kernel and other necessary processes.

Options list can only be exactly one of the following lists (order is imporant):

[Name] - The same as net_kernel:start([Name, longnames, 15000]).

[Name, NameDomain] - The same as net_kernel:start([Name, NameDomain, 15000]).

[Name, NameDomain, TickTime] - The same as net_kernel:start(Name, #{name_domain => NameDomain, net_ticktime => ((TickTime*4-1) div 1000) + 1, net_tickintensity => 4}). Note that TickTime is not the same as net tick time expressed in milliseconds. TickTime is the time between ticks when net tick intensity equals 4.

start(Name, Options)

(since OTP 24.3)

-spec start(Name, Options) -> {ok, pid()} | {error, Reason}
               when
                   Options ::
                       #{name_domain => NameDomain,
                         net_ticktime => NetTickTime,
                         net_tickintensity => NetTickIntensity,
                         dist_listen => boolean(),
                         hidden => boolean()},
                   Name :: atom(),
                   NameDomain :: shortnames | longnames,
                   NetTickTime :: pos_integer(),
                   NetTickIntensity :: 4..1000,
                   Reason :: {already_started, pid()} | term().

Turns a non-distributed node into a distributed node by starting net_kernel and other necessary processes.

If Name is set to undefined the distribution will be started to request a dynamic node name from the first node it connects to. See Dynamic Node Name. Setting Name to undefined implies options dist_listen => false and hidden => true.

Currently supported options:

name_domain => NameDomain - Determines the host name part of the node name. If NameDomain equals longnames, fully qualified domain names will be used which also is the default. If NameDomain equals shortnames, only the short name of the host will be used.

net_ticktime => NetTickTime - Net tick time to use in seconds. Defaults to the value of the net_ticktime kernel(6) parameter. For more information about net tick time, see the kernel parameter. However, note that if the value of the kernel parameter is invalid, it will silently be replaced by a valid value, but if an invalid NetTickTime value is passed as option value to this function, the call will fail.

net_tickintensity => NetTickIntensity - Net tick intensity to use. Defaults to the value of the net_tickintensity kernel(6) parameter. For more information about net tick intensity, see the kernel parameter. However, note that if the value of the kernel parameter is invalid, it will silently be replaced by a valid value, but if an invalid NetTickIntensity value is passed as option value to this function, the call will fail.

dist_listen => boolean() - Enable or disable listening for incoming connections. Defaults to the value of the -dist_listen erl command line argument. Note that dist_listen => false implies hidden => true.

If undefined has been passed as Name, the dist_listen option will be overridden with dist_listen => false.

hidden => boolean() - Enable or disable hidden node. Defaults to true if the -hidden erl command line argument has been passed; otherwise false.

If undefined has been passed as Name, or the option dist_listen equals false, the hidden option will be overridden with hidden => true.

stop()

-spec stop() -> ok | {error, Reason} when Reason :: not_allowed | not_found.

Turns a distributed node into a non-distributed node.

For other nodes in the network, this is the same as the node going down. Only possible when the net kernel was started using start/2, otherwise {error, not_allowed} is returned. Returns {error, not_found} if the local node is not alive.

pg

Distributed named process groups.

This module implements process groups. A message can be sent to one, some, or all group members.

Up until OTP 17 there used to exist an experimental pg module in stdlib. This pg module is not the same module as that experimental pg module, and only share the same module name.

A group of processes can be accessed by a common name. For example, if there is a group named foobar, there can be a set of processes (which can be located on different nodes) that are all members of the group foobar. There are no special functions for sending a message to the group. Instead, client functions are to be written with the functions get_members/1 and get_local_members/1 to determine which processes are members of the group. Then the message can be sent to one or more group members.

If a member terminates, it is automatically removed from the group.

A process may join multiple groups. It may join the same group multiple times. It is only allowed to join processes running on local node.

Process Groups implement strong eventual consistency. Process Groups membership view may temporarily diverge. For example, when processes on node1 and node2 join concurrently, node3 and node4 may receive updates in a different order.

Membership view is not transitive. If node1 is not directly connected to node2, they will not see each other's groups. But if both are connected to node3, node3 will have the full view.

Groups are automatically created when any process joins, and are removed when all processes leave the group. Non-existing group is considered empty (containing no processes).

Process groups can be organised into multiple scopes. Scopes are completely independent of each other. A process may join any number of groups in any number of scopes. Scopes are designed to decouple single mesh into a set of overlay networks, reducing amount of traffic required to propagate group membership information. Default scope pg is started automatically when Kernel is configured to do so.

Note

Scope name is used to register process locally, and to name an ETS table. If there is another process registered under this name, or another ETS table exists, scope fails to start.

Local membership is not preserved if scope process exits and restarts.

A scope can be kept local-only by using a scope name that is unique cluster-wide, e.g. the node name: pg:start_link(node()).

See Also

Kernel

Summary

Types

global_view()

group()

The identifier of a process group.

local_data()

options()

scope()

subscribe_result()

subscription()

subscriptions()

update()

version()

Functions

data_diff(Old, New)

demonitor(Ref)

Equivalent to demonitor(pg, Ref).

demonitor(Scope, Ref)

Unsubscribes the caller from updates (scope or group). Flushes all outstanding updates that were already in the message queue of the calling process.

get_local_members(Group)

Equivalent to get_local_members(pg, Group).

get_local_members(Scope, Group)

Returns all processes running on the local node in the group Group. Processes are returned in no specific order. This function is optimised for speed.

get_members(Group)

Equivalent to get_members(pg, Group).

get_members(Scope, Group)

Returns all processes in the group Group. Processes are returned in no specific order. This function is optimised for speed.

init_global_view(Scope, Options)

init_local_data(Options)

join(Group, PidOrPids)

Equivalent to join(pg, Group, PidOrPids).

join(Scope, Group, PidOrPids)

Joins single process or multiple processes to the group Group. A process can join a group many times and must then leave the group the same number of times.

leave(Group, PidOrPids)

Equivalent to leave(pg, Group, PidOrPids).

leave(Scope, Group, PidOrPids)

Makes the process PidOrPids leave the group Group. If the process is not a member of the group, not_joined is returned.

monitor(Group)

Equivalent to monitor(pg, Group).

monitor(Scope, Group)

Subscribes the caller to updates for the specified group.

monitor_scope()

Equivalent to monitor_scope(pg).

monitor_scope(Scope)

Subscribes the caller to updates from the specified scope.

new_subscription/2

start(Scope)

Starts additional scope.

start_link()

Starts the default pg scope within supervision tree.

start_link(Scope)

Equivalent to start(Scope), except that it also creates a link/1 with the calling process.

stop_global_view/1

translate_local_data/3

translate_message/2

translate_update/3

update_global_view_and_notify/4

update_local_data/2

version()

which_groups()

Equivalent to which_groups(pg).

which_groups(Scope)

Returns a list of all known groups.

Types

global_view()

(not exported) (since OTP 23.0)

-type global_view() :: {atom(), #{pid() => {reference(), [group()]}}}.

group()

(not exported) (since OTP 23.0)

-type group() :: term().

The identifier of a process group.

local_data()

(not exported) (since OTP 23.0)

-type local_data() :: #{group() => [pid()]}.

options()

(not exported) (since OTP 23.0)

-type options() :: map().

scope()

(not exported) (since OTP 23.0)

-type scope() :: atom().

subscribe_result()

(not exported) (since OTP 23.0)

-type subscribe_result() :: #{group() => [pid()]} | [pid()].

subscription()

(not exported) (since OTP 23.0)

-type subscription() :: scope | {group, group()}.

subscriptions()

(not exported) (since OTP 23.0)

-type subscriptions() :: #{subscription() => #{reference() => pid()}}.

update()

(not exported) (since OTP 23.0)

-type update() :: [{group(), Add :: [pid()], Remove :: [pid()]}].

version()

(not exported) (since OTP 23.0)

-type version() :: 0 | 1.

Functions

data_diff(Old, New)

(since OTP @OTP-20055@)

-spec data_diff(Old :: local_data(), New :: local_data()) -> update().

demonitor(Ref)

(since OTP 25.1)

-spec demonitor(Ref :: reference()) -> ok | false.

Equivalent to demonitor(pg, Ref).

demonitor(Scope, Ref)

(since OTP 25.1)

-spec demonitor(Scope :: atom(), Ref :: reference()) -> ok | false.

Unsubscribes the caller from updates (scope or group). Flushes all outstanding updates that were already in the message queue of the calling process.

get_local_members(Group)

(since OTP 23.0)

-spec get_local_members(Group :: group()) -> [pid()].

Equivalent to get_local_members(pg, Group).

get_local_members(Scope, Group)

(since OTP 23.0)

-spec get_local_members(Scope :: atom(), Group :: group()) -> [pid()].

Returns all processes running on the local node in the group Group. Processes are returned in no specific order. This function is optimised for speed.

get_members(Group)

(since OTP 23.0)

-spec get_members(Group :: group()) -> [pid()].

Equivalent to get_members(pg, Group).

get_members(Scope, Group)

(since OTP 23.0)

-spec get_members(Scope :: atom(), Group :: group()) -> [pid()].

Returns all processes in the group Group. Processes are returned in no specific order. This function is optimised for speed.

init_global_view(Scope, Options)

(since OTP @OTP-20055@)

-spec init_global_view(scope(), options()) -> global_view().

init_local_data(Options)

(since OTP @OTP-20055@)

-spec init_local_data(options()) -> local_data().

join(Group, PidOrPids)

(since OTP 23.0)

-spec join(Group :: group(), PidOrPids :: pid() | [pid()]) -> ok.

Equivalent to join(pg, Group, PidOrPids).

join(Scope, Group, PidOrPids)

(since OTP 23.0)

-spec join(Scope :: atom(), Group :: group(), PidOrPids :: pid() | [pid()]) -> ok.

Joins single process or multiple processes to the group Group. A process can join a group many times and must then leave the group the same number of times.

PidOrPids may contain the same process multiple times.

leave(Group, PidOrPids)

(since OTP 23.0)

-spec leave(Group :: group(), PidOrPids :: pid() | [pid()]) -> ok | not_joined.

Equivalent to leave(pg, Group, PidOrPids).

leave(Scope, Group, PidOrPids)

(since OTP 23.0)

-spec leave(Scope :: atom(), Group :: group(), PidOrPids :: pid() | [pid()]) -> ok | not_joined.

Makes the process PidOrPids leave the group Group. If the process is not a member of the group, not_joined is returned.

When list of processes is passed as PidOrPids, function returns not_joined only when all processes of the list are not joined.

monitor(Group)

(since OTP 25.1)

-spec monitor(Group :: group()) -> {reference(), [pid()]}.

Equivalent to monitor(pg, Group).

monitor(Scope, Group)

(since OTP 25.1)

-spec monitor(Scope :: atom(), Group :: group()) -> {reference(), [pid()]}.

Subscribes the caller to updates for the specified group.

Returns list of processes currently in the group, and a reference to match the upcoming notifications.

See monitor_scope/0 for the update message structure.

monitor_scope()

(since OTP 25.1)

-spec monitor_scope() -> {reference(), #{group() => [pid()]}}.

Equivalent to monitor_scope(pg).

monitor_scope(Scope)

(since OTP 25.1)

-spec monitor_scope(Scope :: atom()) -> {reference(), #{group() => [pid()]}}.

Subscribes the caller to updates from the specified scope.

Returns content of the entire scope and a reference to match the upcoming notifications.

Whenever any group membership changes, an update message is sent to the subscriber:

{Ref, join, Group, [JoinPid1, JoinPid2]}

{Ref, leave, Group, [LeavePid1]}

new_subscription/2

(since OTP @OTP-20055@)

-spec new_subscription(subscription(), global_view()) -> subscribe_result().

start(Scope)

(since OTP 23.0)

-spec start(Scope :: atom()) -> {ok, pid()} | {error, term()}.

Starts additional scope.

start_link()

(since OTP 23.0)

-spec start_link() -> {ok, pid()} | {error, term()}.

Starts the default pg scope within supervision tree.

Kernel may be configured to do it automatically by setting the Kernel configuration parameter start_pg.

start_link(Scope)

(since OTP 23.0)

-spec start_link(Scope :: atom()) -> {ok, pid()} | {error, term()}.

Equivalent to start(Scope), except that it also creates a link/1 with the calling process.

stop_global_view/1

(since OTP @OTP-20055@)

-spec stop_global_view(global_view()) -> term().

translate_local_data/3

(since OTP @OTP-20055@)

-spec translate_local_data(MyVersion :: version(), PeerVersion :: version(), local_data()) ->
                              local_data() | {'$plain_message', dynamic()}.

translate_message/2

(since OTP @OTP-20055@)

-spec translate_message({join, pid(), group(), pid() | [pid()]}, global_view()) ->
                           {update, pid(), update(), global_view()};
                       ({leave, pid(), pid() | [pid()], [group()]}, global_view()) ->
                           {update, pid(), update(), global_view()};
                       ({{'DOWN', pg}, reference(), process, pid(), dynamic()}, global_view()) ->
                           {update, update(), global_view()} | {drop, global_view()};
                       ({sync, pid(), [{group(), [pid()]}]}, global_view()) ->
                           {local_data, pid(), version(), local_data(), global_view()};
                       ({discover, pid()}, global_view()) -> {discover, pid(), version(), global_view()}.

translate_update/3

(since OTP @OTP-20055@)

-spec translate_update(MyVersion :: version(), PeerVersion :: version(), update()) ->
                          update() | {'$plain_messages', [dynamic()]}.

update_global_view_and_notify/4

(since OTP @OTP-20055@)

-spec update_global_view_and_notify(node(), update(), subscriptions(), global_view()) -> global_view().

update_local_data/2

(since OTP @OTP-20055@)

-spec update_local_data(update(), local_data()) -> local_data().

version()

(since OTP @OTP-20055@)

-spec version() -> version().

which_groups()

(since OTP 23.0)

-spec which_groups() -> [Group :: group()].

Equivalent to which_groups(pg).

which_groups(Scope)

(since OTP 23.0)

-spec which_groups(Scope :: atom()) -> [Group :: group()].

Returns a list of all known groups.

rpc

Remote Procedure Call services.

This module contains services similar to Remote Procedure Calls. It also contains broadcast facilities and parallel evaluators. A remote procedure call is a method to call a function on a remote node and collect the answer. It is used for collecting information on a remote node, or for running a function with some specific side effects on the remote node.

Note

rpc:call/4 and related functions make it difficult to distinguish between successful results, raised exceptions, and other errors. This behavior cannot be changed for compatibility reasons.

The erpc module was introduced in Erlang/OTP 23 to provide an API that allows clear distinction between these different outcomes. The erpc module offers the core subset of the functionality provided by the rpc module. It also features a more scalable and higher-performance implementation compared to the original rpc module.

Since the introduction of erpc, the rpc module has been updated to use erpc internally for most of its core functionality. As a result, the rpc module does not fall short in scalability or performance compared to erpc.

Note

For some important information about distributed signals, see the Blocking Signaling Over Distribution section in the Processes chapter of the Erlang Reference Manual. Blocking signaling can, for example, cause timeouts in rpc to be significantly delayed.

Summary

Types

key()

Opaque value returned by async_call/4.

Functions

abcast(Name, Msg)

Equivalent to abcast([node()|nodes()], Name, Msg).

abcast(Nodes, Name, Msg)

Broadcasts the message Msg asynchronously to the registered process Name on the specified nodes.

async_call(Node, Module, Function, Args)

Implements call streams with promises, a type of RPC that does not suspend the caller until the result is finished. Instead, a key is returned, which can be used later to collect the value. The key can be viewed as a promise to deliver the answer.

block_call(Node, Module, Function, Args)

The same as calling rpc:block_call(Node, Module, Function, Args, infinity).

block_call(Node, Module, Function, Args, Timeout)

The same as calling rpc:call(Node, Module, Function, Args, Timeout) with the exception that it also blocks other rpc:block_call/5 operations from executing concurrently on the node Node.

call(Node, Module, Function, Args)

Evaluates apply(Module, Function, Args) on node Node and returns the corresponding value Res, or {badrpc, Reason} if the call fails. The same as calling rpc:call(Node, Module, Function, Args, infinity).

call(Node, Module, Function, Args, Timeout)

Evaluates apply(Module, Function, Args) on node Node and returns the corresponding value Res, or {badrpc, Reason} if the call fails. Timeout is a time-out value in milliseconds. If the call times out, Reason is timeout.

cast(Node, Module, Function, Args)

Evaluates apply(Module, Function, Args) on node Node. No response is delivered and the calling process is not suspended until the evaluation is complete, as is the case with call/4,5.

eval_everywhere(Module, Function, Args)

Equivalent to eval_everywhere([node()|nodes()], Module, Function, Args).

eval_everywhere(Nodes, Module, Function, Args)

Evaluates apply(Module, Function, Args) on the specified nodes. No answers are collected.

multi_server_call(Name, Msg)

Equivalent to multi_server_call([node()|nodes()], Name, Msg).

multi_server_call(Nodes, Name, Msg)

Can be used when interacting with servers called Name on the specified nodes. It is assumed that the servers receive messages in the format {From, Msg} and reply using From ! {Name, Node, Reply}, where Node is the name of the node where the server is located. The function returns {Replies, BadNodes}, where Replies is a list of all Reply values, and BadNodes is one of the following

multicall(Module, Function, Args)

Equivalent to multicall([node()|nodes()], Module, Function, Args, infinity).

multicall/4

Equivalent to multicall(Nodes, Module, Function, Args, infinity).

multicall(Nodes, Module, Function, Args, Timeout)

In contrast to an RPC, a multicall is an RPC that is sent concurrently from one client to multiple servers. This is useful for collecting information from a set of nodes, or for calling a function on a set of nodes to achieve some side effects. It is semantically the same as iteratively making a series of RPCs on all the nodes, but the multicall is faster, as all the requests are sent at the same time and are collected one by one as they come back.

nb_yield(Key)

Equivalent to nb_yield(Key, 0).

nb_yield(Key, Timeout)

Non-blocking version of yield/1. It returns the tuple {value, Val} when the computation is finished, or timeout when Timeout milliseconds has elapsed.

parallel_eval(FuncCalls)

Evaluates, for every tuple in FuncCalls, apply(Module, Function, Args) on some node in the network. Returns the list of return values, in the same order as in FuncCalls.

pinfo(Pid)

Location transparent version of the BIF erlang:process_info/1 in ERTS.

pinfo/2

Location transparent version of the BIF erlang:process_info/2 in ERTS.

pmap(FuncSpec, ExtraArgs, List1)

Evaluates apply(Module, Function, [Elem|ExtraArgs]) for every element Elem in List1, in parallel. Returns the list of return values, in the same order as in List1.

sbcast(Name, Msg)

Equivalent to sbcast([node()|nodes()], Name, Msg).

sbcast(Nodes, Name, Msg)

Broadcasts the message Msg synchronously to the registered process Name on the specified nodes.

server_call(Node, Name, ReplyWrapper, Msg)

Can be used when interacting with a server called Name on node Node. It is assumed that the server receives messages in the format {From, Msg} and replies using From ! {ReplyWrapper, Node, Reply}. This function makes such a server call and ensures that the entire call is packed into an atomic transaction, which either succeeds or fails. It never hangs, unless the server itself hangs.

yield(Key)

Returns the promised answer from a previous async_call/4. If the answer is available, it is returned immediately. Otherwise, the calling process is suspended until the answer arrives from Node.

Types

key()

-opaque key()

Opaque value returned by async_call/4.

Functions

abcast(Name, Msg)

-spec abcast(Name, Msg) -> abcast when Name :: atom(), Msg :: term().

Equivalent to abcast([node()|nodes()], Name, Msg).

abcast(Nodes, Name, Msg)

-spec abcast(Nodes, Name, Msg) -> abcast when Nodes :: [node()], Name :: atom(), Msg :: term().

Broadcasts the message Msg asynchronously to the registered process Name on the specified nodes.

async_call(Node, Module, Function, Args)

-spec async_call(Node, Module, Function, Args) -> Key
                    when
                        Node :: node(),
                        Module :: module(),
                        Function :: atom(),
                        Args :: [term()],
                        Key :: key().

Implements call streams with promises, a type of RPC that does not suspend the caller until the result is finished. Instead, a key is returned, which can be used later to collect the value. The key can be viewed as a promise to deliver the answer.

In this case, the key Key is returned, which can be used in a subsequent call to yield/1 or nb_yield/1,2 to retrieve the value of evaluating apply(Module, Function, Args) on node Node.

Note

If you want the ability to distinguish between results, you may want to consider using the erpc:send_request() function from the erpc module instead. This also gives you the ability retrieve the results in other useful ways.

Note

yield/1 and nb_yield/1,2 must be called by the same process from which this function was made otherwise they will never yield correctly.

Note

You cannot make any assumptions about the process that will perform the apply(). It may be an rpc server, another server, or a freshly spawned process.

block_call(Node, Module, Function, Args)

-spec block_call(Node, Module, Function, Args) -> Res | {badrpc, Reason}
                    when
                        Node :: node(),
                        Module :: module(),
                        Function :: atom(),
                        Args :: [term()],
                        Res :: term(),
                        Reason :: term().

The same as calling rpc:block_call(Node, Module, Function, Args, infinity).

block_call(Node, Module, Function, Args, Timeout)

-spec block_call(Node, Module, Function, Args, Timeout) -> Res | {badrpc, Reason}
                    when
                        Node :: node(),
                        Module :: module(),
                        Function :: atom(),
                        Args :: [term()],
                        Res :: term(),
                        Reason :: term(),
                        Timeout :: 0..4294967295 | infinity.

The same as calling rpc:call(Node, Module, Function, Args, Timeout) with the exception that it also blocks other rpc:block_call/5 operations from executing concurrently on the node Node.

Warning

Note that it also blocks other operations than just rpc:block_call/5 operations, so use it with care.

call(Node, Module, Function, Args)

-spec call(Node, Module, Function, Args) -> Res | {badrpc, Reason}
              when
                  Node :: node(),
                  Module :: module(),
                  Function :: atom(),
                  Args :: [term()],
                  Res :: term(),
                  Reason :: term().

Evaluates apply(Module, Function, Args) on node Node and returns the corresponding value Res, or {badrpc, Reason} if the call fails. The same as calling rpc:call(Node, Module, Function, Args, infinity).

call(Node, Module, Function, Args, Timeout)

-spec call(Node, Module, Function, Args, Timeout) -> Res | {badrpc, Reason}
              when
                  Node :: node(),
                  Module :: module(),
                  Function :: atom(),
                  Args :: [term()],
                  Res :: term(),
                  Reason :: term(),
                  Timeout :: 0..4294967295 | infinity.

Evaluates apply(Module, Function, Args) on node Node and returns the corresponding value Res, or {badrpc, Reason} if the call fails. Timeout is a time-out value in milliseconds. If the call times out, Reason is timeout.

If the reply arrives after the call times out, no message contaminates the caller's message queue.

Note

If you want the ability to distinguish between results, you may want to consider using the erpc:call() function from the erpc module instead.

Note

Here follows the details of what exactly is returned.

{badrpc, Reason} will be returned in the following circumstances:

The called function fails with an exit exception.

The called function fails with an error exception.

The called function returns a term that matches {'EXIT', _}.

The called function throws a term that matches {'EXIT', _}.

Res is returned in the following circumstances:

The called function returns normally with a term that does not match {'EXIT',_}.

The called function throws a term that does not match {'EXIT',_}.

Note

You cannot make any assumptions about the process that will perform the apply(). It may be the calling process itself, an rpc server, another server, or a freshly spawned process.

cast(Node, Module, Function, Args)

-spec cast(Node, Module, Function, Args) -> true
              when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()].

Evaluates apply(Module, Function, Args) on node Node. No response is delivered and the calling process is not suspended until the evaluation is complete, as is the case with call/4,5.

Note

You cannot make any assumptions about the process that will perform the apply(). It may be an rpc server, another server, or a freshly spawned process.

eval_everywhere(Module, Function, Args)

-spec eval_everywhere(Module, Function, Args) -> abcast
                         when Module :: module(), Function :: atom(), Args :: [term()].

Equivalent to eval_everywhere([node()|nodes()], Module, Function, Args).

eval_everywhere(Nodes, Module, Function, Args)

-spec eval_everywhere(Nodes, Module, Function, Args) -> abcast
                         when
                             Nodes :: [node()], Module :: module(), Function :: atom(), Args :: [term()].

Evaluates apply(Module, Function, Args) on the specified nodes. No answers are collected.

multi_server_call(Name, Msg)

-spec multi_server_call(Name, Msg) -> {Replies, BadNodes}
                           when
                               Name :: atom(),
                               Msg :: term(),
                               Replies :: [Reply :: term()],
                               BadNodes :: [node()].

Equivalent to multi_server_call([node()|nodes()], Name, Msg).

multi_server_call(Nodes, Name, Msg)

-spec multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes}
                           when
                               Nodes :: [node()],
                               Name :: atom(),
                               Msg :: term(),
                               Replies :: [Reply :: term()],
                               BadNodes :: [node()].

Can be used when interacting with servers called Name on the specified nodes. It is assumed that the servers receive messages in the format {From, Msg} and reply using From ! {Name, Node, Reply}, where Node is the name of the node where the server is located. The function returns {Replies, BadNodes}, where Replies is a list of all Reply values, and BadNodes is one of the following:

A list of the nodes that do not exist

A list of the nodes where the server does not exist

A list of the nodes where the server terminated before sending any reply.

multicall(Module, Function, Args)

-spec multicall(Module, Function, Args) -> {ResL, BadNodes}
                   when
                       Module :: module(),
                       Function :: atom(),
                       Args :: [term()],
                       ResL :: [Res :: term() | {badrpc, Reason :: term()}],
                       BadNodes :: [node()].

Equivalent to multicall([node()|nodes()], Module, Function, Args, infinity).

multicall/4

-spec multicall(Nodes, Module, Function, Args) -> {ResL, BadNodes}
                   when
                       Nodes :: [node()],
                       Module :: module(),
                       Function :: atom(),
                       Args :: [term()],
                       ResL :: [Res :: term() | {badrpc, Reason :: term()}],
                       BadNodes :: [node()];
               (Module, Function, Args, Timeout) -> {ResL, BadNodes}
                   when
                       Module :: module(),
                       Function :: atom(),
                       Args :: [term()],
                       Timeout :: 0..4294967295 | infinity,
                       ResL :: [Res :: term() | {badrpc, Reason :: term()}],
                       BadNodes :: [node()].

Equivalent to multicall(Nodes, Module, Function, Args, infinity).

Equivalent to multicall([node()|nodes()], Module, Function, Args, Timeout).

multicall(Nodes, Module, Function, Args, Timeout)

-spec multicall(Nodes, Module, Function, Args, Timeout) -> {ResL, BadNodes}
                   when
                       Nodes :: [node()],
                       Module :: module(),
                       Function :: atom(),
                       Args :: [term()],
                       Timeout :: 0..4294967295 | infinity,
                       ResL :: [Res :: term() | {badrpc, Reason :: term()}],
                       BadNodes :: [node()].

In contrast to an RPC, a multicall is an RPC that is sent concurrently from one client to multiple servers. This is useful for collecting information from a set of nodes, or for calling a function on a set of nodes to achieve some side effects. It is semantically the same as iteratively making a series of RPCs on all the nodes, but the multicall is faster, as all the requests are sent at the same time and are collected one by one as they come back.

The function evaluates apply(Module, Function, Args) on the specified nodes and collects the answers. It returns {ResL, BadNodes}, where BadNodes is a list of the nodes that do not exist, and ResL is a list of the return values, or {badrpc, Reason} for failing calls. Timeout is a time (integer) in milliseconds, or infinity.

The following example is useful when new object code is to be loaded on all nodes in the network, and indicates some side effects that RPCs can produce:

%% Find object code for module Mod
{Mod, Bin, File} = code:get_object_code(Mod),

%% and load it on all nodes including this one
{ResL, _} = rpc:multicall(code, load_binary, [Mod, File, Bin]),

%% and then maybe check the ResL list.

Note

If you want the ability to distinguish between results, you may want to consider using the erpc:multicall() function from the erpc module instead.

Note

You cannot make any assumptions about the process that will perform the apply(). It may be the calling process itself, an rpc server, another server, or a freshly spawned process.

nb_yield(Key)

-spec nb_yield(Key) -> {value, Val} | timeout
                  when Key :: key(), Val :: (Res :: term()) | {badrpc, Reason :: term()}.

Equivalent to nb_yield(Key, 0).

nb_yield(Key, Timeout)

-spec nb_yield(Key, Timeout) -> {value, Val} | timeout
                  when
                      Key :: key(),
                      Timeout :: 0..4294967295 | infinity,
                      Val :: (Res :: term()) | {badrpc, Reason :: term()}.

Non-blocking version of yield/1. It returns the tuple {value, Val} when the computation is finished, or timeout when Timeout milliseconds has elapsed.

See the note in call/4 for more details of Val.

Note

This function must be called by the same process from which async_call/4 was made otherwise it will only return timeout.

parallel_eval(FuncCalls)

-spec parallel_eval(FuncCalls) -> ResL
                       when
                           FuncCalls :: [{Module, Function, Args}],
                           Module :: module(),
                           Function :: atom(),
                           Args :: [term()],
                           ResL :: [term()].

Evaluates, for every tuple in FuncCalls, apply(Module, Function, Args) on some node in the network. Returns the list of return values, in the same order as in FuncCalls.

pinfo(Pid)

-spec pinfo(Pid) -> [{Item, Info}] | undefined when Pid :: pid(), Item :: atom(), Info :: term().

Location transparent version of the BIF erlang:process_info/1 in ERTS.

pinfo/2

-spec pinfo(Pid, Item) -> {Item, Info} | undefined | []
               when Pid :: pid(), Item :: atom(), Info :: term();
           (Pid, ItemList) -> [{Item, Info}] | undefined | []
               when Pid :: pid(), Item :: atom(), ItemList :: [Item], Info :: term().

Location transparent version of the BIF erlang:process_info/2 in ERTS.

pmap(FuncSpec, ExtraArgs, List1)

-spec pmap(FuncSpec, ExtraArgs, List1) -> List2
              when
                  FuncSpec :: {Module, Function},
                  Module :: module(),
                  Function :: atom(),
                  ExtraArgs :: [term()],
                  List1 :: [Elem :: term()],
                  List2 :: [term()].

Evaluates apply(Module, Function, [Elem|ExtraArgs]) for every element Elem in List1, in parallel. Returns the list of return values, in the same order as in List1.

sbcast(Name, Msg)

-spec sbcast(Name, Msg) -> {GoodNodes, BadNodes}
                when Name :: atom(), Msg :: term(), GoodNodes :: [node()], BadNodes :: [node()].

Equivalent to sbcast([node()|nodes()], Name, Msg).

sbcast(Nodes, Name, Msg)

-spec sbcast(Nodes, Name, Msg) -> {GoodNodes, BadNodes}
                when
                    Name :: atom(),
                    Msg :: term(),
                    Nodes :: [node()],
                    GoodNodes :: [node()],
                    BadNodes :: [node()].

Broadcasts the message Msg synchronously to the registered process Name on the specified nodes.

Returns {GoodNodes, BadNodes}, where GoodNodes is the list of nodes that have Name as a registered process.

The function is synchronous in the sense that it is known that all servers have received the message when the call returns. It is not possible to know that the servers have processed the message.

Any further messages sent to the servers, after this function has returned, are received by all servers after this message.

server_call(Node, Name, ReplyWrapper, Msg)

-spec server_call(Node, Name, ReplyWrapper, Msg) -> Reply | {error, Reason}
                     when
                         Node :: node(),
                         Name :: atom(),
                         ReplyWrapper :: term(),
                         Msg :: term(),
                         Reply :: term(),
                         Reason :: nodedown.

Can be used when interacting with a server called Name on node Node. It is assumed that the server receives messages in the format {From, Msg} and replies using From ! {ReplyWrapper, Node, Reply}. This function makes such a server call and ensures that the entire call is packed into an atomic transaction, which either succeeds or fails. It never hangs, unless the server itself hangs.

The function returns the answer Reply as produced by the server Name, or {error, Reason}.

yield(Key)

-spec yield(Key) -> Res | {badrpc, Reason} when Key :: key(), Res :: term(), Reason :: term().

Returns the promised answer from a previous async_call/4. If the answer is available, it is returned immediately. Otherwise, the calling process is suspended until the answer arrives from Node.

Note

This function must be called by the same process from which async_call/4 was made otherwise it will never return.

See the note in call/4 for more details of the return value.

code

Interface to the Erlang code server process.

This module contains the interface to the Erlang code server, which deals with the loading of compiled code into a running Erlang runtime system.

The runtime system can be started in interactive or embedded mode. Which one is decided by the command-line flag -mode:

% erl -mode embedded

The modes are as follows:

In interactive mode, which is default, only the modules needed by the runtime system are loaded during system startup. Other code is dynamically loaded when first referenced. When a call to a function in a certain module is made, and that module is not loaded, the code server searches for and tries to load that module.

In embedded mode, modules are not auto-loaded. Trying to use a module that has not been loaded results in an error. This mode is recommended when the boot script loads all modules, as it is typically done in OTP releases. (Code can still be loaded later by explicitly ordering the code server to do so).

To prevent accidentally reloading of modules affecting the Erlang runtime system, directories kernel, stdlib, and compiler are considered sticky. This means that the system issues a warning and rejects the request if a user tries to reload a module residing in any of them. The feature can be disabled by using command-line flag -nostick.

Code Path

In interactive mode, the code server maintains a code path, consisting of a list of directories, which it searches sequentially when trying to load a module.

Initially, the code path consists of the current working directory and all Erlang object code directories under library directory $OTPROOT/lib, where $OTPROOT is the installation directory of Erlang/OTP, code:root_dir(). Directories can be named Name[-Vsn] and the code server, by default, chooses the directory with the highest version number among those having the same Name. Suffix -Vsn is optional. If an ebin directory exists under Name[-Vsn], this directory is added to the code path.

Environment variable ERL_LIBS (defined in the operating system) can be used to define more library directories to be handled in the same way as the standard OTP library directory described above, except that directories without an ebin directory are ignored.

All application directories found in the additional directories appear before the standard OTP applications, except for the Kernel and STDLIB applications, which are placed before any additional applications. In other words, modules found in any of the additional library directories override modules with the same name in OTP, except for modules in Kernel and STDLIB.

Environment variable ERL_LIBS (if defined) is to contain a colon-separated (for Unix-like systems) or semicolon-separated (for Windows) list of additional libraries.

Example:

On a Unix-like system, ERL_LIBS can be set to the following:

/usr/local/jungerl:/home/some_user/my_erlang_lib

The code paths specified by $OTPROOT, ERL_LIBS, and boot scripts have their listings cached by default (except for ".") The code server will lookup the contents in their directories once and avoid future file system traversals. Therefore, modules added to such directories after the Erlang VM boots will not be picked up. This behaviour can be disabled by setting -cache_boot_paths false or by calling code:set_path(code:get_path()).

Change

The support for caching directories in the code path was added in Erlang/OTP 26.

Directories given by the command line options -pa and -pz are not cached by default. Many of the functions that manipulate the code path accept the cache atom as an optional argument to enable caching selectively.

Loading of Code From Archive Files

Change

The existing experimental support for archive files will be changed in a future release. As of Erlang/OTP 27, the function code:lib_dir/2, the -code_path_choice flag, and using erl_prim_loader for reading files from an archive are deprecated.

escript scripts that use archive files should use escript:extract/2 to read data files from its archive instead of using code:lib_dir/2 and erl_prim_loader.

The Erlang archives are ZIP files with extension .ez. Erlang archives can also be enclosed in escript files whose file extension is arbitrary.

Erlang archive files can contain entire Erlang applications or parts of applications. The structure in an archive file is the same as the directory structure for an application. If you, for example, create an archive of mnesia-4.4.7, the archive file must be named mnesia-4.4.7.ez and it must contain a top directory named mnesia-4.4.7. If the version part of the name is omitted, it must also be omitted in the archive. That is, a mnesia.ez archive must contain a mnesia top directory.

An archive file for an application can, for example, be created like this:

zip:create("mnesia-4.4.7.ez",
	["mnesia-4.4.7"],
	[{cwd, code:lib_dir()},
	 {compress, all},
	 {uncompress,[".beam",".app"]}]).

Any file in the archive can be compressed, but to speed up the access of frequently read files, it can be a good idea to store beam and app files uncompressed in the archive.

Normally the top directory of an application is located in library directory $OTPROOT/lib or in a directory referred to by environment variable ERL_LIBS. At startup, when the initial code path is computed, the code server also looks for archive files in these directories and possibly adds ebin directories in archives to the code path. The code path then contains paths to directories that look like $OTPROOT/lib/mnesia.ez/mnesia/ebin or $OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin.

The code server uses module erl_prim_loader in ERTS (possibly through erl_boot_server) to read code files from archives. However, the functions in erl_prim_loader can also be used by other applications to read files from archives. For example, the call erl_prim_loader:list_dir( "/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/examples/bench)" would list the contents of a directory inside an archive. See erl_prim_loader.

An application archive file and a regular application directory can coexist. This can be useful when it is needed to have parts of the application as regular files. A typical case is the priv directory, which must reside as a regular directory to link in drivers dynamically and start port programs. For other applications that do not need this, directory priv can reside in the archive and the files under the directory priv can be read through erl_prim_loader.

When a directory is added to the code path and when the entire code path is (re)set, the code server decides which subdirectories in an application that are to be read from the archive and which that are to be read as regular files. If directories are added or removed afterwards, the file access can fail if the code path is not updated (possibly to the same path as before, to trigger the directory resolution update).

For each directory on the second level in the application archive (ebin, priv, src, and so on), the code server first chooses the regular directory if it exists and second from the archive. Function code:lib_dir/2 returns the path to the subdirectory. For example, code:lib_dir(megaco, ebin) can return /otp/root/lib/megaco-3.9.1.1.ez/megaco-3.9.1.1/ebin while code:lib_dir(megaco, priv) can return /otp/root/lib/megaco-3.9.1.1/priv.

When an escript file contains an archive, there are no restrictions on the name of the escript and no restrictions on how many applications that can be stored in the embedded archive. Single Beam files can also reside on the top level in the archive. At startup, the top directory in the embedded archive and all (second level) ebin directories in the embedded archive are added to the code path. See escript.

A future-proof way for escript scripts to read data files from the archive is to use the escript:extract/2 function.

When the choice of directories in the code path is strict (which is the default as of Erlang/OTP 27), the directory that ends up in the code path is exactly the stated one. This means that if, for example, the directory $OTPROOT/lib/mnesia-4.4.7/ebin is explicitly added to the code path, the code server does not load files from $OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin.

This behavior can be controlled through command-line flag -code_path_choice Choice. If the flag is set to relaxed, the code server instead chooses a suitable directory depending on the actual file structure. If a regular application ebin directory exists, it is chosen. Otherwise, the directory ebin in the archive is chosen if it exists. If neither of them exists, the original directory is chosen.

Command-line flag -code_path_choice Choice also affects how module init interprets the boot script. The interpretation of the explicit code paths in the boot script can be strict or relaxed. It is particularly useful to set the flag to relaxed when elaborating with code loading from archives without editing the boot script. The default has changed to strict in OTP 27 and the option is scheduled for removal in OTP 28. See module init in the Erts application.

Current and Old Code

The code for a module can exist in two variants in a system: current code and old code. When a module is loaded into the system for the first time, the module code becomes current and the global export table is updated with references to all functions exported from the module.

When a new instance of the module is loaded, the code of the previous instance becomes old, and all export entries referring to the previous instance are removed. After that, the new instance is loaded as for the first time, and becomes current.

Both old and current code for a module are valid, and can even be executed concurrently. The difference is that exported functions in old code are unavailable. Hence, a global call cannot be made to an exported function in old code, but old code can still be executed because of processes lingering in it.

If a third instance of the module is loaded, the code server removes (purges) the old code and any processes lingering in it are terminated. Then the third instance becomes current and the previously current code becomes old.

For more information about old and current code, and how to make a process switch from old to current code, see section Compilation and Code Loading in the Erlang Reference Manual.

Native Coverage Support

In runtime systems that use the JIT, native coverage is a light-weight way to find out which functions or lines that have been executed, or how many times each function or line has been executed.

Change

The support for native coverage was added in Erlang/OTP 27.

Native coverage works by instrumenting code at load-time. When a module has been instrumented for native coverage collection it is not possible to later disable the coverage collection, except by reloading the module. However, the overhead for keeping coverage collection running is often neligible, especially for coverage mode function that only keeps track of which functions that have been executed.

The cover tool in the Tools application will automatically use the native coverage support if the runtime system supports it.

It is only necessary to use the functionality described next if cover is not sufficient, for example:

If one wants to collect coverage information for the code that runs when the runtime system is starting (module init and so on). cover can only be used when the Erlang system has started, and it will reload every module that is to be analyzed.

If it is necessary to collect coverage information with the absolute minimum disturbance of the test system. cover always counts how many times each line is executed (coverage mode line_counters), but by using native coverage one can use a less expensive coverage mode such as function, which has almost negligible overhead.

Short summary of using native coverage

If the line or line_counters coverage mode is to be used, the code to be tested must be compiled with option line_coverage.

Use set_coverage_mode(Mode) to set a coverage mode for all code subsequently loaded, or set it with option +JPcover for erl.

Optionally reset coverage information for all modules that are to be tested by calling reset_coverage(Module).

Run the code whose coverage information is to be collected.

Read out the counters for all interesting modules by calling get_coverage(Level, Module), where Level is either function or line.

The other native coverage BIFs

The following BIFs are sometimes useful, for example to fail gracefully if the runtime system does not support native coverage:

coverage_support() - check whether the runtime system supports native coverage

get_coverage_mode() - get the current coverage mode

get_coverage_mode(Module) - get the coverage mode for module Module

Argument Types and Invalid Arguments

Module and application names are atoms, while file and directory names are strings. For backward compatibility reasons, some functions accept both strings and atoms, but a future release will probably only allow the arguments that are documented.

Functions in this module generally fail with an exception if they are passed an incorrect type (for example, an integer or a tuple where an atom is expected). An error tuple is returned if the argument type is correct, but there are some other errors (for example, a non-existing directory is specified to set_path/1).

Error Reasons for Code-Loading Functions

Functions that load code (such as load_file/1) will return {error,Reason} if the load operation fails. Here follows a description of the common reasons.

badfile - The object code has an incorrect format or the module name in the object code is not the expected module name.

nofile - No file with object code was found.

not_purged - The object code could not be loaded because an old version of the code already existed.

on_load_failure - The module has an -on_load function that failed when it was called.

sticky_directory - The object code resides in a sticky directory.

Summary

Types

add_path_ret()

cache()

coverage_mode()

debug_atom_or_var()

debug_call()

debug_frame()

debug_info()

debug_line()

debug_name()

debug_source()

debug_value()

debug_var()

load_error_rsn()

load_ret()

loaded_filename()

loaded_ret_atoms()

module_status()

prepared_code()

An opaque term holding prepared code.

replace_path_ret()

set_path_ret()

Functions

add_path(Dir)

Equivalent to add_pathz(Dir, nocache).

add_path(Dir, Cache)

Equivalent to add_pathz(Dir, Cache).

add_patha(Dir)

Equivalent to add_patha(Dir, nocache).

add_patha(Dir, Cache)

Adds Dir to the beginning of the code path.

add_paths(Dirs)

Equivalent to add_pathsz(Dirs, nocache).

add_paths(Dirs, Cache)

Equivalent to add_pathsz(Dirs, Cache).

add_pathsa(Dirs)

Equivalent to add_pathsa(Dirs, nocache).

add_pathsa(Dirs, Cache)

Traverses Dirs and adds each Dir to the beginning of the code path.

add_pathsz(Dirs)

Equivalent to add_pathsz(Dirs, nocache).

add_pathsz(Dirs, Cache)

Adds the directories in Dirs to the end of the code path.

add_pathz(Dir)

Equivalent to add_pathz(Dir, nocache).

add_pathz(Dir, Cache)

Adds Dir as the directory last in the code path.

all_available()

Returns a list of tuples {Module, Filename, Loaded} for all available modules.

all_loaded()

Returns a list of tuples {Module, Loaded} for all loaded modules.

atomic_load(Modules)

Tries to load all of the modules in the list Modules atomically.

clash()

Searches all directories in the code path for module names with identical names and writes a report to stdout.

clear_cache()

Clears the code path cache.

compiler_dir()

Returns the compiler library directory.

coverage_support()

Returns true if the system supports coverage and false otherwise.

del_path(NameOrDir)

Deletes a directory from the code path.

del_paths(NamesOrDirs)

Deletes directories from the code path.

delete(Module)

Removes the current code for Module, that is, the current code for Module is made old.

ensure_loaded(Module)

Tries to load a module in the same way as load_file/1, unless the module is already loaded.

ensure_modules_loaded(Modules)

Tries to load any modules not already loaded in the list Modules in the same way as load_file/1.

finish_loading(Prepared)

Tries to load code for all modules that have been previously prepared by prepare_loading/1.

get_coverage(Level, Module)

Return either function or line coverage data for module Module.

get_coverage_mode()

Returns the coverage mode as set by option +JPcover for erl or set_coverage_mode/1.

get_coverage_mode(Module)

Get coverage mode for the given module.

get_debug_info(Module)

get_doc(Module)

Returns EEP 48 style documentation for Module if available.

get_mode()

Returns an atom describing the mode of the code server: interactive or embedded.

get_object_code(Module)

Returns the object code for module Module if found in the code path.

get_path()

Returns the code path.

is_loaded(Module)

Checks whether Module is loaded.

is_sticky(Module)

Returns true if Module is the name of a module that has been loaded from a sticky directory (in other words: an attempt to reload the module will fail), or false if Module is not a loaded module or is not sticky.

lib_dir()

Returns the library directory, $OTPROOT/lib, where $OTPROOT is the root directory of Erlang/OTP.

lib_dir(Name)

Returns the path for the library directory, the top directory, for an application Name located under $OTPROOT/lib or in a directory referred to with environment variable ERL_LIBS.

lib_dir(Name, SubDir) deprecated

Returns the path to a subdirectory directly under the top directory of an application.

load_abs(Filename)

Equivalent to load_file(Module), except that Filename is an absolute or relative filename.

load_binary(Module, Filename, Binary)

Loads object code from a binary.

load_file(Module)

Tries to load the Erlang module Module using the code path.

modified_modules()

Returns the list of all currently loaded modules for which module_status/1 returns modified.

module_status()

See module_status/1 and all_loaded/0 for details.

module_status(Module)

Returns the status of Module in relation to object file on disk.

objfile_extension()

Returns the object code file extension corresponding to the Erlang machine used.

prepare_loading(Modules)

Prepares to load the modules in the list Modules.

priv_dir(Name)

Returns the path to the priv directory in an application.

purge(Module)

Purges the code for Module, that is, removes code marked as old.

replace_path(Name, Dir)

Equivalent to replace_path(Name, Dir, nocache).

replace_path(Name, Dir, Cache)

Replaces an old occurrence of a directory named .../Name[-Vsn][/ebin] in the code path, with Dir.

reset_coverage(Module)

Resets coverage information for module Module.

root_dir()

Returns the root directory of Erlang/OTP, which is the directory where it is installed.

set_coverage_mode(Mode)

Sets the coverage mode for modules that are subsequently loaded, similar to option +JPcover for erl.

set_path(Path)

Equivalent to set_path(PathList, nocache).

set_path(PathList, Cache)

Sets the code path to the list of directories Path.

soft_purge(Module)

Purges the code for Module, that is, removes code marked as old, but only if no processes linger in it.

stick_dir(Dir)

Marks Dir as sticky.

unstick_dir(Dir)

Unsticks a directory that is marked as sticky.

where_is_file(Filename)

Searches the code path for Filename, which is a file of arbitrary type.

which(Module)

If the module is not loaded, this function searches the code path for the first file containing object code for Module and returns the absolute filename.

Types

add_path_ret()

(not exported)

-type add_path_ret() :: true | {error, bad_directory}.

cache()

(not exported)

-type cache() :: cache | nocache.

coverage_mode()

-type coverage_mode() :: none | function | function_counters | line | line_counters.

debug_atom_or_var()

-nominal debug_atom_or_var() :: atom() | debug_var().

debug_call()

-nominal debug_call() ::
             MFA ::
                 {debug_atom_or_var(), debug_atom_or_var(), arity()} |
                 (FA :: {debug_atom_or_var(), arity()} | debug_var()).

debug_frame()

-nominal debug_frame() :: non_neg_integer() | entry | none.

debug_info()

-nominal debug_info() ::
             [{debug_line(),
               #{frame_size => debug_frame(), vars => [debug_value()], calls => [debug_call()]}}].

debug_line()

-nominal debug_line() :: pos_integer().

debug_name()

-nominal debug_name() :: debug_var() | 1..255.

debug_source()

-nominal debug_source() :: {x, non_neg_integer()} | {y, non_neg_integer()} | {value, _}.

debug_value()

-nominal debug_value() :: {debug_name(), debug_source()}.

debug_var()

-nominal debug_var() :: binary().

load_error_rsn()

-type load_error_rsn() :: badfile | nofile | not_purged | on_load_failure | sticky_directory.

load_ret()

-type load_ret() :: {error, What :: load_error_rsn()} | {module, Module :: module()}.

loaded_filename()

(not exported)

-type loaded_filename() :: (Filename :: file:filename()) | loaded_ret_atoms().

loaded_ret_atoms()

(not exported)

-type loaded_ret_atoms() :: cover_compiled | preloaded.

module_status()

-type module_status() :: not_loaded | loaded | modified | removed.

prepared_code()

-opaque prepared_code()

An opaque term holding prepared code.

replace_path_ret()

(not exported)

-type replace_path_ret() :: true | {error, bad_directory | bad_name | {badarg, _}}.

set_path_ret()

(not exported)

-type set_path_ret() :: true | {error, bad_directory}.

Functions

add_path(Dir)

-spec add_path(Dir) -> add_path_ret() when Dir :: file:filename().

Equivalent to add_pathz(Dir, nocache).

add_path(Dir, Cache)

(since OTP 26.0)

-spec add_path(Dir, cache()) -> add_path_ret() when Dir :: file:filename().

Equivalent to add_pathz(Dir, Cache).

add_patha(Dir)

-spec add_patha(Dir) -> add_path_ret() when Dir :: file:filename().

Equivalent to add_patha(Dir, nocache).

add_patha(Dir, Cache)

(since OTP 26.0)

-spec add_patha(Dir, cache()) -> add_path_ret() when Dir :: file:filename().

Adds Dir to the beginning of the code path.

If Dir exists, it is removed from the old position in the code path.

Argument Cache controls whether the content of the directory should be cached on first traversal. If Cache is cache the directory contents will be cached; if Cache is nocache it will not be cached.

Returns true if successful, or {error, bad_directory} if Dir is not the name of a directory.

add_paths(Dirs)

-spec add_paths(Dirs) -> ok when Dirs :: [Dir :: file:filename()].

Equivalent to add_pathsz(Dirs, nocache).

add_paths(Dirs, Cache)

(since OTP 26.0)

-spec add_paths(Dirs, cache()) -> ok when Dirs :: [Dir :: file:filename()].

Equivalent to add_pathsz(Dirs, Cache).

add_pathsa(Dirs)

-spec add_pathsa(Dirs) -> ok when Dirs :: [Dir :: file:filename()].

Equivalent to add_pathsa(Dirs, nocache).

add_pathsa(Dirs, Cache)

(since OTP 26.0)

-spec add_pathsa(Dirs, cache()) -> ok when Dirs :: [Dir :: file:filename()].

Traverses Dirs and adds each Dir to the beginning of the code path.

This means that the order of Dirs is reversed in the resulting code path. For example, if Dirs is [Dir1,Dir2], the resulting path will be [Dir2,Dir1|OldCodePath].

If a Dir already exists in the code path, it is removed from the old position.

Argument Cache controls whether the content of the directory should be cached on first traversal. If Cache is cache the directory contents will be cached; if Cache is nocache it will not be cached.

Always returns ok, regardless of the validity of each individual Dir.

add_pathsz(Dirs)

-spec add_pathsz(Dirs) -> ok when Dirs :: [Dir :: file:filename()].

Equivalent to add_pathsz(Dirs, nocache).

add_pathsz(Dirs, Cache)

(since OTP 26.0)

-spec add_pathsz(Dirs, cache()) -> ok when Dirs :: [Dir :: file:filename()].

Adds the directories in Dirs to the end of the code path.

Directories that are already present in the path will not be added.

Argument Cache controls whether the content of the directory should be cached on first traversal. If Cache is cache the directory contents will be cached; if Cache is nocache it will not be cached.

Always returns ok, regardless of the validity of each individual Dir.

add_pathz(Dir)

-spec add_pathz(Dir) -> add_path_ret() when Dir :: file:filename().

Equivalent to add_pathz(Dir, nocache).

add_pathz(Dir, Cache)

(since OTP 26.0)

-spec add_pathz(Dir, cache()) -> add_path_ret() when Dir :: file:filename().

Adds Dir as the directory last in the code path.

If Dir already exists in the path, it is not added.

Argument Cache controls whether the content of the directory should be cached on first traversal. If Cache is cache the directory contents will be cached; if Cache is nocache it will not be cached.

Returns true if successful, or {error, bad_directory} if Dir is not the name of a directory.

all_available()

(since OTP 23.0)

-spec all_available() -> [{Module, Filename, Loaded}]
                       when Module :: string(), Filename :: loaded_filename(), Loaded :: boolean().

Returns a list of tuples {Module, Filename, Loaded} for all available modules.

A module is considered to be available if it either is loaded or would be loaded if called. Filename is normally the absolute filename, as described for is_loaded/1.

all_loaded()

-spec all_loaded() -> [{Module, Loaded}] when Module :: module(), Loaded :: loaded_filename().

Returns a list of tuples {Module, Loaded} for all loaded modules.

Loaded is normally the absolute filename, as described for is_loaded/1.

atomic_load(Modules)

(since OTP 19.0)

-spec atomic_load(Modules) -> ok | {error, [{Module, What}]}
                     when
                         Modules :: [Module | {Module, Filename, Binary}],
                         Module :: module(),
                         Filename :: file:filename(),
                         Binary :: binary(),
                         What ::
                             badfile | nofile | on_load_not_allowed | duplicated | not_purged |
                             sticky_directory | pending_on_load.

Tries to load all of the modules in the list Modules atomically.

That means that either all modules are loaded at the same time, or none of the modules are loaded if there is a problem with any of the modules.

Loading can fail for one the following reasons:

badfile - The object code has an incorrect format or the module name in the object code is not the expected module name.

nofile - No file with object code exists.

on_load_not_allowed - A module contains an -on_load function.

duplicated - A module is included more than once in Modules.

not_purged - The object code cannot be loaded because an old version of the code already exists.

sticky_directory - The object code resides in a sticky directory.

pending_on_load - A previously loaded module contains an -on_load function that never finished.

If it is important to minimize the time that an application is inactive while changing code, use prepare_loading/1 and finish_loading/1 instead of atomic_load/1. Here is an example:

{ok,Prepared} = code:prepare_loading(Modules),
%% Put the application into an inactive state or do any
%% other preparation needed before changing the code.
ok = code:finish_loading(Prepared),
%% Resume the application.

clash()

-spec clash() -> ok.

Searches all directories in the code path for module names with identical names and writes a report to stdout.

clear_cache()

(since OTP 26.0)

-spec clear_cache() -> ok.

Clears the code path cache.

If a directory is cached, its cache is cleared once and then it will be recalculated and cached once more in a future traversal.

To clear the cache for a single path, either re-add it to the code path (with add_path/2) or replace it (with replace_path/3). To disable all caching, reset the code path with code:set_path(code:get_path()).

Always returns ok.

compiler_dir()

-spec compiler_dir() -> file:filename().

Returns the compiler library directory.

Equivalent to code:lib_dir(compiler).

coverage_support()

(since OTP 27.0)

-spec coverage_support() -> Supported when Supported :: boolean().

Returns true if the system supports coverage and false otherwise.

See also: Native Coverage Support

del_path(NameOrDir)

-spec del_path(NameOrDir) -> boolean() | {error, What}
                  when NameOrDir :: Name | Dir, Name :: atom(), Dir :: file:filename(), What :: bad_name.

Deletes a directory from the code path.

The argument can be an atom Name, in which case the directory with the name .../Name[-Vsn][/ebin] is deleted from the code path. Also, the complete directory name Dir can be specified as argument.

Returns:

true - If successful

false - If the directory is not found

{error, bad_name} - If the argument is invalid

del_paths(NamesOrDirs)

(since OTP 26.0)

-spec del_paths(NamesOrDirs) -> ok
                   when NamesOrDirs :: [Name | Dir], Name :: atom(), Dir :: file:filename().

Deletes directories from the code path.

The argument is a list of either atoms or complete directory names. If Name is an atom, the directory with the name .../Name[-Vsn][/ebin] is deleted from the code path.

Always returns ok, regardless of the validity of each individual NamesOrDirs.

delete(Module)

-spec delete(Module) -> boolean() when Module :: module().

Removes the current code for Module, that is, the current code for Module is made old.

This means that processes can continue to execute the code in the module, but no external function calls can be made to it.

Returns true if successful, or false if there is old code for Module that must be purged first, or if Module is not a (loaded) module.

ensure_loaded(Module)

-spec ensure_loaded(Module) -> {module, Module} | {error, What}
                       when Module :: module(), What :: embedded | badfile | nofile | on_load_failure.

Tries to load a module in the same way as load_file/1, unless the module is already loaded.

If called concurrently, this function ensures that only one process attempts to load said module at a given time.

In embedded mode, it does not load a module that is not already loaded, but returns {error, embedded} instead. See Error Reasons for Code-Loading Functions for a description of other possible error reasons.

ensure_modules_loaded(Modules)

(since OTP 19.0)

-spec ensure_modules_loaded([Module]) -> ok | {error, [{Module, What}]}
                               when Module :: module(), What :: badfile | nofile | on_load_failure.

Tries to load any modules not already loaded in the list Modules in the same way as load_file/1.

Unlike ensure_loaded/1, modules are loaded even in embedded mode.

Returns ok if successful, or {error,[{Module,Reason}]} if loading of some modules fails. See Error Reasons for Code-Loading Functions for a description of other possible error reasons.

finish_loading(Prepared)

(since OTP 19.0)

-spec finish_loading(Prepared) -> ok | {error, [{Module, What}]}
                        when
                            Prepared :: prepared_code(),
                            Module :: module(),
                            What :: not_purged | sticky_directory | pending_on_load.

Tries to load code for all modules that have been previously prepared by prepare_loading/1.

The loading occurs atomically, meaning that either all modules are loaded at the same time, or none of the modules are loaded.

This function can fail with one of the following error reasons:

not_purged - The object code cannot be loaded because an old version of the code already exists.

sticky_directory - The object code resides in a sticky directory.

pending_on_load - A previously loaded module contains an -on_load function that never finished.

get_coverage(Level, Module)

(since OTP 27.0)

-spec get_coverage(Level, module()) -> Result
                      when
                          Level :: function | line | cover_id_line,
                          Result :: [{Entity, CoverageInfo}],
                          Entity :: {Function, Arity} | Line | CoverId,
                          CoverageInfo :: Covered | Counter,
                          Function :: atom(),
                          Arity :: arity(),
                          Line :: non_neg_integer(),
                          CoverId :: pos_integer(),
                          Covered :: boolean(),
                          Counter :: non_neg_integer().

Return either function or line coverage data for module Module.

If Level is function, returns function coverage for the given module according to its coverage mode:

function - For each function in module Module, a boolean indicating whether that function has been executed at least once is returned.

function_counters - For each function in module Module, an integer giving the number of times that line has been executed is returned.

line - For each function in module Module, a boolean indicating whether that function has been executed at least once is returned.

line_counters - For each function in module Module, a boolean indicating whether that function has been executed at least once is returned (note that in this mode, counters for the number of times each function has been executed cannot be retrieved).

If Level is line, returns line coverage for the given module according to its coverage mode:

line - For each executable line in the module, a boolean indicating whether that line has been executed at least once is returned.

line_counters - For each executable line in the module, an integer giving the number of times that line was executed is returned.

Level cover_id_line is used by the cover tool.

Failures:

badarg - If Level is not function or line.

badarg - If Module is not an atom.

badarg - If Module does not refer to a loaded module.

badarg - If Module was not loaded in another coverage mode than none.

badarg - If Level is line and Module has not been loaded with either line or line_counters enabled.

badarg - If the runtime system does not support coverage.

See also: Native Coverage Support

get_coverage_mode()

(since OTP 27.0)

-spec get_coverage_mode() -> Mode when Mode :: coverage_mode().

Returns the coverage mode as set by option +JPcover for erl or set_coverage_mode/1.

Failure:

badarg - If the runtime system does not support coverage.

See also: Native Coverage Support

get_coverage_mode(Module)

(since OTP 27.0)

-spec get_coverage_mode(Module) -> Mode when Module :: module(), Mode :: coverage_mode().

Get coverage mode for the given module.

Failures:

badarg - If Module is not an atom.

badarg - If Module does not refer to a loaded module.

badarg - If the runtime system does not support coverage.

See also: Native Coverage Support

get_debug_info(Module)

(since OTP 28.0)

-spec get_debug_info(Module) -> DebugInfo when Module :: module(), DebugInfo :: debug_info().

get_doc(Module)

(since OTP 23.0)

-spec get_doc(Mod) -> {ok, Res} | {error, Reason}
                 when
                     Mod :: module(),
                     Res ::
                         #docs_v1{anno :: term(),
                                  beam_language :: term(),
                                  format :: term(),
                                  module_doc :: term(),
                                  metadata :: term(),
                                  docs :: term()},
                     Reason :: non_existing | missing | file:posix().

Returns EEP 48 style documentation for Module if available.

If Module is not found in the code path, this function returns {error,non_existing}.

If no documentation can be found this function attempts to generate documentation from the debug information in the module. If no debug information is available, this function returns {error,missing}.

For more information about the documentation chunk see Documentation Storage and Format in Kernel's User's Guide.

get_mode()

(since OTP R16B)

-spec get_mode() -> embedded | interactive.

Returns an atom describing the mode of the code server: interactive or embedded.

This information is useful when an external entity (for example, an IDE) provides additional code for a running node. If the code server is in interactive mode, it only has to add the path to the code. If the code server is in embedded mode, the code must be loaded with load_binary/3.

get_object_code(Module)

-spec get_object_code(Module) -> {Module, Binary, Filename} | error
                         when Module :: module(), Binary :: binary(), Filename :: file:filename().

Returns the object code for module Module if found in the code path.

Returns {Module, Binary, Filename} if successful, otherwise error. Binary is a binary data object, which contains the object code for the module. This is useful if code is to be loaded on a remote node in a distributed system. For example, loading module Module on a node Node is done as follows:

...
{_Module, Binary, Filename} = code:get_object_code(Module),
erpc:call(Node, code, load_binary, [Module, Filename, Binary]),
...

get_path()

-spec get_path() -> Path when Path :: [Dir :: file:filename()].

Returns the code path.

is_loaded(Module)

-spec is_loaded(Module) -> {file, Loaded} | false when Module :: module(), Loaded :: loaded_filename().

Checks whether Module is loaded.

If it is, {file, Loaded} is returned, otherwise false.

Normally, Loaded is the absolute filename Filename from which the code is obtained. If the module is preloaded (see script(4)), Loaded =:= preloaded. If the module is Cover-compiled (see cover), Loaded =:= cover_compiled.

is_sticky(Module)

-spec is_sticky(Module) -> boolean() when Module :: module().

Returns true if Module is the name of a module that has been loaded from a sticky directory (in other words: an attempt to reload the module will fail), or false if Module is not a loaded module or is not sticky.

lib_dir()

-spec lib_dir() -> file:filename().

Returns the library directory, $OTPROOT/lib, where $OTPROOT is the root directory of Erlang/OTP.

Example:

1> code:lib_dir().
"/usr/local/otp/lib"

lib_dir(Name)

-spec lib_dir(Name) -> file:filename() | {error, bad_name} when Name :: atom().

Returns the path for the library directory, the top directory, for an application Name located under $OTPROOT/lib or in a directory referred to with environment variable ERL_LIBS.

If a regular directory called Name or Name-Vsn exists in the code path with an ebin subdirectory, the path to this directory is returned (not the ebin directory).

If the directory refers to a directory in an archive, the archive name is stripped away before the path is returned. For example, if directory /usr/local/otp/lib/mnesia-4.2.2.ez/mnesia-4.2.2/ebin is in the path, /usr/local/otp/lib/mnesia-4.2.2/ebin is returned. This means that the library directory for an application is the same, regardless if the application resides in an archive or not.

Warning

Archives are experimental. In a future release, they can be removed or their behavior can change.

Example:

> code:lib_dir(mnesia).
"/usr/local/otp/lib/mnesia-4.23"

Returns {error, bad_name} if Name is not the name of an application under $OTPROOT/lib or on a directory referred to through environment variable ERL_LIBS. Fails with an exception if Name has the wrong type.

Warning

For backward compatibility, Name is also allowed to be a string. That will probably change in a future release.

lib_dir(Name, SubDir)

This function is deprecated. code:lib_dir/2 is deprecated; this functionality will be removed in a future release.

-spec lib_dir(Name, SubDir) -> file:filename() | {error, bad_name} when Name :: atom(), SubDir :: atom().

Returns the path to a subdirectory directly under the top directory of an application.

Change

This function is part of the archive support, which is an experimental feature that will be changed or removed in a future release.

Normally the subdirectories reside under the top directory for the application, but when applications at least partly reside in an archive, the situation is different. Some of the subdirectories can reside as regular directories while others reside in an archive file. It is not checked whether this directory exists.

Instead of using this function, use code:lib_dir/1 and filename:join/2.

Example:

1> filename:join(code:lib_dir(megaco), "priv").
"/usr/local/otp/lib/megaco-3.9.1.1/priv"

Fails with an exception if Name or SubDir has the wrong type.

load_abs(Filename)

-spec load_abs(Filename) -> load_ret() when Filename :: file:filename().

Equivalent to load_file(Module), except that Filename is an absolute or relative filename.

The code path is not searched. It returns a value in the same way as load_file/1. Notice that Filename must not contain the extension (for example, .beam) because load_abs/1 adds the correct extension.

load_binary(Module, Filename, Binary)

-spec load_binary(Module, Filename, Binary) -> {module, Module} | {error, What}
                     when
                         Module :: module(),
                         Filename :: loaded_filename(),
                         Binary :: binary(),
                         What :: badarg | load_error_rsn().

Loads object code from a binary.

This function can be used to load object code on remote Erlang nodes. Argument Binary must contain object code for Module. Filename is only used by the code server to keep a record of from which file the object code for Module originates. Thus, Filename is not opened and read by the code server.

Returns {module, Module} if successful, or {error, Reason} if loading fails. See Error Reasons for Code-Loading Functions for a description of the possible error reasons.

load_file(Module)

-spec load_file(Module) -> load_ret() when Module :: module().

Tries to load the Erlang module Module using the code path.

It looks for the object code file with an extension corresponding to the Erlang machine used, for example, Module.beam. The loading fails if the module name found in the object code differs from the name Module. Use load_binary/3 to load object code with a module name that is different from the file name.

Returns {module, Module} if successful, or {error, Reason} if loading fails. See Error Reasons for Code-Loading Functions for a description of the possible error reasons.

modified_modules()

(since OTP 20.0)

-spec modified_modules() -> [module()].

Returns the list of all currently loaded modules for which module_status/1 returns modified.

See also all_loaded/0.

module_status()

(since OTP 23.0)

-spec module_status() -> [{module(), module_status()}].

See module_status/1 and all_loaded/0 for details.

module_status(Module)

(since OTP 20.0)

-spec module_status(Module :: module() | [module()]) -> module_status() | [{module(), module_status()}].

Returns the status of Module in relation to object file on disk.

The status of a module can be one of:

not_loaded - If Module is not currently loaded.

loaded - If Module is loaded, and the object file exists and contains the same code.

removed - If Module is loaded, but no corresponding object file can be found in the code path.

modified - If Module is loaded, but the object file contains code with a different MD5 checksum.

Preloaded modules are always reported as loaded, without inspecting the contents on disk. Cover-compiled modules will always be reported as modified if an object file exists, or as removed otherwise. Modules whose load path is an empty string (which is the convention for auto-generated code) will only be reported as loaded or not_loaded.

See also modified_modules/0.

objfile_extension()

-spec objfile_extension() -> nonempty_string().

Returns the object code file extension corresponding to the Erlang machine used.

For the official Erlang/OTP release, the return value is always .beam.

prepare_loading(Modules)

(since OTP 19.0)

-spec prepare_loading(Modules) -> {ok, Prepared} | {error, [{Module, What}]}
                         when
                             Modules :: [Module | {Module, Filename, Binary}],
                             Module :: module(),
                             Filename :: file:filename(),
                             Binary :: binary(),
                             Prepared :: prepared_code(),
                             What :: badfile | nofile | on_load_not_allowed | duplicated.

Prepares to load the modules in the list Modules.

Finish the loading by calling finish_loading(Prepared).

This function can fail with one of the following error reasons:

badfile - The object code has an incorrect format or the module name in the object code is not the expected module name.

nofile - No file with object code exists.

on_load_not_allowed - A module contains an -on_load function.

duplicated - A module is included more than once in Modules.

priv_dir(Name)

-spec priv_dir(Name) -> file:filename() | {error, bad_name} when Name :: atom().

Returns the path to the priv directory in an application.

Warning

For backward compatibility, Name is also allowed to be a string. That will probably change in a future release.

purge(Module)

-spec purge(Module) -> boolean() when Module :: module().

Purges the code for Module, that is, removes code marked as old.

If some processes still linger in the old code, these processes are killed before the code is removed.

Change

As of Erlang/OTP 20.0, a process is only considered to be lingering in the code if it has direct references to the code. For more information see documentation of erlang:check_process_code/3, which is used in order to determine whether a process is lingering.

Returns true if successful and any process is needed to be killed, otherwise false.

replace_path(Name, Dir)

-spec replace_path(Name, Dir) -> replace_path_ret() when Name :: atom(), Dir :: file:filename().

Equivalent to replace_path(Name, Dir, nocache).

replace_path(Name, Dir, Cache)

(since OTP 26.0)

-spec replace_path(Name, Dir, cache()) -> replace_path_ret() when Name :: atom(), Dir :: file:filename().

Replaces an old occurrence of a directory named .../Name[-Vsn][/ebin] in the code path, with Dir.

If Name does not exist, it adds the new directory Dir last in the code path. The new directory must also be named .../Name[-Vsn][/ebin]. This function is to be used if a new version of the directory (library) is added to a running system.

Argument Cache controls whether the content of the directory should be cached on first traversal. If Cache is cache the directory contents will be cached; if Cache is nocache it will not be cached.

Returns:

true - If successful

{error, bad_name} - If Name is not found

{error, bad_directory} - If Dir does not exist

{error, {badarg, [Name, Dir]}} - If Name or Dir is invalid

reset_coverage(Module)

(since OTP 27.0)

-spec reset_coverage(Module) -> ok when Module :: module().

Resets coverage information for module Module.

If the coverage mode is either function or line, all booleans for Module keeping track of executed functions or lines are set to false.

If the coverage mode is either function_counters or line_counters, all counters for Module are reset to zero.

Failures:

badarg - If Module is not an atom.

badarg - If Module does not refer to a loaded module.

badarg - If Module was not loaded with coverage enabled.

badarg - If the runtime system does not support coverage.

See also: Native Coverage Support

root_dir()

-spec root_dir() -> file:filename().

Returns the root directory of Erlang/OTP, which is the directory where it is installed.

Example:

1> code:root_dir().
"/usr/local/otp"

set_coverage_mode(Mode)

(since OTP 27.0)

-spec set_coverage_mode(Mode) -> OldMode when Mode :: coverage_mode(), OldMode :: coverage_mode().

Sets the coverage mode for modules that are subsequently loaded, similar to option +JPcover for erl.

The coverage mode will have the following effect on code that is loaded following this call:

function - All modules that are loaded will be instrumented to keep track of which functions are executed. Information about which functions that have been executed can be retrieved by calling get_coverage(function, Module).

function_counters - All modules that are loaded will be instrumented to count how many times each function is executed. Information about how many times each function has been executed can be retrieved by calling get_coverage(function, Module).

line - When modules that have been compiled with the line_coverage option are loaded, they will be instrumented to keep track of which lines have been executed. Information about which lines have been executed can be retrieved by calling get_coverage(line, Module), and information about which functions that have been executed can be retrieved by calling get_coverage(function, Module).

line_counters - When modules that have been compiled with the line_coverage option are loaded, they will be instrumented to count the number of times each line is executed. Information about how many times each line has been executed can be retrieved by calling get_coverage(line, Module), and information about which functions that have been executed can be retrieved by calling get_coverage(function, Module) (note that in this mode, counters for the number of times each function has been executed cannot be retrieved).

none - Modules will be loaded without coverage instrumentation.

Returns the previous coverage mode.

Failures:

badarg - If Mode is not a valid coverage mode.

badarg - If the runtime system does not support coverage.

See also: Native Coverage Support

set_path(Path)

-spec set_path(Path) -> set_path_ret() when Path :: [Dir :: file:filename()].

Equivalent to set_path(PathList, nocache).

set_path(PathList, Cache)

(since OTP 26.0)

-spec set_path(Path, cache()) -> set_path_ret() when Path :: [Dir :: file:filename()].

Sets the code path to the list of directories Path.

Argument Cache controls whether the content of the directory should be cached on first traversal. If Cache is cache the directory contents will be cached; if Cache is nocache it will not be cached.

Returns:

true - If successful

{error, bad_directory} - If any Dir is not a directory name

soft_purge(Module)

-spec soft_purge(Module) -> boolean() when Module :: module().

Purges the code for Module, that is, removes code marked as old, but only if no processes linger in it.

Change

As of Erlang/OTP 20.0, a process is only considered to be lingering in the code if it has direct references to the code. For more information see documentation of erlang:check_process_code/3, which is used in order to determine whether a process is lingering.

Returns false if the module cannot be purged because of processes lingering in old code, otherwise true.

stick_dir(Dir)

-spec stick_dir(Dir) -> ok | error when Dir :: file:filename().

Marks Dir as sticky.

Returns ok if successful, otherwise error.

unstick_dir(Dir)

-spec unstick_dir(Dir) -> ok | error when Dir :: file:filename().

Unsticks a directory that is marked as sticky.

Returns ok if successful, otherwise error.

where_is_file(Filename)

-spec where_is_file(Filename) -> non_existing | Absname
                       when Filename :: file:filename(), Absname :: file:filename().

Searches the code path for Filename, which is a file of arbitrary type.

If found, the full name is returned. non_existing is returned if the file cannot be found. The function can be useful, for example, to locate application resource files.

which(Module)

-spec which(Module) -> Which when Module :: module(), Which :: loaded_filename() | non_existing.

If the module is not loaded, this function searches the code path for the first file containing object code for Module and returns the absolute filename.

If the module is loaded, it returns the name of the file containing the loaded object code.

If the module is preloaded, preloaded is returned.

If the module is Cover-compiled, cover_compiled is returned.

If the module cannot be found, non_existing is returned.

erl_ddll

Dynamic driver loader and linker.

This module provides an interface for loading and unloading Erlang linked-in drivers in runtime.

Note

This is a large reference document. For casual use of this module, and for most real world applications, the descriptions of functions load/2 and unload/1 are enough to getting started.

The driver is to be provided as a dynamically linked library in an object code format specific for the platform in use, that is, .so files on most Unix systems and .ddl files on Windows. An Erlang linked-in driver must provide specific interfaces to the emulator, so this module is not designed for loading arbitrary dynamic libraries. For more information about Erlang drivers, see erl_driver .

When describing a set of functions (that is, a module, a part of a module, or an application), executing in a process and wanting to use a ddll-driver, we use the term user. A process can have many users (different modules needing the same driver) and many processes running the same code, making up many users of a driver.

In the basic scenario, each user loads the driver before starting to use it and unloads the driver when done. The reference counting keeps track of processes and the number of loads by each process. This way the driver is only unloaded when no one wants it (it has no user). The driver also keeps track of ports that are opened to it. This enables delay of unloading until all ports are closed, or killing of all ports that use the driver when it is unloaded.

The interface supports two basic scenarios of loading and unloading. Each scenario can also have the option of either killing ports when the driver is unloading, or waiting for the ports to close themselves. The scenarios are as follows:

Load and Unload on a "When Needed Basis" - This (most common) scenario simply supports that each user of the driver loads it when needed and unloads it when no longer needed. The driver is always reference counted and as long as a process keeping the driver loaded is still alive, the driver is present in the system.

Each user of the driver use literally the same pathname for the driver when demanding load, but the users are not concerned with if the driver is already loaded from the file system or if the object code must be loaded from file system.

The following two pairs of functions support this scenario:

load/2 and unload/1 - When using the load/unload interfaces, the driver is not unloaded until the last port using the driver is closed. Function unload/1 can return immediately, as the users have no interest in when the unloading occurs. The driver is unloaded when no one needs it any longer.

If a process having the driver loaded dies, it has the same effect as if unloading is done.

When loading, function load/2 returns ok when any instance of the driver is present. Thus, if a driver is waiting to get unloaded (because of open ports), it simply changes state to no longer need unloading.

load_driver/2 and unload_driver/1 - These interfaces are intended to be used when it is considered an error that ports are open to a driver that no user has loaded. The ports that are still open when the last user calls unload_driver/1 or when the last process having the driver loaded dies, are killed with reason driver_unloaded.

The function names load_driver and unload_driver are kept for backward compatibility.

Loading and Reloading for Code Replacement - This scenario can occur if the driver code needs replacement during operation of the Erlang emulator. Implementing driver code replacement is a little more tedious than Beam code replacement, as one driver cannot be loaded as both "old" and "new" code. All users of a driver must have it closed (no open ports) before the old code can be unloaded and the new code can be loaded.

The unloading/loading is done as one atomic operation, blocking all processes in the system from using the driver in question while in progress.

The preferred way to do driver code replacement is to let one single process keep track of the driver. When the process starts, the driver is loaded. When replacement is required, the driver is reloaded. Unload is probably never done, or done when the process exits. If more than one user has a driver loaded when code replacement is demanded, the replacement cannot occur until the last "other" user has unloaded the driver.

Demanding reload when a reload is already in progress is always an error. Using the high-level functions, it is also an error to demand reloading when more than one user has the driver loaded.

To simplify driver replacement, avoid designing your system so that more than one user has the driver loaded.

The two functions for reloading drivers are to be used together with corresponding load functions to support the two different behaviors concerning open ports:

load/2 and reload/2 - This pair of functions is used when reloading is to be done after the last open port to the driver is closed.

As reload/2 waits for the reloading to occur, a misbehaving process keeping open ports to the driver (or keeping the driver loaded) can cause infinite waiting for reload. Time-outs must be provided outside of the process demanding the reload or by using the low-level interface try_load/3 in combination with driver monitors.

load_driver/2 and reload_driver/2 - This pair of functions are used when open ports to the driver are to be killed with reason driver_unloaded to allow for new driver code to get loaded.

However, if another process has the driver loaded, calling reload_driver returns error code pending_process. As stated earlier, the recommended design is to not allow other users than the "driver reloader" to demand loading of the driver in question.

See Also

erl_driver(4), driver_entry(4)

Summary

Types

driver()

path()

Functions

demonitor(MonitorRef)

Removes a driver monitor in much the same way as erlang:demonitor/1 in ERTS does with process monitors.

format_error(ErrorDesc)

Takes an ErrorDesc returned by load, unload, or reload functions and returns a string that describes the error or warning.

info()

Returns a list of tuples {DriverName, InfoList}, where InfoList is the result of calling info/1 for that DriverName. Only dynamically linked-in drivers are included in the list.

info(Name)

Returns a list of tuples {Tag, Value}, where Tag is the information item and Value is the result of calling info/2 with this driver name and this tag. The result is a tuple list containing all information available about a driver.

info(Name, Tag)

Returns specific information about one aspect of a driver. Parameter Tag specifies which aspect to get information about. The return Value differs between different tags

load(Path, Name)

Loads and links the dynamic driver Name. Path is a file path to the directory containing the driver. Name must be a shareable object/dynamic library. Two drivers with different Path parameters cannot be loaded under the same name. Name is a string or atom containing at least one character.

load_driver(Path, Name)

Works essentially as load/2, but loads the driver with other options. All ports using the driver are killed with reason driver_unloaded when the driver is to be unloaded.

loaded_drivers()

Returns a list of all the available drivers, both (statically) linked-in and dynamically loaded ones.

monitor(Tag, Item)

Creates a driver monitor and works in many ways as erlang:monitor/2 in ERTS, does for processes. When a driver changes state, the monitor results in a monitor message that is sent to the calling process. MonitorRef returned by this function is included in the message sent.

reload(Path, Name)

Reloads the driver named Name from a possibly different Path than previously used. This function is used in the code change scenario described in the introduction.

reload_driver(Path, Name)

Works exactly as reload/2, but for drivers loaded with the load_driver/2 interface.

try_load(Path, Name, OptionList)

Provides more control than the load/2/reload/2 and load_driver/2/reload_driver/2 interfaces. It never waits for completion of other operations related to the driver, but immediately returns the status of the driver as one of the following

try_unload(Name, OptionList)

This is the low-level function to unload (or decrement reference counts of) a driver. It can be used to force port killing, in much the same way as the driver option kill_ports implicitly does. Also, it can trigger a monitor either because other users still have the driver loaded or because open ports use the driver.

unload(Name)

Unloads, or at least dereferences the driver named Name. If the caller is the last user of the driver, and no more open ports use the driver, the driver gets unloaded. Otherwise, unloading is delayed until all ports are closed and no users remain.

unload_driver(Name)

Unloads, or at least dereferences the driver named Name. If the caller is the last user of the driver, all remaining open ports using the driver are killed with reason driver_unloaded and the driver eventually gets unloaded.

Types

driver()

(not exported)

-type driver() :: iolist() | atom().

path()

(not exported)

-type path() :: string() | atom().

Functions

demonitor(MonitorRef)

-spec demonitor(MonitorRef) -> ok when MonitorRef :: reference().

Removes a driver monitor in much the same way as erlang:demonitor/1 in ERTS does with process monitors.

For details about how to create driver monitors, see monitor/2, try_load/3, and try_unload/2.

The function throws a badarg exception if the parameter is not a reference/0.

format_error(ErrorDesc)

-spec format_error(ErrorDesc) -> string() when ErrorDesc :: term().

Takes an ErrorDesc returned by load, unload, or reload functions and returns a string that describes the error or warning.

Note

Because of peculiarities in the dynamic loading interfaces on different platforms, the returned string is only guaranteed to describe the correct error if format_error/1 is called in the same instance of the Erlang virtual machine as the error appeared in (meaning the same operating system process).

info()

-spec info() -> AllInfoList
              when
                  AllInfoList :: [DriverInfo],
                  DriverInfo :: {DriverName, InfoList},
                  DriverName :: string(),
                  InfoList :: [InfoItem],
                  InfoItem :: {Tag :: atom(), Value :: term()}.

Returns a list of tuples {DriverName, InfoList}, where InfoList is the result of calling info/1 for that DriverName. Only dynamically linked-in drivers are included in the list.

info(Name)

-spec info(Name) -> InfoList
              when
                  Name :: driver(),
                  InfoList :: [InfoItem, ...],
                  InfoItem :: {Tag :: atom(), Value :: term()}.

Returns a list of tuples {Tag, Value}, where Tag is the information item and Value is the result of calling info/2 with this driver name and this tag. The result is a tuple list containing all information available about a driver.

The following tags appears in the list:

processes

driver_options

port_count

linked_in_driver

permanent

awaiting_load

awaiting_unload

For a detailed description of each value, see info/2.

The function throws a badarg exception if the driver is not present in the system.

info(Name, Tag)

-spec info(Name, Tag) -> Value
              when
                  Name :: driver(),
                  Tag ::
                      processes | driver_options | port_count | linked_in_driver | permanent |
                      awaiting_load | awaiting_unload,
                  Value :: term().

Returns specific information about one aspect of a driver. Parameter Tag specifies which aspect to get information about. The return Value differs between different tags:

processes - Returns all processes containing users of the specific drivers as a list of tuples {pid(),integer() >= 0}, where integer/0 denotes the number of users in process pid/0.

driver_options - Returns a list of the driver options provided when loading, and any options set by the driver during initialization. The only valid option is kill_ports.

port_count - Returns the number of ports (an integer() >= 0) using the driver.

linked_in_driver - Returns a boolean/0, which is true if the driver is a statically linked-in one, otherwise false.

permanent - Returns a boolean/0, which is true if the driver has made itself permanent (and is not a statically linked-in driver), otherwise false.

awaiting_load - Returns a list of all processes having monitors for loading active. Each process is returned as {pid(),integer() >= 0}, where integer/0 is the number of monitors held by process pid/0.

awaiting_unload - Returns a list of all processes having monitors for unloading active. Each process is returned as {pid(),integer() >= 0}, where integer/0 is the number of monitors held by process pid/0.

If option linked_in_driver or permanent returns true, all other options return linked_in_driver or permanent, respectively.

The function throws a badarg exception if the driver is not present in the system or if the tag is not supported.

load(Path, Name)

-spec load(Path, Name) -> ok | {error, ErrorDesc}
              when Path :: path(), Name :: driver(), ErrorDesc :: term().

Loads and links the dynamic driver Name. Path is a file path to the directory containing the driver. Name must be a shareable object/dynamic library. Two drivers with different Path parameters cannot be loaded under the same name. Name is a string or atom containing at least one character.

The Name specified is to correspond to the filename of the dynamically loadable object file residing in the directory specified as Path, but without the extension (that is, .so). The driver name provided in the driver initialization routine must correspond with the filename, in much the same way as Erlang module names correspond to the names of the .beam files.

If the driver was previously unloaded, but is still present because of open ports to it, a call to load/2 stops the unloading and keeps the driver (as long as Path is the same), and ok is returned. If you really want the object code to be reloaded, use reload/2 or the low-level interface try_load/3 instead. See also the description of different scenarios for loading/unloading in the introduction.

If more than one process tries to load an already loaded driver with the same Path, or if the same process tries to load it many times, the function returns ok. The emulator keeps track of the load/2 calls, so that a corresponding number of unload/2 calls must be done from the same process before the driver gets unloaded. It is therefore safe for an application to load a driver that is shared between processes or applications when needed. It can safely be unloaded without causing trouble for other parts of the system.

It is not allowed to load multiple drivers with the same name but with different Path parameters.

Note

Path is interpreted literally, so that all loaders of the same driver must specify the same literal Path string, although different paths can point out the same directory in the file system (because of use of relative paths and links).

On success, the function returns ok. On failure, the return value is {error,ErrorDesc}, where ErrorDesc is an opaque term to be translated into human readable form by function format_error/1.

For more control over the error handling, use the try_load/3 interface instead.

The function throws a badarg exception if the parameters are not specified as described here.

load_driver(Path, Name)

-spec load_driver(Path, Name) -> ok | {error, ErrorDesc}
                     when Path :: path(), Name :: driver(), ErrorDesc :: term().

Works essentially as load/2, but loads the driver with other options. All ports using the driver are killed with reason driver_unloaded when the driver is to be unloaded.

The number of loads and unloads by different users influences the loading and unloading of a driver file. The port killing therefore only occurs when the last user unloads the driver, or when the last process having loaded the driver exits.

This interface (or at least the name of the functions) is kept for backward compatibility. Using try_load/3 with {driver_options,[kill_ports]} in the option list gives the same effect regarding the port killing.

The function throws a badarg exception if the parameters are not specified as described here.

loaded_drivers()

-spec loaded_drivers() -> {ok, Drivers} when Drivers :: [Driver], Driver :: string().

Returns a list of all the available drivers, both (statically) linked-in and dynamically loaded ones.

The driver names are returned as a list of strings rather than a list of atoms for historical reasons.

For more information about drivers, see info.

monitor(Tag, Item)

-spec monitor(Tag, Item) -> MonitorRef
                 when
                     Tag :: driver,
                     Item :: {Name, When},
                     Name :: driver(),
                     When :: loaded | unloaded | unloaded_only,
                     MonitorRef :: reference().

Creates a driver monitor and works in many ways as erlang:monitor/2 in ERTS, does for processes. When a driver changes state, the monitor results in a monitor message that is sent to the calling process. MonitorRef returned by this function is included in the message sent.

As with process monitors, each driver monitor set only generates one single message. The monitor is "destroyed" after the message is sent, so it is then not needed to call demonitor/1.

MonitorRef can also be used in subsequent calls to demonitor/1 to remove a monitor.

The function accepts the following parameters:

Tag - The monitor tag is always driver, as this function can only be used to create driver monitors. In the future, driver monitors will be integrated with process monitors, why this parameter has to be specified for consistence.

Item - Parameter Item specifies which driver to monitor (the driver name) and which state change to monitor. The parameter is a tuple of arity two whose first element is the driver name and second element is one of the following:

loaded - Notifies when the driver is reloaded (or loaded if loading is underway). It only makes sense to monitor drivers that are in the process of being loaded or reloaded. A future driver name for loading cannot be monitored. That only results in a DOWN message sent immediately. Monitoring for loading is therefore most useful when triggered by function try_load/3, where the monitor is created because the driver is in such a pending state.

Setting a driver monitor for loading eventually leads to one of the following messages being sent:

{'UP', reference(), driver, Name, loaded} - This message is sent either immediately if the driver is already loaded and no reloading is pending, or when reloading is executed if reloading is pending.

The user is expected to know if reloading is demanded before creating a monitor for loading.

{'UP', reference(), driver, Name, permanent} - This message is sent if reloading was expected, but the (old) driver made itself permanent before reloading. It is also sent if the driver was permanent or statically linked-in when trying to create the monitor.

{'DOWN', reference(), driver, Name, load_cancelled} - This message arrives if reloading was underway, but the requesting user cancelled it by dying or calling try_unload/2 (or unload/1/unload_driver/1) again before it was reloaded.

{'DOWN', reference(), driver, Name, {load_failure, Failure}} - This message arrives if reloading was underway but the loading for some reason failed. The Failure term is one of the errors that can be returned from try_load/3. The error term can be passed to format_error/1 for translation into human readable form. Notice that the translation must be done in the same running Erlang virtual machine as the error was detected in.

unloaded - Monitors when a driver gets unloaded. If one monitors a driver that is not present in the system, one immediately gets notified that the driver got unloaded. There is no guarantee that the driver was ever loaded.

A driver monitor for unload eventually results in one of the following messages being sent:

{'DOWN', reference(), driver, Name, unloaded} - The monitored driver instance is now unloaded. As the unload can be a result of a reload/2 request, the driver can once again have been loaded when this message arrives.

{'UP', reference(), driver, Name, unload_cancelled} - This message is sent if unloading was expected, but while the driver was waiting for all ports to get closed, a new user of the driver appeared, and the unloading was cancelled.

This message appears if {ok, pending_driver} was returned from try_unload/2 for the last user of the driver, and then {ok, already_loaded} is returned from a call to try_load/3.

If one really wants to monitor when the driver gets unloaded, this message distorts the picture, because no unloading was done. Option unloaded_only creates a monitor similar to an unloaded monitor, but never results in this message.

{'UP', reference(), driver, Name, permanent} - This message is sent if unloading was expected, but the driver made itself permanent before unloading. It is also sent if trying to monitor a permanent or statically linked-in driver.

unloaded_only - A monitor created as unloaded_only behaves exactly as one created as unloaded except that the {'UP', reference(), driver, Name, unload_cancelled} message is never sent, but the monitor instead persists until the driver really gets unloaded.

The function throws a badarg exception if the parameters are not specified as described here.

reload(Path, Name)

-spec reload(Path, Name) -> ok | {error, ErrorDesc}
                when
                    Path :: path(),
                    Name :: driver(),
                    ErrorDesc :: pending_process | OpaqueError,
                    OpaqueError :: term().

Reloads the driver named Name from a possibly different Path than previously used. This function is used in the code change scenario described in the introduction.

If there are other users of this driver, the function returns {error, pending_process}, but if there are no other users, the function call hangs until all open ports are closed.

Note

Avoid mixing multiple users with driver reload requests.

To avoid hanging on open ports, use function try_load/3 instead.

The Name and Path parameters have exactly the same meaning as when calling the plain function load/2.

On success, the function returns ok. On failure, the function returns an opaque error, except the pending_process error described earlier. The opaque errors are to be translated into human readable form by function format_error/1.

For more control over the error handling, use the try_load/3 interface instead.

The function throws a badarg exception if the parameters are not specified as described here.

reload_driver(Path, Name)

-spec reload_driver(Path, Name) -> ok | {error, ErrorDesc}
                       when
                           Path :: path(),
                           Name :: driver(),
                           ErrorDesc :: pending_process | OpaqueError,
                           OpaqueError :: term().

Works exactly as reload/2, but for drivers loaded with the load_driver/2 interface.

As this interface implies that ports are killed when the last user disappears, the function does not hang waiting for ports to get closed.

For more details, see scenarios in this module description and the function description for reload/2.

The function throws a badarg exception if the parameters are not specified as described here.

try_load(Path, Name, OptionList)

-spec try_load(Path, Name, OptionList) -> {ok, Status} | {ok, PendingStatus, Ref} | {error, ErrorDesc}
                  when
                      Path :: path(),
                      Name :: driver(),
                      OptionList :: [Option],
                      Option ::
                          {driver_options, DriverOptionList} |
                          {monitor, MonitorOption} |
                          {reload, ReloadOption},
                      DriverOptionList :: [DriverOption],
                      DriverOption :: kill_ports,
                      MonitorOption :: pending_driver | pending,
                      ReloadOption :: pending_driver | pending,
                      Status :: loaded | already_loaded | PendingStatus,
                      PendingStatus :: pending_driver | pending_process,
                      Ref :: reference(),
                      ErrorDesc :: ErrorAtom | OpaqueError,
                      ErrorAtom ::
                          linked_in_driver | inconsistent | permanent | not_loaded_by_this_process |
                          not_loaded | pending_reload | pending_process,
                      OpaqueError :: term().

Provides more control than the load/2/reload/2 and load_driver/2/reload_driver/2 interfaces. It never waits for completion of other operations related to the driver, but immediately returns the status of the driver as one of the following:

{ok, loaded} - The driver was loaded and is immediately usable.

{ok, already_loaded} - The driver was already loaded by another process or is in use by a living port, or both. The load by you is registered and a corresponding try_unload is expected sometime in the future.

{ok, pending_driver}or {ok, pending_driver, reference()} - The load request is registered, but the loading is delayed because an earlier instance of the driver is still waiting to get unloaded (open ports use it). Still, unload is expected when you are done with the driver. This return value mostly occurs when options {reload,pending_driver} or {reload,pending} are used, but can occur when another user is unloading a driver in parallel and driver option kill_ports is set. In other words, this return value always needs to be handled.

{ok, pending_process}or {ok, pending_process, reference()} - The load request is registered, but the loading is delayed because an earlier instance of the driver is still waiting to get unloaded by another user (not only by a port, in which case {ok,pending_driver} would have been returned). Still, unload is expected when you are done with the driver. This return value only occurs when option {reload,pending} is used.

When the function returns {ok, pending_driver} or {ok, pending_process}, one can get information about when the driver is actually loaded by using option {monitor, MonitorOption}.

When monitoring is requested, and a corresponding {ok, pending_driver} or {ok, pending_process} would be returned, the function instead returns a tuple {ok, PendingStatus, reference()} and the process then gets a monitor message later, when the driver gets loaded. The monitor message to expect is described in the function description of monitor/2.

Note

In case of loading, monitoring can not only get triggered by using option {reload, ReloadOption}, but also in special cases where the load error is transient. Thus, {monitor, pending_driver} is to be used under basically all real world circumstances.

The function accepts the following parameters:

Path - The file system path to the directory where the driver object file is located. The filename of the object file (minus extension) must correspond to the driver name (used in parameter Name) and the driver must identify itself with the same name. Path can be provided as an iolist(), meaning it can be a list of other iolist/0s, characters (8-bit integers), or binaries, all to be flattened into a sequence of characters.

The (possibly flattened) Path parameter must be consistent throughout the system. A driver is to, by all users, be loaded using the same literal Path. The exception is when reloading is requested, in which case Path can be specified differently. Notice that all users trying to load the driver later need to use the new Path if Path is changed using a reload option. This is yet another reason to have only one loader of a driver one wants to upgrade in a running system.

Name - This parameter is the name of the driver to be used in subsequent calls to function erlang:open_port in ERTS. The name can be specified as an iolist/0 or an atom/0. The name specified when loading is used to find the object file (with the help of Path and the system-implied extension suffix, that is, .so). The name by which the driver identifies itself must also be consistent with this Name parameter, much as the module name of a Beam file much corresponds to its filename.

OptionList - Some options can be specified to control the loading operation. The options are specified as a list of two-tuples. The tuples have the following values and meanings:

{driver_options, DriverOptionList} - This is to provide options that changes its general behavior and "sticks" to the driver throughout its lifespan.

The driver options for a specified driver name need always to be consistent, even when the driver is reloaded, meaning that they are as much a part of the driver as the name.

The only allowed driver option is kill_ports, which means that all ports opened to the driver are killed with exit reason driver_unloaded when no process any longer has the driver loaded. This situation arises either when the last user calls try_unload/2, or when the last process having loaded the driver exits.

{monitor, MonitorOption} - A MonitorOption tells try_load/3 to trigger a driver monitor under certain conditions. When the monitor is triggered, the function returns a three-tuple {ok, PendingStatus, reference()}, where reference/0 is the monitor reference for the driver monitor.

Only one MonitorOption can be specified. It is one of the following:

The atom pending, which means that a monitor is to be created whenever a load operation is delayed,

The atom pending_driver, in which a monitor is created whenever the operation is delayed because of open ports to an otherwise unused driver.

Option pending_driver is of little use, but is present for completeness, as it is well defined which reload options that can give rise to which delays. However, it can be a good idea to use the same MonitorOption as the ReloadOption, if present.

If reloading is not requested, it can still be useful to specify option monitor, as forced unloads (driver option kill_ports or option kill_ports to try_unload/2) trigger a transient state where driver loading cannot be performed until all closing ports are closed. Thus, as try_unload can, in almost all situations, return {ok, pending_driver}, always specify at least {monitor, pending_driver} in production code (see the monitor discussion earlier).

{reload, ReloadOption} - This option is used to reload a driver from disk, most often in a code upgrade scenario. Having a reload option also implies that parameter Path does not need to be consistent with earlier loads of the driver.

To reload a driver, the process must have loaded the driver before, that is, there must be an active user of the driver in the process.

The reload option can be either of the following:

pending - With the atom pending, reloading is requested for any driver and is effectuated when all ports opened to the driver are closed. The driver replacement in this case takes place regardless if there are still pending users having the driver loaded.

The option also triggers port-killing (if driver option kill_ports is used) although there are pending users, making it usable for forced driver replacement, but laying much responsibility on the driver users. The pending option is seldom used as one does not want other users to have loaded the driver when code change is underway.

pending_driver - This option is more useful. Here, reloading is queued if the driver is not loaded by any other users, but the driver has opened ports, in which case {ok, pending_driver} is returned (a monitor option is recommended).

If the driver is unloaded (not present in the system), error code not_loaded is returned. Option reload is intended for when the user has already loaded the driver in advance.

The function can return numerous errors, some can only be returned given a certain combination of options.

Some errors are opaque and can only be interpreted by passing them to function format_error/1, but some can be interpreted directly:

{error,linked_in_driver} - The driver with the specified name is an Erlang statically linked-in driver, which cannot be manipulated with this API.

{error,inconsistent} - The driver is already loaded with other DriverOptionList or a different literal Path argument.

This can occur even if a reload option is specified, if DriverOptionList differs from the current.

{error, permanent} - The driver has requested itself to be permanent, making it behave like an Erlang linked-in driver and can no longer be manipulated with this API.

{error, pending_process} - The driver is loaded by other users when option {reload, pending_driver} was specified.

{error, pending_reload} - Driver reload is already requested by another user when option {reload, ReloadOption} was specified.

{error, not_loaded_by_this_process} - Appears when option reload is specified. The driver Name is present in the system, but there is no user of it in this process.

{error, not_loaded} - Appears when option reload is specified. The driver Name is not in the system. Only drivers loaded by this process can be reloaded.

All other error codes are to be translated by function format_error/1. Notice that calls to format_error are to be performed from the same running instance of the Erlang virtual machine as the error is detected in, because of system-dependent behavior concerning error values.

If the arguments or options are malformed, the function throws a badarg exception.

try_unload(Name, OptionList)

-spec try_unload(Name, OptionList) -> {ok, Status} | {ok, PendingStatus, Ref} | {error, ErrorAtom}
                    when
                        Name :: driver(),
                        OptionList :: [Option],
                        Option :: {monitor, MonitorOption} | kill_ports,
                        MonitorOption :: pending_driver | pending,
                        Status :: unloaded | PendingStatus,
                        PendingStatus :: pending_driver | pending_process,
                        Ref :: reference(),
                        ErrorAtom ::
                            linked_in_driver | not_loaded | not_loaded_by_this_process | permanent.

This is the low-level function to unload (or decrement reference counts of) a driver. It can be used to force port killing, in much the same way as the driver option kill_ports implicitly does. Also, it can trigger a monitor either because other users still have the driver loaded or because open ports use the driver.

Unloading can be described as the process of telling the emulator that this particular part of the code in this particular process (that is, this user) no longer needs the driver. That can, if there are no other users, trigger unloading of the driver, in which case the driver name disappears from the system and (if possible) the memory occupied by the driver executable code is reclaimed.

If the driver has option kill_ports set, or if kill_ports is specified as an option to this function, all pending ports using this driver are killed when unloading is done by the last user. If no port-killing is involved and there are open ports, the unloading is delayed until no more open ports use the driver. If, in this case, another user (or even this user) loads the driver again before the driver is unloaded, the unloading never takes place.

To allow the user to request unloading to wait for actual unloading, monitor triggers can be specified in much the same way as when loading. However, as users of this function seldom are interested in more than decrementing the reference counts, monitoring is seldom needed.

Note

If option kill_ports is used, monitor trigging is crucial, as the ports are not guaranteed to be killed until the driver is unloaded. Thus, a monitor must be triggered for at least the pending_driver case.

The possible monitor messages to expect are the same as when using option unloaded to function monitor/2.

The function returns one of the following statuses upon success:

{ok, unloaded} - The driver was immediately unloaded, meaning that the driver name is now free to use by other drivers and, if the underlying OS permits it, the memory occupied by the driver object code is now reclaimed.

The driver can only be unloaded when there are no open ports using it and no more users require it to be loaded.

{ok, pending_driver}or {ok, pending_driver, reference()} - Indicates that this call removed the last user from the driver, but there are still open ports using it. When all ports are closed and no new users have arrived, the driver is reloaded and the name and memory reclaimed.

This return value is valid even if option kill_ports was used, as killing ports can be a process that does not complete immediately. However, the condition is in that case transient. Monitors are always useful to detect when the driver is really unloaded.

{ok, pending_process}or {ok, pending_process, reference()} - The unload request is registered, but other users still hold the driver. Notice that the term pending_process can refer to the running process; there can be more than one user in the same process.

This is a normal, healthy, return value if the call was just placed to inform the emulator that you have no further use of the driver. It is the most common return value in the most common scenario described in the introduction.

The function accepts the following parameters:

Name - Name is the name of the driver to be unloaded. The name can be specified as an iolist/0 or as an atom/0.

OptionList - Argument OptionList can be used to specify certain behavior regarding ports and triggering monitors under certain conditions:

kill_ports - Forces killing of all ports opened using this driver, with exit reason driver_unloaded, if you are the last user of the driver.

If other users have the driver loaded, this option has no effect.

To get the consistent behavior of killing ports when the last user unloads, use driver option kill_ports when loading the driver instead.

{monitor, MonitorOption} - Creates a driver monitor if the condition specified in MonitorOption is true. The valid options are:

pending_driver - Creates a driver monitor if the return value is to be {ok, pending_driver}.

pending - Creates a monitor if the return value is {ok, pending_driver} or {ok, pending_process}.

The pending_driver MonitorOption is by far the most useful. It must be used to ensure that the driver really is unloaded and the ports closed whenever option kill_ports is used, or the driver can have been loaded with driver option kill_ports.

Using the monitor triggers in the call to try_unload ensures that the monitor is added before the unloading is executed, meaning that the monitor is always properly triggered, which is not the case if monitor/2 is called separately.

The function can return the following error conditions, all well specified (no opaque values):

{error, linked_in_driver} - You were trying to unload an Erlang statically linked-in driver, which cannot be manipulated with this interface (and cannot be unloaded at all).

{error, not_loaded} - The driver Name is not present in the system.

{error, not_loaded_by_this_process} - The driver Name is present in the system, but there is no user of it in this process.

As a special case, drivers can be unloaded from processes that have done no corresponding call to try_load/3 if, and only if, there are no users of the driver at all, which can occur if the process containing the last user dies.

{error, permanent} - The driver has made itself permanent, in which case it can no longer be manipulated by this interface (much like a statically linked-in driver).

The function throws a badarg exception if the parameters are not specified as described here.

unload(Name)

-spec unload(Name) -> ok | {error, ErrorDesc} when Name :: driver(), ErrorDesc :: term().

Unloads, or at least dereferences the driver named Name. If the caller is the last user of the driver, and no more open ports use the driver, the driver gets unloaded. Otherwise, unloading is delayed until all ports are closed and no users remain.

If there are other users of the driver, the reference counts of the driver is merely decreased, so that the caller is no longer considered a user of the driver. For use scenarios, see the description in the beginning of this module.

The ErrorDesc returned is an opaque value to be passed further on to function format_error/1. For more control over the operation, use the try_unload/2 interface.

The function throws a badarg exception if the parameters are not specified as described here.

unload_driver(Name)

-spec unload_driver(Name) -> ok | {error, ErrorDesc} when Name :: driver(), ErrorDesc :: term().

Unloads, or at least dereferences the driver named Name. If the caller is the last user of the driver, all remaining open ports using the driver are killed with reason driver_unloaded and the driver eventually gets unloaded.

If there are other users of the driver, the reference counts of the driver is merely decreased, so that the caller is no longer considered a user. For use scenarios, see the description in the beginning of this module.

The ErrorDesc returned is an opaque value to be passed further on to function format_error/1. For more control over the operation, use the try_unload/2 interface.

The function throws a badarg exception if the parameters are not specified as described here.

erl_debugger

Erlang debugger support (EXPERIMENTAL).

This module exposes low-level functionality for the implementation of a debugger for Erlang.

Any local process can register itself as the debugger for a node, but there can be at most one such process registered at any given time. Using the BIFs in this module, a debugger can:

set breakpoints;

inspect internal process state, such registers, stack-frames;

get notified on debugger events such as a process hitting a breakpoint;

resume processes paused on breakpoints

At the moment, the API is highly experimental; so don't depend on it, or otherwise expect frequent incompatible changes.

Summary

Types

event()

Debugger events.

event_message()

The debugger process will receive debugger-event messages, wrapped in an envelope of this type.

instrumentation()

Debugging instrumentations that can be applied on module loading.

reg_val()

The value of an X or a Y register, provided it fits within the requested size.

session()

Debugger session identifier.

stack_frame()

A stack-frame, including the value of each slot.

stack_frame_fun()

What is running in each stack frame, including special VM frames.

stack_frame_info()

Extra information about a stack-frame.

stack_frame_slot()

The contents of a stack frame slot can be a Y register or an exception handler.

Functions

breakpoint(Module, Line, Flag)

Sets or clear a breakpoint on the given Module/Line.

breakpoints(Module)

Returns information on available breakpoints for a module.

breakpoints(Module, FunName, Arity)

Returns information on available breakpoints for a given function. .

instrumentations()

Returns the instrumentations that will be applied on module loading.

peek_stack_frame_slot(Pid, FrameNo, Slot, MaxSize)

Gets the value of a slot in a suspended process stack-frame.

peek_xreg(Pid, Reg, MaxSize)

Get the value of an X register for a suspended process.

register(Pid)

Register the given process as the debugger.

stack_frames(Pid, MaxTermSize)

Get the all the stack-frames for a suspended process.

supported()

Returns true if the emulator supports debugging.

toggle_instrumentations(Toggle)

Updates the instrumentations that will be applied on module loading.

unregister(Pid, Session)

Unregisters the given process.

whereis()

Returns the pid of the registered debugger.

xregs_count(Pid)

Get the number of X registers currently in use by a suspended process.

Types

event()

(since OTP 28.0)

-type event() :: {breakpoint, pid(), mfa(), Line :: pos_integer(), Resume :: fun(() -> ok)}.

Debugger events.

Here are the possible events:

{breakpoint, Pid, {M,F,A}, Line, Resume}: process Pid hit a breakpoint on module M, at the given Line. The debugger can resume the process by executing Resume().

event_message()

(since OTP 28.0)

-type event_message() :: {debugger_event, session(), event()}.

The debugger process will receive debugger-event messages, wrapped in an envelope of this type.

instrumentation()

(since OTP 28.0)

-type instrumentation() :: line_breakpoint.

Debugging instrumentations that can be applied on module loading.

line_breakpoint: Allows setting breakpoints at the beginning of executable lines

reg_val()

(since OTP 28.0)

-type reg_val() :: {value, term()} | {too_large, Size :: pos_integer()}.

The value of an X or a Y register, provided it fits within the requested size.

If it is too large, then size of the term.

session()

(since OTP 28.0)

-opaque session()

Debugger session identifier.

It is attached to all debugger events.

stack_frame()

(since OTP 28.0)

-type stack_frame() :: {FrameNo :: non_neg_integer(), stack_frame_fun(), stack_frame_info()}.

A stack-frame, including the value of each slot.

stack_frame_fun()

(since OTP 28.0)

-type stack_frame_fun() ::
          #{function := mfa(), line := pos_integer() | undefined} |
          '' | '' | '' |
          '' | 'unknown function'.

What is running in each stack frame, including special VM frames.

stack_frame_info()

(since OTP 28.0)

-type stack_frame_info() :: #{slots := [stack_frame_slot()], code := pos_integer()}.

Extra information about a stack-frame.

slots: Y-registers (in order [Y0,...Yk]), followed by exception-handlers.

code: Memory address of the next instruction to execute in this frame.

stack_frame_slot()

(since OTP 28.0)

-type stack_frame_slot() :: reg_val() | {'catch', stack_frame_fun()}.

The contents of a stack frame slot can be a Y register or an exception handler.

Functions

breakpoint(Module, Line, Flag)

(since OTP 28.0)

-spec breakpoint(Module, Line, Flag) -> ok | {error, Reason}
                    when
                        Module :: module(),
                        Line :: pos_integer(),
                        Flag :: boolean(),
                        Reason :: {unsupported, Module | Line} | {badkey, Module | Line}.

Sets or clear a breakpoint on the given Module/Line.

When a process hits a breakpoint, it will pause and a breakpoint message is sent to the registered debugger.

Returns ok on success. It can fail with the following reasons:

{badkey, Module}: The given module is not loaded.

{unsupported, Module}: The module was loaded without support for line breakpoints.

{badkey, Line}: The line is not relevant; it could refer to a comment, not existing in the module source, and so on.

{unsupported, Line}: It is not possible to set a breakpoint in in the given line; for example, if it refers to a function head.

breakpoints(Module)

(since OTP 28.0)

-spec breakpoints(Module) -> {ok, Result} | {error, Reason}
                     when
                         Module :: module(),
                         Result :: #{Fun => #{Line => boolean()}},
                         Fun :: {atom(), arity()},
                         Line :: pos_integer(),
                         Reason :: badkey.

Returns information on available breakpoints for a module.

For each function in the module, returns a map #{Line => boolean()}, where the keys are lines where breakpoints can be set, and the value represents whether be breakpoint is enabled (true) or not (false).

breakpoints(Module, FunName, Arity)

(since OTP 28.0)

-spec breakpoints(Module, FunName, Arity) -> {ok, Result} | {error, Reason}
                     when
                         Module :: module(),
                         FunName :: atom(),
                         Arity :: arity(),
                         Result :: #{Line => boolean()},
                         Line :: pos_integer(),
                         Reason :: {badkey, module() | {FunName, Arity}}.

Returns information on available breakpoints for a given function. .

The function need not be exported.

Returns a map #{Line => boolean()}, where the keys are lines where breakpoints can be set, and the value represents whether be breakpoint is enabled (true) or not (false).

instrumentations()

(since OTP 28.0)

-spec instrumentations() -> #{instrumentation() => boolean()}.

Returns the instrumentations that will be applied on module loading.

Modules that are already loaded may have had a different set of instrumentations applied.

peek_stack_frame_slot(Pid, FrameNo, Slot, MaxSize)

(since OTP 28.0)

-spec peek_stack_frame_slot(Pid, FrameNo, Slot, MaxSize) -> running | undefined | stack_frame_slot()
                               when
                                   Pid :: pid(),
                                   FrameNo :: pos_integer(),
                                   Slot :: non_neg_integer(),
                                   MaxSize :: non_neg_integer().

Gets the value of a slot in a suspended process stack-frame.

Returns running if the process is not suspended, and undefined if the frame or the slot does not exist for that process. Otherwise, returns the slot, that can be a term, if its size is less than MaxTermSize, or an exeption handler.

peek_xreg(Pid, Reg, MaxSize)

(since OTP 28.0)

-spec peek_xreg(Pid, Reg, MaxSize) -> running | undefined | reg_val()
                   when Pid :: pid(), Reg :: non_neg_integer(), MaxSize :: non_neg_integer().

Get the value of an X register for a suspended process.

register(Pid)

(since OTP 28.0)

-spec register(Pid) -> {ok, session()} | {error, already_exists} when Pid :: pid().

Register the given process as the debugger.

If the registration succeeds, it returns {ok, Session}, where Session is a token that will be included in every message sent to the process.

Returns {error, already_exists} if some process is currently registered as debugger.

stack_frames(Pid, MaxTermSize)

(since OTP 28.0)

-spec stack_frames(Pid, MaxTermSize) -> running | [stack_frame()]
                      when Pid :: pid(), MaxTermSize :: non_neg_integer().

Get the all the stack-frames for a suspended process.

If the given process is not in a suspended state, returns running. Otherwise, a list of stack frames including the content of each slot is returned. For slots containing terms, MaxTermSize controls the maximum size of values that are allowed to be returned (to avoid accidentally blowing the heap of the caller).

supported()

(since OTP 28.0)

-spec supported() -> boolean().

Returns true if the emulator supports debugging.

The debugger can only be used if the +D argument was passed to the emulator on start-up.

toggle_instrumentations(Toggle)

(since OTP 28.0)

-spec toggle_instrumentations(Toggle) -> ok when Toggle :: #{instrumentation() => boolean()}.

Updates the instrumentations that will be applied on module loading.

Modules that are already loaded will keep the instrumentation they had at their time of loading.

unregister(Pid, Session)

(since OTP 28.0)

-spec unregister(Pid, Session) -> ok when Pid :: pid(), Session :: session().

Unregisters the given process.

The session given on registration needs to be provided.

whereis()

(since OTP 28.0)

-spec whereis() -> undefined | pid().

Returns the pid of the registered debugger.

xregs_count(Pid)

(since OTP 28.0)

-spec xregs_count(Pid) -> running | non_neg_integer() when Pid :: pid().

Get the number of X registers currently in use by a suspended process.

seq_trace

Sequential tracing of information transfers.

Sequential tracing makes it possible to trace information flows between processes resulting from one initial transfer of information. Sequential tracing is independent of the ordinary tracing in Erlang, which is controlled by the erlang:trace/3 BIF. For more information about what sequential tracing is and how it can be used, see section Sequential Tracing.

seq_trace provides functions that control all aspects of sequential tracing. There are functions for activation, deactivation, inspection, and for collection of the trace output.

Trace Messages Sent to the System Tracer

The format of the messages is one of the following, depending on if flag timestamp of the trace token is set to true or false:

{seq_trace, Label, SeqTraceInfo, TimeStamp}

or

{seq_trace, Label, SeqTraceInfo}

Where:

Label = int()
TimeStamp = {Seconds, Milliseconds, Microseconds}
  Seconds = Milliseconds = Microseconds = int()

SeqTraceInfo can have the following formats:

{send, Serial, From, To, Message} - Used when a process From with its trace token flag send set to true has sent information. To may be a process identifier, a registered name on a node represented as {NameAtom, NodeAtom}, or a node name represented as an atom. From may be a process identifier or a node name represented as an atom. Message contains the information passed along in this information transfer. If the transfer is done via message passing, it is the actual message.

{'receive', Serial, From, To, Message} - Used when a process To receives information with a trace token that has flag 'receive' set to true. To may be a process identifier, or a node name represented as an atom. From may be a process identifier or a node name represented as an atom. Message contains the information passed along in this information transfer. If the transfer is done via message passing, it is the actual message.

{print, Serial, From, _, Info} - Used when a process From has called seq_trace:print(Label, TraceInfo) and has a trace token with flag print set to true, and label set to Label.

Serial is a tuple {PreviousSerial, ThisSerial}, where:

Integer PreviousSerial denotes the serial counter passed in the last received information that carried a trace token. If the process is the first in a new sequential trace, PreviousSerial is set to the value of the process internal "trace clock".

Integer ThisSerial is the serial counter that a process sets on outgoing messages. It is based on the process internal "trace clock", which is incremented by one before it is attached to the trace token in the message.

Sequential Tracing

Sequential tracing is a way to trace a sequence of information transfers between different local or remote processes, where the sequence is initiated by a single transfer. The typical information transfer is an ordinary Erlang message passed between two processes, but information is transferred also in other ways. In short, it works as follows:

Each process has a trace token, which can be empty or not empty. When not empty, the trace token can be seen as the tuple {Label, Flags, Serial, From}. The trace token is passed invisibly when information is passed between processes. In most cases the information is passed in ordinary messages between processes, but information is also passed between processes by other means. For example, by spawning a new process. An information transfer between two processes is represented by a send event and a receive event regardless of how it is passed.

To start a sequential trace, the user must explicitly set the trace token in the process that will send the first information in a sequence.

The trace token of a process is set each time the process receives information. This is typically when the process matches a message in a receive statement, according to the trace token carried by the received message, empty or not.

On each Erlang node, a process can be set as the system tracer. This process will receive trace messages each time information with a trace token is sent or received (if the trace token flag send or 'receive' is set). The system tracer can then print each trace event, write it to a file, or whatever suitable.

Note

The system tracer only receives those trace events that occur locally within the Erlang node. To get the whole picture of a sequential trace, involving processes on many Erlang nodes, the output from the system tracer on each involved node must be merged (offline).

The following sections describe sequential tracing and its most fundamental concepts.

Different Information Transfers

Information flows between processes in a lot of different ways. Not all flows of information will be covered by sequential tracing. One example is information passed via ETS tables. Below is a list of information paths that are covered by sequential tracing:

Message Passing - All ordinary messages passed between Erlang processes.

Exit signals - An exit signal is represented as an {'EXIT', Pid, Reason} tuple.

Process Spawn - A process spawn is represented as multiple information transfers. At least one spawn request and one spawn reply. The actual amount of information transfers depends on what type of spawn it is and may also change in future implementations. Note that this is more or less an internal protocol that you are peeking at. The spawn request will be represented as a tuple with the first element containing the atom spawn_request, but this is more or less all that you can depend on.

Note

If you do ordinary send or receive trace on the system, you will only see ordinary message passing, not the other information transfers listed above.

Note

When a send event and corresponding receive event do not both correspond to ordinary Erlang messages, the Message part of the trace messages may not be identical. This since all information not necessarily are available when generating the trace messages.

Trace Token

Each process has a current trace token which is "invisibly" passed from the parent process on creation of the process.

The current token of a process is set in one of the following two ways:

Explicitly by the process itself, through a call to seq_trace:set_token/1,2

When information is received. This is typically when a received message is matched out in a receive expression, but also when information is received in other ways.

In both cases, the current token is set. In particular, if the token of a received message is empty, the current token of the process is set to empty.

A trace token contains a label and a set of flags. Both the label and the flags are set in both alternatives above.

Serial

The trace token contains a component called serial. It consists of two integers, Previous and Current. The purpose is to uniquely identify each traced event within a trace sequence, as well as to order the messages chronologically and in the different branches, if any.

The algorithm for updating Serial can be described as follows:

Let each process have two counters, prev_cnt and curr_cnt, both are set to 0 when a process is created outside of a trace sequence. The counters are updated at the following occasions:

When the process is about to pass along information to another process and the trace token is not empty. This typically occurs when sending a message, but also, for example, when spawning another process.

Let the serial of the trace token be tprev and tcurr.

curr_cnt := curr_cnt + 1
tprev := prev_cnt
tcurr := curr_cnt

The trace token with tprev and tcurr is then passed along with the information passed to the other process.

When the process calls seq_trace:print(Label, Info), Label matches the label part of the trace token and the trace token print flag is true.

The algorithm is the same as for send above.

When information is received that also contains a non-empty trace token. For example, when a message is matched out in a receive expression, or when a new process is spawned.

The process trace token is set to the trace token from the message.

Let the serial of the trace token be tprev and tcurr.

if (curr_cnt < tcurr )
   curr_cnt := tcurr
prev_cnt := tcurr

curr_cnt of a process is incremented each time the process is involved in a sequential trace. The counter can reach its limit (27 bits) if a process is very long-lived and is involved in much sequential tracing. If the counter overflows, the serial for ordering of the trace events cannot be used. To prevent the counter from overflowing in the middle of a sequential trace, function seq_trace:reset_trace/0 can be called to reset prev_cnt and curr_cnt of all processes in the Erlang node. This function also sets all trace tokens in processes and their message queues to empty, and thus stops all ongoing sequential tracing.

Performance Considerations

The performance degradation for a system that is enabled for sequential tracing is negligible as long as no tracing is activated. When tracing is activated, there is an extra cost for each traced message, but all other messages are unaffected.

Ports

Sequential tracing is not performed across ports.

If the user for some reason wants to pass the trace token to a port, this must be done manually in the code of the port controlling process. The port controlling processes have to check the appropriate sequential trace settings (as obtained from seq_trace:get_token/1) and include trace information in the message data sent to their respective ports.

Similarly, for messages received from a port, a port controller has to retrieve trace-specific information, and set appropriate sequential trace flags through calls to seq_trace:set_token/2.

Distribution

Sequential tracing between nodes is performed transparently. This applies to C-nodes built with Erl_Interface too. A C-node built with Erl_Interface only maintains one trace token, which means that the C-node appears as one process from the sequential tracing point of view.

Example of Use

This example gives a rough idea of how the new primitives can be used and what kind of output it produces.

Assume that you have an initiating process with Pid == <0.30.0> like this:

-module(seqex).
-compile(export_all).

loop(Port) ->
    receive
        {Port,Message} ->
            seq_trace:set_token(label,17),
            seq_trace:set_token('receive',true),
            seq_trace:set_token(print,true),
            seq_trace:print(17,"**** Trace Started ****"),
            call_server ! {self(),the_message};
        {ack,Ack} ->
            ok
    end,
    loop(Port).

And a registered process call_server with Pid == <0.31.0> like this:

loop() ->
    receive
        {PortController,Message} ->
            Ack = {received, Message},
            seq_trace:print(17,"We are here now"),
            PortController ! {ack,Ack}
    end,
    loop().

A possible output from the system's sequential_tracer can be like this:

17:<0.30.0> Info {0,1} WITH
"**** Trace Started ****"
17:<0.31.0> Received {0,2} FROM <0.30.0> WITH
{<0.30.0>,the_message}
17:<0.31.0> Info {2,3} WITH
"We are here now"
17:<0.30.0> Received {2,4} FROM <0.31.0> WITH
{ack,{received,the_message}}

The implementation of a system tracer process that produces this printout can look like this:

tracer() ->
    receive
        {seq_trace,Label,TraceInfo} ->
           print_trace(Label,TraceInfo,false);
        {seq_trace,Label,TraceInfo,Ts} ->
           print_trace(Label,TraceInfo,Ts);
        _Other -> ignore
    end,
    tracer().

print_trace(Label,TraceInfo,false) ->
    io:format("~p:",[Label]),
    print_trace(TraceInfo);
print_trace(Label,TraceInfo,Ts) ->
    io:format("~p ~p:",[Label,Ts]),
    print_trace(TraceInfo).

print_trace({print,Serial,From,_,Info}) ->
    io:format("~p Info ~p WITH~n~p~n", [From,Serial,Info]);
print_trace({'receive',Serial,From,To,Message}) ->
    io:format("~p Received ~p FROM ~p WITH~n~p~n",
              [To,Serial,From,Message]);
print_trace({send,Serial,From,To,Message}) ->
    io:format("~p Sent ~p TO ~p WITH~n~p~n",
              [From,Serial,To,Message]).

The code that creates a process that runs this tracer function and sets that process as the system tracer can look like this:

start() ->
    Pid = spawn(?MODULE,tracer,[]),
    seq_trace:set_system_tracer(Pid), % set Pid as the system tracer
    ok.

With a function like test/0, the whole example can be started:

test() ->
    P = spawn(?MODULE, loop, [port]),
    register(call_server, spawn(?MODULE, loop, [])),
    start(),
    P ! {port,message}.

Summary

Types

component()

flag()

token()

An opaque term (a tuple) representing a trace token.

tracer()

value()

Functions

get_system_tracer()

Returns the pid, port identifier or tracer module of the current system tracer or false if no system tracer is activated.

get_token()

Returns the value of the trace token for the calling process. If [] is returned, it means that tracing is not active. Any other value returned is the value of an active trace token. The value returned can be used as input to the set_token/1 function.

get_token(Component)

Returns the value of the trace token component Component. See set_token/2 for possible values of Component and Val.

print(TraceInfo)

Puts the Erlang term TraceInfo into the sequential trace output if the calling process currently is executing within a sequential trace and the print flag of the trace token is set.

print(Label, TraceInfo)

Same as print/1 with the additional condition that TraceInfo is output only if Label is equal to the label component of the trace token.

reset_trace()

Sets the trace token to empty for all processes on the local node. The process internal counters used to create the serial of the trace token is set to 0. The trace token is set to empty for all messages in message queues. Together this will effectively stop all ongoing sequential tracing in the local node.

set_system_tracer(Tracer)

Sets the system tracer. The system tracer can be either a process, port or tracer module denoted by Tracer. Returns the previous value (which can be false if no system tracer is active).

set_token(Token)

Sets the trace token for the calling process to Token. If Token == [] then tracing is disabled, otherwise Token should be an Erlang term returned from get_token/0 or set_token/1. set_token/1 can be used to temporarily exclude message passing from the trace by setting the trace token to empty like this

set_token(Component, Val)

Sets the individual Component of the trace token to Val. Returns the previous value of the component.

Types

component()

(not exported)

-type component() :: label | serial | flag().

flag()

(not exported)

-type flag() :: send | 'receive' | print | timestamp | monotonic_timestamp | strict_monotonic_timestamp.

token()

(not exported)

-type token() :: {integer(), boolean(), _, _, _}.

An opaque term (a tuple) representing a trace token.

tracer()

(not exported)

-type tracer() :: (Pid :: pid()) | port() | (TracerModule :: {module(), term()}) | false.

value()

(not exported)

-type value() ::
          (Label :: term()) |
          {Previous :: non_neg_integer(), Current :: non_neg_integer()} |
          (Bool :: boolean()).

Functions

get_system_tracer()

-spec get_system_tracer() -> Tracer when Tracer :: tracer().

Returns the pid, port identifier or tracer module of the current system tracer or false if no system tracer is activated.

get_token()

-spec get_token() -> [] | token().

Returns the value of the trace token for the calling process. If [] is returned, it means that tracing is not active. Any other value returned is the value of an active trace token. The value returned can be used as input to the set_token/1 function.

get_token(Component)

-spec get_token(Component) -> [] | {Component, Val} when Component :: component(), Val :: value().

Returns the value of the trace token component Component. See set_token/2 for possible values of Component and Val.

print(TraceInfo)

-spec print(TraceInfo) -> ok when TraceInfo :: term().

Puts the Erlang term TraceInfo into the sequential trace output if the calling process currently is executing within a sequential trace and the print flag of the trace token is set.

print(Label, TraceInfo)

-spec print(Label, TraceInfo) -> ok when Label :: integer(), TraceInfo :: term().

Same as print/1 with the additional condition that TraceInfo is output only if Label is equal to the label component of the trace token.

reset_trace()

-spec reset_trace() -> true.

Sets the trace token to empty for all processes on the local node. The process internal counters used to create the serial of the trace token is set to 0. The trace token is set to empty for all messages in message queues. Together this will effectively stop all ongoing sequential tracing in the local node.

set_system_tracer(Tracer)

-spec set_system_tracer(Tracer) -> OldTracer when Tracer :: tracer(), OldTracer :: tracer().

Sets the system tracer. The system tracer can be either a process, port or tracer module denoted by Tracer. Returns the previous value (which can be false if no system tracer is active).

Failure: {badarg, Info}} if Pid is not an existing local pid.

set_token(Token)

-spec set_token(Token) -> PreviousToken | ok when Token :: [] | token(), PreviousToken :: [] | token().

Sets the trace token for the calling process to Token. If Token == [] then tracing is disabled, otherwise Token should be an Erlang term returned from get_token/0 or set_token/1. set_token/1 can be used to temporarily exclude message passing from the trace by setting the trace token to empty like this:

OldToken = seq_trace:set_token([]), % set to empty and save
                                    % old value
% do something that should not be part of the trace
io:format("Exclude the signalling caused by this~n"),
seq_trace:set_token(OldToken), % activate the trace token again
...

Returns the previous value of the trace token.

set_token(Component, Val)

-spec set_token(Component, Val) -> OldVal
                   when Component :: component(), Val :: value(), OldVal :: value().

Sets the individual Component of the trace token to Val. Returns the previous value of the component.

set_token(label, Label) - The label component is a term which identifies all events belonging to the same sequential trace. If several sequential traces can be active simultaneously, label is used to identify the separate traces. Default is 0.

Warning

Labels were restricted to small signed integers (28 bits) prior to OTP 21. The trace token will be silently dropped if it crosses over to a node that does not support the label.

set_token(serial, SerialValue) - SerialValue = {Previous, Current}. The serial component contains counters which enables the traced messages to be sorted, should never be set explicitly by the user as these counters are updated automatically. Default is {0, 0}.

set_token(send, Bool) - A trace token flag (true | false) which enables/disables tracing on information sending. Default is false.

set_token('receive', Bool) - A trace token flag (true | false) which enables/disables tracing on information reception. Default is false.

set_token(print, Bool) - A trace token flag (true | false) which enables/disables tracing on explicit calls to seq_trace:print/1. Default is false.

set_token(timestamp, Bool) - A trace token flag (true | false) which enables/disables a timestamp to be generated for each traced event. Default is false.

set_token(strict_monotonic_timestamp, Bool) - A trace token flag (true | false) which enables/disables a strict monotonic timestamp to be generated for each traced event. Default is false. Timestamps will consist of Erlang monotonic time and a monotonically increasing integer. The time-stamp has the same format and value as produced by {erlang:monotonic_time(nanosecond), erlang:unique_integer([monotonic])}.

set_token(monotonic_timestamp, Bool) - A trace token flag (true | false) which enables/disables a strict monotonic timestamp to be generated for each traced event. Default is false. Timestamps will use Erlang monotonic time. The time-stamp has the same format and value as produced by erlang:monotonic_time(nanosecond).

If multiple timestamp flags are passed, timestamp has precedence over strict_monotonic_timestamp which in turn has precedence over monotonic_timestamp. All timestamp flags are remembered, so if two are passed and the one with highest precedence later is disabled the other one will become active.

trace

The Erlang trace interface.

The Erlang run-time system exposes several trace points that allow users to be notified when they are triggered. Trace points are things such as function calls, message sending and receiving, garbage collection, and process scheduling.

The functions in this module can be used directly, but can also be used as building blocks to build more sophisticated debugging or profiling tools. For debugging Erlang code it is recommended to use dbg and for profiling to use tprof.

Trace Sessions

All tracing is done within a trace session. Trace sessions can be created and destroyed dynamically. Each session has its own tracer that will receive all trace messages. Several sessions can exist at the same time without interfering with each other. When a trace session is destroyed, all its trace settings are automatically cleaned up.

Example:

%% Create a tracer process that will receive the trace events
1> Tracer = spawn(fun F() -> receive M -> io:format("~p~n",[M]), F() end end).
<0.91.0>
%% Create a session using the Tracer
2> Session = trace:session_create(my_session, Tracer, []).
{#Ref<0.1543805153.1548353537.92331>,{my_session, 0}}
%% Setup call tracing on self()
3> trace:process(Session, self(), true, [call]).
1
%% Setup call tracing on lists:seq/2
4> trace:function(Session, {lists,seq,2}, [], []).
1
%% Call the traced function
5> lists:seq(1, 10).
{trace,<0.89.0>,call,{lists,seq,[1,10]}} % The trace message
[1,2,3,4,5,6,7,8,9,10] % The return value
%% Cleanup the trace session
6> trace:session_destroy(Session).
ok

Node Local Tracing Only

The functions in this module only operates on the local node. That is, both the traced processes/ports as well as the tracer process/port/module must all reside on the same local node as the call is made. To trace remote nodes use dbg or ttb.

Change

This trace module was introduced in OTP 27.0. The interface and semantics are similar to the older functions erlang:trace/3, erlang:trace_pattern/3, and erlang:trace_info/2.

The main difference is the old functions operate on a single static trace session per node. That could impose the problem that different users and tools would interfere with each other's trace settings. The new trace functions in this module all operate on dynamically created trace sesssions isolated from each other. Also, this makes it easier to safely disable all trace settings when done by a single call to session_destroy/1.

To change an existing tool to use the interface the following table can be useful:

Old function call | corresponds to
erlang:trace(Pid, ...) | process(S, Pid, ...)
erlang:trace(processes, ...) | process(S, all, ...)
erlang:trace(existing_processes, ...) | process(S, existing, ...)
erlang:trace(new_processes, ...) | process(S, new, ...)
erlang:trace(Port, ...) | port(S, Port, ...)
erlang:trace(ports, ...) | port(S, all, ...)
erlang:trace(existing_ports, ...) | port(S, existing, ...)
erlang:trace(new_ports, ...) | port(S, new, ...)
erlang:trace(all, ...) | process(S, all, ...) and port(S, all, ...)
erlang:trace(existing, ...) | process(S, existing, ...) and port(S, existing, ...)
erlang:trace(new, ...) | process(S, new, ...) and port(S, new, ...)
erlang:trace_pattern(MFA, ...) | function(S, MFA, ...)
erlang:trace_pattern(send, ...) | send(S, ...)
erlang:trace_pattern('receive', ...) | recv(S, ...)
erlang:trace_info(...) | info(S, ...)

Argument S is the trace session that must first be created with session_create/3. The other arguments (implied by ...) are mostly the same. The only other difference is that the tracer is always the tracer specified when the session was created. Options {tracer,T}, {tracer,M,S}, {meta,T}, and {meta,M,S} are therefore not allowed, and the default tracer is never the calling process.

Summary

Types

match_variable()

session()

A handle to an isolated trace session.

session_strong_ref()

session_weak_ref()

A weak session handle as returned by session_info/1. A weak session handle can be used like a full session handle, but it will not prevent the session from being destroyed when the last strong handle is garbage collected.

system_event()

system_value()

trace_flag()

trace_info_flag()

trace_info_item_result()

trace_info_return()

trace_info_system_item()

trace_match_spec()

trace_pattern_flag()

trace_pattern_mfa()

Functions

delivered(Session, Tracee)

Equivalent to erlang:trace_delivered(Tracee) except that it is run within the given session/0.

function(Session, MFA, MatchSpec, FlagList)

Enable or disable call tracing for one or more functions.

info(Session, PidPortFuncEvent, Item)

Return trace information about a port, process, function, or event.

port(Session, Ports, How, FlagList)

Turn on or off trace flags for one or more ports.

process(Session, Procs, How, FlagList)

Turn on or off trace flags for one or more processes.

recv(Session, MatchSpec, FlagList)

Set trace pattern for message receiving.

send(Session, MatchSpec, FlagList)

Set trace pattern for message sending.

session_create(Name, Tracer, Opts)

Create a new trace session.

session_destroy(Session)

Destroy a trace session and cleanup all its settings on processes, ports, and functions.

session_info(PidPortFuncEvent)

Return which trace sessions that affect a port, process, function, or event.

system(Session, Event, Value)

Enable/disable monitoring of system events.

Types

match_variable()

(not exported) (since OTP 27.0)

-type match_variable() :: atom().

session()

(since OTP 27.0)

-type session() :: {session_strong_ref(), session_weak_ref()} | session_weak_ref().

A handle to an isolated trace session.

session_strong_ref()

(since OTP 27.0)

-opaque session_strong_ref()

session_weak_ref()

(since OTP 27.0)

-opaque session_weak_ref()

A weak session handle as returned by session_info/1. A weak session handle can be used like a full session handle, but it will not prevent the session from being destroyed when the last strong handle is garbage collected.

system_event()

(not exported) (since OTP 27.0)

-type system_event() ::
          busy_port | busy_dist_port | long_gc | long_message_queue | long_schedule | large_heap.

system_value()

(not exported) (since OTP 27.0)

-type system_value() ::
          true | false | non_neg_integer() | {Disable :: non_neg_integer(), Enable :: pos_integer()}.

trace_flag()

(not exported) (since OTP 27.0)

-type trace_flag() :: trace_info_flag() | all | cpu_timestamp.

trace_info_flag()

(not exported) (since OTP 27.0)

-type trace_info_flag() ::
          arity | call | exiting | garbage_collection | monotonic_timestamp | procs | ports |
          'receive' | return_to | running | running_procs | running_ports | send | set_on_first_link |
          set_on_first_spawn | set_on_link | set_on_spawn | silent | strict_monotonic_timestamp |
          timestamp.

trace_info_item_result()

(not exported) (since OTP 27.0)

-type trace_info_item_result() ::
          {traced, global | local | false | undefined} |
          {match_spec, trace_match_spec() | false | undefined} |
          {meta, pid() | port() | false | undefined | []} |
          {meta, module(), term()} |
          {meta_match_spec, trace_match_spec() | false | undefined} |
          {call_count, non_neg_integer() | boolean() | undefined} |
          {call_time,
           [{pid(), non_neg_integer(), non_neg_integer(), non_neg_integer()}] | boolean() | undefined} |
          {call_memory, [{pid(), non_neg_integer(), non_neg_integer()}] | boolean() | undefined}.

trace_info_return()

(not exported) (since OTP 27.0)

-type trace_info_return() ::
          undefined |
          {flags, [trace_info_flag()]} |
          {tracer, pid() | port() | []} |
          {tracer, module(), term()} |
          trace_info_item_result() |
          {all, [trace_info_item_result()] | false | undefined} |
          {system, [trace_info_system_item()]}.

trace_info_system_item()

(not exported) (since OTP 27.0)

-type trace_info_system_item() ::
          busy_port | busy_dist_port |
          {long_gc, non_neg_integer()} |
          {long_message_queue, {Disable :: non_neg_integer(), Enable :: pos_integer()}} |
          {long_schedule, non_neg_integer()} |
          {large_heap, non_neg_integer()}.

trace_match_spec()

(not exported) (since OTP 27.0)

-type trace_match_spec() :: [{[term()] | '_' | match_variable(), [term()], [term()]}].

trace_pattern_flag()

(not exported) (since OTP 27.0)

-type trace_pattern_flag() :: global | local | meta | call_count | call_time | call_memory.

trace_pattern_mfa()

(not exported) (since OTP 27.0)

-type trace_pattern_mfa() :: {atom(), atom(), arity() | '_'}.

Functions

delivered(Session, Tracee)

(since OTP 27.0)

-spec delivered(Session :: session(), Tracee :: pid() | all) -> reference().

Equivalent to erlang:trace_delivered(Tracee) except that it is run within the given session/0.

function(Session, MFA, MatchSpec, FlagList)

(since OTP 27.0)

-spec function(Session, MFA, MatchSpec, FlagList) -> non_neg_integer()
                  when
                      Session :: session(),
                      MFA :: trace_pattern_mfa() | on_load,
                      MatchSpec :: trace_match_spec() | boolean() | restart | pause,
                      FlagList :: [trace_pattern_flag()].

Enable or disable call tracing for one or more functions.

Must be combined with process/4 to set the call trace flag for one or more processes.

Conceptually, call tracing works as follows. In each trace session, a set of processes and a set of functions have been marked for tracing. If a traced process calls a traced function, the trace action is taken. Otherwise, nothing happens.

To add or remove one or more processes to the set of traced processes, use process/4.

Use this function to add or remove functions to the set of traced functions in a trace session.

Argument Session is the trace session to operate on as returned by session_create/3.

Argument MFA is to be a tuple, such as {Module, Function, Arity}, or the atom on_load (described below). The MFA tuple specifies the module, function, and arity for the functions to be traced. The atom '_' can be used as a wildcard in any of the following ways:

{Module,Function,'_'} - All functions of any arity named Function in module Module.

{Module,'_','_'} - All functions in module Module.

{'_','_','_'} - All functions in all loaded modules.

Other combinations, such as {Module,'_',Arity}, are not allowed.

If argument MFA is the atom on_load, the match specification and flag list are used on all functions in all modules that are newly loaded.

Argument MatchSpec can take the following forms:

true - Enable tracing for the matching functions. Any match specification is removed.

false - Disable tracing for the matching functions. Any match specification is removed.

MatchExpression - A match specification. An empty list is equivalent to true. For a description of match specifications, see section Match Specifications in Erlang in the User's Guide for the ERTS application.

restart - For the FlagList options call_count, call_time and call_memory: restarts the existing counters. The behavior is undefined for other FlagList options.

pause - For the FlagList options call_count, call_time and call_memory: pauses the existing counters. The behavior is undefined for other FlagList options.

Argument FlagList is a list of options. The following are the valid options:

global - Turn on or off call tracing for global function calls (that is, calls specifying the module explicitly). Only exported functions match and only global calls generate trace messages. This is the default if FlagList is empty.

local - Turn on or off call tracing for all types of function calls. Trace messages are sent whenever any of the specified functions are called, regardless of how they are called. If flag return_to is set for the process, a return_to message is also sent when this function returns to its caller.

meta - Turn on or off meta-tracing for all types of function calls. Trace messages are sent to the tracer whenever any of the specified functions are called.

Meta-tracing traces all processes and does not care about the process trace flags set by process/4, the trace flags are instead fixed to [call, timestamp].

The match specification function {return_trace} works with meta-trace.

call_count - Start (MatchSpec == true) or stop (MatchSpec == false) call count tracing for all types of function calls. For every function, a counter is incremented when the function is called, in any process. No process trace flags need to be activated.

If call count tracing is started while already running, the count is restarted from zero. To pause running counters, use MatchSpec == pause. Paused and running counters can be restarted from zero with MatchSpec == restart.

To read the counter value for a function, call trace:info(_, MFA, call_count).

call_time - Start (MatchSpec is true) or stops (MatchSpec is false) call time tracing for all types of function calls. For every function, a counter is incremented when the function is called and the time spent in the function is measured and accumulated in another counter. The counters are stored for each call traced process.

If call time tracing is started while already running, the count and time restart from zero. To pause running counters, use MatchSpec == pause. Paused and running counters can be restarted from zero with MatchSpec == restart.

To read the counter values, use info/3.

call_memory - Start (MatchSpec == true) or stop (MatchSpec == false) call memory tracing for all types of function calls. For every function, a counter is incremented when the function is called and the memory consumed by the function is measured and accumulated in another counter. Separate counters are stored for each call traced process.

If call memory tracing is started while already running, counters and allocations restart from zero. To pause running counters, use MatchSpec == pause. Paused and running counters can be restarted from zero with MatchSpec == restart.

To read the counter value, use info/3.

Option global cannot be combined with any of the other options, which all perform some kind of local tracing. If global tracing is specified for a set of functions, then local, meta, call_count, call_time, and call_memory tracing for the matching set of functions are disabled, and vice versa.

When disabling trace, the option must match the type of trace set on the function. That is, local tracing must be disabled with option local and global tracing with option global (or no option), and so on.

Part of a match specification cannot be changed directly. If a function has a match specification, it can be replaced with a new one. Function info/3 can be used to retrieve the existing match specification.

Returns the number of functions matching argument MFA. Zero is returned if none matched or if on_load was specified.

Fails by raising an error exception with an error reason of:

badarg - If an argument is invalid.

system_limit - If a match specification passed as argument has excessive nesting which causes scheduler stack exhaustion for the scheduler that the calling process is executing on. Scheduler stack size can be configured when starting the runtime system.

info(Session, PidPortFuncEvent, Item)

(since OTP 27.0)

-spec info(Session, PidPortFuncEvent, Item) -> Res
              when
                  Session :: session(),
                  PidPortFuncEvent ::
                      pid() |
                      port() |
                      new | new_processes | new_ports | MFA | on_load | send | 'receive' | system,
                  MFA :: {module(), atom(), arity()},
                  Item ::
                      flags | tracer | traced | match_spec | meta | meta_match_spec | call_count |
                      call_time | call_memory | all,
                  Res :: trace_info_return().

Return trace information about a port, process, function, or event.

Argument Session is the trace session to inspect as returned by session_create/3 or session_info/1.

To get information about a port or process, PidPortFuncEvent is to be a process identifier (pid), port identifier, or one of the atoms new, new_processes, or new_ports. The atom new or new_processes means that the default trace state for processes to be created is returned. The atom new_ports means that the default trace state for ports to be created is returned.

Valid Item values for ports and processes:

flags - Returns a list of atoms indicating what kind of traces is enabled for the process. The list is empty if no traces are enabled, and one or more of trace_info_flag() if traces are enabled. The order is arbitrary.

tracer - Returns the identifier for process, port, or a tuple containing the tracer module and tracer state tracing this process. If this process is not traced, the return value is [].

To get information about a function, PidPortFuncEvent is to be the three-element tuple {Module, Function, Arity} or the atom on_load. No wildcards are allowed. Returns undefined if the function does not exist or false if the function is not traced. If PidPortFuncEvent is on_load, the information returned refers to the default value for code that will be loaded.

Valid Item values for functions:

traced - Returns global if this function is traced on global function calls, local if this function is traced on local function calls (that is, local and global function calls), and false if local or global function calls are not traced.

match_spec - Returns the match specification for this function, if it has one. If the function is locally or globally traced but has no match specification defined, the returned value is [].

meta - Returns the meta-trace tracer process, port, or trace module for this function, if it has one. If the function is not meta-traced, the returned value is false. If the function is meta-traced but has once detected that the tracer process is invalid, the returned value is [].

meta_match_spec - Returns the meta-trace match specification for this function, if it has one. If the function is meta-traced but has no match specification defined, the returned value is [].

call_count - Returns the call count value for this function or true for the pseudo function on_load if call count tracing is active. Otherwise false is returned.

See also function/4.

call_time - Returns the call time values for this function or true for the pseudo function on_load if call time tracing is active. Otherwise false is returned. The call time values returned, [{Pid, Count, S, Us}], is a list of each process that executed the function and its specific counters. Count is the call count. S and Us are the accumulated call time expressed in seconds and microseconds.

See also function/4.

call_memory - Returns the accumulated number of words allocated by this function. Accumulation stops at the next memory traced function: if there are outer, middle and inner functions each allocating 3 words, but only outer is traced, it will report 9 allocated words. If outer and inner are traced, 6 words are reported for outer and 3 for inner. When function is not traced, false is returned. Returned tuple is [{Pid, Count, Words}], for each process that executed the function.

See also function/4.

all - Returns a list containing the {Item, Value} tuples for all other items, or returns false if no tracing is active for this function.

To get information about an event, PidPortFuncEvent is to be one of the atoms send or 'receive'.

One valid Item for events exists:

match_spec - Returns the match specification for this event, if it has one, or true if no match specification has been set.

To get information about monitored system events, PidPortFuncEvent is to be the atom system.

Only valid Item for system is

all - Returns a list of all monitored system events enabled by system/3.

The return value is {Item, Value}, where Value is the requested information as described earlier. If a pid for a dead process was specified, or the name of a non-existing function, Value is undefined.

port(Session, Ports, How, FlagList)

(since OTP 27.0)

-spec port(Session, Ports, How, FlagList) -> integer()
              when
                  Session :: session(),
                  Ports :: port() | all | existing | new,
                  How :: boolean(),
                  FlagList :: [trace_flag()].

Turn on or off trace flags for one or more ports.

Argument Session is the trace session to operate on as returned by session_create/3.

Ports is either a port identifier for a local port or one of the following atoms:

all - All currently existing ports and all that will be created in the future.

existing - All currently existing ports.

new - All ports that will be created in the future.

FlagList can contain any number of the following flags (the "message tags" refers to the list of trace messages):

all - Sets all trace flags except cpu_timestamp, which are in its nature different than the others.

send - Traces sending of messages.

Message tags: send and send_to_non_existing_process.

'receive' - Traces receiving of messages.

Message tags: 'receive'.

ports - Traces port-related events.

Message tags: open, closed, register, unregister, getting_linked, and getting_unlinked.

running_ports - Traces scheduling of ports.

Message tags: in and out.

timestamp, cpu_timestamp, monotonic_timestamp, strict_monotonic_timestamp - Same as for timestamps in process/4.

The tracing process receives the trace messages described in the following list. Port is the port identifier of the traced port in which the traced event has occurred. The third tuple element is the message tag.

If flag timestamp, strict_monotonic_timestamp, or monotonic_timestamp is specified, the first tuple element is trace_ts instead, and the time stamp is added as an extra element last in the message tuple. If multiple time stamp flags are passed, timestamp has precedence over strict_monotonic_timestamp, which in turn has precedence over monotonic_timestamp. All time stamp flags are remembered, so if two are passed and the one with highest precedence later is disabled, the other one becomes active.

If a match specification (applicable only for send and 'receive' tracing) contains a {message} action function with a non-boolean value, that value is added as an extra element to the message tuple either in the last position or before the timestamp (if it is present).

Trace messages:

{trace, Port, send, Msg, To} - When Port sends message Msg to process To.

{trace, Port, send_to_non_existing_process, Msg, To} - When Port sends message Msg to the non-existing process To.

{trace, Port, 'receive', Msg} - When Port receives message Msg. If Msg is set to time-out, a receive statement can have timed out, or the process received a message with the payload timeout.

{trace, Port, register, RegName} - When Port gets the name RegName registered.

{trace, Port, unregister, RegName} - When Port gets the name RegName unregistered. This is done automatically when a registered process or port exits.

{trace, Port, getting_linked, Pid2} - When Port gets linked to a process Pid2.

{trace, Port, getting_unlinked, Pid2} - When Port gets unlinked from a process Pid2.

{trace, Port, open, Pid, Driver} - When Pid opens a new port Port with the running Driver.

Driver is the name of the driver as an atom.

{trace, Port, closed, Reason} - When Port closes with Reason.

{trace, Port, in, Command | 0} - When Port is scheduled to run. Command is the first thing the port will execute, it can however run several commands before being scheduled out. On some rare occasions, the current function cannot be determined, then the last element is 0.

The possible commands are call, close, command, connect, control, flush, info, link, open, and unlink.

{trace, Port, out, Command | 0} - When Port is scheduled out. The last command run was Command. On some rare occasions, the current function cannot be determined, then the last element is 0. Command can contain the same commands as in

If the tracing process/port dies or the tracer module returns remove, the flags are silently removed.

Returns a number indicating the number of ports that matched Ports. If Ports is a port identifier, the return value is 1. If Ports is all or existing, the return value is the number of existing ports. If Ports is new, the return value is 0.

Failure: badarg if the specified arguments are not supported. For example, cpu_timestamp is not supported on all platforms.

process(Session, Procs, How, FlagList)

(since OTP 27.0)

-spec process(Session, Procs, How, FlagList) -> integer()
                 when
                     Session :: session(),
                     Procs :: pid() | all | existing | new,
                     How :: boolean(),
                     FlagList :: [trace_flag()].

Turn on or off trace flags for one or more processes.

Argument Session is the trace session to operate on as returned by session_create/3.

Argument Procs is either a process identifier (pid) for a local process or one of the following atoms:

all - All currently existing processes and all that will be created in the future.

existing - All currently existing processes.

new - All processes that will be created in the future.

Argument How is either true to turn on trace flags or false to turn them off.

Argument FlagList can contain any number of the following flags (the "message tags" refers to the list of trace messages):

all - Sets all trace flags except cpu_timestamp, which is in its nature different than the others.

send - Traces sending of messages. Limit which sent messages to trace by calling send/3.

Message tags: send and send_to_non_existing_process.

'receive' - Traces receiving of messages. Limit which received messages to trace by calling recv/3.

Message tags: 'receive'.

call - Traces certain function calls. Specify which function calls to trace by calling function/4.

Message tags: call and return_from.

silent - Used with the call trace flag. The call, return_from, and return_to trace messages are inhibited if this flag is set, but they are executed as normal if there are match specifications.

Silent mode is inhibited by executing trace:process(_, _, false, [silent|_]), or by a match specification executing the function {silent, false}.

The silent trace flag facilitates setting up a trace on many or even all processes in the system. The trace can then be activated and deactivated using the match specification function {silent,Bool}, giving a high degree of control of which functions with which arguments that trigger the trace.

Message tags: call, return_from, and return_to. Or rather, the absence of.

return_to - Used with the call trace flag. Traces the exit from call traced functions back to where the execution resumes. Only works for functions traced with option local to function/4.

The semantics is that a return_to trace message is sent when a call traced function returns or throws and exception that is caught. For tail calls, only one trace message is sent per chain of tail calls, so the properties of tail recursiveness for function calls are kept while tracing with this flag. Similar for exceptions, only one return_to trace message is sent, even if the exception passed more than one call traced function before it was caught.

Using call and return_to trace together makes it possible to know exactly in which function a process executes at any time.

To get trace messages containing return values from functions, use the {return_trace} match specification action instead.

Message tags: return_to.

procs - Traces process-related events.

Message tags: spawn, spawned, exit, register, unregister, link, unlink, getting_linked, and getting_unlinked.

running - Traces scheduling of processes.

Message tags: in and out.

exiting - Traces scheduling of exiting processes.

Message tags: in_exiting, out_exiting, and out_exited.

running_procs - Traces scheduling of processes just like running. However, this option also includes schedule events when the process executes within the context of a port without being scheduled out itself.

Message tags: in and out.

garbage_collection - Traces garbage collections of processes.

Message tags: gc_minor_start, gc_max_heap_size, and gc_minor_end.

timestamp - Includes a time stamp in all trace messages. The time stamp (Ts) has the same form as returned by erlang:now/0.

cpu_timestamp - A global trace flag for the Erlang node that makes all trace time stamps using flag timestamp to be in CPU time, not wall clock time. That is, cpu_timestamp is not be used if monotonic_timestamp or strict_monotonic_timestamp is enabled. Only allowed with Procs==all. If the host machine OS does not support high-resolution CPU time measurements, process/4 exits with badarg. Notice that most OS do not synchronize this value across cores, so be prepared that time can seem to go backwards when using this option.

monotonic_timestamp - Includes an Erlang monotonic time time stamp in all trace messages. The time stamp (Ts) has the same format and value as produced by erlang:monotonic_time(nanosecond). This flag overrides flag cpu_timestamp.

strict_monotonic_timestamp - Includes an time stamp consisting of Erlang monotonic time and a monotonically increasing integer in all trace messages. The time stamp (Ts) has the same format and value as produced by { erlang:monotonic_time(nanosecond), erlang:unique_integer([monotonic])}. This flag overrides flag cpu_timestamp.

If multiple time stamp flags are passed, timestamp has precedence over strict_monotonic_timestamp, which in turn has precedence over monotonic_timestamp. All time stamp flags are remembered, so if two are passed and the one with highest precedence later is disabled, the other one becomes active.

arity - Used with the call trace flag. {M, F, Arity} is specified instead of {M, F, Args} in call trace messages.

set_on_spawn - Makes any process created by a traced process inherit all its trace flags, including flag set_on_spawn itself.

set_on_first_spawn - Makes the first process created by a traced process inherit all its trace flags, excluding flag set_on_first_spawn itself. That is, after the first spawn is done, set_on_first_spawn will be cleared in both the spawned process and the spawning process.

If both are set, set_on_first_spawn will supersede set_on_spawn.

set_on_link - Makes any process linked by a traced process inherit all its trace flags, including flag set_on_link itself.

set_on_first_link - Makes the first process linked to by a traced process inherit all its trace flags, excluding flag set_on_first_link itself. That is, after the first link is done, set_on_first_link will be cleared in both the linked process and the linking process.

If both are set, set_on_first_link will supersede set_on_link.

The tracing process receives the trace messages described in the following list. Pid is the process identifier of the traced process in which the traced event has occurred. The third tuple element is the message tag.

If flag timestamp, strict_monotonic_timestamp, or monotonic_timestamp is specified, the first tuple element is trace_ts instead, and the time stamp is added as an extra element last in the message tuple.

If a match specification (applicable only for call, send, and 'receive' tracing) contains a {message} action function with a non-boolean value, that value is added as an extra element to the message tuple either in the last position or before the timestamp (if it is present).

Trace messages:

{trace, Pid, send, Msg, To} - When process Pid sends message Msg to process To.

{trace, Pid, send_to_non_existing_process, Msg, To} - When process Pid sends message Msg to the non-existing process To.

{trace, Pid, 'receive', Msg} - When process Pid receives message Msg. If Msg is set to time-out, a receive statement can have timed out, or the process received a message with the payload timeout.

{trace, Pid, call, {M, F, Args}} - When process Pid calls a traced function. The return values of calls are never supplied, only the call and its arguments.

Trace flag arity can be used to change the contents of this message, so that Arity is specified instead of Args.

{trace, Pid, return_to, {M, F, Arity}} - When process Pid returns to the specified function. This trace message is sent if both the flags call and return_to are set, and the function is set to be traced on local function calls. The message is only sent when returning from a chain of tail recursive function calls, where at least one call generated a call trace message (that is, the functions match specification matched, and {message, false} was not an action).

{trace, Pid, return_from, {M, F, Arity}, ReturnValue} - When Pid returns from the specified function. This trace message is sent if flag call is set, and the function has a match specification with a return_trace or exception_trace action.

{trace, Pid, exception_from, {M, F, Arity}, {Class, Value}} - When Pid exits from the specified function because of an exception. This trace message is sent if flag call is set, and the function has a match specification with an exception_trace action.

{trace, Pid, spawn, Pid2, {M, F, Args}} - When Pid spawns a new process Pid2 with the specified function call as entry point.

Args is supposed to be the argument list, but can be any term if the spawn is erroneous.

{trace, Pid, spawned, Pid2, {M, F, Args}} - When Pid is spawned by process Pid2 with the specified function call as entry point.

Args is supposed to be the argument list, but can be any term if the spawn is erroneous.

{trace, Pid, exit, Reason} - When Pid exits with reason Reason.

{trace, Pid, register, RegName} - When process Pid gets the name RegName registered.

{trace, Pid, unregister, RegName} - When process Pid gets the name RegName unregistered. This is done automatically when a registered process or port exits.

{trace, Pid, link, Pid2} - When Pid links to a process Pid2.

{trace, Pid, unlink, Pid2} - When Pid removes the link from a process Pid2.

{trace, Pid, getting_linked, Pid2} - When Pid gets linked to a process Pid2.

{trace, Pid, getting_unlinked, Pid2} - When Pid gets unlinked from a process Pid2.

{trace, Port, open, Pid, Driver} - When Pid opens a new port Port with the running Driver.

Driver is the name of the driver as an atom.

{trace, Pid, in | in_exiting, {M, F, Arity} | 0} When Pid is scheduled to run. The process runs in function {M, F, Arity}. On some rare occasions, the current function cannot be determined, then the last element is 0.

{trace, Pid, out | out_exiting | out_exited, {M, F, Arity} | 0} When Pid is scheduled out. The process was running in function {M, F, Arity}. On some rare occasions, the current function cannot be determined, then the last element is 0.

{trace, Pid, gc_minor_start, Info} - Sent when a garbage collection of the young generation is about to be started. Info is a list of two-element tuples, where the first element is a key, and the second is the value. Do not depend on any order of the tuples. The following keys are defined:

heap_size - The size of the used part of the heap.

heap_block_size - The size of the memory block used for storing the heap and the stack.

old_heap_size - The size of the used part of the old heap.

old_heap_block_size - The size of the memory block used for storing the old heap.

stack_size - The size of the stack.

recent_size - The size of the data that survived the previous garbage collection.

mbuf_size - The combined size of message buffers associated with the process.

bin_vheap_size - The total size of unique off-heap binaries referenced from the process heap.

bin_vheap_block_size - The total size of binaries allowed in the virtual heap in the process before doing a garbage collection.

bin_old_vheap_size - The total size of unique off-heap binaries referenced from the process old heap.

bin_old_vheap_block_size - The total size of binaries allowed in the virtual old heap in the process before doing a garbage collection.

wordsize - For the gc_minor_start event it is the size of the need that triggered the GC. For the corresponding gc_minor_end event it is the size of reclaimed memory = start heap_size - end heap_size.

All sizes are in words.

{trace, Pid, gc_max_heap_size, Info} - Sent when the max_heap_size is reached during garbage collection. Info contains the same kind of list as in message gc_start, but the sizes reflect the sizes that triggered max_heap_size to be reached.

{trace, Pid, gc_minor_end, Info} - Sent when young garbage collection is finished. Info contains the same kind of list as in message gc_minor_start, but the sizes reflect the new sizes after garbage collection.

{trace, Pid, gc_major_start, Info} - Sent when fullsweep garbage collection is about to be started. Info contains the same kind of list as in message gc_minor_start.

{trace, Pid, gc_major_end, Info} - Sent when fullsweep garbage collection is finished. Info contains the same kind of list as in message gc_minor_start, but the sizes reflect the new sizes after a fullsweep garbage collection.

If the tracing process dies or the tracer module returns remove, the flags are silently removed.

Returns a number indicating the number of processes that matched Procs. If Procs is a process identifier, the return value is 1. If Procs is all or existing, the return value is the number of processes running. If Procs is new, the return value is 0.

Failure: badarg if the specified arguments are not supported. For example, cpu_timestamp is not supported on all platforms.

recv(Session, MatchSpec, FlagList)

(since OTP 27.0)

-spec recv(Session, MatchSpec, FlagList) -> non_neg_integer()
              when Session :: session(), MatchSpec :: trace_match_spec() | boolean(), FlagList :: [].

Set trace pattern for message receiving.

Must be combined with process/4 or port/4 to set the 'receive' trace flag for one or more processes or ports.

Argument Session is the trace session to operate on as returned by session_create/3.

The default value for the receive trace pattern in each session is true. That is, all messages received by processes having 'receive' trace enabled will be traced. Use this function to limit traced 'receive' events based on the message content, the sender, and/or the receiver.

Argument MatchSpec can take the following forms:

MatchExpression - A match specification. The matching is done on the list [Node, Sender, Msg]. Node is the node name of the sender. Sender is the process or port identity of the sender, or the atom undefined if the sender is not known (which can be the case for remote senders). Msg is the message term. The pid of the receiving process can be accessed with the guard function self/0. An empty list is the same as true. For more information, see section Match Specifications in Erlang in the User's Guide for the ERTS application.

true - Enable tracing for all received messages (to 'receive' traced processes). Any match specification is removed. This is the default.

false - Disable tracing for all received messages. Any match specification is removed.

Argument FlagList must be [] for receive tracing.

The return value is always 1.

Examples:

Only trace messages from a specific process Pid:

> trace:recv(Session, [{['_',Pid, '_'],[],[]}], []).
1

Only trace messages matching {reply, _}:

> trace:recv(Session, [{['_','_', {reply,'_'}],[],[]}], []).
1

Only trace messages from other nodes:

> trace:recv(Session, [{['$1', '_', '_'],[{'=/=','$1',{node}}],[]}], []).
1

Note

A match specification for 'receive' trace can use all guard and body functions except caller, is_seq_trace, get_seq_token, set_seq_token, enable_trace, disable_trace, trace, silent, and process_dump.

Fails by raising an error exception with an error reason of:

badarg - If an argument is invalid.

system_limit - If a match specification passed as argument has excessive nesting which causes scheduler stack exhaustion for the scheduler that the calling process is executing on. Scheduler stack size can be configured when starting the runtime system.

send(Session, MatchSpec, FlagList)

(since OTP 27.0)

-spec send(Session, MatchSpec, FlagList) -> non_neg_integer()
              when Session :: session(), MatchSpec :: trace_match_spec() | boolean(), FlagList :: [].

Set trace pattern for message sending.

Must be combined with process/4 or port/4 to set the send trace flag for one or more processes or ports.

Argument Session is the trace session to operate on as returned by session_create/3.

The default value for the send trace pattern in each session is true. That is, all messages sent from processes having send trace enabled will be traced. Use this function to limit traced send events based on the message content, the sender, and/or the receiver.

Argument MatchSpec can take the following forms:

MatchExpression - A match specification. The matching is done on the list [Receiver, Msg]. Receiver is the process or port identity of the receiver and Msg is the message term. The pid of the sending process can be accessed with the guard function self/0. An empty list is the same as true. For more information, see section Match Specifications in Erlang in the User's Guide for the ERTS application.

true - Enable tracing for all sent messages (from send traced processes). Any match specification is removed.

false - Disable tracing for all sent messages. Any match specification is removed.

Argument FlagList must be [].

The return value is always 1.

Examples:

Only trace messages to a specific process Pid:

> trace:send(Session, [{[Pid, '_'],[],[]}], []).
1

Only trace messages matching {reply, _}:

> trace:send(Session, [{['_', {reply,'_'}],[],[]}], []).
1

Only trace messages sent to the sender itself:

> trace:send(Session, [{['$1', '_'],[{'=:=','$1',{self}}],[]}], []).
1

Only trace messages sent to other nodes:

> trace:send(Session, [{['$1', '_'],[{'=/=',{node,'$1'},{node}}],[]}], []).
1

Note

A match specification for send trace can use all guard and body functions except caller.

Fails by raising an error exception with an error reason of:

badarg - If an argument is invalid.

system_limit - If a match specification passed as argument has excessive nesting which causes scheduler stack exhaustion for the scheduler that the calling process is executing on. Scheduler stack size can be configured when starting the runtime system.

session_create(Name, Tracer, Opts)

(since OTP 27.0)

-spec session_create(Name, Tracer, Opts) -> session()
                        when Name :: atom(), Tracer :: pid() | port() | {module(), term()}, Opts :: [].

Create a new trace session.

Argument Name is an atom name for the session. It will be returned when inspecting with session_info/1.

Argument Tracer specifies the consumer of all trace events for the session. It can be an identifier of a local process or port to receive all trace messages.

Tracer can also be a tuple {TracerModule, TracerState} for a tracer module to be called instead of sending a trace message. The tracer module can then ignore or change the trace message. For more details on how to write a tracer module, see module erl_tracer.

Argument Opts must be [].

Returns an opaque handle to the trace session. The handle will keep the session alive. If the handle is dropped and garbage collected, the session will be destroyed and cleaned up as if session_destroy/1 was called.

session_destroy(Session)

(since OTP 27.0)

-spec session_destroy(Session) -> true | false when Session :: session().

Destroy a trace session and cleanup all its settings on processes, ports, and functions.

The only things not cleaned up are trace messages that have already been sent.

Returns true if the session was active. Returns false if the session had already been destroyed by either an earler call to this function or the garbage collector.

session_info(PidPortFuncEvent)

(since OTP 27.0)

-spec session_info(PidPortFuncEvent) -> Res
                      when
                          PidPortFuncEvent ::
                              all |
                              pid() |
                              port() |
                              new | new_processes | new_ports | MFA | on_load | send | 'receive',
                          MFA :: {module(), atom(), arity()},
                          Res :: undefined | [session_weak_ref()].

Return which trace sessions that affect a port, process, function, or event.

Argument all returns all active trace sessions that exists on the node.

Returns a list of weak session handles or undefined if the process/port/function does not exists.

system(Session, Event, Value)

(since OTP 28.0)

-spec system(Session :: session(), Event :: system_event(), Value :: system_value()) -> ok.

Enable/disable monitoring of system events.

Argument Session is the trace session to operate on as returned by session_create/3.

Argument Event is an atom describing the kind of system event to monitor. To enable monitoring argument Value is, depending on event, either a limit of that event or the atom true. To disable monitoring pass Value as the atom false.

When a monitored system event happens, a message is sent to the session tracer. The session tracer must be a process otherwise the function call will fail.

The following Events with Values can be monitored:

long_gc, Time - If a garbage collection in the system takes at least Time wall clock milliseconds, a message {monitor, GcPid, long_gc, Info} is sent. GcPid is the pid that was garbage collected. Info is a list of two-element tuples describing the result of the garbage collection.

One of the tuples is {timeout, GcTime}, where GcTime is the time for the garbage collection in milliseconds. The other tuples are tagged with heap_size, heap_block_size, stack_size, mbuf_size, old_heap_size, and old_heap_block_size. These tuples are explained in the description of trace message gc_minor_start (see trace:process/4). New tuples can be added, and the order of the tuples in the Info list can be changed at any time without prior notice.

long_message_queue, {Disable, Enable} - If the number of messages in the message queue of a process reach Enable, a message {monitor, Pid, long_message_queue, Long} is sent. Pid is the process identifier of the process that got a long message queue and Long will equal true indicating that it is in a long message queue state. No more long_message_queue monitor messages will be sent due to the process identified by Pid until its message queue length falls down to a length of Disable length. When this happens, a long_message_queue monitor message with Long equal to false will be sent indicating that the process is no longer in a long message queue state. As of this, if the message queue length should again reach Enable length, a new long_message_queue monitor message with Long set to true will again be sent. That is, a long_message_queue monitor message is sent when a process enters or leaves a long message queue state where these state changes are defined by the Enable and Disable parameters.

Enable must be an integer larger than zero. Disable must be an integer larger than or equal to zero and smaller than Enable. If the above is not satisfied the operation will fail with a badarg error exception. You are recommended to use a much smaller value for Disable length than Enable length in order not to be flooded with long_message_queue monitor messages.

long_schedule, Time - If a process or port in the system runs uninterrupted for at least Time wall clock milliseconds, a message {monitor, PidOrPort, long_schedule, Info} is sent. PidOrPort is the process or port that was running. Info is a list of two-element tuples describing the event.

If a pid/0, the tuples {timeout, Millis}, {in, Location}, and {out, Location} are present, where Location is either an MFA ({Module, Function, Arity}) describing the function where the process was scheduled in/out, or the atom undefined.

If a port/0, the tuples {timeout, Millis} and {port_op,Op} are present. Op is one of proc_sig, timeout, input, output, event, or dist_cmd, depending on which driver callback was executing.

proc_sig is an internal operation and is never to appear, while the others represent the corresponding driver callbacks timeout, ready_input, ready_output, event, and outputv (when the port is used by distribution). Value Millis in tuple timeout informs about the uninterrupted execution time of the process or port, which always is equal to or higher than the Time value supplied when starting the trace. New tuples can be added to the Info list in a future release. The order of the tuples in the list can be changed at any time without prior notice.

This can be used to detect problems with NIFs or drivers that take too long to execute. 1 ms is considered a good maximum time for a driver callback or a NIF. However, a time-sharing system is usually to consider everything < 100 ms as "possible" and fairly "normal". However, longer schedule times can indicate swapping or a misbehaving NIF/driver. Misbehaving NIFs and drivers can cause bad resource utilization and bad overall system performance.

large_heap, Size - If a garbage collection in the system results in the allocated size of a heap being at least Size words, a message {monitor, GcPid, large_heap, Info} is sent. GcPid and Info are the same as for long_gc described above, except that the tuple tagged with timeout is not present.

The monitor message is sent if the sum of the sizes of all memory blocks allocated for all heap generations after a garbage collection is equal to or higher than Size.

When a process is killed by max_heap_size, it is killed before the garbage collection is complete and thus no large heap message is sent.

busy_port, true - If a process in the system gets suspended because it sends to a busy port, a message {monitor, SusPid, busy_port, Port} is sent. SusPid is the pid that got suspended when sending to Port.

busy_dist_port, true If a process in the system gets suspended because it sends to a process on a remote node whose inter-node communication was handled by a busy port, a message {monitor, SusPid, busy_dist_port, Port} is sent. SusPid is the pid that got suspended when sending through the inter-node communication port Port.

To disable system monitoring of a event pass the value as false. There are no other special values (like zero) to disable monitoring of an event. Some of the events have an unspecified minimum value. Lower values will be adjusted to the minimum value. For example, it is currently not possible to monitor all garbage collections with {long_gc, 0}.

Note

If the session tracer process gets so large that it itself starts to cause system monitor messages when garbage collecting, the messages enlarge the process message queue and probably make the problem worse.

Keep the tracer process neat and do not set the system monitor limits too tight.

Failures:

badarg - If the session tracer is not a local process.