diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/kernel/doc/src | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/kernel/doc/src')
43 files changed, 16626 insertions, 0 deletions
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile new file mode 100644 index 0000000000..f8c1cac8b3 --- /dev/null +++ b/lib/kernel/doc/src/Makefile @@ -0,0 +1,150 @@ +# ``The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved via the world wide web at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# The Initial Developer of the Original Code is Ericsson Utvecklings AB. +# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +# AB. All Rights Reserved.'' +# +# $Id$ +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../../vsn.mk +VSN=$(KERNEL_VSN) +APPLICATION=kernel + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +XML_APPLICATION_FILES = ref_man.xml +XML_REF3_FILES = application.xml \ + auth.xml \ + code.xml \ + disk_log.xml \ + erl_boot_server.xml \ + erl_ddll.xml \ + erl_prim_loader_stub.xml \ + erlang_stub.xml \ + error_handler.xml \ + error_logger.xml \ + file.xml \ + gen_tcp.xml \ + gen_udp.xml \ + gen_sctp.xml \ + global.xml \ + global_group.xml \ + heart.xml \ + inet.xml \ + inet_res.xml \ + init_stub.xml \ + net_adm.xml \ + net_kernel.xml \ + os.xml \ + packages.xml \ + pg2.xml \ + rpc.xml \ + seq_trace.xml \ + wrap_log_reader.xml \ + user.xml \ + zlib_stub.xml + +XML_REF4_FILES = app.xml config.xml + +XML_REF6_FILES = kernel_app.xml + +XML_PART_FILES = part_notes.xml part_notes_history.xml +XML_CHAPTER_FILES = notes.xml notes_history.xml + +BOOK_FILES = book.xml + +XML_FILES = \ + $(BOOK_FILES) $(XML_CHAPTER_FILES) \ + $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_REF4_FILES) \ + $(XML_REF6_FILES) $(XML_APPLICATION_FILES) + +# ---------------------------------------------------- + +HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \ + $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html) + +INFO_FILE = ../../info + +MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3) +MAN4_FILES = $(XML_REF4_FILES:%.xml=$(MAN4DIR)/%.4) +MAN6_FILES = $(XML_REF6_FILES:%_app.xml=$(MAN6DIR)/%.6) + +HTML_REF_MAN_FILE = $(HTMLDIR)/index.html + +TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf + + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +XML_FLAGS += + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +$(HTMLDIR)/%.gif: %.gif + $(INSTALL_DATA) $< $@ + +docs: pdf html man + +$(TOP_PDF_FILE): $(XML_FILES) + +pdf: $(TOP_PDF_FILE) + +html: gifs $(HTML_REF_MAN_FILE) + +man: $(MAN3_FILES) $(MAN4_FILES) $(MAN6_FILES) + +gifs: $(GIF_FILES:%=$(HTMLDIR)/%) +debug opt: + +clean clean_docs: + rm -rf $(HTMLDIR)/* + rm -f $(MAN3DIR)/* + rm -f $(MAN4DIR)/* + rm -f $(MAN6DIR)/* + rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) + rm -f errs core *~ + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_docs_spec: docs + $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf + $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf + $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DATA) $(HTMLDIR)/* \ + $(RELSYSDIR)/doc/html + $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) + $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 + $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + $(INSTALL_DIR) $(RELEASE_PATH)/man/man4 + $(INSTALL_DATA) $(MAN4_FILES) $(RELEASE_PATH)/man/man4 + $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 + $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 + +release_spec: + diff --git a/lib/kernel/doc/src/app.xml b/lib/kernel/doc/src/app.xml new file mode 100644 index 0000000000..ef1f5985f4 --- /dev/null +++ b/lib/kernel/doc/src/app.xml @@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE fileref SYSTEM "fileref.dtd"> + +<fileref> + <header> + <copyright> + <year>1997</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>app</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <file>app</file> + <filesummary>Application resource file.</filesummary> + <description> + <p>The <em>application resource file</em> specifies the resources an + application uses, and how the application is started. There must + always be one application resource file called + <c>Application.app</c> for each application <c>Application</c> in + the system.</p> + <p>The file is read by the application controller when an + application is loaded/started. It is also used by the functions in + <c>systools</c>, for example when generating start scripts.</p> + </description> + + <section> + <title>FILE SYNTAX</title> + <p>The application resource file should be called + <c>Application.app</c> where <c>Application</c> is the name of + the application. The file should be located in the <c>ebin</c> + directory for the application.</p> + <p>It must contain one single Erlang term, which is called an + <em>application specification</em>:</p> + <code type="none"> +{application, Application, + [{description, Description}, + {id, Id}, + {vsn, Vsn}, + {modules, Modules}, + {maxP, MaxP}, + {maxT, MaxT}, + {registered, Names}, + {included_applications, Apps}, + {applications, Apps}, + {env, Env}, + {mod, Start}, + {start_phases, Phases}]}. + + Value Default + ----- ------- +Application atom() - +Description string() "" +Id string() "" +Vsn string() "" +Modules [Module] [] +MaxP int() infinity +MaxT int() infinity +Names [Name] [] +Apps [App] [] +Env [{Par,Val}] [] +Start {Module,StartArgs} undefined +Phases [{Phase,PhaseArgs}] undefined + Module = Name = App = Par = Phase = atom() + Val = StartArgs = PhaseArgs = term()</code> + <p><c>Application</c> is the name of the application.</p> + <p>For the application controller, all keys are optional. + The respective default values are used for any omitted keys.</p> + <p>The functions in <c>systools</c> require more information. If + they are used, the following keys are mandatory: + <c>description</c>, <c>vsn</c>, <c>modules</c>, <c>registered</c> + and <c>applications</c>. The other keys are ignored by + <c>systools</c>.</p> + <taglist> + <tag><c>description</c></tag> + <item> + <p>A one-line description of the application.</p> + </item> + <tag><c>id</c></tag> + <item> + <p>Product identification, or similar.</p> + </item> + <tag><c>vsn</c></tag> + <item> + <p>The version of the application.</p> + </item> + <tag><c>modules</c></tag> + <item> + <p>All modules introduced by this application. <c>systools</c> + uses this list when generating start scripts and tar files. A + module can only be defined in one application.</p> + </item> + <tag><c>maxP</c></tag> + <item> + <p><em>Deprecated - will be ignored</em> <br></br> + + The maximum number of processes allowed in the application.</p> + </item> + <tag><c>maxT</c></tag> + <item> + <p>The maximum time in milliseconds that the application is + allowed to run. After the specified time the application will + automatically terminate.</p> + </item> + <tag><c>registered</c></tag> + <item> + <p>All names of registered processes started in this + application. <c>systools</c> uses this list to detect name + clashes between different applications.</p> + </item> + <tag><c>included_applications</c></tag> + <item> + <p>All applications which are included by this application. + When this application is started, all included application + will automatically be loaded, but not started, by + the application controller. It is assumed that the topmost + supervisor of the included application is started by a + supervisor of this application.</p> + </item> + <tag><c>applications</c></tag> + <item> + <p>All applications which must be started before this + application is allowed to be started. <c>systools</c> uses + this list to generate correct start scripts. Defaults to + the empty list, but note that all applications have + dependencies to (at least) <c>kernel</c> and <c>stdlib</c>.</p> + </item> + <tag><c>env</c></tag> + <item> + <p>Configuration parameters used by the application. The value + of a configuration parameter is retrieved by calling + <c>application:get_env/1,2</c>. The values in the application + resource file can be overridden by values in a configuration + file (see <c>config(4)</c>) or by command line flags (see + <c>erl(1)</c>).</p> + </item> + <tag><c>mod</c></tag> + <item> + <p>Specifies the application callback module and a start + argument, see <c>application(3)</c>.</p> + <p>The <c>mod</c> key is necessary for an application + implemented as a supervision tree, or the application + controller will not know how to start it. The <c>mod</c> key + can be omitted for applications without processes, typically + code libraries such as the application STDLIB.</p> + </item> + <tag><c>start_phases</c></tag> + <item> + <p>A list of start phases and corresponding start arguments for + the application. If this key is present, the application + master will - in addition to the usual call to + <c>Module:start/2</c> - also call + <c>Module:start_phase(Phase,Type,PhaseArgs)</c> for each + start phase defined by the <c>start_phases</c> key, and only + after this extended start procedure will + <c>application:start(Application)</c> return.</p> + <p></p> + <p>Start phases may be used to synchronize startup of an + application and its included applications. In this case, + the <c>mod</c> key must be specified as:</p> + <code type="none"> +{mod, {application_starter,[Module,StartArgs]}}</code> + <p>The application master will then call <c>Module:start/2</c> + for the primary application, followed by calls to + <c>Module:start_phase/3</c> for each start phase (as defined + for the primary application) both for the primary application + and for each of its included application, for which the start + phase is defined.</p> + <p></p> + <p>This implies that for an included application, the set of + start phases must be a subset of the set of phases defined + for the primary application. Refer to <em>OTP Design Principles</em> for more information.</p> + </item> + </taglist> + </section> + + <section> + <title>SEE ALSO</title> + <p><seealso marker="application">application(3)</seealso>, + systools(3)</p> + </section> +</fileref> + diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml new file mode 100644 index 0000000000..08ef0b1e52 --- /dev/null +++ b/lib/kernel/doc/src/application.xml @@ -0,0 +1,622 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>application</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>application</module> + <modulesummary>Generic OTP application functions</modulesummary> + <description> + <p>In OTP, <em>application</em> denotes a component implementing + some specific functionality, that can be started and stopped as a + unit, and which can be re-used in other systems as well. This + module interfaces the <em>application controller</em>, a process + started at every Erlang runtime system, and contains functions + for controlling applications (for example starting and stopping + applications), and functions to access information about + applications (for example configuration parameters).</p> + <p>An application is defined by an <em>application specification</em>. The specification is normally located in an + <em>application resource file</em> called <c>Application.app</c>, + where <c>Application</c> is the name of the application. Refer to + <seealso marker="app">app(4)</seealso> for more information about + the application specification.</p> + <p>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 should be located in an <em>application callback module</em> exporting a pre-defined set of functions.</p> + <p>Refer to <seealso marker="doc/design_principles:des_princ">OTP Design Principles</seealso> for more information about + applications and behaviours.</p> + </description> + <funcs> + <func> + <name>get_all_env() -> Env</name> + <name>get_all_env(Application) -> Env</name> + <fsummary>Get the configuration parameters for an application</fsummary> + <type> + <v>Application = atom()</v> + <v>Env = [{Par,Val}]</v> + <v> Par = atom()</v> + <v> Val = term()</v> + </type> + <desc> + <p>Returns the configuration parameters and their values for + <c>Application</c>. If the argument is omitted, it defaults to + the application of the calling process.</p> + <p>If the specified application is not loaded, or if the process + executing the call does not belong to any application, + the function returns <c>[]</c>.</p> + </desc> + </func> + <func> + <name>get_all_key() -> {ok, Keys} | []</name> + <name>get_all_key(Application) -> {ok, Keys} | undefined </name> + <fsummary>Get the application specification keys</fsummary> + <type> + <v>Application = atom()</v> + <v>Keys = [{Key,Val}]</v> + <v> Key = atom()</v> + <v> Val = term()</v> + </type> + <desc> + <p>Returns the application specification keys and their values + for <c>Application</c>. If the argument is omitted, it + defaults to the application of the calling process.</p> + <p>If the specified application is not loaded, the function + returns <c>undefined</c>. If the process executing the call + does not belong to any application, the function returns + <c>[]</c>.</p> + </desc> + </func> + <func> + <name>get_application() -> {ok, Application} | undefined</name> + <name>get_application(Pid | Module) -> {ok, Application} | undefined</name> + <fsummary>Get the name of an application containing a certain process or module</fsummary> + <type> + <v>Pid = pid()</v> + <v>Module = atom()</v> + <v>Application = atom()</v> + </type> + <desc> + <p>Returns the name of the application to which the process + <c>Pid</c> or the module <c>Module</c> belongs. Providing no + argument is the same as calling + <c>get_application(self())</c>.</p> + <p>If the specified process does not belong to any application, + or if the specified process or module does not exist, + the function returns <c>undefined</c>.</p> + </desc> + </func> + <func> + <name>get_env(Par) -> {ok, Val} | undefined</name> + <name>get_env(Application, Par) -> {ok, Val} | undefined</name> + <fsummary>Get the value of a configuration parameter</fsummary> + <type> + <v>Application = atom()</v> + <v>Par = atom()</v> + <v>Val = term()</v> + </type> + <desc> + <p>Returns the value of the configuration parameter <c>Par</c> + for <c>Application</c>. If the application argument is + omitted, it defaults to the application of the calling + process.</p> + <p>If the specified application is not loaded, or + the configuration parameter does not exist, or if the process + executing the call does not belong to any application, + the function returns <c>undefined</c>.</p> + </desc> + </func> + <func> + <name>get_key(Key) -> {ok, Val} | undefined</name> + <name>get_key(Application, Key) -> {ok, Val} | undefined</name> + <fsummary>Get the value of an application specification key</fsummary> + <type> + <v>Application = atom()</v> + <v>Key = atom()</v> + <v>Val = term()</v> + </type> + <desc> + <p>Returns the value of the application specification key + <c>Key</c> for <c>Application</c>. If the application + argument is omitted, it defaults to the application of + the calling process.</p> + <p>If the specified application is not loaded, or + the specification key does not exist, or if the process + executing the call does not belong to any application, + the function returns <c>undefined</c>.</p> + </desc> + </func> + <func> + <name>load(AppDescr) -> ok | {error, Reason}</name> + <name>load(AppDescr, Distributed) -> ok | {error, Reason}</name> + <fsummary>Load an application</fsummary> + <type> + <v>AppDescr = Application | AppSpec</v> + <v> Application = atom()</v> + <v> AppSpec = {application,Application,AppSpecKeys}</v> + <v> AppSpec = [{Key,Val}]</v> + <v> Key = atom()</v> + <v> Val = term()</v> + <v>Distributed = {Application,Nodes} | {Application,Time,Nodes} | default</v> + <v> Nodes = [node() | {node(),..,node()}]</v> + <v> Time = integer() > 0</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Loads the application specification for an application into + the application controller. It will also load the application + specifications for any included applications. Note that + the function does not load the actual Erlang object code.</p> + <p>The application can be given by its name <c>Application</c>. + In this case the application controller will search the code + path for the application resource file <c>Application.app</c> + and load the specification it contains.</p> + <p>The application specification can also be given directly as a + tuple <c>AppSpec</c>. This tuple should have the format and + contents as described in <c>app(4)</c>.</p> + <p>If <c>Distributed == {Application,[Time,]Nodes}</c>, + the application will be distributed. The argument overrides + the value for the application in the Kernel configuration + parameter <c>distributed</c>. <c>Application</c> must be + the name of the application (same as in the first argument). + If a node crashes and <c>Time</c> has been specified, then + the application controller will wait for <c>Time</c> + milliseconds before attempting to restart the application on + another node. If <c>Time</c> is not specified, it will + default to 0 and the application will be restarted + immediately.</p> + <p><c>Nodes</c> is a list of node names where the application + may run, in priority from left to right. Node names can be + grouped using tuples to indicate that they have the same + priority. Example:</p> + <code type="none"> +Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code> + <p>This means that the application should preferably be started + at <c>cp1@cave</c>. If <c>cp1@cave</c> is down, + the application should be started at either <c>cp2@cave</c> + or <c>cp3@cave</c>.</p> + <p>If <c>Distributed == default</c>, the value for + the application in the Kernel configuration parameter + <c>distributed</c> will be used.</p> + </desc> + </func> + <func> + <name>loaded_applications() -> [{Application, Description, Vsn}]</name> + <fsummary>Get the currently loaded applications</fsummary> + <type> + <v>Application = atom()</v> + <v>Description = string()</v> + <v>Vsn = string()</v> + </type> + <desc> + <p>Returns a list with information about the applications which + have been loaded using <c>load/1,2</c>, also included + applications. <c>Application</c> is the application name. + <c>Description</c> and <c>Vsn</c> are the values of its + <c>description</c> and <c>vsn</c> application specification + keys, respectively.</p> + </desc> + </func> + <func> + <name>permit(Application, Bool) -> ok | {error, Reason}</name> + <fsummary>Change an application's permission to run on a node.</fsummary> + <type> + <v>Application = atom()</v> + <v>Bool = bool()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Changes the permission for <c>Application</c> to run at + the current node. The application must have been loaded using + <c>load/1,2</c> for the function to have effect.</p> + <p>If the permission of a loaded, but not started, application + is set to <c>false</c>, <c>start</c> will return <c>ok</c> but + the application will not be started until the permission is + set to <c>true</c>.</p> + <p>If the permission of a running application is set to + <c>false</c>, the application will be stopped. If + the permission later is set to <c>true</c>, it will be + restarted.</p> + <p>If the application is distributed, setting the permission to + <c>false</c> means that the application will be started at, or + moved to, another node according to how its distribution is + configured (see <c>load/2</c> above).</p> + <p>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 <c>true</c> + the function may return <c>ok</c> even though the application + itself has not started. This is true when an application + cannot start because it has dependencies to other + applications which have not yet been started. When they have + been started, <c>Application</c> will be started as well.</p> + <p>By default, all applications are loaded with permission + <c>true</c> on all nodes. The permission is configurable by + using the Kernel configuration parameter <c>permissions</c>.</p> + </desc> + </func> + <func> + <name>set_env(Application, Par, Val) -> ok</name> + <name>set_env(Application, Par, Val, Timeout) -> ok</name> + <fsummary>Set the value of a configuration parameter</fsummary> + <type> + <v>Application = atom()</v> + <v>Par = atom()</v> + <v>Val = term()</v> + <v>Timeout = int() | infinity</v> + </type> + <desc> + <p>Sets the value of the configuration parameter <c>Par</c> for + <c>Application</c>.</p> + <p><c>set_env/3</c> uses the standard <c>gen_server</c> timeout + value (5000 ms). A <c>Timeout</c> argument can be provided + if another timeout value is useful, for example, in situations + where the application controller is heavily loaded.</p> + <warning> + <p>Use this function only if you know what you are doing, + that is, on your own applications. It is very application + and configuration parameter dependent when and how often + the value is read by the application, and careless use + of this function may put the application in a + weird, inconsistent, and malfunctioning state. </p> + </warning> + </desc> + </func> + <func> + <name>start(Application) -> ok | {error, Reason}</name> + <name>start(Application, Type) -> ok | {error, Reason}</name> + <fsummary>Load and start an application</fsummary> + <type> + <v>Application = atom()</v> + <v>Type = permanent | transient | temporary</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Starts <c>Application</c>. If it is not loaded, + the application controller will first load it using + <c>load/1</c>. It will make sure any included applications + are loaded, but will not start them. That is assumed to be + taken care of in the code for <c>Application</c>.</p> + <p>The application controller checks the value of + the application specification key <c>applications</c>, to + ensure that all applications that should be started before + this application are running. If not, + <c>{error,{not_started,App}}</c> is returned, where <c>App</c> + is the name of the missing application.</p> + <p>The application controller then creates an <em>application master</em> for the application. The application master is + the group leader of all the processes in the application. + The application master starts the application by calling + the application callback function <c>Module:start/2</c> as + defined by the application specification key <c>mod</c>.</p> + <p>The <c>Type</c> argument specifies the type of + the application. If omitted, it defaults to <c>temporary</c>.</p> + <list type="bulleted"> + <item>If a permanent application terminates, all other + applications and the entire Erlang node are also terminated.</item> + <item>If a transient application terminates with <c>Reason == normal</c>, this is reported but no other applications are + terminated. If a transient application terminates + abnormally, all other applications and the entire Erlang + node are also terminated.</item> + <item>If a temporary application terminates, this is reported + but no other applications are terminated.</item> + </list> + <p>Note that it is always possible to stop an application + explicitly by calling <c>stop/1</c>. Regardless of the type of + the application, no other applications will be affected.</p> + <p>Note also that the transient type is of little practical use, + since when a supervision tree terminates, the reason is set to + <c>shutdown</c>, not <c>normal</c>.</p> + </desc> + </func> + <func> + <name>start_type() -> StartType | local | undefined</name> + <fsummary>Get the start type of an ongoing application startup.</fsummary> + <type> + <v>StartType = normal | {takeover,Node} | {failover,Node}</v> + <v> Node = node()</v> + </type> + <desc> + <p>This function is intended to be called by a process belonging + to an application, when the application is being started, to + determine the start type which is either <c>StartType</c> or + <c>local</c>.</p> + <p>See <c>Module:start/2</c> for a description of + <c>StartType</c>.</p> + <p><c>local</c> is returned if only parts of the application is + being restarted (by a supervisor), or if the function is + called outside a startup.</p> + <p>If the process executing the call does not belong to any + application, the function returns <c>undefined</c>.</p> + </desc> + </func> + <func> + <name>stop(Application) -> ok | {error, Reason}</name> + <fsummary>Stop an application</fsummary> + <type> + <v>Application = atom()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Stops <c>Application</c>. The application master calls + <c>Module:prep_stop/1</c>, if such a function is defined, and + then tells the top supervisor of the application to shutdown + (see <c>supervisor(3)</c>). This means that the entire + supervision tree, including included applications, is + terminated in reversed start order. After the shutdown, + the application master calls <c>Module:stop/1</c>. + <c>Module</c> is the callback module as defined by + the application specification key <c>mod</c>.</p> + <p>Last, the application master itself terminates. Note that all + processes with the application master as group leader, i.e. + processes spawned from a process belonging to the application, + thus are terminated as well.</p> + <p>When stopped, the application is still loaded.</p> + <p>In order to stop a distributed application, <c>stop/1</c> + has to be called on all nodes where it can execute (that is, + on all nodes where it has been started). The call to + <c>stop/1</c> on the node where the application currently + executes will stop its execution. The application will not be + moved between nodes due to <c>stop/1</c> being called on + the node where the application currently executes before + <c>stop/1</c> is called on the other nodes.</p> + </desc> + </func> + <func> + <name>takeover(Application, Type) -> ok | {error, Reason}</name> + <fsummary>Take over a distributed application</fsummary> + <type> + <v>Application = atom()</v> + <v>Type = permanent | transient | temporary</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Performs a takeover of the distributed application + <c>Application</c>, which executes at another node + <c>Node</c>. At the current node, the application is + restarted by calling + <c>Module:start({takeover,Node},StartArgs)</c>. <c>Module</c> + and <c>StartArgs</c> are retrieved from the loaded application + specification. The application at the other node is not + stopped until the startup is completed, i.e. when + <c>Module:start/2</c> and any calls to + <c>Module:start_phase/3</c> have returned.</p> + <p>Thus two instances of the application will run simultaneously + during the takeover, which makes it possible to transfer data + from the old to the new instance. If this is not acceptable + behavior, parts of the old instance may be shut down when + the new instance is started. Note that the application may + not be stopped entirely however, at least the top supervisor + must remain alive.</p> + <p>See <c>start/1,2</c> for a description of <c>Type</c>.</p> + </desc> + </func> + <func> + <name>unload(Application) -> ok | {error, Reason}</name> + <fsummary>Unload an application</fsummary> + <type> + <v>Application = atom()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Unloads the application specification for <c>Application</c> + from the application controller. It will also unload + the application specifications for any included applications. + Note that the function does not purge the actual Erlang + object code.</p> + </desc> + </func> + <func> + <name>unset_env(Application, Par) -> ok</name> + <name>unset_env(Application, Par, Timeout) -> ok</name> + <fsummary>Unset the value of a configuration parameter</fsummary> + <type> + <v>Application = atom()</v> + <v>Par = atom()</v> + <v>Timeout = int() | infinity</v> + </type> + <desc> + <p>Removes the configuration parameter <c>Par</c> and its value + for <c>Application</c>.</p> + <p><c>unset_env/2</c> uses the standard <c>gen_server</c> + timeout value (5000 ms). A <c>Timeout</c> argument can be + provided if another timeout value is useful, for example, in + situations where the application controller is heavily loaded.</p> + <warning> + <p>Use this function only if you know what you are doing, + that is, on your own applications. It is very application + and configuration parameter dependent when and how often + the value is read by the application, and careless use + of this function may put the application in a + weird, inconsistent, and malfunctioning state. </p> + </warning> + </desc> + </func> + <func> + <name>which_applications() -> [{Application, Description, Vsn}]</name> + <name>which_applications(Timeout) -> [{Application, Description, Vsn}]</name> + <fsummary>Get the currently running applications</fsummary> + <type> + <v>Application = atom()</v> + <v>Description = string()</v> + <v>Vsn = string()</v> + <v>Timeout = int() | infinity</v> + </type> + <desc> + <p>Returns a list with information about the applications which + are currently running. <c>Application</c> is the application + name. <c>Description</c> and <c>Vsn</c> are the values of its + <c>description</c> and <c>vsn</c> application specification + keys, respectively.</p> + <p><c>which_applications/0</c> uses the standard + <c>gen_server</c> timeout value (5000 ms). A <c>Timeout</c> + argument can be provided if another timeout value is useful, + for example, in situations where the application controller + is heavily loaded.</p> + </desc> + </func> + </funcs> + + <section> + <title>CALLBACK MODULE</title> + <p>The following functions should be exported from an + <c>application</c> callback module.</p> + </section> + <funcs> + <func> + <name>Module:start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State} | {error, Reason}</name> + <fsummary>Start an application</fsummary> + <type> + <v>StartType = normal | {takeover,Node} | {failover,Node}</v> + <v> Node = node()</v> + <v>StartArgs = term()</v> + <v>Pid = pid()</v> + <v>State = term()</v> + </type> + <desc> + <p>This function is called whenever an application is started + using <c>application:start/1,2</c>, and should 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.</p> + <p><c>StartType</c> defines the type of start:</p> + <list type="bulleted"> + <item><c>normal</c> if its a normal startup.</item> + <item><c>normal</c> also if the application is distributed and + started at the current node due to a failover from another + node, and the application specification key <c>start_phases == undefined</c>.</item> + <item><c>{takeover,Node}</c> if the application is + distributed and started at the current node due to a + takeover from <c>Node</c>, either because + <c>application:takeover/2</c> has been called or because + the current node has higher priority than <c>Node</c>.</item> + <item><c>{failover,Node}</c> if the application is + distributed and started at the current node due to a + failover from <c>Node</c>, and the application + specification key <c>start_phases /= undefined</c>.</item> + </list> + <p><c>StartArgs</c> is the <c>StartArgs</c> argument defined by + the application specification key <c>mod</c>.</p> + <p>The function should return <c>{ok,Pid}</c> or + <c>{ok,Pid,State}</c> where <c>Pid</c> is the pid of the top + supervisor and <c>State</c> is any term. If omitted, + <c>State</c> defaults to <c>[]</c>. If later the application + is stopped, <c>State</c> is passed to + <c>Module:prep_stop/1</c>.</p> + </desc> + </func> + <func> + <name>Module:start_phase(Phase, StartType, PhaseArgs) -> ok | {error, Reason}</name> + <fsummary>Extended start of an application</fsummary> + <type> + <v>Phase = atom()</v> + <v>StartType = normal | {takeover,Node} | {failover,Node}</v> + <v> Node = node()</v> + <v>PhaseArgs = term()</v> + <v>Pid = pid()</v> + <v>State = state()</v> + </type> + <desc> + <p>This function is used to start an application with included + applications, when there is a need for synchronization between + processes in the different applications during startup.</p> + <p>The start phases is defined by the application specification + key <c>start_phases == [{Phase,PhaseArgs}]</c>. For included + applications, the set of phases must be a subset of the set of + phases defined for the including application.</p> + <p>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.</p> + <p>See <c>Module:start/2</c> for a description of + <c>StartType</c>.</p> + </desc> + </func> + <func> + <name>Module:prep_stop(State) -> NewState</name> + <fsummary>Prepare an application for termination</fsummary> + <type> + <v>State = NewState = term()</v> + </type> + <desc> + <p>This function is called when an application is about to be + stopped, before shutting down the processes of + the application.</p> + <p><c>State</c> is the state returned from + <c>Module:start/2</c>, or <c>[]</c> if no state was returned. + <c>NewState</c> is any term and will be passed to + <c>Module:stop/1</c>.</p> + <p>The function is optional. If it is not defined, the processes + will be terminated and then <c>Module:stop(State)</c> is + called.</p> + </desc> + </func> + <func> + <name>Module:stop(State)</name> + <fsummary>Clean up after termination of an application</fsummary> + <type> + <v>State = term()</v> + </type> + <desc> + <p>This function is called whenever an application has stopped. + It is intended to be the opposite of <c>Module:start/2</c> + and should do any necessary cleaning up. The return value is + ignored.</p> + <p><c>State</c> is the return value of + <c>Module:prep_stop/1</c>, if such a function exists. + Otherwise <c>State</c> is taken from the return value of + <c>Module:start/2</c>.</p> + </desc> + </func> + <func> + <name>Module:config_change(Changed, New, Removed) -> ok</name> + <fsummary>Update the configuration parameters for an application.</fsummary> + <type> + <v>Changed = [{Par,Val}]</v> + <v>New = [{Par,Val}]</v> + <v>Removed = [Par]</v> + <v> Par = atom()</v> + <v> Val = term()</v> + </type> + <desc> + <p>This function is called by an application after a code + replacement, if there are any changes to the configuration + parameters.</p> + <p><c>Changed</c> is a list of parameter-value tuples with all + configuration parameters with changed values, <c>New</c> is + a list of parameter-value tuples with all configuration + parameters that have been added, and <c>Removed</c> is a list + of all parameters that have been removed.</p> + </desc> + </func> + </funcs> + + <section> + <title>SEE ALSO</title> + <p><seealso marker="doc/design_principles:des_princ">OTP Design Principles</seealso>, + <seealso marker="kernel_app">kernel(6)</seealso>, + <seealso marker="app">app(4)</seealso></p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/auth.xml b/lib/kernel/doc/src/auth.xml new file mode 100644 index 0000000000..f53fc8b29a --- /dev/null +++ b/lib/kernel/doc/src/auth.xml @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>auth</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>auth</module> + <modulesummary>Erlang Network Authentication Server</modulesummary> + <description> + <p>This module is deprecated. For a description of the Magic + Cookie system, refer to + <seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso> in the Erlang Reference Manual.</p> + </description> + <funcs> + <func> + <name>is_auth(Node) -> yes | no</name> + <fsummary>Status of communication authorization (deprecated)</fsummary> + <type> + <v>Node = node()</v> + </type> + <desc> + <p>Returns <c>yes</c> if communication with <c>Node</c> is + authorized. Note that a connection to <c>Node</c> will + be established in this case. Returns <c>no</c> if <c>Node</c> + does not exist or communication is not authorized (it has + another cookie than <c>auth</c> thinks it has).</p> + <p>Use <seealso marker="net_adm#ping/1">net_adm:ping(Node)</seealso> + instead.</p> + </desc> + </func> + <func> + <name>cookie() -> Cookie</name> + <fsummary>Magic cookie for local node (deprecated)</fsummary> + <type> + <v>Cookie = atom()</v> + </type> + <desc> + <p>Use + <seealso marker="erts:erlang#erlang:get_cookie/0">erlang:get_cookie()</seealso> + instead.</p> + </desc> + </func> + <func> + <name>cookie(TheCookie) -> true</name> + <fsummary>Set the magic for the local node (deprecated)</fsummary> + <type> + <v>TheCookie = Cookie | [Cookie]</v> + <d>The cookie may also be given as a list with a single atom element</d> + <v> Cookie = atom()</v> + </type> + <desc> + <p>Use + <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(node(), Cookie)</seealso> + instead.</p> + </desc> + </func> + <func> + <name>node_cookie([Node, Cookie]) -> yes | no</name> + <fsummary>Set the magic cookie for a node and verify authorization (deprecated)</fsummary> + <type> + <v>Node = node()</v> + <v>Cookie = atom()</v> + </type> + <desc> + <p>Equivalent to + <seealso marker="#node_cookie/2">node_cookie(Node, Cookie)</seealso>.</p> + </desc> + </func> + <func> + <name>node_cookie(Node, Cookie) -> yes | no</name> + <fsummary>Set the magic cookie for a node and verify authorization (deprecated)</fsummary> + <type> + <v>Node = node()</v> + <v>Cookie = atom()</v> + </type> + <desc> + <p>Sets the magic cookie of <c>Node</c> to <c>Cookie</c>, and + verifies the status of the authorization. + Equivalent to calling + <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(Node, Cookie)</seealso>, followed by + <seealso marker="#is_auth/1">auth:is_auth(Node)</seealso>.</p> + </desc> + </func> + </funcs> +</erlref> + diff --git a/lib/kernel/doc/src/book.xml b/lib/kernel/doc/src/book.xml new file mode 100644 index 0000000000..caf13fd001 --- /dev/null +++ b/lib/kernel/doc/src/book.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE book SYSTEM "book.dtd"> + +<book xmlns:xi="http://www.w3.org/2001/XInclude"> + <header titlestyle="normal"> + <copyright> + <year>1997</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>Kernel</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <insidecover> + </insidecover> + <pagetext>Kernel</pagetext> + <preamble> + <contents level="2"></contents> + </preamble> + <applications> + <xi:include href="ref_man.xml"/> + </applications> + <releasenotes> + <xi:include href="notes.xml"/> + </releasenotes> + <listofterms></listofterms> + <index></index> +</book> + diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml new file mode 100644 index 0000000000..19e1d3221c --- /dev/null +++ b/lib/kernel/doc/src/code.xml @@ -0,0 +1,829 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>code</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>code</module> + <modulesummary>Erlang Code Server</modulesummary> + <description> + <p>This module contains the interface to the Erlang + <em>code server</em>, which deals with the loading of compiled + code into a running Erlang runtime system.</p> + <p>The runtime system can be started in either <em>embedded</em> or + <em>interactive</em> mode. Which one is decided by the command + line flag <c>-mode</c>.</p> + <pre> +% <input>erl -mode interactive</input></pre> + <p>Default mode is <c>interactive</c>.</p> + <list type="bulleted"> + <item> + <p>In embedded mode, all code is loaded during system start-up + according to the boot script. (Code can also be loaded later + by explicitly ordering the code server to do so).</p> + </item> + <item> + <p>In interactive mode, only some code is loaded during system + startup-up, basically the modules needed by the runtime + system itself. Other code is dynamically loaded when first + referenced. When a call to a function in a certain module is + made, and the module is not loaded, the code server searches + for and tries to load the module.</p> + </item> + </list> + <p>To prevent accidentaly reloading modules affecting the Erlang + runtime system itself, the <c>kernel</c>, <c>stdlib</c> and + <c>compiler</c> directories are considered <em>sticky</em>. 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 the command line flag + <c>-nostick</c>.</p> + </description> + + <section> + <title>Code Path</title> + <p>In interactive mode, the code server maintains a search path -- + usually called the <em>code path</em> -- consisting of a list of + directories, which it searches sequentially when trying to load a + module.</p> + <p>Initially, the code path consists of the current working + directory and all Erlang object code directories under the library + directory <c>$OTPROOT/lib</c>, where <c>$OTPROOT</c> is + the installation directory of Erlang/OTP, <c>code:root_dir()</c>. + Directories can be named <c>Name[-Vsn]</c> and the code server, + by default, chooses the directory with the highest version number + among those which have the same <c>Name</c>. The <c>-Vsn</c> + suffix is optional. If an <c>ebin</c> directory exists under + <c>Name[-Vsn]</c>, it is this directory which is added to + the code path.</p> + <p>The environment variable <c>ERL_LIBS</c> (defined in the operating + system) can be used to define additional library directories that + will be handled in the same way as the standard OTP library + directory described above, except that directories that do not + have an <c>ebin</c> directory will be ignored.</p> + <p>All application directories found in the additional directories + will appear before the standard OTP applications, except for the + Kernel and STDLIB applications, which will be placed before any + additional applications. In other words, modules found in any + of the additional library directories will override modules with + the same name in OTP, except for modules in Kernel and + STDLIB.</p> + <p>The environment variable <c>ERL_LIBS</c> (if defined) shold contain + a colon-separated (for Unix-like systems) or semicolon-separated + (for Windows) list of additional libraries.</p> + <p>Example: On an Unix-like system, <c>ERL_LIBS</c> could be set to + <c>/usr/local/jungerl:/home/some_user/my_erlang_lib</c>. (On Windows, + use semi-colon as separator.)</p> + </section> + + <section> + <title>Code Path Cache</title> + <p>The code server incorporates a code path cache. The cache + functionality is disabled by default. To activate it, start + the emulator with the command line flag <c>-code_path_cache</c> + or call <c>code:rehash()</c>. When the cache is created (or + updated), the code server searches for modules in the code path + directories. This may take some time if the the code path is long. + After the cache creation, the time for loading modules in a large + system (one with a large directory structure) is significantly + reduced compared to having the cache disabled. The code server + is able to look up the location of a module from the cache in + constant time instead of having to search through the code path + directories.</p> + <p>Application resource files (<c>.app</c> files) are also stored + in the code path cache. This feature is used by the application + controller (see + <seealso marker="application">application(3)</seealso>) to load + applications efficiently in large systems.</p> + <p>Note that when the code path cache is created (or updated), any + relative directory names in the code path are converted to + absolute.</p> + </section> + + <section> + <title>Loading of Code From Archive Files</title> + + <warning><p>The support for loading of code from archive files is + experimental. The sole purpose of releasing it before it is ready + is to obtain early feedback. The file format, semantics, + interfaces etc. may be changed in a future release. The function + <c>lib_dir/2</c> and the flag <c>-code_path_choice</c> are also + experimental.</p></warning> + + <p>In the current implementation, Erlang archives are <c>ZIP</c> + files with <c>.ez</c> extension. Erlang archives may also be + enclosed in <c>escript</c> files whose file extension is arbitrary.</p> + + <p>Erlang archive files may 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 would create an archive of <c>mnesia-4.4.7</c>, the + archive file must be named <c>mnesia-4.4.7.ez</c> and it must + contain a top directory with the name <c>mnesia-4.4.7</c>. If the + version part of the name is omitted, it must also be omitted in + the archive. That is, a <c>mnesia.ez</c> archive must contain a + <c>mnesia</c> top directory.</p> + + <p>An archive file for an application may for example be + created like this:</p> + +<pre> + zip:create("mnesia-4.4.7.ez", + ["mnesia-4.4.7"], + [{cwd, code:lib_dir()}, + {compress, all}, + {uncompress,[".beam",".app"]}]).</pre> + + <p>Any file in the archive may be compressed, but in order to + speed up the access of frequently read files, it may be a good + idea to store <c>beam</c> and <c>app</c> files uncompressed in + the archive.</p> + + <p>Normally the top directory of an application is located either + in the library directory <c>$OTPROOT/lib</c> or in a directory + referred to by the environment variable <c>ERL_LIBS</c>. At + startup when the initial code path is computed, the code server + will also look for archive files in these directories and + possibly add <c>ebin</c> directories in archives to the code path. The + code path will then contain paths to directories that looks like + <c>$OTPROOT/lib/mnesia.ez/mnesia/ebin</c> or + <c>$OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin</c>.</p> + + <p>The code server uses the module <c>erl_prim_loader</c> + (possibly via the <c>erl_boot_server</c>) to read code files from + archives. But the functions in <c>erl_prim_loader</c> may also be + used by other applications to read files from archives. For + example, the call + <c>erl_prim_loader:list_dir("/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/examples/bench)"</c> + would list the contents of a directory inside an archive. + See <seealso marker="erts:erl_prim_loader">erl_prim_loader(3)</seealso></p> + + <p>An application archive file and a regular application directory + may coexist. This may be useful when there is a need of having + parts of the application as regular files. A typical case is the + <c>priv</c> directory which must reside as a regular directory in + order to be able to dynamically link in drivers and start port + programs. For other applications that do not have this need, the + <c>priv</c> directory may reside in the archive and the files + under the <c>priv</c> directory may be read via the + <c>erl_prim_loader</c>.</p> + + <p>At the time point when a directory is added to the code path as + well as when the entire code path is (re)set, the code server + will decide which subdirectories in an application that shall be + read from the archive and which that shall be read as regular + files. If directories are added or removed afterwards, the file + access may fail if the code path is not updated (possibly to the + same path as before in order to trigger the directory resolution + update). For each directory on the second level (ebin, priv, src + etc.) in the application archive, the code server will firstly + choose the regular directory if it exists and secondly from the + archive. The function + <c>code:lib_dir/2</c> returns the path to the subdirectory. For + example <c>code:lib_dir(megaco,ebin)</c> may return + <c>/otp/root/lib/megaco-3.9.1.1.ez/megaco-3.9.1.1/ebin</c> while + <c>code:lib_dir(megaco,priv)</c> may return + <c>/otp/root/lib/megaco-3.9.1.1/priv</c>.</p> + + <p>When an <c>escript</c> file contains an archive, there are + neither restrictions on the name of the <c>escript</c> nor on how + many applications that may be stored in the embedded + archive. Single <c>beam</c> files may also reside on the top + level in the archive. At startup, both the top directory in the + embedded archive as well as all (second level) <c>ebin</c> + directories in the embedded archive are added to the code path. + See <seealso marker="erts:escript">escript(1)</seealso></p> + + <p>When the choice of directories in the code path is + <c>strict</c>, the directory that ends up in the code path will + be exactly the stated one. This means that if for example the + directory <c>$OTPROOT/lib/mnesia-4.4.7/ebin</c> is explicitly + added to the code path, the code server will not load files from + <c>$OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin</c> and vice + versa. </p> + + <p>This behavior can be controlled via the command line flag + <c>-code_path_choice Choice</c>. If the flag is set to <c>relaxed</c>, + the code server will instead choose a suitable directory + depending on the actual file structure. If there exists a regular + application ebin directory,situation it will be choosen. But if it does + not exist, the ebin directory in the archive is choosen if it + exists. If neither of them exists the original directory will be + choosen.</p> + + <p>The command line flag <c>-code_path_choice Choice</c> does also + affect how <c>init</c> interprets the <c>boot script</c>. The + interpretation of the explicit code paths in the <c>boot + script</c> may be <c>strict</c> or <c>relaxed</c>. It is + particular useful to set the flag to <c>relaxed</c> when you want + to elaborate with code loading from archives without editing the + <c>boot script</c>. The default is <c>relaxed</c>. See <seealso + marker="erts:init">init(3)</seealso></p> </section> + + <section> + + <title>Current and Old Code</title> + <p>The code of a module can exists in two variants in a system: + <em>current code</em> and <em>old code</em>. When a module is + loaded into the system for the first time, the code of the module + becomes 'current' and the global <em>export table</em> is updated + with references to all functions exported from the module.</p> + <p>If then a new instance of the module is loaded (perhaps because + of the correction of an error), then 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 if it was loaded for the first time, as described above, + and becomes 'current'.</p> + <p>Both old and current code for a module are valid, and may even be + evaluated concurrently. The difference is that exported functions + in old code are unavailable. Hence there is no way to make a + global call to an exported function in old code, but old code may + still be evaluated because of processes lingering in it.</p> + <p>If a third instance of the module is loaded, the code server will + remove (purge) the old code and any processes lingering in it will + be terminated. Then the third instance becomes 'current' and + the previously current code becomes 'old'.</p> + <p>For more information about old and current code, and how to + make a process switch from old to current code, refer to + <seealso marker="doc/reference_manual:code_loading">Erlang Reference Manual</seealso>.</p> + </section> + + <section> + <title>Argument Types and Invalid Arguments</title> + + <p>Generally, 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.</p> + + <p>From the R12B release, functions in this module will generally fail with an + exception if they are passed an incorrect type (for instance, an integer or a tuple + where an atom was expected). An error tuple will be returned if type of argument + was correct, but there was some other error (for instance, a non-existing directory + given to <c>set_path/1</c>.</p> + </section> + + <funcs> + <func> + <name>set_path(Path) -> true | {error, What}</name> + <fsummary>Set the code server search path</fsummary> + <type> + <v>Path = [Dir]</v> + <v>Dir = string()</v> + <v>What = bad_directory | bad_path</v> + </type> + <desc> + <p>Sets the code path to the list of directories <c>Path</c>.</p> + <p>Returns <c>true</c> if successful, or + <c>{error, bad_directory}</c> if any <c>Dir</c> is not + the name of a directory, or <c>{error, bad_path}</c> if + the argument is invalid.</p> + </desc> + </func> + <func> + <name>get_path() -> Path</name> + <fsummary>Return the code server search path</fsummary> + <type> + <v>Path = [Dir]</v> + <v>Dir = string()</v> + </type> + <desc> + <p>Returns the code path</p> + </desc> + </func> + <func> + <name>add_path(Dir) -> true | {error, What}</name> + <name>add_pathz(Dir) -> true | {error, What}</name> + <fsummary>Add a directory to the end of the code path</fsummary> + <type> + <v>Dir = string()</v> + <v>What = bad_directory</v> + </type> + <desc> + <p>Adds <c>Dir</c> to the code path. The directory is added as + the last directory in the new path. If <c>Dir</c> already + exists in the path, it is not added.</p> + <p>Returns <c>true</c> if successful, or + <c>{error, bad_directory}</c> if <c>Dir</c> is not the name + of a directory.</p> + </desc> + </func> + <func> + <name>add_patha(Dir) -> true | {error, What}</name> + <fsummary>Add a directory to the beginning of the code path</fsummary> + <type> + <v>Dir = string()</v> + <v>What = bad_directory</v> + </type> + <desc> + <p>Adds <c>Dir</c> to the beginning of the code path. If + <c>Dir</c> already exists, it is removed from the old + position in the code path.</p> + <p>Returns <c>true</c> if successful, or + <c>{error, bad_directory}</c> if <c>Dir</c> is not the name + of a directory.</p> + </desc> + </func> + <func> + <name>add_paths(Dirs) -> ok</name> + <name>add_pathsz(Dirs) -> ok</name> + <fsummary>Add directories to the end of the code path</fsummary> + <type> + <v>Dirs = [Dir]</v> + <v>Dir = string()</v> + </type> + <desc> + <p>Adds the directories in <c>Dirs</c> to the end of the code + path. If a <c>Dir</c> already exists, it is not added. This + function always returns <c>ok</c>, regardless of the validity + of each individual <c>Dir</c>.</p> + </desc> + </func> + <func> + <name>add_pathsa(Dirs) -> ok</name> + <fsummary>Add directories to the beginning of the code path</fsummary> + <type> + <v>Dirs = [Dir]</v> + <v>Dir = string()</v> + </type> + <desc> + <p>Adds the directories in <c>Dirs</c> to the beginning of + the code path. If a <c>Dir</c> already exists, it is removed + from the old position in the code path. This function always + returns <c>ok</c>, regardless of the validity of each + individual <c>Dir</c>.</p> + </desc> + </func> + <func> + <name>del_path(Name | Dir) -> true | false | {error, What}</name> + <fsummary>Delete a directory from the code path</fsummary> + <type> + <v>Name = atom()</v> + <v>Dir = string()</v> + <v>What = bad_name</v> + </type> + <desc> + <p>Deletes a directory from the code path. The argument can be + an atom <c>Name</c>, in which case the directory with + the name <c>.../Name[-Vsn][/ebin]</c> is deleted from the code + path. It is also possible to give the complete directory name + <c>Dir</c> as argument.</p> + <p>Returns <c>true</c> if successful, or <c>false</c> if + the directory is not found, or <c>{error, bad_name}</c> if + the argument is invalid.</p> + </desc> + </func> + <func> + <name>replace_path(Name, Dir) -> true | {error, What}</name> + <fsummary>Replace a directory with another in the code path</fsummary> + <type> + <v>Name = atom()</v> + <v>Dir = string()</v> + <v>What = bad_name | bad_directory | {badarg, term()}</v> + </type> + <desc> + <p>This function replaces an old occurrence of a directory + named <c>.../Name[-Vsn][/ebin]</c>, in the code path, with + <c>Dir</c>. If <c>Name</c> does not exist, it adds the new + directory <c>Dir</c> last in the code path. The new directory + must also be named <c>.../Name[-Vsn][/ebin]</c>. This function + should be used if a new version of the directory (library) is + added to a running system.</p> + <p>Returns <c>true</c> if successful, or + <c>{error, bad_name}</c> if <c>Name</c> is not found, or + <c>{error, bad_directory}</c> if <c>Dir</c> does not exist, or + <c>{error, {badarg, [Name, Dir]}}</c> if <c>Name</c> or + <c>Dir</c> is invalid.</p> + </desc> + </func> + <func> + <name>load_file(Module) -> {module, Module} | {error, What}</name> + <fsummary>Load a module</fsummary> + <type> + <v>Module = atom()</v> + <v>What = nofile | sticky_directory | badarg | term()</v> + </type> + <desc> + <p>Tries to load the Erlang module <c>Module</c>, using + the code path. It looks for the object code file with an + extension that corresponds to the Erlang machine used, for + example <c>Module.beam</c>. The loading fails if the module + name found in the object code differs from the name + <c>Module</c>. + <seealso marker="#load_binary/3">load_binary/3</seealso> must + be used to load object code with a module name that is + different from the file name.</p> + <p>Returns <c>{module, Module}</c> if successful, or + <c>{error, nofile}</c> if no object code is found, or + <c>{error, sticky_directory}</c> if the object code resides in + a sticky directory, or <c>{error, badarg}</c> if the argument + is invalid. Also if the loading fails, an error tuple is + returned. See + <seealso marker="erts:erlang#load_module/2">erlang:load_module/2</seealso> + for possible values of <c>What</c>.</p> + </desc> + </func> + <func> + <name>load_abs(Filename) -> {module, Module} | {error, What}</name> + <fsummary>Load a module, residing in a given file</fsummary> + <type> + <v>Filename = string()</v> + <v>Module = atom()</v> + <v>What = nofile | sticky_directory | badarg | term()</v> + </type> + <desc> + <p>Does the same as <c>load_file(Module)</c>, but + <c>Filename</c> is either an absolute file name, or a + relative file name. The code path is not searched. It returns + a value in the same way as + <seealso marker="#load_file/1">load_file/1</seealso>. Note + that <c>Filename</c> should not contain the extension (for + example <c>".beam"</c>); <c>load_abs/1</c> adds the correct + extension itself.</p> + </desc> + </func> + <func> + <name>ensure_loaded(Module) -> {module, Module} | {error, What}</name> + <fsummary>Ensure that a module is loaded</fsummary> + <type> + <v>Module = atom()</v> + <v>What = nofile | sticky_directory | embedded | badarg | term()</v> + </type> + <desc> + <p>Tries to to load a module in the same way as + <seealso marker="#load_file/1">load_file/1</seealso>, + unless the module is already loaded. + In embedded mode, however, it does not load a module which is not + already loaded, but returns <c>{error, embedded}</c> instead.</p> + </desc> + </func> + <func> + <name>load_binary(Module, Filename, Binary) -> {module, Module} | {error, What}</name> + <fsummary>Load object code for a module</fsummary> + <type> + <v>Module = atom()</v> + <v>Filename = string()</v> + <v>What = sticky_directory | badarg | term()</v> + </type> + <desc> + <p>This function can be used to load object code on remote + Erlang nodes. The argument <c>Binary</c> must contain + object code for <c>Module</c>. + <c>Filename</c> is only used by the code server to keep a + record of from which file the object code for <c>Module</c> + comes. Accordingly, <c>Filename</c> is not opened and read by + the code server.</p> + <p>Returns <c>{module, Module}</c> if successful, or + <c>{error, sticky_directory}</c> if the object code resides in + a sticky directory, or <c>{error, badarg}</c> if any argument + is invalid. Also if the loading fails, an error tuple is + returned. See + <seealso marker="erts:erlang#load_module/2">erlang:load_module/2</seealso> + for possible values of <c>What</c>.</p> + </desc> + </func> + <func> + <name>delete(Module) -> true | false</name> + <fsummary>Removes current code for a module</fsummary> + <type> + <v>Module = atom()</v> + </type> + <desc> + <p>Removes the current code for <c>Module</c>, that is, + the current code for <c>Module</c> is made old. This means + that processes can continue to execute the code in the module, + but that no external function calls can be made to it.</p> + <p>Returns <c>true</c> if successful, or <c>false</c> if there + is old code for <c>Module</c> which must be purged first, or + if <c>Module</c> is not a (loaded) module.</p> + </desc> + </func> + <func> + <name>purge(Module) -> true | false</name> + <fsummary>Removes old code for a module</fsummary> + <type> + <v>Module = atom()</v> + </type> + <desc> + <p>Purges the code for <c>Module</c>, 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.</p> + <p>Returns <c>true</c> if successful and any process needed to + be killed, otherwise <c>false</c>.</p> + </desc> + </func> + <func> + <name>soft_purge(Module) -> true | false</name> + <fsummary>Removes old code for a module, unless no process uses it</fsummary> + <type> + <v>Module = atom()</v> + </type> + <desc> + <p>Purges the code for <c>Module</c>, that is, removes code + marked as old, but only if no processes linger in it.</p> + <p>Returns <c>false</c> if the module could not be purged due + to processes lingering in old code, otherwise <c>true</c>.</p> + </desc> + </func> + <func> + <name>is_loaded(Module) -> {file, Loaded} | false</name> + <fsummary>Check if a module is loaded</fsummary> + <type> + <v>Module = atom()</v> + <v>Loaded = Absname | preloaded | cover_compiled</v> + <v>Absname = string()</v> + </type> + <desc> + <p>Checks if <c>Module</c> is loaded. If it is, + <c>{file, Loaded}</c> is returned, otherwise <c>false</c>.</p> + <p>Normally, <c>Loaded</c> is the absolute file name + <c>Absname</c> from which the code was obtained. If the module + is preloaded (see + <seealso marker="sasl:script">script(4)</seealso>), + <c>Loaded==preloaded</c>. If the module is Cover compiled (see + <seealso marker="tools:cover">cover(3)</seealso>), + <c>Loaded==cover_compiled</c>.</p> + </desc> + </func> + <func> + <name>all_loaded() -> [{Module, Loaded}]</name> + <fsummary>Get all loaded modules</fsummary> + <type> + <v>Module = atom()</v> + <v>Loaded = Absname | preloaded | cover_compiled</v> + <v>Absname = string()</v> + </type> + <desc> + <p>Returns a list of tuples <c>{Module, Loaded}</c> for all + loaded modules. <c>Loaded</c> is normally the absolute file + name, as described for + <seealso marker="#is_loaded/1">is_loaded/1</seealso>.</p> + </desc> + </func> + <func> + <name>which(Module) -> Which</name> + <fsummary>The object code file of a module</fsummary> + <type> + <v>Module = atom()</v> + <v>Which = Filename | non_existing | preloaded | cover_compiled</v> + <v>Filename = string()</v> + </type> + <desc> + <p>If the module is not loaded, this function searches the code + path for the first file which contains object code for + <c>Module</c> and returns the absolute file name. If + the module is loaded, it returns the name of the file which + contained the loaded object code. If the module is pre-loaded, + <c>preloaded</c> is returned. If the module is Cover compiled, + <c>cover_compiled</c> is returned. <c>non_existing</c> is + returned if the module cannot be found.</p> + </desc> + </func> + <func> + <name>get_object_code(Module) -> {Module, Binary, Filename} | error</name> + <fsummary>Get the object code for a module</fsummary> + <type> + <v>Module = atom()</v> + <v>Binary = binary()</v> + <v>Filename = string()</v> + </type> + <desc> + <p>Searches the code path for the object code of the module + <c>Module</c>. It returns <c>{Module, Binary, Filename}</c> + if successful, and <c>error</c> if not. <c>Binary</c> is a + binary data object which contains the object code for + the module. This can be useful if code is to be loaded on a + remote node in a distributed system. For example, loading + module <c>Module</c> on a node <c>Node</c> is done as + follows:</p> + <code type="none"> +... +{_Module, Binary, Filename} = code:get_object_code(Module), +rpc:call(Node, code, load_binary, [Module, Filename, Binary]), +...</code> + </desc> + </func> + <func> + <name>root_dir() -> string()</name> + <fsummary>Root directory of Erlang/OTP</fsummary> + <desc> + <p>Returns the root directory of Erlang/OTP, which is + the directory where it is installed.</p> + <pre> +> <input>code:root_dir().</input> +"/usr/local/otp"</pre> + </desc> + </func> + <func> + <name>lib_dir() -> string()</name> + <fsummary>Library directory of Erlang/OTP</fsummary> + <desc> + <p>Returns the library directory, <c>$OTPROOT/lib</c>, where + <c>$OTPROOT</c> is the root directory of Erlang/OTP.</p> + <pre> +> <input>code:lib_dir().</input> +"/usr/local/otp/lib"</pre> + </desc> + </func> + <func> + <name>lib_dir(Name) -> string() | {error, bad_name}</name> + <fsummary>Library directory for an application</fsummary> + <type> + <v>Name = atom()</v> + </type> + <desc> + <p>This function is mainly intended for finding out the path + for the "library directory", the top directory, for an + application <c>Name</c> located under <c>$OTPROOT/lib</c> or + on a directory referred to via the <c>ERL_LIBS</c> + environment variable.</p> + <p>If there is a regular directory called <c>Name</c> or + <c>Name-Vsn</c> in the code path with an <c>ebin</c> + subdirectory, the path to this directory is returned (not + the <c>ebin</c> 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 the directory + <c>/usr/local/otp/lib/mnesia-4.2.2.ez/mnesia-4.2.2/ebin</c> + is in the path, <c>/usr/local/otp/lib/mnesia-4.2.2/ebin</c> + will be returned. This means that the library directory for + an application is the same, regardless of whether the + application resides in an archive or not.</p> + + <pre> +> <input>code:lib_dir(mnesia).</input> +"/usr/local/otp/lib/mnesia-4.2.2"</pre> + <p>Returns <c>{error, bad_name}</c> if <c>Name</c> + is not the name of an application under <c>$OTPROOT/lib</c> or + on a directory referred to via the <c>ERL_LIBS</c> + environment variable. Fails with an exception if <c>Name</c> + has the wrong type.</p> + + <warning><p>For backward compatibility, <c>Name</c> is also allowed to + be a string. That will probably change in a future release.</p></warning> + </desc> + </func> + <func> + <name>lib_dir(Name, SubDir) -> string() | {error, bad_name}</name> + <fsummary>subdirectory for an application</fsummary> + <type> + <v>Name = atom()</v> + <v>SubDir = atom()</v> + </type> + <desc> + <p>Returns the path to a subdirectory directly under the top + directory of an application. Normally the subdirectories + resides under the top directory for the application, but when + applications at least partly resides in an archive the + situation is different. Some of the subdirectories may reside + as regular directories while other resides in an archive + file. It is not checked if this directory really exists.</p> + + <pre> +> <input>code:lib_dir(megaco, priv).</input> +"/usr/local/otp/lib/megaco-3.9.1.1/priv"</pre> + + <p>Fails with an exception if <c>Name</c> or <c>SubDir</c> has + the wrong type.</p> + </desc> + </func> + <func> + <name>compiler_dir() -> string()</name> + <fsummary>Library directory for the compiler</fsummary> + <desc> + <p>Returns the compiler library directory. Equivalent to + <c>code:lib_dir(compiler)</c>.</p> + </desc> + </func> + <func> + <name>priv_dir(Name) -> string() | {error, bad_name}</name> + <fsummary>Priv directory for an application</fsummary> + <type> + <v>Name = atom()</v> + </type> + <desc> + <p>Returns the path to the <c>priv</c> directory in an + application. Equivalent to <c>code:lib_dir(Name,priv).</c>.</p> + + <warning><p>For backward compatibility, <c>Name</c> is also allowed to + be a string. That will probably change in a future release.</p></warning> + </desc> + </func> + <func> + <name>objfile_extension() -> ".beam"</name> + <fsummary>Object code file extension</fsummary> + <desc> + <p>Returns the object code file extension that corresponds to + the Erlang machine used, namely <c>".beam"</c>.</p> + </desc> + </func> + <func> + <name>stick_dir(Dir) -> ok | error</name> + <fsummary>Mark a directory as sticky</fsummary> + <type> + <v>Dir = string()</v> + <v>What = term()</v> + </type> + <desc> + <p>This function marks <c>Dir</c> as sticky.</p> + <p>Returns <c>ok</c> if successful or <c>error</c> if not.</p> + </desc> + </func> + <func> + <name>unstick_dir(Dir) -> ok | error</name> + <fsummary>Remove a sticky directory mark</fsummary> + <type> + <v>Dir = string()</v> + <v>What = term()</v> + </type> + <desc> + <p>This function unsticks a directory which has been marked as + sticky.</p> + <p>Returns <c>ok</c> if successful or <c>error</c> if not.</p> + </desc> + </func> + <func> + <name>is_sticky(Module) -> true | false</name> + <fsummary>Test whether a module is sticky</fsummary> + <type> + <v>Module = atom()</v> + </type> + <desc> + <p>This function returns <c>true</c> if <c>Module</c> is the + name of a module that has been loaded from a sticky directory + (or in other words: an attempt to reload the module will fail), + or <c>false</c> if <c>Module</c> is not a loaded module or is + not sticky.</p> + </desc> + </func> + <func> + <name>rehash() -> ok</name> + <fsummary>Rehash or create code path cache</fsummary> + <desc> + <p>This function creates or rehashes the code path cache.</p> + </desc> + </func> + <func> + <name>where_is_file(Filename) -> Absname | non_existing</name> + <fsummary>Full name of a file located in the code path</fsummary> + <type> + <v>Filename = Absname = string()</v> + </type> + <desc> + <p>Searches the code path for <c>Filename</c>, a file of + arbitrary type. If found, the full name is returned. + <c>non_existing</c> is returned if the file cannot be found. + The function can be useful, for example, to locate + application resource files. If the code path cache is used, + the code server will efficiently read the full name from + the cache, provided that <c>Filename</c> is an object code + file or an <c>.app</c> file.</p> + </desc> + </func> + <func> + <name>clash() -> ok</name> + <fsummary>Search for modules with identical names.</fsummary> + <desc> + <p>Searches the entire code space for module names with + identical names and writes a report to <c>stdout</c>.</p> + </desc> + </func> + <func> + <name>is_module_native(Module) -> true | false | undefined</name> + <fsummary>Test whether a module has native code</fsummary> + <type> + <v>Module = atom()</v> + </type> + <desc> + <p>This function returns <c>true</c> if <c>Module</c> is + name of a loaded module that has native code loaded, and + <c>false</c> if <c>Module</c> is loaded but does not have + native. If <c>Module</c> is not loaded, this function returns + <c>undefined</c>.</p> + </desc> + </func> + </funcs> +</erlref> + diff --git a/lib/kernel/doc/src/config.xml b/lib/kernel/doc/src/config.xml new file mode 100644 index 0000000000..34398e90ac --- /dev/null +++ b/lib/kernel/doc/src/config.xml @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE fileref SYSTEM "fileref.dtd"> + +<fileref> + <header> + <copyright> + <year>1997</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>config</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <file>config</file> + <filesummary>Configuration file.</filesummary> + <description> + <p>A <em>configuration file</em> contains values for configuration + parameters for the applications in the system. The <c>erl</c> + command line argument <c>-config Name</c> tells the system to use + data in the system configuration file <c>Name.config</c>.</p> + <p>Configuration parameter values in the configuration file will + override the values in the application resource files (see + <c>app(4)</c>). The values in the configuration file can be + overridden by command line flags (see <c>erl(1)</c>).</p> + <p>The value of a configuration parameter is retrieved by calling + <c>application:get_env/1,2</c>.</p> + </description> + + <section> + <title>FILE SYNTAX</title> + <p>The configuration file should be called <c>Name.config</c> where + <c>Name</c> is an arbitrary name.</p> + <p>The <c>.config</c> file contains one single Erlang term. + The file has the following syntax:</p> + <code type="none"> +[{Application1, [{Par11, Val11}, ..]}, + .. + {ApplicationN, [{ParN1, ValN1}, ..]}].</code> + <list type="bulleted"> + <item> + <p><c>Application = atom()</c> is the name of the application.</p> + </item> + <item> + <p><c>Par = atom()</c> is the name of a configuration parameter.</p> + </item> + <item> + <p><c>Val = term()</c> is the value of a configuration + parameter.</p> + </item> + </list> + </section> + + <section> + <title>sys.config</title> + <p>When starting Erlang in embedded mode, it is assumed that + exactly one system configuration file is used, named + <c>sys.config</c>. This file should be located in + <c>$ROOT/releases/Vsn</c>, where <c>$ROOT</c> is the Erlang/OTP + root installation directory and <c>Vsn</c> is the release version.</p> + <p>Release handling relies on this assumption. When installing a + new release version, the new <c>sys.config</c> is read and used + to update the application configurations.</p> + <p>This means that specifying another, or additional, <c>.config</c> + files would lead to inconsistent update of application + configurations. Therefore, in Erlang 5.4/OTP R10B, the syntax of + <c>sys.config</c> was extended to allow pointing out other + <c>.config</c> files:</p> + <code type="none"> +[{Application, [{Par, Val}]} | File].</code> + <list type="bulleted"> + <item> + <p><c>File = string()</c> is the name of another <c>.config</c> + file. The extension <c>.config</c> may be omitted. It is + recommended to use absolute paths. A relative path is + relative the current working directory of the emulator.</p> + </item> + </list> + <p>When traversing the contents of <c>sys.config</c> and a filename + is encountered, its contents are read and merged with the result + so far. When an application configuration tuple + <c>{Application, Env}</c> is found, it is merged with the result + so far. Merging means that new parameters are added and existing + parameter values overwritten. Example:</p> + <code type="none"> +sys.config: + +[{myapp,[{par1,val1},{par2,val2}]}, + "/home/user/myconfig"]. + + +myconfig.config: + +[{myapp,[{par2,val3},{par3,val4}]}].</code> + <p>This will yield the following environment for <c>myapp</c>:</p> + <code type="none"> +[{par1,val1},{par2,val3},{par3,val4}]</code> + <p>The behaviour if a file specified in <c>sys.config</c> does not + exist or is erroneous in some other way, is backwards compatible. + Starting the runtime system will fail. Installing a new release + version will not fail, but an error message is given and + the erroneous file is ignored.</p> + </section> + + <section> + <title>SEE ALSO</title> + <p><c>app(4)</c>, <c>erl(1)</c>, <em>OTP Design Principles</em></p> + </section> +</fileref> + diff --git a/lib/kernel/doc/src/disk_log.xml b/lib/kernel/doc/src/disk_log.xml new file mode 100644 index 0000000000..07c1844485 --- /dev/null +++ b/lib/kernel/doc/src/disk_log.xml @@ -0,0 +1,1162 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year> + <year>2007</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>disk_log</title> + <prepared>Claes Wikström</prepared> + <responsible>Claes Wikström</responsible> + <docno></docno> + <approved>nobody</approved> + <checked>no</checked> + <date>1999-10-10</date> + <rev>D</rev> + <file>disk_log.sgml</file> + </header> + <module>disk_log</module> + <modulesummary>A disk based term logging facility</modulesummary> + <description> + <p><c>disk_log</c> is a disk based term logger which makes + it possible to efficiently log items on files. + Two types of logs are supported, + <em>halt logs</em> and <em>wrap logs</em>. A halt log + appends items to a single file, the size of which may or may + not be limited by the disk log module, whereas a wrap log utilizes + a sequence of wrap log files of limited size. As a wrap log file + has been filled up, further items are logged onto to the next + file in the sequence, starting all over with the first file when + the last file has been filled up. For the sake of efficiency, + items are always written to files as binaries. + </p> + <p>Two formats of the log files are supported, the <em>internal format</em> and the <em>external format</em>. The internal + format supports automatic repair of log files that have not been + properly closed, and makes it possible to efficiently read + logged items in <em>chunks</em> using a set of functions defined + in this module. In fact, this is the only way to read internally + formatted logs. The external format leaves it up to the user to + read the logged deep byte lists. The disk log module cannot + repair externally 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). + </p> + <p>For each open disk log there is one process that handles requests + made to the disk log; the disk log process is created when <c>open/1</c> + is called, provided there exists no process handling the disk log. + A process that opens a disk log can either be an <em>owner</em> + or an anonymous <em>user</em> of the disk log. Each owner is + linked to the disk log + process, and the disk log is closed by the owner should the + owner terminate. Owners can subscribe to <em>notifications</em>, + messages of the form <c>{disk_log, Node, Log, Info}</c> that are sent + from the disk log process when certain events occur, see + the commands below and in particular the <c>open/1</c> option + <seealso marker="#notify">notify</seealso>. + There can be several owners of a log, but a process cannot own a + log more than once. One and the same process may, however, + open the log + as a user more than once. For a disk log process to properly close + its file 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. + </p> + <p>Items can be logged <em>synchronously</em> by using the functions + <c>log/2</c>, <c>blog/2</c>, <c>log_terms/2</c> and + <c>blog_terms/2</c>. For each of these functions, the caller is put + on hold until the items have been logged (but not necessarily + written, use <c>sync/1</c> to ensure that). By adding an <c>a</c> + to each of the mentioned function names we get functions that log + items <em>asynchronously</em>. Asynchronous functions do not wait for + the disk log process to actually write the items to the file, but + return the control to the caller more or less immediately. + </p> + <p>When using the internal format for logs, the functions + <c>log/2</c>, <c>log_terms/2</c>, <c>alog/2</c>, and + <c>alog_terms/2</c> should be used. These functions log one or + more Erlang terms. By prefixing each of the functions with + a <c>b</c> (for "binary") we get the corresponding <c>blog</c> + functions for the external format. These functions log one or + more deep lists of bytes or, alternatively, binaries of deep lists + of bytes. + For example, to log the string <c>"hello"</c> in ASCII format, we + can use <c>disk_log:blog(Log, "hello")</c>, or + <c>disk_log:blog(Log, list_to_binary("hello"))</c>. The two + alternatives are equally efficient. The <c>blog</c> functions + can be used for internally formatted logs as well, but in + this case they must be called with binaries constructed with + calls to <c>term_to_binary/1</c>. 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 <c>chunk/2,3</c> and automatic repair + functions will fail. The corresponding terms (not the binaries) + will be returned when <c>chunk/2,3</c> is called. + </p> + <p>A collection of open disk logs with the same name running on + different nodes is said to be a <em>a distributed disk log</em> + if requests made to any one of the logs are automatically made to + the other logs as well. The members of such a collection will be + called individual distributed disk logs, or just distributed + disk logs if there is no risk of confusion. There is no order + between the members of such a collection. For instance, logged + terms are not necessarily written onto the node where the + request was made before written onto the other nodes. One could + note here that there are a few functions that do not make + requests to all members of distributed disk logs, namely + <c>info</c>, <c>chunk</c>, <c>bchunk</c>, <c>chunk_step</c> and + <c>lclose</c>. An open disk log that is not a distributed disk + log is said to be a <em>local disk log</em>. A local disk log is + accessible only from the node where the disk log process runs, + whereas a distributed disk log is accessible from all nodes in + the Erlang system, with exception for those nodes where a local + disk log with the same name as the distributed disk log exists. + All processes on nodes that have access to a local or + distributed disk log can log items or otherwise change, inspect + or close the log. + </p> + <p>It is not guaranteed that all log files of a distributed disk log + contain the same log items; there is no attempt made to synchronize + the contents of the files. However, as long as at least one of + the involved nodes is alive at each time, all items will be logged. + When logging items to a distributed log, or otherwise trying to + change the log, the replies from individual logs are + ignored. If all nodes are down, the disk log functions + reply with a <c>nonode</c> error. + </p> + <note> + <p>In some applications it may not be acceptable that + replies from individual logs are ignored. An alternative in such + situations is to use several local disk logs instead of one + distributed disk log, and implement the distribution without use + of the disk log module.</p> + </note> + <p>Errors are reported differently for asynchronous log attempts + and other uses of the disk log module. When used synchronously + the disk log module replies with an error message, but when called + asynchronously, the disk log module does not know where to send + the error message. Instead owners subscribing to notifications will + receive an <c>error_status</c> message. + </p> + <p>The disk log module itself does not report errors to the + <c>error_logger</c> module; it is up to the caller to decide + whether the error logger should be employed or not. The function + <c>format_error/1</c> can be used to produce readable messages + from error replies. Information events are however sent to the + error logger in two situations, namely when a log is repaired, + or when a file is missing while reading chunks. + </p> + <p>The error message <c>no_such_log</c> means that the given + disk log is not currently open. Nothing is said about + whether the disk log files exist or not. + </p> + <note> + <p>If an attempt to reopen or truncate a log fails (see + <c>reopen</c> and <c>truncate</c>) the disk log process + immediately terminates. Before the process terminates links to + to owners and blocking processes (see <c>block</c>) are removed. + The effect is that the links work in one direction only; any + process using a disk log has to check for the error message + <c>no_such_log</c> if some other process might truncate or + reopen the log simultaneously.</p> + </note> + </description> + <funcs> + <func> + <name>accessible_logs() -> {[LocalLog], [DistributedLog]}</name> + <fsummary>Return the accessible disk logs on the current node.</fsummary> + <type> + <v>LocalLog = DistributedLog = term()</v> + </type> + <desc> + <p>The <c>accessible_logs/0</c> function returns + the names of the disk logs accessible on the current node. + The first list contains local disk logs, and the + second list contains distributed disk logs. + </p> + </desc> + </func> + <func> + <name>alog(Log, Term)</name> + <name>balog(Log, Bytes) -> ok | {error, Reason}</name> + <fsummary>Asynchronously log an item onto a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>Term = term()</v> + <v>Bytes = binary() | [Byte]</v> + <v>Byte = [Byte] | 0 =< integer() =< 255</v> + <v>Reason = no_such_log</v> + </type> + <desc> + <p>The <c>alog/2</c> and <c>balog/2</c> functions asynchronously + append an item to a disk log. The function <c>alog/2</c> is + used for internally formatted logs, and the function <c>balog/2</c> + for externally formatted logs. <c>balog/2</c> can be used + for internally formatted logs as well provided the binary was + constructed with a call to <c>term_to_binary/1</c>. + </p> + <p>The owners that subscribe to notifications will receive the + message <c>read_only</c>, <c>blocked_log</c> + or <c>format_external</c> in case the item cannot be written + on the log, and possibly one of the messages <c>wrap</c>, + <c>full</c> and <c>error_status</c> if an item was written + on the log. The message <c>error_status</c> is sent if there + is something wrong with the header function or a file error + occurred. + </p> + </desc> + </func> + <func> + <name>alog_terms(Log, TermList)</name> + <name>balog_terms(Log, BytesList) -> ok | {error, Reason}</name> + <fsummary>Asynchronously log several items onto a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>TermList = [term()]</v> + <v>BytesList = [Bytes]</v> + <v>Bytes = binary() | [Byte]</v> + <v>Byte = [Byte] | 0 =< integer() =< 255</v> + <v>Reason = no_such_log</v> + </type> + <desc> + <p>The <c>alog_terms/2</c> and <c>balog_terms/2</c> functions + asynchronously append a list of items to a disk log. + The function <c>alog_terms/2</c> is used for internally + formatted logs, and the function <c>balog_terms/2</c> + for externally formatted logs. <c>balog_terms/2</c> can be used + for internally formatted logs as well provided the binaries were + constructed with calls to <c>term_to_binary/1</c>. + </p> + <p>The owners that subscribe to notifications will receive the + message <c>read_only</c>, <c>blocked_log</c> + or <c>format_external</c> in case the items cannot be written + on the log, and possibly one or more of the messages <c>wrap</c>, + <c>full</c> and <c>error_status</c> if items were written + on the log. The message <c>error_status</c> is sent if there + is something wrong with the header function or a file error + occurred. + </p> + </desc> + </func> + <func> + <name>block(Log)</name> + <name>block(Log, QueueLogRecords) -> ok | {error, Reason}</name> + <fsummary>Block a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>QueueLogRecords = bool()</v> + <v>Reason = no_such_log | nonode | {blocked_log, Log}</v> + </type> + <desc> + <p>With a call to <c>block/1,2</c> 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 is used to ensure that the disk log is + unblocked should the blocking process terminate without + first closing or unblocking the log. + </p> + <p>Any process can probe a blocked log with <c>info/1</c> or + close it with <c>close/1</c>. The blocking process can also + use the functions <c>chunk/2,3</c>, <c>bchunk/2,3</c>, + <c>chunk_step/3</c>, and <c>unblock/1</c> without being + affected by the block. Any other attempt than those hitherto + mentioned to update or read a blocked log suspends the + calling process until the log is unblocked or returns an + error message <c>{blocked_log, Log}</c>, depending on + whether the value of <c>QueueLogRecords</c> is <c>true</c> + or <c>false</c>. The default value of <c>QueueLogRecords</c> + is <c>true</c>, which is used by <c>block/1</c>. + </p> + </desc> + </func> + <func> + <name>change_header(Log, Header) -> ok | {error, Reason}</name> + <fsummary>Change the head or head_func option for an owner of a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>Header = {head, Head} | {head_func, {M,F,A}}</v> + <v>Head = none | term() | binary() | [Byte]</v> + <v>Byte = [Byte] | 0 =< integer() =< 255</v> + <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {badarg, head}</v> + </type> + <desc> + <p>The <c>change_header/2</c> function changes the value of + the <c>head</c> or <c>head_func</c> option of a disk log.</p> + </desc> + </func> + <func> + <name>change_notify(Log, Owner, Notify) -> ok | {error, Reason}</name> + <fsummary>Change the notify option for an owner of a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>Owner = pid()</v> + <v>Notify = bool()</v> + <v>Reason = no_such_log | nonode | {blocked_log, Log} | {badarg, notify} | {not_owner, Owner}</v> + </type> + <desc> + <p>The <c>change_notify/3</c> function changes the value of the + <c>notify</c> option for an owner of a disk log. </p> + </desc> + </func> + <func> + <name>change_size(Log, Size) -> ok | {error, Reason}</name> + <fsummary>Change the size of an open disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>Size = integer() > 0 | infinity | {MaxNoBytes, MaxNoFiles}</v> + <v>MaxNoBytes = integer() > 0</v> + <v>MaxNoFiles = integer() > 0</v> + <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {new_size_too_small, CurrentSize} | {badarg, size} | {file_error, FileName, FileError}</v> + </type> + <desc> + <p>The <c>change_size/2</c> function changes the size of an open log. + For a halt log it is always possible to increase the size, + but it is not possible to decrease the size to something less than + the current size of the file. + </p> + <p>For a wrap log it is always possible to increase both the + size and number of files, as long as the number of files does not + exceed 65000. If the maximum number of files is decreased, the + change will not be valid until the current file is full and the + log wraps to the next file. + The redundant files will be removed next time the log wraps around, + i.e. starts to log to file number 1. + </p> + <p>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, the files 7 to 10 will be removed when file number 6 + is full and the log starts to write to file number 1 again. + Otherwise the files greater than the current + file will be removed when the current file is full (e.g. if + the current file is 8, the files 9 and 10); the files between + new maximum number of files and the current + file (i.e. files 7 and 8) will be removed next time file number 6 + is full. + </p> + <p>If the size of the files is decreased the change will immediately + affect the current log. It will not of course change the + size of log files already full until next time they are used. + </p> + <p>If the log size is decreased for instance to save space, + the function <c>inc_wrap_file/1</c> can be used to force the log + to wrap. + </p> + </desc> + </func> + <func> + <name>chunk(Log, Continuation)</name> + <name>chunk(Log, Continuation, N) -> {Continuation2, Terms} | {Continuation2, Terms, Badbytes} | eof | {error, Reason}</name> + <name>bchunk(Log, Continuation)</name> + <name>bchunk(Log, Continuation, N) -> {Continuation2, Binaries} | {Continuation2, Binaries, Badbytes} | eof | {error, Reason}</name> + <fsummary>Read a chunk of items written to a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>Continuation = start | cont()</v> + <v>N = integer() > 0 | infinity</v> + <v>Continuation2 = cont()</v> + <v>Terms = [term()]</v> + <v>Badbytes = integer()</v> + <v>Reason = no_such_log | {format_external, Log} | {blocked_log, Log} | {badarg, continuation} | {not_internal_wrap, Log} | {corrupt_log_file, FileName} | {file_error, FileName, FileError}</v> + <v>Binaries = [binary()]</v> + </type> + <desc> + <p>The <c>chunk/2,3</c> and <c>bchunk/2,3</c> functions make + it possible to efficiently read the terms which have been + appended to an internally formatted log. It minimizes disk + I/O by reading 64 kilobyte chunks from the file. The + <c>bchunk/2,3</c> functions return the binaries read from + the file; they do not call <c>binary_to_term</c>. Otherwise + the work just like <c>chunk/2,3</c>. + </p> + <p>The first time <c>chunk</c> (or <c>bchunk</c>) is called, + an initial continuation, the atom <c>start</c>, must be + provided. If there is a disk log process running on the + current node, terms are read from that log, otherwise an + individual distributed log on some other node is chosen, if + such a log exists. + </p> + <p>When <c>chunk/3</c> is called, <c>N</c> controls the + maximum number of terms that are read from the log in each + chunk. Default is <c>infinity</c>, which means that all the + terms contained in the 64 kilobyte chunk are read. If less than + <c>N</c> terms are returned, this does not necessarily mean + that the end of the file has been reached. + </p> + <p>The <c>chunk</c> function returns a tuple + <c>{Continuation2, Terms}</c>, where <c>Terms</c> is a list + of terms found in the log. <c>Continuation2</c> is yet + another continuation which must be passed on to any + subsequent calls to <c>chunk</c>. With a series of calls to + <c>chunk</c> it is possible to extract all terms from a log. + </p> + <p>The <c>chunk</c> function returns a tuple + <c>{Continuation2, Terms, Badbytes}</c> if the log is opened + in read-only mode and the read chunk is corrupt. <c>Badbytes</c> + is the number of bytes in the file which were found not to be + Erlang terms in the chunk. Note also that the log is not repaired. + When trying to read chunks from a log opened in read-write mode, + the tuple <c>{corrupt_log_file, FileName}</c> is returned if the + read chunk is corrupt. + </p> + <p><c>chunk</c> returns <c>eof</c> when the end of the log is + reached, or <c>{error, Reason}</c> if an error occurs. Should + a wrap log file be missing, a message is output on the error log. + </p> + <p>When <c>chunk/2,3</c> is used with wrap logs, the returned + continuation may or may not be valid in the next call to + <c>chunk</c>. This is because the log may wrap and delete + the file into which the continuation points. To make sure + this does not happen, the log can be blocked during the + search. + </p> + </desc> + </func> + <func> + <name>chunk_info(Continuation) -> InfoList | {error, Reason}</name> + <fsummary>Return information about a chunk continuation of a disk log.</fsummary> + <type> + <v>Continuation = cont()</v> + <v>Reason = {no_continuation, Continuation}</v> + </type> + <desc> + <p>The <c>chunk_info/1</c> function returns the following pair + describing the chunk continuation returned by + <c>chunk/2,3</c>, <c>bchunk/2,3</c>, or <c>chunk_step/3</c>: + </p> + <list type="bulleted"> + <item> + <p><c>{node, Node}</c>. Terms are read from + the disk log running on <c>Node</c>.</p> + </item> + </list> + </desc> + </func> + <func> + <name>chunk_step(Log, Continuation, Step) -> {ok, Continuation2} | {error, Reason}</name> + <fsummary>Step forward or backward among the wrap log files of a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>Continuation = start | cont()</v> + <v>Step = integer()</v> + <v>Continuation2 = cont()</v> + <v>Reason = no_such_log | end_of_log | {format_external, Log} | {blocked_log, Log} | {badarg, continuation} | {file_error, FileName, FileError}</v> + </type> + <desc> + <p>The function <c>chunk_step</c> can be used in conjunction + with <c>chunk/2,3</c> and <c>bchunk/2,3</c> to search + through an internally formatted wrap log. It takes as + argument a continuation as returned by <c>chunk/2,3</c>, + <c>bchunk/2,3</c>, or <c>chunk_step/3</c>, and steps forward + (or backward) <c>Step</c> files in the wrap log. The + continuation returned points to the first log item in the + new current file. + </p> + <p>If the atom <c>start</c> is given as continuation, a disk log + to read terms from is chosen. A local or distributed disk log + on the current node is preferred to an + individual distributed log on some other node. + </p> + <p>If the wrap log is not full because all files have not been + used yet, <c>{error, end_of_log}</c> is returned if trying to + step outside the log. + </p> + </desc> + </func> + <func> + <name>close(Log) -> ok | {error, Reason}</name> + <fsummary>Close a disk log.</fsummary> + <type> + <v>Reason = no_such_log | nonode | {file_error, FileName, FileError}</v> + </type> + <desc> + <p> <marker id="close_1"></marker> +The function <c>close/1</c> closes a + local or distributed 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 will be activated next time the + log is opened. + </p> + <p>The disk log process in not terminated as long as there are + owners or users of the log. It should be stressed that each + and every owner must close the log, possibly by terminating, + and that any other process - not only the processes that have + opened the log anonymously - can decrement the <c>users</c> + counter by closing the log. + Attempts to close a log by a process that is + not an owner are simply ignored if there are no users. + </p> + <p>If the log is blocked by the closing process, the log is also + unblocked. + </p> + </desc> + </func> + <func> + <name>format_error(Error) -> Chars</name> + <fsummary>Return an English description of a disk log error reply.</fsummary> + <type> + <v>Chars = [char() | Chars]</v> + </type> + <desc> + <p>Given the error returned by any function in this module, + the function <c>format_error</c> returns a descriptive string + of the error in English. For file errors, the function + <c>format_error/1</c> in the <c>file</c> module is called.</p> + </desc> + </func> + <func> + <name>inc_wrap_file(Log) -> ok | {error, Reason}</name> + <fsummary>Change to the next wrap log file of a disk log.</fsummary> + <type> + <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {halt_log, Log} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v> + </type> + <desc> + <p>The <c>inc_wrap_file/1</c> function forces the internally formatted + disk log to start logging to the + next log file. It can be used, for instance, in conjunction with + <c>change_size/2</c> to reduce the amount of disk space allocated + by the disk log. + </p> + <p>The owners that subscribe to notifications will normally + receive a <c>wrap</c> message, but in case of + an error with a reason tag of <c>invalid_header</c> or + <c>file_error</c> an <c>error_status</c> message will be sent.</p> + </desc> + </func> + <func> + <name>info(Log) -> InfoList | {error, no_such_log}</name> + <fsummary>Return information about a disk log.</fsummary> + <desc> + <p>The <c>info/1</c> function returns a list of <c>{Tag, Value}</c> + pairs describing the log. If there is a disk log process running + on the current node, that log is used as source of information, + otherwise an individual distributed log on + some other node is chosen, if such a log exists. + </p> + <p>The following pairs are returned for all logs: + </p> + <list type="bulleted"> + <item> + <p><c>{name, Log}</c>, where <c>Log</c> is the name of + the log as given by the <c>open/1</c> option <c>name</c>.</p> + </item> + <item> + <p><c>{file, File}</c>. For halt logs <c>File</c> is the + filename, and for wrap logs <c>File</c> is the base name.</p> + </item> + <item> + <p><c>{type, Type}</c>, where <c>Type</c> is the type of + the log as given by the <c>open/1</c> option <c>type</c>.</p> + </item> + <item> + <p><c>{format, Format}</c>, where <c>Format</c> is the format + of the log as given by the <c>open/1</c> option <c>format</c>.</p> + </item> + <item> + <p><c>{size, Size}</c>, where <c>Size</c> is the size + of the log as given by the <c>open/1</c> option <c>size</c>, + or the size set by <c>change_size/2</c>. The value set by + <c>change_size/2</c> is reflected immediately.</p> + </item> + <item> + <p><c>{mode, Mode}</c>, where <c>Mode</c> is the mode + of the log as given by the <c>open/1</c> option <c>mode</c>.</p> + </item> + <item> + <p><c>{owners, [{pid(), Notify}]}</c> where <c>Notify</c> + is the value set by the <c>open/1</c> option <c>notify</c> + or the function <c>change_notify/3</c> for the owners of + the log.</p> + </item> + <item> + <p><c>{users, Users}</c> where <c>Users</c> is the number + of anonymous users of the log, see the <c>open/1</c> option + <seealso marker="#linkto">linkto</seealso>.</p> + </item> + <item> + <p><c>{status, Status}</c>, where <c>Status</c> is <c>ok</c> + or <c>{blocked, QueueLogRecords}</c> as set by the functions + <c>block/1,2</c> and <c>unblock/1</c>.</p> + </item> + <item> + <p><c>{node, Node}</c>. The information returned by the + current invocation of the <c>info/1</c> function has been + gathered from the disk log process running on <c>Node</c>.</p> + </item> + <item> + <p><c>{distributed, Dist}</c>. If the log is local on + the current node, then <c>Dist</c> has the value <c>local</c>, + otherwise all nodes where the log is distributed + are returned as a list.</p> + </item> + </list> + <p>The following pairs are returned for all logs opened in + <c>read_write</c> mode: + </p> + <list type="bulleted"> + <item> + <p><c>{head, Head}</c>. Depending of the value of + the <c>open/1</c> options <c>head</c> and <c>head_func</c> + or set by the function <c>change_header/2</c>, the value + of <c>Head</c> is <c>none</c> (default), + <c>{head, H}</c> (<c>head</c> option) or <c>{M,F,A}</c> + (<c>head_func</c> option).</p> + </item> + <item> + <p><c>{no_written_items, NoWrittenItems}</c>, where + <c>NoWrittenItems</c> is the number of items + written to the log since the disk log process was created.</p> + </item> + </list> + <p>The following pair is returned for halt logs opened in + <c>read_write</c> mode: + </p> + <list type="bulleted"> + <item> + <p><c>{full, Full}</c>, where <c>Full</c> is <c>true</c> or + <c>false</c> depending on whether the halt log is full or not.</p> + </item> + </list> + <p>The following pairs are returned for wrap logs opened in + <c>read_write</c> mode: + </p> + <list type="bulleted"> + <item> + <p><c>{no_current_bytes, integer() >= 0}</c> is the number + of bytes written to the current wrap log file.</p> + </item> + <item> + <p><c>{no_current_items, integer() >= 0}</c> is the number + of items written to the current wrap log file, header + inclusive.</p> + </item> + <item> + <p><c>{no_items, integer() >= 0}</c> is the total number + of items in all wrap log files.</p> + </item> + <item> + <p><c>{current_file, integer()}</c> is the ordinal for + the current wrap log file in the range <c>1..MaxNoFiles</c>, + where <c>MaxNoFiles</c> is given by the <c>open/1</c> option + <c>size</c> or set by <c>change_size/2</c>.</p> + </item> + <item> + <p><c>{no_overflows, {SinceLogWasOpened, SinceLastInfo}}</c>, + where <c>SinceLogWasOpened</c> (<c>SinceLastInfo</c>) is + the number of times a wrap log file has been filled up and a + new one opened or <c>inc_wrap_file/1</c> has been called since + the disk log was last opened (<c>info/1</c> + was last called). The first time <c>info/2</c> is called + after a log was (re)opened or truncated, the two values + are equal.</p> + </item> + </list> + <p>Note that the <c>chunk/2,3</c>, <c>bchunk/2,3</c>, and + <c>chunk_step/3</c> functions do not affect any value + returned by <c>info/1</c>. + </p> + </desc> + </func> + <func> + <name>lclose(Log)</name> + <name>lclose(Log, Node) -> ok | {error, Reason}</name> + <fsummary>Close a disk log on one node.</fsummary> + <type> + <v>Node = node()</v> + <v>Reason = no_such_log | {file_error, FileName, FileError}</v> + </type> + <desc> + <p>The function <c>lclose/1</c> closes a local log or an + individual distributed log on the current node. + The function <c>lclose/2</c> closes an individual + distributed log on the specified node if the node + is not the current one. + <c>lclose(Log)</c> is equivalent to + <c>lclose(Log, node())</c>. + See also <seealso marker="#close_1">close/1</seealso>. + </p> + <p>If there is no log with the given name + on the specified node, <c>no_such_log</c> is returned. + </p> + </desc> + </func> + <func> + <name>log(Log, Term)</name> + <name>blog(Log, Bytes) -> ok | {error, Reason}</name> + <fsummary>Log an item onto a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>Term = term()</v> + <v>Bytes = binary() | [Byte]</v> + <v>Byte = [Byte] | 0 =< integer() =< 255</v> + <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {format_external, Log} | {blocked_log, Log} | {full, Log} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v> + </type> + <desc> + <p>The <c>log/2</c> and <c>blog/2</c> functions synchronously + append a term to a disk log. They return <c>ok</c> or + <c>{error, Reason}</c> when the term has been written to + disk. If the log is distributed, <c>ok</c> is always + returned, unless all nodes are down. Terms are written by + means of the ordinary <c>write()</c> function of the + operating system. Hence, there is no guarantee that the term + has actually been written to the disk, it might linger in + the operating system kernel for a while. To make sure the + item is actually written to disk, the <c>sync/1</c> function + must be called. + </p> + <p>The <c>log/2</c> function is used for internally formatted logs, + and <c>blog/2</c> for externally formatted logs. + <c>blog/2</c> can be used + for internally formatted logs as well provided the binary was + constructed with a call to <c>term_to_binary/1</c>. + </p> + <p>The owners that subscribe to notifications will be notified + of an error with an <c>error_status</c> message if the error + reason tag is <c>invalid_header</c> or <c>file_error</c>. + </p> + </desc> + </func> + <func> + <name>log_terms(Log, TermList)</name> + <name>blog_terms(Log, BytesList) -> ok | {error, Reason}</name> + <fsummary>Log several items onto a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>TermList = [term()]</v> + <v>BytesList = [Bytes]</v> + <v>Bytes = binary() | [Byte]</v> + <v>Byte = [Byte] | 0 =< integer() =< 255</v> + <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {format_external, Log} | {blocked_log, Log} | {full, Log} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v> + </type> + <desc> + <p>The <c>log_terms/2</c> and <c>blog_terms/2</c> functions + synchronously append a list of items to the log. The benefit + of using these functions rather than the <c>log/2</c> and + <c>blog/2</c> functions is that of efficiency: the given + 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. + </p> + <p>The <c>log_terms/2</c> function is used for internally formatted + logs, and <c>blog_terms/2</c> for externally formatted logs. + <c>blog_terms/2</c> can be used + for internally formatted logs as well provided the binaries were + constructed with calls to <c>term_to_binary/1</c>. + </p> + <p>The owners that subscribe to notifications will be notified + of an error with an <c>error_status</c> message if the error + reason tag is <c>invalid_header</c> or <c>file_error</c>. + </p> + </desc> + </func> + <func> + <name>open(ArgL) -> OpenRet | DistOpenRet</name> + <fsummary>Open a disk log file.</fsummary> + <type> + <v>ArgL = [Opt]</v> + <v>Opt = {name, term()} | {file, FileName}, {linkto, LinkTo} | {repair, Repair} | {type, Type} | {format, Format} | {size, Size} | {distributed, [Node]} | {notify, bool()} | {head, Head} | {head_func, {M,F,A}} | {mode, Mode}</v> + <v>FileName = string() | atom()</v> + <v>LinkTo = pid() | none</v> + <v>Repair = true | false | truncate</v> + <v>Type = halt | wrap</v> + <v>Format = internal | external</v> + <v>Size = integer() > 0 | infinity | {MaxNoBytes, MaxNoFiles}</v> + <v>MaxNoBytes = integer() > 0</v> + <v>MaxNoFiles = 0 < integer() < 65000</v> + <v>Rec = integer()</v> + <v>Bad = integer()</v> + <v>Head = none | term() | binary() | [Byte]</v> + <v>Byte = [Byte] | 0 =< integer() =< 255</v> + <v>Mode = read_write | read_only</v> + <v>OpenRet = Ret | {error, Reason}</v> + <v>DistOpenRet = {[{Node, Ret}], [{BadNode, {error, DistReason}}]}</v> + <v>Node = BadNode = atom()</v> + <v>Ret = {ok, Log} | {repaired, Log, {recovered, Rec}, {badbytes, Bad}}</v> + <v>DistReason = nodedown | Reason</v> + <v>Reason = no_such_log | {badarg, Arg} | {size_mismatch, CurrentSize, NewSize} | {arg_mismatch, OptionName, CurrentValue, Value} | {name_already_open, Log} | {open_read_write, Log} | {open_read_only, Log} | {need_repair, Log} | {not_a_log_file, FileName} | {invalid_index_file, FileName} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError} | {node_already_open, Log}</v> + </type> + <desc> + <p>The <c>ArgL</c> parameter is a list of options which have + the following meanings:</p> + <list type="bulleted"> + <item> + <p><c>{name, Log}</c> specifies the name of the log. + This is the name which must be passed on as a parameter in + all subsequent logging operations. A name must always + be supplied. + </p> + </item> + <item> + <p><c>{file, FileName}</c> specifies the name of the + file which will be used for logged terms. If this value is + omitted and the name of the log is either an atom or a string, + the file name will default to <c>lists:concat([Log, ".LOG"])</c> for halt logs. For wrap logs, this will be + the base name of the files. Each file in a wrap log + will be called <c><![CDATA[<base_name>.N]]></c>, where <c>N</c> is an + integer. Each wrap log will also have two files called + <c><![CDATA[<base_name>.idx]]></c> and <c><![CDATA[<base_name>.siz]]></c>. + </p> + </item> + <item> + <p><c>{linkto, LinkTo}</c>. <marker id="linkto"></marker> +If + <c>LinkTo</c> is a pid, that pid becomes an owner of the + log. If <c>LinkTo</c> is <c>none</c> the log records + that it is used anonymously by some process by + incrementing the <c>users</c> counter. By default, the + process which calls <c>open/1</c> owns the log. + </p> + </item> + <item> + <p><c>{repair, Repair}</c>. If <c>Repair</c> is <c>true</c>, + the current log file will be repaired, if needed. As the + restoration is initiated, a message is output on the error log. + If <c>false</c> is given, + no automatic repair will be attempted. Instead, the + tuple <c>{error, {need_repair, Log}}</c> is returned if an + attempt is made to open a corrupt log file. + If <c>truncate</c> is given, the log file will + be truncated, creating an empty log. Default is + <c>true</c>, which has no effect on logs opened in + read-only mode. + </p> + </item> + <item> + <p><c>{type, Type}</c> is the type of the log. Default + is <c>halt</c>. + </p> + </item> + <item> + <p><c>{format, Format}</c> specifies the format of the + disk log. Default is <c>internal</c>. + </p> + </item> + <item> + <p><c>{size, Size}</c> specifies the size of the log. + When a halt log has reached its maximum size, all attempts to + log more items are rejected. The default size is + <c>infinity</c>, which for halt implies that there is no + maximum size. For wrap logs, the <c>Size</c> parameter + may be either a pair + <c>{MaxNoBytes, MaxNoFiles}</c> or <c>infinity</c>. In the + latter case, if the files of an already 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 <c>MaxNoBytes</c> bytes on each file + and use <c>MaxNoFiles</c> files before starting all over with + the first wrap log file. Regardless of <c>MaxNoBytes</c>, + at least the header (if there is one) and one + item is written on each wrap log file before + wrapping to the next file. + When opening an existing wrap log, it is not + necessary to supply a value for the option <c>Size</c>, but any + supplied value must equal the current size of the log, otherwise + the tuple <c>{error, {size_mismatch, CurrentSize, NewSize}}</c> + is returned. + </p> + </item> + <item> + <p><c>{distributed, Nodes}</c>. This option can be used for + adding members to a distributed disk log. The + default value is <c>[]</c>, which means that + the log is local on the current node. + </p> + </item> + <item> + <marker id="notify"></marker> + <p><c>{notify, bool()}</c>. If <c>true</c>, the owners of the + log are notified when certain events occur in the log. + Default is <c>false</c>. The owners are sent one of the + following messages when an event occurs: + </p> + <list type="bulleted"> + <item> + <p><c>{disk_log, Node, Log, {wrap, NoLostItems}}</c> is sent when a wrap log has + filled up one of its files and a new file is + opened. <c>NoLostItems</c> is the number of + previously logged items that have been lost when + truncating existing files. + </p> + </item> + <item> + <p><c>{disk_log, Node, Log, {truncated, NoLostItems}}</c> is sent when a log has been + truncated or reopened. For halt logs <c>NoLostItems</c> + is the number of items written on the log since the + disk log process was created. For wrap logs + <c>NoLostItems</c> is the number of items on all + wrap log files. + </p> + </item> + <item> + <p><c>{disk_log, Node, Log, {read_only, Items}}</c> + is sent when an asynchronous log attempt is made to + a log file opened in read-only mode. + <c>Items</c> is the items from the log attempt. + </p> + </item> + <item> + <p><c>{disk_log, Node, Log, {blocked_log, Items}}</c> + is sent when an asynchronous log attempt is made to + a blocked log that does not queue log attempts. + <c>Items</c> is the items from the log attempt. + </p> + </item> + <item> + <p><c>{disk_log, Node, Log, {format_external, Items}}</c> + is sent when <c>alog/2</c> or <c>alog_terms/2</c> is + used for internally formatted logs. <c>Items</c> is the + items from the log attempt. + </p> + </item> + <item> + <p><c>{disk_log, Node, Log, full}</c> is sent when + an attempt to log items to a wrap log would write more + bytes than the limit set by the <c>size</c> option. + </p> + </item> + <item> + <p><c>{disk_log, Node, Log, {error_status, Status}}</c> + is sent when the error status changes. The error status + is defined by the outcome of the last attempt to log + items to a the log or to truncate the log or the last + use of <c>sync/1</c>, <c>inc_wrap_file/1</c> or + <c>change_size/2</c>. <c>Status</c> is one of <c>ok</c> and + <c>{error, Error}</c>, the former being the initial value. + </p> + </item> + </list> + </item> + <item> + <p><c>{head, Head}</c> specifies a header to be + written first on the log file. If the log is a wrap + log, the item <c>Head</c> is written first in each new file. + <c>Head</c> should be a term if the format is + <c>internal</c>, and a deep list of bytes (or a binary) + otherwise. Default is <c>none</c>, which means that + no header is written first on the file. + </p> + </item> + <item> + <p><c>{head_func, {M,F,A}}</c> specifies a function + to be called each time a new log file is opened. + The call <c>M:F(A)</c> is assumed to return <c>{ok, Head}</c>. + The item <c>Head</c> is written first in each file. + <c>Head</c> should be a term if the format is + <c>internal</c>, and a deep list of bytes (or a binary) + otherwise. + </p> + </item> + <item> + <p><c>{mode, Mode}</c> specifies if the log is to be + opened in read-only or read-write mode. It defaults to + <c>read_write</c>. + </p> + </item> + </list> + <p>The <c>open/1</c> function returns <c>{ok, Log}</c> if the + log file was successfully opened. If the file was + successfully repaired, the tuple <c>{repaired, Log, {recovered, Rec}, {badbytes, Bad}}</c> is returned, where + <c>Rec</c> is the number of whole Erlang terms found in the + file and <c>Bad</c> is the number of bytes in the file which + were non-Erlang terms. If the <c>distributed</c> parameter + was given, <c>open/1</c> returns a list of + successful replies and a list of erroneous replies. Each + reply is tagged with the node name. + </p> + <p>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 + will commence from there. If the format is <c>internal</c> + and the existing file is not recognized as an internally + formatted log, a tuple <c>{error, {not_a_log_file, FileName}}</c> + is returned. + </p> + <p>The <c>open/1</c> function cannot be used for changing the + values of options of an already open log; when there are prior + owners or users of a log, all option values except <c>name</c>, + <c>linkto</c> and <c>notify</c> are just checked against + the values that have been supplied before as option values + to <c>open/1</c>, <c>change_header/2</c>, <c>change_notify/3</c> + or <c>change_size/2</c>. As a consequence, + none of the options except <c>name</c> is mandatory. If some + given value differs from the current value, a tuple + <c>{error, {arg_mismatch, OptionName, CurrentValue, Value}}</c> + is returned. Caution: an owner's attempt to open a log + as owner once again is acknowledged with the return value + <c>{ok, Log}</c>, but the state of the disk log is not + affected in any way. + </p> + <p>If a log with a given name is local on some node, + and one tries to open the log distributed on the same node, + then the tuple <c>{error, {node_already_open, Name}}</c> is + returned. The same tuple is returned if the log is distributed on + some node, and one tries to open the log locally on the same node. + Opening individual distributed disk logs for the first time + adds those logs to a (possibly empty) distributed disk log. + The option values supplied are used + on all nodes mentioned by the <c>distributed</c> option. + Individual distributed logs know nothing + about each other's option values, so each node can be + given unique option values by creating a distributed + log with several calls to <c>open/1</c>. + </p> + <p>It is possible to open a log file more than once by giving + different values to the option <c>name</c> or by using the + same file when distributing a log on different nodes. + It is up to the user of the <c>disk_log</c> + module to ensure that no more than one + disk log process has write access to any file, or the + the file may be corrupted. + </p> + <p>If an attempt to open a log file for the first time fails, + the disk log process terminates with the EXIT message + <c>{{failed,Reason},[{disk_log,open,1}]}</c>. + The function returns <c>{error, Reason}</c> for all other errors. + </p> + </desc> + </func> + <func> + <name>pid2name(Pid) -> {ok, Log} | undefined</name> + <fsummary>Return the name of the disk log handled by a pid.</fsummary> + <type> + <v>Log = term()</v> + <v>Pid = pid()</v> + </type> + <desc> + <p>The <c>pid2name/1</c> function returns the name of the log + given the pid of a disk log process on the current node, or + <c>undefined</c> if the given pid is not a disk log process. + </p> + <p>This function is meant to be used for debugging only. + </p> + </desc> + </func> + <func> + <name>reopen(Log, File)</name> + <name>reopen(Log, File, Head)</name> + <name>breopen(Log, File, BHead) -> ok | {error, Reason}</name> + <fsummary>Reopen a disk log and save the old log.</fsummary> + <type> + <v>Log = term()</v> + <v>File = string()</v> + <v>Head = term()</v> + <v>BHead = binary() | [Byte]</v> + <v>Byte = [Byte] | 0 =< integer() =< 255</v> + <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {same_file_name, Log} | {invalid_index_file, FileName} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v> + </type> + <desc> + <p>The <c>reopen</c> functions first rename the log file + to <c>File</c> and then re-create a new log file. + In case of a wrap log, <c>File</c> is used as the base name + of the renamed files. + By default the header given to <c>open/1</c> is written first in + the newly opened log file, but if the <c>Head</c> or the + <c>BHead</c> argument is given, this item is used instead. + The header argument is used once only; next time a wrap log file + is opened, the header given to <c>open/1</c> is used. + </p> + <p>The <c>reopen/2,3</c> functions are used for internally formatted + logs, and <c>breopen/3</c> for externally formatted logs. + </p> + <p>The owners that subscribe to notifications will receive + a <c>truncate</c> message. + </p> + <p>Upon failure to reopen the log, the disk log process terminates + with the EXIT message <c>{{failed,Error},[{disk_log,Fun,Arity}]}</c>, + and other processes that have requests queued receive the message + <c>{disk_log, Node, {error, disk_log_stopped}}</c>. + </p> + </desc> + </func> + <func> + <name>sync(Log) -> ok | {error, Reason}</name> + <fsummary>Flush the contents of a disk log to the disk.</fsummary> + <type> + <v>Log = term()</v> + <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {file_error, FileName, FileError}</v> + </type> + <desc> + <p>The <c>sync/1</c> function ensures that the contents of the + log are actually written to the disk. + This is usually a rather expensive operation. + </p> + </desc> + </func> + <func> + <name>truncate(Log)</name> + <name>truncate(Log, Head)</name> + <name>btruncate(Log, BHead) -> ok | {error, Reason}</name> + <fsummary>Truncate a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>Head = term()</v> + <v>BHead = binary() | [Byte]</v> + <v>Byte = [Byte] | 0 =< integer() =< 255</v> + <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v> + </type> + <desc> + <p>The <c>truncate</c> functions remove all items from a disk log. + If the <c>Head</c> or the <c>BHead</c> argument is + given, this item is written first in the newly truncated + log, otherwise the header given to <c>open/1</c> is used. + The header argument is only used once; next time a wrap log file + is opened, the header given to <c>open/1</c> is used. + </p> + <p>The <c>truncate/1,2</c> functions are used for internally + formatted logs, and <c>btruncate/2</c> for externally formatted + logs. + </p> + <p>The owners that subscribe to notifications will receive + a <c>truncate</c> message. + </p> + <p>If the attempt to truncate the log fails, the disk log process + terminates with the EXIT message + <c>{{failed,Reason},[{disk_log,Fun,Arity}]}</c>, and + other processes that have requests queued receive the message + <c>{disk_log, Node, {error, disk_log_stopped}}</c>. + </p> + </desc> + </func> + <func> + <name>unblock(Log) -> ok | {error, Reason}</name> + <fsummary>Unblock a disk log.</fsummary> + <type> + <v>Log = term()</v> + <v>Reason = no_such_log | nonode | {not_blocked, Log} | {not_blocked_by_pid, Log}</v> + </type> + <desc> + <p>The <c>unblock/1</c> function unblocks a log. + A log can only be unblocked by the blocking process. + </p> + </desc> + </func> + </funcs> + + <section> + <title>See Also</title> + <p><seealso marker="file">file(3)</seealso>, + <seealso marker="pg2">pg2(3)</seealso>, + <seealso marker="wrap_log_reader">wrap_log_reader(3)</seealso></p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/erl_boot_server.xml b/lib/kernel/doc/src/erl_boot_server.xml new file mode 100644 index 0000000000..4e7533810e --- /dev/null +++ b/lib/kernel/doc/src/erl_boot_server.xml @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>erl_boot_server</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>erl_boot_server</module> + <modulesummary>Boot Server for Other Erlang Machines</modulesummary> + <description> + <p>This server is used to assist diskless Erlang nodes which fetch + all Erlang code from another machine.</p> + <p>This server is used to fetch all code, including the start + script, if an Erlang runtime system is started with + the <c>-loader inet</c> command line flag. All hosts specified + with the <c>-hosts Host</c> command line flag must have one + instance of this server running.</p> + <p>This server can be started with the <c>kernel</c> configuration + parameter <c>start_boot_server</c>.</p> + <p>The <c>erl_boot_server</c> can both read regular files as well as + files in archives. See <seealso marker="code">code(3)</seealso> + and <seealso marker="erts:erl_prim_loader">erl_prim_loader(3)</seealso>.</p> + <warning><p>The support for loading of code from archive files is + experimental. The sole purpose of releasing it before it is ready + is to obtain early feedback. The file format, semantics, + interfaces etc. may be changed in a future release.</p></warning> + </description> + <funcs> + <func> + <name>start(Slaves) -> {ok, Pid} | {error, What}</name> + <fsummary>Start the boot server</fsummary> + <type> + <v>Slaves = [Host]</v> + <v>Host = atom()</v> + <v>Pid = pid()</v> + <v>What = term()</v> + </type> + <desc> + <p>Starts the boot server. <c>Slaves</c> is a list of IP + addresses for hosts which are allowed to use this server as a + boot server.</p> + </desc> + </func> + <func> + <name>start_link(Slaves) -> {ok, Pid} | {error, What}</name> + <fsummary>Start the boot server and links the caller</fsummary> + <type> + <v>Slaves = [Host]</v> + <v>Host = atom()</v> + <v>Pid = pid()</v> + <v>What = term()()</v> + </type> + <desc> + <p>Starts the boot server and links to the caller. This function + is used to start the server if it is included in a supervision + tree.</p> + </desc> + </func> + <func> + <name>add_slave(Slave) -> ok | {error, What}</name> + <fsummary>Add a slave to the list of allowed slaves</fsummary> + <type> + <v>Slave = Host</v> + <v>Host = atom()</v> + <v>What = term()</v> + </type> + <desc> + <p>Adds a <c>Slave</c> node to the list of allowed slave hosts.</p> + </desc> + </func> + <func> + <name>delete_slave(Slave) -> ok | {error, What}</name> + <fsummary>Delete a slave from the list of allowed slaves</fsummary> + <type> + <v>Slave = Host</v> + <v>Host = atom()</v> + <v>What = void()</v> + </type> + <desc> + <p>Deletes a <c>Slave</c> node from the list of allowed slave + hosts.</p> + </desc> + </func> + <func> + <name>which_slaves() -> Slaves</name> + <fsummary>Return the current list of allowed slave hosts</fsummary> + <type> + <v>Slaves = [Host]</v> + <v>Host = atom()</v> + </type> + <desc> + <p>Returns the current list of allowed slave hosts.</p> + </desc> + </func> + </funcs> + + <section> + <title>SEE ALSO</title> + <p><seealso marker="erts:init">init(3)</seealso>, + <seealso marker="erts:erl_prim_loader">erl_prim_loader(3)</seealso></p> + </section> +</erlref> + + diff --git a/lib/kernel/doc/src/erl_ddll.xml b/lib/kernel/doc/src/erl_ddll.xml new file mode 100644 index 0000000000..75dca8a85d --- /dev/null +++ b/lib/kernel/doc/src/erl_ddll.xml @@ -0,0 +1,1165 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>erl_ddll</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>erl_ddll</module> + <modulesummary>Dynamic Driver Loader and Linker</modulesummary> + <description> + <p>The <c>erl_ddll</c> module provides an interface for loading + and unloading <em>erlang linked in drivers</em> in runtime.</p> + <note> + <p>This is a large reference document. For casual use of the + module, as well as for most real world applications, the + descriptions of the functions <seealso marker="#load/2">load/2</seealso> and <seealso marker="#unload/1">unload/1</seealso> are enough to get + going. </p> + </note> + <p>The driver should be provided as a dynamically linked library + in a object code format specific for the platform in use, + i. e. <c>.so</c> files on most Unix systems and <c>.ddl</c> + files on windows. An erlang linked in driver has to provide + specific interfaces to the emulator, so this module is not + designed for loading arbitrary dynamic libraries. For further + information about erlang drivers, refer to the ERTS reference + manual section <seealso marker="erts:erl_driver">erl_driver</seealso>.</p> + <marker id="users"></marker> + <p>When describing a set of functions, (i.e. 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 <em>user</em>. There can be + several users in one process (different modules needing the same + driver) and several processes running the same code, making up + several <em>users</em> 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 as well as the number of loads by each process, so that + the driver will only be unloaded when no one wants it + (it has no user). The driver also keeps track of ports that are + opened towards it, so that one can delay unloading until all + ports are closed or kill all ports using the driver when it is + unloaded. </p> + <marker id="scenarios"></marker> + <p>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:</p> + <taglist> + <tag><em>Load and unload on a "when needed basis"</em></tag> + <item> + <p>This (most common) scenario simply supports that each + <seealso marker="#users">user</seealso> of the driver loads + it when it is needed and unloads it when the <seealso marker="#users">user</seealso> no longer have any use for + it. 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.</p> + <p>Each <seealso marker="#users">user</seealso> of the driver + use <em>literally</em> the same pathname for the driver when + demanding load, but the <seealso marker="#users">users</seealso> are not really concerned + with if the driver is already loaded from the filesystem or + if the object code has to be loaded from filesystem.</p> + <p>Two pairs of functions support this scenario:</p> + <taglist> + <tag><em>load/2 and unload/1</em></tag> + <item> + <p>When using the <c>load/unload</c> interfaces, the + driver will not <em>actually</em> get unloaded until the + <em>last port</em> using the driver is closed. The function + <c>unload/1</c> can return immediately, as the <seealso marker="#users">users</seealso> are not really concerned + with when the actual unloading occurs. The + driver will actually get unloaded when no one needs it any longer.</p> + <p>If a process having the driver loaded dies, it will have + the same effect as if unloading was done. </p> + <p>When loading, the function <c>load/2</c> returns + <c>ok</c> as soon as there is any instance of the driver + present, so that if a driver is waiting to get unloaded + (due to open ports), it will simply change state to no + longer need unloading.</p> + </item> + <tag><em>load_driver/2 and unload_driver/1</em></tag> + <item> + <p>These interfaces is intended to be used when it is considered an + error that ports are open towards a driver that no <seealso marker="#users">user</seealso> + has loaded. The ports still open when the + last <seealso marker="#users">user</seealso> calls + <c>unload_driver/1</c> or when the last process having the + driver loaded dies, will get killed with reason + <c>driver_unloaded</c>.</p> + <p>The function names <c>load_driver</c> and + <c>unload_driver</c> are kept for backward + compatibility.</p> + </item> + </taglist> + </item> + <tag><em>Loading and reloading for code replacement</em></tag> + <item> + <p>This scenario occurs when the driver code might need + replacement during operation of the Erlang + emulator. Implementing driver code replacement is somewhat + more tedious than beam code replacement, as one driver + cannot be loaded as both "old" and "new" code. All <seealso marker="#users">users</seealso> of a driver must have it + closed (no open ports) before the old code can be unloaded + and the new code can be loaded.</p> + <p>The actual unloading/loading is done as one atomic + operation, blocking all processes in the system from using + the driver concerned while in progress.</p> + <p>The preferred way to do driver code replacement is to let + <em>one single process</em> keep track of the driver. When + the process start, 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 <seealso marker="#users">user</seealso> has a driver loaded when code + replacement is demanded, the replacement cannot occur until + the last "other" <seealso marker="#users">user</seealso> has + unloaded the driver.</p> + <p>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 <seealso marker="#users">user</seealso> has the driver loaded. To + simplify driver replacement, avoid designing your system so + that more than than one <seealso marker="#users">user</seealso> has the driver loaded.</p> + <p>The two functions for reloading drivers should be used + together with corresponding load functions, to support the two + different behaviors concerning open ports:</p> + <taglist> + <tag><em>load/2 and reload/2</em></tag> + <item> + <p>This pair of functions is used when reloading should be + done after the last open port towards the driver is + closed.</p> + <p>As <c>reload/2</c> actually waits for the reloading to + occur, a misbehaving process keeping open ports towards + the driver (or keeping the driver loaded) might cause + infinite waiting for reload. Timeouts has to be provided + outside of the process demanding the reload or by using + the low-level interface <seealso marker="#try_load/3">try_load/3</seealso> in combination + with driver monitors (see below).</p> + </item> + <tag><em>load_driver/2 and reload_driver/2</em></tag> + <item> + <p>This pair of functions are used when open ports towards + the driver should be killed with reason + <c>driver_unloaded</c> to allow for new driver code to + get loaded.</p> + <p>If, however, another process has the driver loaded, + calling <c>reload_driver</c> returns the error code + <c>pending_process</c>. As stated earlier, + the recommended design is to not allow other <seealso marker="#users">users</seealso> than the "driver + reloader" to actually demand loading of the concerned + driver.</p> + </item> + </taglist> + </item> + </taglist> + </description> + <funcs> + <func> + <name>demonitor(MonitorRef) -> ok</name> + <fsummary>Remove a monitor for a driver</fsummary> + <type> + <v>MonitorRef = ref()</v> + </type> + <desc> + <p>Removes a driver monitor in much the same way as + <seealso marker="erts:erlang#erlang:demonitor/1">erlang:demonitor/1</seealso> does with process + monitors. See <seealso marker="#monitor/2">monitor/2</seealso>, <seealso marker="#try_load/3">try_load/3</seealso> and <seealso marker="#try_unload/2">try_unload/2</seealso> for details + about how to create driver monitors.</p> + <p>The function throws a <c>badarg</c> exception if the + parameter is not a ref(). </p> + </desc> + </func> + <func> + <name>info() -> AllInfoList</name> + <fsummary>Retrieve information about all drivers</fsummary> + <type> + <v>AllInfoList = [ DriverInfo ]</v> + <v>DriverInfo = {DriverName, InfoList}</v> + <v>DriverName = string()</v> + <v>InfoList = [ InfoItem ]</v> + <v>InfoItem = {Tag, Value}</v> + <v>Tag = atom()</v> + <v>Value = term()</v> + </type> + <desc> + <p>Returns a list of tuples <c>{DriverName, InfoList}</c>, where + <c>InfoList</c> is the result of calling <seealso marker="#info/1">info/1</seealso> for that + <c>DriverName</c>. Only dynamically linked in drivers are + included in the list.</p> + </desc> + </func> + <func> + <name>info(Name) -> InfoList</name> + <fsummary>Retrieve information about one driver</fsummary> + <type> + <v>Name = string() | atom()</v> + <v>InfoList = [ InfoItem ]</v> + <v>InfoItem = {Tag, Value}</v> + <v>Tag = atom()</v> + <v>Value = term()</v> + </type> + <desc> + <p>Returns a list of tuples <c>{Tag, Value}</c>, where + <c>Tag</c> is the information item and <c>Value</c> is the result + of calling <seealso marker="#info/2">info/2</seealso> with this driver name and + this tag. The result being a tuple list containing all + information available about a driver. </p> + <p>The different tags that will appear in the list are:</p> + <list type="bulleted"> + <item>processes</item> + <item>driver_options</item> + <item>port_count</item> + <item>linked_in_driver</item> + <item>permanent</item> + <item>awaiting_load</item> + <item>awaiting_unload</item> + </list> + <p>For a detailed description of each value, please read the + description of <seealso marker="#info/2">info/2</seealso> below.</p> + <p>The function throws a <c>badarg</c> exception if the driver + is not present in the system.</p> + </desc> + </func> + <func> + <name>info(Name, Tag) -> Value</name> + <fsummary>Retrieve specific information about one driver</fsummary> + <type> + <v>Name = string() | atom()</v> + <v>Tag = processes | driver_options | port_count | linked_in_driver | permanent | awaiting_load | awaiting_unload</v> + <v>Value = term()</v> + </type> + <desc> + <p>This function returns specific information about one aspect + of a driver. The <c>Tag</c> parameter specifies which aspect + to get information about. The <c>Value</c> return differs + between different tags:</p> + <taglist> + <tag><em>processes</em></tag> + <item> + <p>Return all processes containing <seealso marker="#users">users</seealso> of the specific drivers + as a list of tuples <c>{pid(),int()}</c>, where the + <c>int()</c> denotes the number of users in the process + <c>pid()</c>.</p> + </item> + <tag><em>driver_options</em></tag> + <item> + <p>Return a list of the driver options provided when + loading, as well as any options set by the driver itself + during initialization. The currently only valid option + being <c>kill_ports</c>.</p> + </item> + <tag><em>port_count</em></tag> + <item> + <p>Return the number of ports (an <c>int()</c>) using the driver.</p> + </item> + <tag><em>linked_in_driver</em></tag> + <item> + <p>Return a <c>bool()</c>, being <c>true</c> if the driver is a + statically linked in one and <c>false</c> otherwise.</p> + </item> + <tag><em>permanent</em></tag> + <item> + <p>Return a <c>bool()</c>, being <c>true</c> if the driver has made + itself permanent (and is <em>not</em> a statically + linked in driver). <c>false</c> otherwise.</p> + </item> + <tag><em>awaiting_load</em></tag> + <item> + <p>Return a list of all processes having monitors for + <c>loading</c> active, each process returned as + <c>{pid(),int()}</c>, where the <c>int()</c> is the + number of monitors held by the process <c>pid()</c>.</p> + </item> + <tag><em>awaiting_unload</em></tag> + <item> + <p>Return a list of all processes having monitors for + <c>unloading</c> active, each process returned as + <c>{pid(),int()}</c>, where the <c>int()</c> is the + number of monitors held by the process <c>pid()</c>.</p> + </item> + </taglist> + <p>If the options <c>linked_in_driver</c> or <c>permanent</c> + return true, all other options will return the value + <c>linked_in_driver</c> or <c>permanent</c> respectively.</p> + <p>The function throws a <c>badarg</c> exception if the driver + is not present in the system or the tag is not supported.</p> + </desc> + </func> + <func> + <name>load(Path, Name) -> ok | {error, ErrorDesc}</name> + <fsummary>Load a driver</fsummary> + <type> + <v>Path = Name = string() | atom()</v> + <v>ErrorDesc = term()</v> + </type> + <desc> + <p>Loads and links the dynamic driver <c>Name</c>. <c>Path</c> + is a file path to the directory containing the driver. + <c>Name</c> must be a sharable object/dynamic library. Two + drivers with different <c>Path</c> parameters cannot be + loaded under the same name. The <c>Name</c> is a string or + atom containing at least one character.</p> + <p>The <c>Name</c> given should correspond to the filename + of the actual dynamically loadable object file residing in + the directory given as <c>Path</c>, but <em>without</em> the + extension (i.e. <c>.so</c>). 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 <c>.beam</c> files.</p> + <p>If the driver has been previously unloaded, but is still + present due to open ports against it, a call to + <c>load/2</c> will stop the unloading and keep the driver + (as long as the <c>Path</c> is the same) and <c>ok</c> is + returned. If one actually wants the object code to be + reloaded, one uses <seealso marker="#reload/2">reload/2</seealso> or the low-level + interface <seealso marker="#try_load/3">try_load/3</seealso> + instead. Please refer to the description of <seealso marker="#scenarios">different scenarios</seealso> for + loading/unloading in the introduction.</p> + <p>If more than one process tries to load an already loaded + driver withe the same <c>Path</c>, or if the same process + tries to load it several times, the function will return + <c>ok</c>. The emulator will keep track of the + <c>load/2</c> calls, so that a corresponding number of + <c>unload/2</c> calls will have to be done from the same + process before the driver will actually get 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. </p> + <p>It is not allowed to load + several drivers with the same name but with different + <c>Path</c> parameters.</p> + <note> + <p>Note especially that the <c>Path</c> is interpreted + literally, so that all loaders of the same driver needs to + give the same <em>literal</em><c>Path</c> string, even + though different paths might point out the same directory + in the filesystem (due to use of relative paths and + links).</p> + </note> + <p>On success, the function returns <c>ok</c>. On + failure, the return value is <c>{error,ErrorDesc}</c>, + where <c>ErrorDesc</c> is an opaque term to be + translated into human readable form by the <seealso marker="#format_error/1">format_error/1</seealso> + function.</p> + <p>For more control over the error handling, again use the + <seealso marker="#try_load/3">try_load/3</seealso> + interface instead.</p> + <p>The function throws a <c>badarg</c> exception if the + parameters are not given as described above. </p> + </desc> + </func> + <func> + <name>load_driver(Path, Name) -> ok | {error, ErrorDesc}</name> + <fsummary>Load a driver</fsummary> + <type> + <v>Path = Name = string() | atom()</v> + <v>ErrorDesc = term()</v> + </type> + <desc> + <p>Works essentially as <c>load/2</c>, but will load the driver + with options other options. All ports that are using the + driver will get killed with the reason + <c>driver_unloaded</c> when the driver is to be unloaded.</p> + <p>The number of loads and unloads by different <seealso marker="#users">users</seealso> influence the actual loading + and unloading of a driver file. The port killing will + therefore only happen when the <em>last</em><seealso marker="#users">user</seealso> unloads the driver, or the + last process having loaded the driver exits.</p> + <p>This interface (or at least the name of the functions) is + kept for backward compatibility. Using <seealso marker="#try_load/3">try_load/3</seealso> with + <c>{driver_options,[kill_ports]} </c> in the option list will + give the same effect regarding the port killing.</p> + <p>The function throws a <c>badarg</c> exception if the + parameters are not given as described above. </p> + </desc> + </func> + <func> + <name>monitor(Tag, Item) -> MonitorRef</name> + <fsummary>Create a monitor for a driver</fsummary> + <type> + <v>Tag = driver </v> + <v>Item = {Name, When}</v> + <v>Name = atom() | string()</v> + <v>When = loaded | unloaded | unloaded_only</v> + <v>MonitorRef = ref()</v> + </type> + <desc> + <p>This function creates a driver monitor and works in many + ways as the function <seealso marker="erts:erlang#erlang:monitor/2">erlang:monitor/2</seealso>, + does for processes. When a driver changes state, the monitor + results in a monitor-message being sent to the calling + process. The <c>MonitorRef</c> returned by this function is + included in the message sent.</p> + <p>As with process monitors, each driver monitor set will only + generate <em>one single message</em>. The monitor is + "destroyed" after the message is sent and there is then no + need to call <seealso marker="#demonitor/1">demonitor/1</seealso>.</p> + <p>The <c>MonitorRef</c> can also be used in subsequent calls + to <seealso marker="#demonitor/1">demonitor/1</seealso> to + remove a monitor.</p> + <p>The function accepts the following parameters:</p> + <taglist> + <tag><em>Tag</em></tag> + <item> + <p>The monitor tag is always <c>driver</c> 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 given for consistence.</p> + </item> + <tag><em>Item</em></tag> + <item> + <p>The <c>Item</c> parameter specifies which driver one + wants to monitor (the name of the driver) as well as + which state change one wants to monitor. The parameter + is a tuple of arity two whose first element is the + driver name and second element is either of:</p> + <taglist> + <tag><em>loaded</em></tag> + <item> + <p>Notify me 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. One cannot monitor a future-to-be driver + name for loading, that will only result in a + <c>'DOWN'</c> message being immediately sent. + Monitoring for loading is therefore most useful when + triggered by the <seealso marker="#try_load/3">try_load/3</seealso> function, + where the monitor is created <em>because</em> the + driver is in such a pending state.</p> + <p>Setting a driver monitor for <c>loading</c> will + eventually lead to one of the following messages + being sent:</p> + <taglist> + <tag><em>{'UP', ref(), driver, Name, loaded}</em></tag> + <item> + <p>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. </p> + <p>The <seealso marker="#users">user</seealso> is + expected to know if reloading is demanded prior + to creating a monitor for loading.</p> + </item> + <tag><em>{'UP', ref(), driver, Name, permanent}</em></tag> + <item> + <p>This message will be sent if reloading was + expected, but the (old) driver made itself + permanent prior to reloading. It will also be + sent if the driver was permanent or statically + linked in when trying to create the monitor.</p> + </item> + <tag><em>{'DOWN', ref(), driver, Name, load_cancelled}</em></tag> + <item> + <p>This message will arrive if reloading was + underway, but the <seealso marker="#users">user</seealso> having requested + reload cancelled it by either dying or calling + <seealso marker="#try_unload/2">try_unload/2</seealso> + (or <c>unload/1</c>/<c>unload_driver/1</c>) + again before it was reloaded.</p> + </item> + <tag><em>{'DOWN', ref(), driver, Name, {load_failure, Failure}}</em></tag> + <item> + <p>This message will arrive if reloading was + underway but the loading for some reason + failed. The <c>Failure</c> term is one of the + errors that can be returned from <seealso marker="#try_load/3">try_load/3</seealso>. The + error term can be passed to <seealso marker="#format_error/1">format_error/1</seealso> + for translation into human readable form. Note + that the translation has to be done in the same + running erlang virtual machine as the error + was detected in.</p> + </item> + </taglist> + </item> + <tag><em>unloaded</em></tag> + <item> + <p>Monitor when a driver gets unloaded. If one + monitors a driver that is not present in the system, + one will immediately get notified that the driver got + unloaded. There is no guarantee that the driver was + actually ever loaded.</p> + <p>A driver monitor for unload will eventually result + in one of the following messages being sent:</p> + <taglist> + <tag><em>{'DOWN', ref(), driver, Name, unloaded}</em></tag> + <item> + <p>The driver instance monitored is now + unloaded. As the unload might have been due to a + <c>reload/2</c> request, the driver might once + again have been loaded when this message + arrives.</p> + </item> + <tag><em>{'UP', ref(), driver, Name, unload_cancelled}</em></tag> + <item> + <p>This message will be sent if unloading was + expected, but while the driver was waiting for + all ports to get closed, a new <seealso marker="#users">user</seealso> of the driver + appeared and the unloading was cancelled.</p> + <p>This message appears when an <c>{ok, pending_driver}</c>) was returned from <seealso marker="#try_unload/2">try_unload/2</seealso>) + for the last <seealso marker="#users">user</seealso> of the driver and + then a <c>{ok, already_loaded}</c> is returned + from a call to <seealso marker="#try_load/3">try_load/3</seealso>.</p> + <p>If one wants to <em>really</em> monitor when the + driver gets unloaded, this message will distort + the picture, no unloading was really done. + The <c>unloaded_only</c> option creates a monitor + similar to an <c>unloaded</c> monitor, but does + never result in this message.</p> + </item> + <tag><em>{'UP', ref(), driver, Name, permanent}</em></tag> + <item> + <p>This message will be sent if unloading was + expected, but the driver made itself + permanent prior to unloading. It will also be + sent if trying to monitor a permanent or + statically linked in driver.</p> + </item> + </taglist> + </item> + <tag><em>unloaded_only</em></tag> + <item> + <p>A monitor created as <c>unloaded_only</c> behaves + exactly as one created as <c>unloaded</c> with the + exception that the <c>{'UP', ref(), driver, Name, unload_cancelled}</c> message will never be + sent, but the monitor instead persists until the + driver <em>really</em> gets unloaded.</p> + </item> + </taglist> + </item> + </taglist> + <p>The function throws a <c>badarg</c> exception if the + parameters are not given as described above. </p> + </desc> + </func> + <func> + <name>reload(Path, Name) -> ok | {error, ErrorDesc}</name> + <fsummary>Replace a driver</fsummary> + <type> + <v>Path = Name = string() | atom()</v> + <v>ErrorDesc = pending_process | OpaqueError</v> + <v>OpaqueError = term()</v> + </type> + <desc> + <p>Reloads the driver named <c>Name</c> from a possibly + different <c>Path</c> than was previously used. This + function is used in the code change <seealso marker="#scenarios">scenario</seealso> described in the + introduction.</p> + <p>If there are other <seealso marker="#users">users</seealso> + of this driver, the function will return <c>{error, pending_process}</c>, but if there are no more users, the + function call will hang until all open ports are closed.</p> + <note> + <p>Avoid mixing + several <seealso marker="#users">users</seealso> + with driver reload requests.</p> + </note> + <p>If one wants to avoid hanging on open ports, one should use + the <seealso marker="#try_load/3">try_load/3</seealso> + function instead.</p> + <p>The <c>Name</c> and <c>Path</c> parameters have exactly the + same meaning as when calling the plain <seealso marker="#load/2">load/2</seealso> function.</p> + <note> + <p>Avoid mixing + several <seealso marker="#users">users</seealso> + with driver reload requests.</p> + </note> + <p>On success, the function returns <c>ok</c>. On + failure, the function returns an opaque error, with the + exception of the <c>pending_process</c> error described + above. The opaque errors are to be translated into human + readable form by the <seealso marker="#format_error/1">format_error/1</seealso> function.</p> + <p>For more control over the error handling, again use the + <seealso marker="#try_load/3">try_load/3</seealso> + interface instead.</p> + <p>The function throws a <c>badarg</c> exception if the + parameters are not given as described above. </p> + </desc> + </func> + <func> + <name>reload_driver(Path, Name) -> ok | {error, ErrorDesc}</name> + <fsummary>Replace a driver</fsummary> + <type> + <v>Path = Name = string() | atom()</v> + <v>ErrorDesc = pending_process | OpaqueError</v> + <v>OpaqueError = term()</v> + </type> + <desc> + <p>Works exactly as <seealso marker="#reload/2">reload/2</seealso>, but for drivers + loaded with the <seealso marker="#load_driver/2">load_driver/2</seealso> interface. </p> + <p>As this interface implies that ports are being killed when + the last user disappears, the function wont hang waiting for + ports to get closed.</p> + <p>For further details, see the <seealso marker="#scenarios">scenarios</seealso> in the module + description and refer to the <seealso marker="#reload/2">reload/2</seealso> function description.</p> + <p>The function throws a <c>badarg</c> exception if the + parameters are not given as described above. </p> + </desc> + </func> + <func> + <name>try_load(Path, Name, OptionList) -> {ok,Status} | {ok, PendingStatus, Ref} | {error, ErrorDesc}</name> + <fsummary>Load a driver</fsummary> + <type> + <v>Path = Name = string() | atom()</v> + <v>OptionList = [ Option ]</v> + <v>Option = {driver_options, DriverOptionList} | {monitor, MonitorOption} | {reload, ReloadOption}</v> + <v>DriverOptionList = [ DriverOption ]</v> + <v>DriverOption = kill_ports</v> + <v>MonitorOption = pending_driver | pending</v> + <v>ReloadOption = pending_driver | pending</v> + <v>Status = loaded | already_loaded | PendingStatus </v> + <v>PendingStatus = pending_driver | pending_process</v> + <v>Ref = ref()</v> + <v>ErrorDesc = ErrorAtom | OpaqueError</v> + <v>ErrorAtom = linked_in_driver | inconsistent | permanent | not_loaded_by_this_process | not_loaded | pending_reload | pending_process</v> + </type> + <desc> + <p>This function provides more control than the + <c>load/2</c>/<c>reload/2</c> and + <c>load_driver/2</c>/<c>reload_driver/2</c> interfaces. It + will never wait for completion of other operations related + to the driver, but immediately return the status of the + driver as either:</p> + <taglist> + <tag><em>{ok, loaded}</em></tag> + <item> + <p>The driver was actually loaded and is immediately + usable.</p> + </item> + <tag><em>{ok, already_loaded}</em></tag> + <item> + <p>The driver was already loaded by another process + and/or is in use by a living port. The load by you is + registered and a corresponding <c>try_unload</c> is + expected sometime in the future.</p> + </item> + <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, ref()}</em></tag> + <item> + <p>The load request is registered, but the loading is + delayed due to the fact that an earlier instance of the + driver is still waiting to get unloaded (there are open + ports using it). Still, unload is expected when you are + done with the driver. This return value will + <em>mostly</em> happen when the + <c>{reload,pending_driver}</c> or + <c>{reload,pending}</c> options are used, but + <em>can</em> happen when another <seealso marker="#users">user</seealso> is unloading a driver in + parallel and the <c>kill_ports</c> driver option is + set. In other words, this return value will always need + to be handled!</p> + </item> + <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, ref()}</em></tag> + <item> + <p>The load request is registered, but the loading is + delayed due to the fact that an earlier instance of the + driver is still waiting to get unloaded by another + <seealso marker="#users">user</seealso> (not only by a + port, in which case <c>{ok,pending_driver}</c> would + have been returned). Still, unload is expected when you + are done with the driver. This return value will + <em>only</em> happen when the <c>{reload,pending}</c> + option is used.</p> + </item> + </taglist> + <p>When the function returns <c>{ok, pending_driver}</c> or + <c>{ok, pending_process}</c>, one might want to get information + about when the driver is <em>actually</em> loaded. This can + be achieved by using the <c>{monitor, PendingOption}</c> option.</p> + <p>When monitoring is requested, and a corresponding <c>{ok, pending_driver}</c> or <c>{ok, pending_process}</c> would be + returned, the function will instead return a tuple <c>{ok, PendingStatus, ref()}</c> and the process will, at a later + time when the driver actually gets loaded, get a monitor + message. The monitor message one can expect is described in + the <seealso marker="#monitor/2">monitor/2</seealso> + function description. </p> + <note> + <p>Note that in case of loading, monitoring can + <em>not</em> only get triggered by using the <c>{reload, ReloadOption}</c> option, but also in special cases where + the load-error is transient, why <c>{monitor, pending_driver}</c> should be used under basically + <em>all</em> real world circumstances!</p> + </note> + <p>The function accepts the following parameters:</p> + <taglist> + <tag><em>Path</em></tag> + <item> + <p>The filesystem path to the directory where the driver + object file is situated. The filename of the object file + (minus extension) must correspond to the driver name + (used in the name parameter) and the driver must + identify itself with the very same name. The + <c>Path</c> might be provided as an <em>io_list</em>, + meaning it can be a list of other io_lists, characters + (eight bit integers) or binaries, all to be flattened + into a sequence of characters.</p> + <p>The (possibly flattened) <c>Path</c> parameter must be + consistent throughout the system, a driver should, by + all <seealso marker="#users">users</seealso>, be loaded + using the same <em>literal</em><c>Path</c>. The + exception is when <em>reloading</em> is requested, in + which case the <c>Path</c> may be specified + differently. Note that all <seealso marker="#users">users</seealso> trying to load the + driver at a later time will need to use the <em>new</em><c>Path</c> if the <c>Path</c> is changed using a + <c>reload</c> option. This is yet another reason + to have <em>only one loader</em> of a driver one wants to + upgrade in a running system! </p> + </item> + <tag><em>Name</em></tag> + <item> + <p>The name parameter is the name of the driver to be used + in subsequent calls to <seealso marker="erts:erlang#open_port/2">open_port</seealso>. The + name can be specified either as an <c>io_list()</c> or + as an <c>atom()</c>. The name given when loading is used + to find the actual object file (with the + help of the <c>Path</c> and the system implied + extension suffix, i.e. <c>.so</c>). The name by which + the driver identifies itself must also be consistent + with this <c>Name</c> parameter, much as a beam-file's + module name much correspond to it's filename.</p> + </item> + <tag><em>OptionList</em></tag> + <item> + <p>A number of options can be specified to control the + loading operation. The options are given as a list of + two-tuples, the tuples having the following values and + meanings:</p> + <taglist> + <tag><em>{driver_options, DriverOptionsList}</em></tag> + <item> + <p>This option is to provide options that will change + it's general behavior and will "stick" to the driver + throughout it's lifespan.</p> + <p>The driver options for a given driver name need + always to be consistent, <em>even when the driver is reloaded</em>, meaning that they are as much a part + of the driver as the actual name.</p> + <p>Currently the only allowed driver option is + <c>kill_ports</c>, which means that all ports opened + towards the driver are killed with the exit-reason + <c>driver_unloaded</c> when no process any longer + has the driver loaded. This situation arises either + when the last <seealso marker="#users">user</seealso> calls <seealso marker="#try_unload/2">try_unload/2</seealso>, or + the last process having loaded the driver exits.</p> + </item> + <tag><em>{monitor, MonitorOption}</em></tag> + <item> + <p>A <c>MonitorOption</c> tells <c>try_load/3</c> to + trigger a driver monitor under certain + conditions. When the monitor is triggered, the + function will return a three-tuple <c>{ok, PendingStatus, ref()}</c>, where the <c>ref()</c> is + the monitor ref for the driver monitor.</p> + <p>Only one <c>MonitorOption</c> can be specified and + it is either the atom <c>pending</c>, which means + that a monitor should be created whenever a load + operation is delayed, and the atom + <c>pending_driver</c>, in which a monitor is + created whenever the operation is delayed due to + open ports towards an otherwise unused driver. The + <c>pending_driver</c> option is of little use, but + is present for completeness, it is very well defined + which reload-options might give rise to which + delays. It might, however, be a good idea to use the + same <c>MonitorOption</c> as the <c>ReloadOption</c> + if present.</p> + <p>If reloading is not requested, it might still be + useful to specify the <c>monitor</c> option, as + forced unloads (<c>kill_ports</c> driver option or + the <c>kill_ports</c> option to <seealso marker="#try_unload/2">try_unload/2</seealso>) will + trigger a transient state where driver loading + cannot be performed until all closing ports are + actually closed. So, as <c>try_unload</c> can, in + almost all situations, return <c>{ok, pending_driver}</c>, one should always specify at least + <c>{monitor, pending_driver}</c> in production + code (see the monitor discussion above). </p> + </item> + <tag><em>{reload,RealoadOption}</em></tag> + <item> + <p>This option is used when one wants to + <em>reload</em> a driver from disk, most often in a + code upgrade scenario. Having a <c>reload</c> option + also implies that the <c>Path</c> parameter need + <em>not</em> be consistent with earlier loads of + the driver.</p> + <p>To reload a driver, the process needs to have previously + loaded the driver, i.e there has to be an active <seealso marker="#users">user</seealso> of the driver in the process. </p> + <p>The <c>reload</c> option can be either the atom + <c>pending</c>, in which reloading is requested for + any driver and will be effectuated when <em>all</em> + ports opened against the driver are closed. The + replacement of the driver will in this case take + place regardless of if there are still + pending <seealso marker="#users">users</seealso> + having the driver loaded! + The option also triggers port-killing (if the + <c>kill_ports</c> driver option is used) even though + there are pending users, making it usable for forced + driver replacement, but laying a lot of + responsibility on the driver <seealso marker="#users">users</seealso>. The pending option is + seldom used as one does not want other <seealso marker="#users">users</seealso> to have loaded the + driver when code change is underway. </p> + <p>The more useful option is <c>pending_driver</c>, + which means that reloading will be queued if the + driver is <em>not</em> loaded by any other <seealso marker="#users">users</seealso>, but the driver has + opened ports, in which case <c>{ok, pending_driver}</c> will be returned (a + <c>monitor</c> option is of course recommended).</p> + <p>If the driver is unloaded (not present in the + system), the error code + <c>not_loaded</c> will be returned. The + <c>reload</c> option is intended for when the user + has already loaded the driver in advance.</p> + </item> + </taglist> + </item> + </taglist> + <p>The function might return numerous errors, of which some + only can be returned given a certain combination of options.</p> + <p>A number of errors are opaque and can only be interpreted by + passing them to the <seealso marker="#format_error/1">format_error/1</seealso> function, + but some can be interpreted directly:</p> + <taglist> + <tag><em>{error,linked_in_driver}</em></tag> + <item> + <p>The driver with the specified name is an erlang + statically linked in driver, which cannot be manipulated + with this API.</p> + </item> + <tag><em>{error,inconsistent}</em></tag> + <item> + <p>The driver has already been loaded with either other + <c>DriverOptions</c> or a different <em>literal</em><c>Path</c> argument.</p> + <p>This can happen even if a <c>reload</c> option is given, + if the <c>DriverOptions</c> differ from the current.</p> + </item> + <tag><em>{error, permanent}</em></tag> + <item> + <p>The driver has requested itself to be permanent, making + it behave like an erlang linked in driver and it can no + longer be manipulated with this API.</p> + </item> + <tag><em>{error, pending_process}</em></tag> + <item> + <p>The driver is loaded by other <seealso marker="#users">users</seealso> when the <c>{reload, pending_driver}</c> option was given.</p> + </item> + <tag><em>{error, pending_reload}</em></tag> + <item> + <p>Driver reload is already requested by another <seealso marker="#users">user</seealso> when the <c>{reload, ReloadOption}</c> option was given.</p> + </item> + <tag><em>{error, not_loaded_by_this_process}</em></tag> + <item> + <p>Appears when the <c>reload</c> option is given. The + driver <c>Name</c> is present in the system, but there is no + <seealso marker="#users">user</seealso> of it in this + process.</p> + </item> + <tag><em>{error, not_loaded}</em></tag> + <item> + <p>Appears when the <c>reload</c> option is given. The + driver <c>Name</c> is not in the system. Only drivers + loaded by this process can be reloaded.</p> + </item> + </taglist> + <p>All other error codes are to be translated by the <seealso marker="#format_error/1">format_error/1</seealso> + function. Note that calls to <c>format_error</c> should be + performed from the same running instance of the erlang + virtual machine as the error was detected in, due to system + dependent behavior concerning error values.</p> + <p>If the arguments or options are malformed, the function will + throw a <c>badarg</c> exception.</p> + </desc> + </func> + <func> + <name>try_unload(Name, OptionList) -> {ok,Status} | {ok, PendingStatus, Ref} | {error, ErrorAtom}</name> + <fsummary>Unload a driver</fsummary> + <type> + <v>Name = string() | atom()</v> + <v>OptionList = [ Option ]</v> + <v>Option = {monitor, MonitorOption} | kill_ports</v> + <v>MonitorOption = pending_driver | pending</v> + <v>Status = unloaded | PendingStatus </v> + <v>PendingStatus = pending_driver | pending_process</v> + <v>Ref = ref()</v> + <v>ErrorAtom = linked_in_driver | not_loaded | not_loaded_by_this_process | permanent</v> + </type> + <desc> + <p>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 + <c>kill_ports</c> implicitly does, and it can trigger a + monitor either due to other <seealso marker="#users">users</seealso> still having the driver + loaded or that there are open ports using the driver.</p> + <p>Unloading can be described as the process of telling the + emulator that this particular part of the code in this + particular process (i.e. this <seealso marker="#users">user</seealso>) no longer needs the + driver. That can, if there are no other users, trigger + actual 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 the <c>kill_ports</c> option set, or if + <c>kill_ports</c> was specified as an option to this + function, all pending ports using this driver will get + killed when unloading is done by the last <seealso marker="#users">user</seealso>. If no port-killing is + involved and there are open ports, the actual unloading + is delayed until there are no more open ports using the + driver. If, in this case, another <seealso marker="#users">user</seealso> (or even this user) loads the + driver again before the driver is actually unloaded, the + unloading will never take place.</p> + <p>To allow the <seealso marker="#users">user</seealso> that + <em>requests unloading</em> to wait for <em>actual unloading</em> to + take place, <c>monitor</c> triggers can be specified in much + the same way as when loading. As <seealso marker="#users">users</seealso> of this function however + seldom are interested in more than decrementing the + reference counts, monitoring is more seldom needed. If the + <c>kill_ports</c> option is used however, monitor trigging is + crucial, as the ports are not guaranteed to have been killed + until the driver is unloaded, why a monitor should be + triggered for at least the <c>pending_driver</c> case.</p> + <p>The possible monitor messages that can be expected are the + same as when using the <c>unloaded</c> option to the + <seealso marker="#monitor/2">monitor/2</seealso> function.</p> + <p>The function will return one of the following statuses upon + success:</p> + <taglist> + <tag><em>{ok, unloaded}</em></tag> + <item> + <p>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.</p> + <p>The driver can only be unloaded when there are no open + ports using it and there are no more <seealso marker="#users">users</seealso> requiring it to be + loaded.</p> + </item> + <tag><em>{ok, pending_driver}</em>or <em>{ok, pending_driver, ref()}</em></tag> + <item> + <p>This return value indicates that this call removed the + last <seealso marker="#users">user</seealso> from the + driver, but there are still open ports using it. + When all ports are closed and no new <seealso marker="#users">users</seealso> have arrived, the driver + will actually be reloaded and the name and memory + reclaimed.</p> + <p>This return value is valid even when the option + <c>kill_ports</c> was used, as killing ports may not be + a process that completes immediately. The condition is, + in that case, however transient. Monitors are as always + useful to detect when the driver is really unloaded.</p> + </item> + <tag><em>{ok, pending_process}</em>or <em>{ok, pending_process, ref()}</em></tag> + <item> + <p>The unload request is registered, but there are still + other <seealso marker="#users">users</seealso> holding + the driver. Note that the term <c>pending_process</c> + might refer to the running process, there might be more + than one <seealso marker="#users">user</seealso> in the + same process.</p> + <p>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 actually the most + common return value in the most common <seealso marker="#scenarios">scenario</seealso> + described in the introduction.</p> + </item> + </taglist> + <p>The function accepts the following parameters:</p> + <taglist> + <tag><em>Name</em></tag> + <item> + <p>The name parameter is the name of the driver to be + unloaded. The name can be specified either as an + <c>io_list()</c> or as an <c>atom()</c>. </p> + </item> + <tag><em>OptionList</em></tag> + <item> + <p>The <c>OptionList</c> argument can be used to specify + certain behavior regarding ports as well as triggering + monitors under certain conditions:</p> + <taglist> + <tag><em>kill_ports</em></tag> + <item> + <p>Force killing of all ports opened using this driver, + with the exit reason <c>driver_unloaded</c>, if you are + the <em>last</em><seealso marker="#users">user</seealso> of the driver.</p> + <p>If there are other <seealso marker="#users">users</seealso> having the driver + loaded, this option will have no effect.</p> + <p>If one wants the consistent behavior of killing ports + when the last <seealso marker="#users">user</seealso> + unloads, one should use the driver option + <c>kill_ports</c> when loading the driver instead.</p> + </item> + <tag><em>{monitor, MonitorOption}</em></tag> + <item> + <p>This option creates a driver monitor if the condition + given in <c>MonitorOptions</c> is true. The valid + options are:</p> + <taglist> + <tag><em>pending_driver</em></tag> + <item> + <p>Create a driver monitor if the return value is to + be <c>{ok, pending_driver}</c>.</p> + </item> + <tag><em>pending</em></tag> + <item> + <p>Create a monitor if the return value will be either + <c>{ok, pending_driver}</c> or <c>{ok, pending_process}</c>.</p> + </item> + </taglist> + <p>The <c>pending_driver</c><c>MonitorOption</c> is by far + the most useful and it has to be used to ensure that the + driver has really been unloaded and the ports closed + whenever the <c>kill_ports</c> option is used or the + driver may have been loaded with the <c>kill_ports</c> + driver option.</p> + <p>By using the monitor-triggers in the call to + <c>try_unload</c> one can be sure that the monitor is + actually added before the unloading is executed, meaning + that the monitor will always get properly triggered, + which would not be the case if one called + <c>erl_ddll:monitor/2</c> separately.</p> + </item> + </taglist> + </item> + </taglist> + <p>The function may return several error conditions, of which + all are well specified (no opaque values):</p> + <taglist> + <tag><em>{error, linked_in_driver}</em></tag> + <item> + <p>You were trying to unload an erlang statically linked in + driver, which cannot be manipulated with this interface + (and cannot be unloaded at all).</p> + </item> + <tag><em>{error, not_loaded}</em></tag> + <item> + <p>The driver <c>Name</c> is not present in the system.</p> + </item> + <tag><em>{error, not_loaded_by_this_process}</em></tag> + <item> + <p>The driver <c>Name</c> is present in the system, but + there is no <seealso marker="#users">user</seealso> of + it in this process. </p> + <p>As a special case, drivers can be unloaded from + processes that has done no corresponding call to + <c>try_load/3</c> if, and only if, there are <em>no users of the driver at all</em>, which may happen if the + process containing the last user dies.</p> + </item> + <tag><em>{error, permanent}</em></tag> + <item> + <p>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).</p> + </item> + </taglist> + <p>The function throws a <c>badarg</c> exception if the + parameters are not given as described above. </p> + </desc> + </func> + <func> + <name>unload(Name) -> ok | {error, ErrorDesc}</name> + <fsummary>Unload a driver</fsummary> + <type> + <v>Name = string() | atom()</v> + <v>ErrorDesc = term()</v> + </type> + <desc> + <p>Unloads, or at least dereferences the driver named + <c>Name</c>. If the caller is the last <seealso marker="#users">user</seealso> of the driver, and there + are no more open ports using the driver, the driver will + actually get unloaded. In all other cases, actual unloading + will be delayed until all ports are closed and there are no + remaining <seealso marker="#users">users</seealso>.</p> + <p>If there are other <seealso marker="#users">users</seealso> 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 usage + scenarios, see the <seealso marker="#scenarios">description</seealso> in the beginning + of this document. </p> + <p>The <c>ErrorDesc</c> returned is an opaque value to be + passed further on to the <seealso marker="#format_error/1">format_error/1</seealso> + function. For more control over the operation, use the + <seealso marker="#try_unload/2">try_unload/2</seealso> + interface.</p> + <p>The function throws a <c>badarg</c> exception if the + parameters are not given as described above. </p> + </desc> + </func> + <func> + <name>unload_driver(Name) -> ok | {error, ErrorDesc}</name> + <fsummary>Unload a driver</fsummary> + <type> + <v>Name = string() | atom()</v> + <v>ErrorDesc = term()</v> + </type> + <desc> + <p>Unloads, or at least dereferences the driver named + <c>Name</c>. If the caller is the last <seealso marker="#users">user</seealso> of the driver, all + remaining open ports using the driver will get killed with + the reason <c>driver_unloaded</c> and the driver will + eventually get unloaded.</p> + <p>If there are other <seealso marker="#users">users</seealso> + of the driver, the reference counts of the driver is merely + decreased, so that the caller is no longer considered a + <seealso marker="#users">user</seealso>. For + usage scenarios, see the <seealso marker="#scenarios">description</seealso> in the beginning + of this document.</p> + <p>The <c>ErrorDesc</c> returned is an opaque value to be + passed further on to the <seealso marker="#format_error/1">format_error/1</seealso> + function. For more control over the operation, use the + <seealso marker="#try_unload/2">try_unload/2</seealso> + interface.</p> + <p>The function throws a <c>badarg</c> exception if the + parameters are not given as described above. </p> + </desc> + </func> + <func> + <name>loaded_drivers() -> {ok, Drivers}</name> + <fsummary>List loaded drivers</fsummary> + <type> + <v>Drivers = [Driver()]</v> + <v>Driver = string()</v> + </type> + <desc> + <p>Returns a list of all the available drivers, both + (statically) linked-in and dynamically loaded ones.</p> + <p>The driver names are returned as a list of strings rather + than a list of atoms for historical reasons.</p> + <p>More information about drivers can be obtained using one of + the <seealso marker="#info/0">info</seealso> functions.</p> + </desc> + </func> + <func> + <name>format_error(ErrorDesc) -> string()</name> + <fsummary>Format an error descriptor</fsummary> + <type> + <v>ErrorDesc -- see below</v> + </type> + <desc> + <p>Takes an <c>ErrorDesc</c> returned by load, unload or + reload functions and returns a string which + describes the error or warning.</p> + <note> + <p>Due to peculiarities in the dynamic loading interfaces on + different platform, the returned string is only guaranteed + to describe the correct error <em>if format_error/1 is called in the same instance of the erlang virtual machine as the error appeared in</em> (meaning the same operating + system process)!</p> + </note> + </desc> + </func> + </funcs> + + <section> + <title>SEE ALSO</title> + <p>erl_driver(4), driver_entry(4)</p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/erl_prim_loader_stub.xml b/lib/kernel/doc/src/erl_prim_loader_stub.xml new file mode 100644 index 0000000000..e6324b8168 --- /dev/null +++ b/lib/kernel/doc/src/erl_prim_loader_stub.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year> + <year>2009</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>erl_prim_loader</title> + <prepared>[email protected]</prepared> + <docno></docno> + <date>2008-12-16</date> + <rev>A</rev> + </header> + <module>erl_prim_loader</module> + <modulesummary>Low Level Erlang Loader</modulesummary> + <description><p> + + The module erl_prim_loader is moved to the runtime system + application. Please see <seealso + marker="erts:erl_prim_loader">erl_prim_loader(3)</seealso> in the + erts reference manual instead. + + </p></description> +</erlref> diff --git a/lib/kernel/doc/src/erlang_stub.xml b/lib/kernel/doc/src/erlang_stub.xml new file mode 100644 index 0000000000..333c4fedaf --- /dev/null +++ b/lib/kernel/doc/src/erlang_stub.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year> + <year>2009</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>erlang</title> + <prepared>[email protected]</prepared> + <docno></docno> + <date>2008-12-16</date> + <rev>A</rev> + </header> + <module>erlang</module> + <modulesummary>The Erlang BIFs</modulesummary> + <description><p> + + The module erlang is moved to the runtime system + application. Please see <seealso + marker="erts:erlang">erlang(3)</seealso> in the + erts reference manual instead. + + </p></description> +</erlref> diff --git a/lib/kernel/doc/src/error_handler.xml b/lib/kernel/doc/src/error_handler.xml new file mode 100644 index 0000000000..94824688d1 --- /dev/null +++ b/lib/kernel/doc/src/error_handler.xml @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year> + <year>2007</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>error_handler</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>error_handler</module> + <modulesummary>Default System Error Handler</modulesummary> + <description> + <p>The error handler module defines what happens when certain types + of errors occur.</p> + </description> + <funcs> + <func> + <name>undefined_function(Module, Function, Args) -> term()</name> + <fsummary>Called when an undefined function is encountered</fsummary> + <type> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <d>A (possibly empty) list of arguments <c>Arg1,..,ArgN</c></d> + </type> + <desc> + <p>This function is evaluated if a call is made to + <c>Module:Function(Arg1,.., ArgN)</c> and + <c>Module:Function/N</c> is undefined. Note that + <c>undefined_function/3</c> is evaluated inside the process + making the original call.</p> + <p>If <c>Module</c> is interpreted, the interpreter is invoked + and the return value of the interpreted + <c>Function(Arg1,.., ArgN)</c> call is returned.</p> + <p>Otherwise, it returns, if possible, the value of + <c>apply(Module, Function, Args)</c> after an attempt has been + made to autoload <c>Module</c>. If this is not possible, the + call to <c>Module:Function(Arg1,.., ArgN)</c> fails with + exit reason <c>undef</c>.</p> + </desc> + </func> + <func> + <name>undefined_lambda(Module, Fun, Args) -> term()</name> + <fsummary>Called when an undefined lambda (fun) is encountered</fsummary> + <type> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <d>A (possibly empty) list of arguments <c>Arg1,..,ArgN</c></d> + </type> + <desc> + <p>This function is evaluated if a call is made to + <c>Fun(Arg1,.., ArgN)</c> when the module defining the fun is + not loaded. The function is evaluated inside the process + making the original call.</p> + <p>If <c>Module</c> is interpreted, the interpreter is invoked + and the return value of the interpreted + <c>Fun(Arg1,.., ArgN)</c> call is returned.</p> + <p>Otherwise, it returns, if possible, the value of + <c>apply(Fun, Args)</c> after an attempt has been made to + autoload <c>Module</c>. If this is not possible, the call + fails with exit reason <c>undef</c>.</p> + </desc> + </func> + </funcs> + + <section> + <title>Notes</title> + <p>The code in <c>error_handler</c> is complex and should not be + changed without fully understanding the interaction between + the error handler, the <c>init</c> process of the code server, + and the I/O mechanism of the code.</p> + <p>Changes in the code which may seem small can cause a deadlock + as unforeseen consequences may occur. The use of <c>input</c> is + dangerous in this type of code.</p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/error_logger.xml b/lib/kernel/doc/src/error_logger.xml new file mode 100644 index 0000000000..e107d9b746 --- /dev/null +++ b/lib/kernel/doc/src/error_logger.xml @@ -0,0 +1,450 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>error_logger</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>error_logger</module> + <modulesummary>Erlang Error Logger</modulesummary> + <description> + <p>The Erlang <em>error logger</em> is an event manager (see + <seealso marker="doc/design_principles:des_princ">OTP Design Principles</seealso> and + <seealso marker="stdlib:gen_event">gen_event(3)</seealso>), + registered as <c>error_logger</c>. Error, warning and info events + are sent to the error logger from the Erlang runtime system and + the different Erlang/OTP applications. The events are, by default, + logged to tty. Note that an event from a process <c>P</c> is + logged at the node of the group leader of <c>P</c>. This means + that log output is directed to the node from which a process was + created, which not necessarily is the same node as where it is + executing.</p> + <p>Initially, <c>error_logger</c> only has a primitive event + handler, which buffers and prints the raw event messages. During + system startup, the application Kernel replaces this with a + <em>standard event handler</em>, by default one which writes + nicely formatted output to tty. Kernel can also be configured so + that events are logged to file instead, or not logged at all, see + <seealso marker="kernel_app">kernel(6)</seealso>.</p> + <p>Also the SASL application, if started, adds its own event + handler, which by default writes supervisor-, crash- and progress + reports to tty. See + <seealso marker="sasl:sasl_app">sasl(6)</seealso>.</p> + <p>It is recommended that user defined applications should report + errors through the error logger, in order to get uniform reports. + User defined event handlers can be added to handle application + specific events. (<c>add_report_handler/1,2</c>). Also, there is + a useful event handler in STDLIB for multi-file logging of events, + see <c>log_mf_h(3)</c>.</p> + <p>Warning events was introduced in Erlang/OTP R9C. To retain + backwards compatibility, these are by default tagged as errors, + thus showing up as error reports in the logs. By using + the command line flag <c><![CDATA[+W <w | i>]]></c>, they can instead + be tagged as warnings or info. Tagging them as warnings may + require rewriting existing user defined event handlers.</p> + </description> + <funcs> + <func> + <name>error_msg(Format) -> ok</name> + <name>error_msg(Format, Data) -> ok</name> + <name>format(Format, Data) -> ok</name> + <fsummary>Send an standard error event to the error logger</fsummary> + <type> + <v>Format = string()</v> + <v>Data = [term()]</v> + </type> + <desc> + <p>Sends a standard error event to the error logger. + The <c>Format</c> and <c>Data</c> arguments are the same as + the arguments of <c>io:format/2</c>. The event is handled by + the standard event handler.</p> + <pre> +1> <input>error_logger:error_msg("An error occurred in ~p~n", [a_module]).</input> + +=ERROR REPORT==== 11-Aug-2005::14:03:19 === +An error occurred in a_module +ok</pre> + <warning> + <p>If called with bad arguments, this function can crash + the standard event handler, meaning no further events are + logged. When in doubt, use <c>error_report/1</c> instead.</p> + </warning> + </desc> + </func> + <func> + <name>error_report(Report) -> ok</name> + <fsummary>Send a standard error report event to the error logger</fsummary> + <type> + <v>Report = [{Tag, Data} | term()] | string() | term()</v> + <v> Tag = Data = term()</v> + </type> + <desc> + <p>Sends a standard error report event to the error logger. + The event is handled by the standard event handler.</p> + <pre> +2> <input>error_logger:error_report([{tag1,data1},a_term,{tag2,data}]).</input> + +=ERROR REPORT==== 11-Aug-2005::13:45:41 === + tag1: data1 + a_term + tag2: data +ok +3> <input>error_logger:error_report("Serious error in my module").</input> + +=ERROR REPORT==== 11-Aug-2005::13:45:49 === +Serious error in my module +ok</pre> + </desc> + </func> + <func> + <name>error_report(Type, Report) -> ok</name> + <fsummary>Send a user defined error report event to the error logger</fsummary> + <type> + <v>Type = term()</v> + <v>Report = [{Tag, Data} | term()] | string() | term()</v> + <v> Tag = Data = term()</v> + </type> + <desc> + <p>Sends a user defined error report event to the error logger. + An event handler to handle the event is supposed to have been + added. The event is ignored by the standard event handler.</p> + <p>It is recommended that <c>Report</c> follows the same + structure as for <c>error_report/1</c>.</p> + </desc> + </func> + <func> + <name>warning_map() -> Tag</name> + <fsummary>Return the current mapping for warning events</fsummary> + <type> + <v>Tag = error | warning | info</v> + </type> + <desc> + <p>Returns the current mapping for warning events. Events sent + using <c>warning_msg/1,2</c> or <c>warning_report/1,2</c> + are tagged as errors (default), warnings or info, depending + on the value of the command line flag <c>+W</c>.</p> + <pre> +os$ <input>erl</input> +Erlang (BEAM) emulator version 5.4.8 [hipe] [threads:0] [kernel-poll] + +Eshell V5.4.8 (abort with ^G) +1> <input>error_logger:warning_map().</input> +error +2> <input>error_logger:warning_msg("Warnings tagged as: ~p~n", [error]).</input> + +=ERROR REPORT==== 11-Aug-2005::15:31:23 === +Warnings tagged as: error +ok +3> +User switch command + --> q +os$ <input>erl +W w</input> +Erlang (BEAM) emulator version 5.4.8 [hipe] [threads:0] [kernel-poll] + +Eshell V5.4.8 (abort with ^G) +1> <input>error_logger:warning_map().</input> +warning +2> <input>error_logger:warning_msg("Warnings tagged as: ~p~n", [warning]).</input> + +=WARNING REPORT==== 11-Aug-2005::15:31:55 === +Warnings tagged as: warning +ok</pre> + </desc> + </func> + <func> + <name>warning_msg(Format) -> ok</name> + <name>warning_msg(Format, Data) -> ok</name> + <fsummary>Send a standard warning event to the error logger</fsummary> + <type> + <v>Format = string()</v> + <v>Data = [term()]</v> + </type> + <desc> + <p>Sends a standard warning event to the error logger. + The <c>Format</c> and <c>Data</c> arguments are the same as + the arguments of <c>io:format/2</c>. The event is handled by + the standard event handler. It is tagged either as an error, + warning or info, see + <seealso marker="#warning_map/0">warning_map/0</seealso>.</p> + <warning> + <p>If called with bad arguments, this function can crash + the standard event handler, meaning no further events are + logged. When in doubt, use <c>warning_report/1</c> instead.</p> + </warning> + </desc> + </func> + <func> + <name>warning_report(Report) -> ok</name> + <fsummary>Send a standard warning report event to the error logger</fsummary> + <type> + <v>Report = [{Tag, Data} | term()] | string() | term()</v> + <v> Tag = Data = term()</v> + </type> + <desc> + <p>Sends a standard warning report event to the error logger. + The event is handled by the standard event handler. It is + tagged either as an error, warning or info, see + <seealso marker="#warning_map/0">warning_map/0</seealso>.</p> + </desc> + </func> + <func> + <name>warning_report(Type, Report) -> ok</name> + <fsummary>Send a user defined warning report event to the error logger</fsummary> + <type> + <v>Type = term()</v> + <v>Report = [{Tag, Data} | term()] | string() | term()</v> + <v> Tag = Data = term()</v> + </type> + <desc> + <p>Sends a user defined warning report event to the error + logger. An event handler to handle the event is supposed to + have been added. The event is ignored by the standard event + handler. It is tagged either as an error, warning or info, + depending on the value of + <seealso marker="#warning_map/0">warning_map/0</seealso>.</p> + </desc> + </func> + <func> + <name>info_msg(Format) -> ok</name> + <name>info_msg(Format, Data) -> ok</name> + <fsummary>Send a standard information event to the error logger</fsummary> + <type> + <v>Format = string()</v> + <v>Data = [term()]</v> + </type> + <desc> + <p>Sends a standard information event to the error logger. + The <c>Format</c> and <c>Data</c> arguments are the same as + the arguments of <c>io:format/2</c>. The event is handled by + the standard event handler.</p> + <pre> +1> <input>error_logger:info_msg("Something happened in ~p~n", [a_module]).</input> + +=INFO REPORT==== 11-Aug-2005::14:06:15 === +Something happened in a_module +ok</pre> + <warning> + <p>If called with bad arguments, this function can crash + the standard event handler, meaning no further events are + logged. When in doubt, use <c>info_report/1</c> instead.</p> + </warning> + </desc> + </func> + <func> + <name>info_report(Report) -> ok</name> + <fsummary>Send a standard information report event to the error logger</fsummary> + <type> + <v>Report = [{Tag, Data} | term()] | string() | term()</v> + <v> Tag = Data = term()</v> + </type> + <desc> + <p>Sends a standard information report event to the error + logger. The event is handled by the standard event handler.</p> + <pre> +2> <input>error_logger:info_report([{tag1,data1},a_term,{tag2,data}]).</input> + +=INFO REPORT==== 11-Aug-2005::13:55:09 === + tag1: data1 + a_term + tag2: data +ok +3> <input>error_logger:info_report("Something strange happened").</input> + +=INFO REPORT==== 11-Aug-2005::13:55:36 === +Something strange happened +ok</pre> + </desc> + </func> + <func> + <name>info_report(Type, Report) -> ok</name> + <fsummary>Send a user defined information report event to the error logger</fsummary> + <type> + <v>Type = term()</v> + <v>Report = [{Tag, Data} | term()] | string() | term()</v> + <v> Tag = Data = term()</v> + </type> + <desc> + <p>Sends a user defined information report event to the error + logger. An event handler to handle the event is supposed to + have been added. The event is ignored by the standard event + handler.</p> + <p>It is recommended that <c>Report</c> follows the same + structure as for <c>info_report/1</c>.</p> + </desc> + </func> + <func> + <name>add_report_handler(Handler) -> Result</name> + <name>add_report_handler(Handler, Args) -> Result</name> + <fsummary>Add an event handler to the error logger</fsummary> + <type> + <v>Handler, Args, Result -- see gen_event:add_handler/3</v> + </type> + <desc> + <p>Adds a new event handler to the error logger. The event + handler must be implemented as a <c>gen_event</c> callback + module, see + <seealso marker="stdlib:gen_event">gen_event(3)</seealso>.</p> + <p><c>Handler</c> is typically the name of the callback module + and <c>Args</c> is an optional term (defaults to []) passed + to the initialization callback function <c>Module:init/1</c>. + The function returns <c>ok</c> if successful.</p> + <p>The event handler must be able to handle the + <seealso marker="#events">events</seealso> described below.</p> + </desc> + </func> + <func> + <name>delete_report_handler(Handler) -> Result</name> + <fsummary>Delete an event handler from the error logger</fsummary> + <type> + <v>Handler, Result -- see gen_event:delete_handler/3</v> + </type> + <desc> + <p>Deletes an event handler from the error logger by calling + <c>gen_event:delete_handler(error_logger, Handler, [])</c>, + see <seealso marker="stdlib:gen_event">gen_event(3)</seealso>.</p> + </desc> + </func> + <func> + <name>tty(Flag) -> ok</name> + <fsummary>Enable or disable printouts to the tty</fsummary> + <type> + <v>Flag = bool()</v> + </type> + <desc> + <p>Enables (<c>Flag == true</c>) or disables + (<c>Flag == false</c>) printout of standard events to the tty.</p> + <p>This is done by adding or deleting the standard event handler + for output to tty, thus calling this function overrides + the value of the Kernel <c>error_logger</c> configuration + parameter.</p> + </desc> + </func> + <func> + <name>logfile(Request) -> ok | Filename | {error, What}</name> + <fsummary>Enable or disable error printouts to a file</fsummary> + <type> + <v>Request = {open, Filename} | close | filename</v> + <v> Filename = atom() | string()</v> + <v>What = allready_have_logfile | no_log_file | term()</v> + </type> + <desc> + <p>Enables or disables printout of standard events to a file.</p> + <p>This is done by adding or deleting the standard event handler + for output to file, thus calling this function overrides + the value of the Kernel <c>error_logger</c> configuration + parameter.</p> + <p>Enabling file logging can be used in combination with calling + <c>tty(false)</c>, in order to have a silent system, where + all standard events are logged to a file only. + There can only be one active log file at a time.</p> + <p><c>Request</c> is one of:</p> + <taglist> + <tag><c>{open, Filename}</c></tag> + <item> + <p>Opens the log file <c>Filename</c>. Returns <c>ok</c> if + successful, or <c>{error, allready_have_logfile}</c> if + logging to file is already enabled, or an error tuple if + another error occurred. For example, if <c>Filename</c> + could not be opened.</p> + </item> + <tag><c>close</c></tag> + <item> + <p>Closes the current log file. Returns <c>ok</c>, or + <c>{error, What}</c>.</p> + </item> + <tag><c>filename</c></tag> + <item> + <p>Returns the name of the log file <c>Filename</c>, or + <c>{error, no_log_file}</c> if logging to file is not + enabled.</p> + </item> + </taglist> + </desc> + </func> + </funcs> + + <section> + <marker id="events"></marker> + <title>Events</title> + <p>All event handlers added to the error logger must handle + the following events. <c>Gleader</c> is the group leader pid of + the process which sent the event, and <c>Pid</c> is the process + which sent the event.</p> + <taglist> + <tag><c>{error, Gleader, {Pid, Format, Data}}</c></tag> + <item> + <p>Generated when <c>error_msg/1,2</c> or <c>format</c> is + called.</p> + </item> + <tag><c>{error_report, Gleader, {Pid, std_error, Report}}</c></tag> + <item> + <p>Generated when <c>error_report/1</c> is called.</p> + </item> + <tag><c>{error_report, Gleader, {Pid, Type, Report}}</c></tag> + <item> + <p>Generated when <c>error_report/2</c> is called.</p> + </item> + <tag><c>{warning_msg, Gleader, {Pid, Format, Data}}</c></tag> + <item> + <p>Generated when <c>warning_msg/1,2</c> is called, provided + that warnings are set to be tagged as warnings.</p> + </item> + <tag><c>{warning_report, Gleader, {Pid, std_warning, Report}}</c></tag> + <item> + <p>Generated when <c>warning_report/1</c> is called, provided + that warnings are set to be tagged as warnings.</p> + </item> + <tag><c>{warning_report, Gleader, {Pid, Type, Report}}</c></tag> + <item> + <p>Generated when <c>warning_report/2</c> is called, provided + that warnings are set to be tagged as warnings.</p> + </item> + <tag><c>{info_msg, Gleader, {Pid, Format, Data}}</c></tag> + <item> + <p>Generated when <c>info_msg/1,2</c> is called.</p> + </item> + <tag><c>{info_report, Gleader, {Pid, std_info, Report}}</c></tag> + <item> + <p>Generated when <c>info_report/1</c> is called.</p> + </item> + <tag><c>{info_report, Gleader, {Pid, Type, Report}}</c></tag> + <item> + <p>Generated when <c>info_report/2</c> is called.</p> + </item> + </taglist> + <p>Note that also a number of system internal events may be + received, a catch-all clause last in the definition of + the event handler callback function <c>Module:handle_event/2</c> + is necessary. This also holds true for + <c>Module:handle_info/2</c>, as there are a number of system + internal messages the event handler must take care of as well.</p> + </section> + + <section> + <title>SEE ALSO</title> + <p>gen_event(3), log_mf_h(3), kernel(6), sasl(6)</p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/fascicules.xml b/lib/kernel/doc/src/fascicules.xml new file mode 100644 index 0000000000..43090b4aed --- /dev/null +++ b/lib/kernel/doc/src/fascicules.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE fascicules SYSTEM "fascicules.dtd"> + +<fascicules> + <fascicule file="ref_man" href="ref_man_frame.html" entry="yes"> + Reference Manual + </fascicule> + <fascicule file="part_notes" href="part_notes_frame.html" entry="no"> + Release Notes + </fascicule> + <fascicule file="" href="../../../../doc/print.html" entry="no"> + Off-Print + </fascicule> +</fascicules> + diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml new file mode 100644 index 0000000000..2303617542 --- /dev/null +++ b/lib/kernel/doc/src/file.xml @@ -0,0 +1,2002 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>file</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>file</module> + <modulesummary>File Interface Module</modulesummary> + <description> + <p>The module <c>file</c> provides an interface to the file system.</p> + <p>On operating systems with thread support, it is possible to let + file operations be performed in threads of their own, allowing + other Erlang processes to continue executing in parallel with + the file operations. See the command line flag + <c>+A</c> in <seealso marker="erts:erl">erl(1)</seealso>.</p> + </description> + + <section> + <title>DATA TYPES</title> + <code type="none"> +iodata() = iolist() | binary() + iolist() = [char() | binary() | iolist()] + +io_device() + as returned by file:open/2, a process handling IO protocols + +name() = string() | atom() | DeepList + DeepList = [char() | atom() | DeepList] + +posix() + an atom which is named from the POSIX error codes used in + Unix, and in the runtime libraries of most C compilers + +ext_posix() = posix() | badarg + +time() = {{Year, Month, Day}, {Hour, Minute, Second}} + Year = Month = Day = Hour = Minute = Second = int() + Must denote a valid date and time</code> + </section> + <funcs> + <func> + <name>change_group(Filename, Gid) -> ok | {error, Reason}</name> + <fsummary>Change group of a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Gid = int()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Changes group of a file. See + <seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p> + </desc> + </func> + <func> + <name>change_owner(Filename, Uid) -> ok | {error, Reason}</name> + <fsummary>Change owner of a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Uid = int()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Changes owner of a file. See + <seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p> + </desc> + </func> + <func> + <name>change_owner(Filename, Uid, Gid) -> ok | {error, Reason}</name> + <fsummary>Change owner and group of a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Uid = int()</v> + <v>Gid = int()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Changes owner and group of a file. See + <seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p> + </desc> + </func> + <func> + <name>change_time(Filename, Mtime) -> ok | {error, Reason}</name> + <fsummary>Change the modification time of a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Mtime = time()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Changes the modification and access times of a file. See + <seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p> + </desc> + </func> + <func> + <name>change_time(Filename, Mtime, Atime) -> ok | {error, Reason}</name> + <fsummary>Change the modification and last access time of a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Mtime = Atime = time()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Changes the modification and last access times of a file. See + <seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p> + </desc> + </func> + <func> + <name>close(IoDevice) -> ok | {error, Reason}</name> + <fsummary>Close a file</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Closes the file referenced by <c>IoDevice</c>. It mostly + returns <c>ok</c>, expect for some severe errors such as out + of memory.</p> + <p>Note that if the option <c>delayed_write</c> was + used when opening the file, <c>close/1</c> might return an + old write error and not even try to close the file. See + <seealso marker="#open/2">open/2</seealso>.</p> + </desc> + </func> + <func> + <name>consult(Filename) -> {ok, Terms} | {error, Reason}</name> + <fsummary>Read Erlang terms from a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Terms = [term()]</v> + <v>Reason = ext_posix() | terminated | system_limit + | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see below</v> + </type> + <desc> + <p>Reads Erlang terms, separated by '.', from <c>Filename</c>. + Returns one of the following:</p> + <taglist> + <tag><c>{ok, Terms}</c></tag> + <item> + <p>The file was successfully read.</p> + </item> + <tag><c>{error, atom()}</c></tag> + <item> + <p>An error occurred when opening the file or reading it. + See <seealso marker="#open/2">open/2</seealso> for a list + of typical error codes.</p> + </item> + <tag><c>{error, {Line, Mod, Term}}</c></tag> + <item> + <p>An error occurred when interpreting the Erlang terms in + the file. Use <c>format_error/1</c> to convert + the three-element tuple to an English description of + the error.</p> + </item> + </taglist> + <p>Example:</p> + <code type="none"> +f.txt: {person, "kalle", 25}. + {person, "pelle", 30}.</code> + <pre> +1> <input>file:consult("f.txt").</input> +{ok,[{person,"kalle",25},{person,"pelle",30}]}</pre> + </desc> + </func> + <func> + <name>copy(Source, Destination) -></name> + <name>copy(Source, Destination, ByteCount) -> {ok, BytesCopied} | {error, Reason}</name> + <fsummary>Copy file contents</fsummary> + <type> + <v>Source = Destination = io_device() | Filename | {Filename, Modes}</v> + <v> Filename = name()</v> + <v> Modes = [Mode] -- see open/2</v> + <v>ByteCount = int() >= 0 | infinity</v> + <v>BytesCopied = int()</v> + </type> + <desc> + <p>Copies <c>ByteCount</c> bytes from <c>Source</c> to + <c>Destination</c>. <c>Source</c> and <c>Destination</c> refer + to either filenames or IO devices from e.g. <c>open/2</c>. + <c>ByteCount</c> defaults <c>infinity</c>, denoting an + infinite number of bytes.</p> + <p>The argument <c>Modes</c> is a list of possible modes, see + <seealso marker="#open/2">open/2</seealso>, and defaults to + [].</p> + <p>If both <c>Source</c> and <c>Destination</c> refer to + filenames, the files are opened with <c>[read, binary]</c> + and <c>[write, binary]</c> prepended to their mode lists, + respectively, to optimize the copy.</p> + <p>If <c>Source</c> refers to a filename, it is opened with + <c>read</c> mode prepended to the mode list before the copy, + and closed when done.</p> + <p>If <c>Destination</c> refers to a filename, it is opened + with <c>write</c> mode prepended to the mode list before + the copy, and closed when done.</p> + <p>Returns <c>{ok, BytesCopied}</c> where <c>BytesCopied</c> is + the number of bytes that actually was copied, which may be + less than <c>ByteCount</c> if end of file was encountered on + the source. If the operation fails, <c>{error, Reason}</c> is + returned.</p> + <p>Typical error reasons: As for <c>open/2</c> if a file had to + be opened, and as for <c>read/2</c> and <c>write/2</c>.</p> + </desc> + </func> + <func> + <name>del_dir(Dir) -> ok | {error, Reason}</name> + <fsummary>Delete a directory</fsummary> + <type> + <v>Dir = name()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Tries to delete the directory <c>Dir</c>. The directory must + be empty before it can be deleted. Returns <c>ok</c> if + successful.</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>eacces</c></tag> + <item> + <p>Missing search or write permissions for the parent + directories of <c>Dir</c>.</p> + </item> + <tag><c>eexist</c></tag> + <item> + <p>The directory is not empty.</p> + </item> + <tag><c>enoent</c></tag> + <item> + <p>The directory does not exist.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p>A component of <c>Dir</c> is not a directory. On some + platforms, <c>enoent</c> is returned instead.</p> + </item> + <tag><c>einval</c></tag> + <item> + <p>Attempt to delete the current directory. On some + platforms, <c>eacces</c> is returned instead.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>delete(Filename) -> ok | {error, Reason}</name> + <fsummary>Delete a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Tries to delete the file <c>Filename</c>. Returns <c>ok</c> + if successful.</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>enoent</c></tag> + <item> + <p>The file does not exist.</p> + </item> + <tag><c>eacces</c></tag> + <item> + <p>Missing permission for the file or one of its parents.</p> + </item> + <tag><c>eperm</c></tag> + <item> + <p>The file is a directory and the user is not super-user.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p>A component of the file name is not a directory. On some + platforms, <c>enoent</c> is returned instead.</p> + </item> + <tag><c>einval</c></tag> + <item> + <p><c>Filename</c> had an improper type, such as tuple.</p> + </item> + </taglist> + <warning> + <p>In a future release, a bad type for the <c>Filename</c> + argument will probably generate an exception.</p> + <p></p> + </warning> + </desc> + </func> + <func> + <name>eval(Filename) -> ok | {error, Reason}</name> + <fsummary>Evaluate Erlang expressions in a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Reason = ext_posix() | terminated | system_limit + | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see below</v> + </type> + <desc> + <p>Reads and evaluates Erlang expressions, separated by '.' (or + ',', a sequence of expressions is also an expression), from + <c>Filename</c>. The actual 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:</p> + <taglist> + <tag><c>ok</c></tag> + <item> + <p>The file was read and evaluated.</p> + </item> + <tag><c>{error, atom()}</c></tag> + <item> + <p>An error occurred when opening the file or reading it. + See <c>open/2</c> for a list of typical error codes.</p> + </item> + <tag><c>{error, {Line, Mod, Term}}</c></tag> + <item> + <p>An error occurred when interpreting the Erlang + expressions in the file. Use <c>format_error/1</c> to + convert the three-element tuple to an English description + of the error.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>eval(Filename, Bindings) -> ok | {error, Reason}</name> + <fsummary>Evaluate Erlang expressions in a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Bindings -- see erl_eval(3)</v> + <v>Reason = ext_posix() | terminated | system_limit + | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see eval/1</v> + </type> + <desc> + <p>The same as <c>eval/1</c> but the variable bindings + <c>Bindings</c> are used in the evaluation. See + <seealso marker="stdlib:erl_eval">erl_eval(3)</seealso> about + variable bindings.</p> + </desc> + </func> + <func> + <name>file_info(Filename) -> {ok, FileInfo} | {error, Reason}</name> + <fsummary>Get information about a file (deprecated)</fsummary> + <desc> + <p>This function is obsolete. Use <c>read_file_info/1</c> + instead.</p> + </desc> + </func> + <func> + <name>format_error(Reason) -> Chars</name> + <fsummary>Return a descriptive string for an error reason</fsummary> + <type> + <v>Reason = atom() | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see eval/1</v> + <v>Chars = [char() | Chars]</v> + </type> + <desc> + <p>Given the error reason returned by any function in this + module, returns a descriptive string of the error in English.</p> + </desc> + </func> + <func> + <name>get_cwd() -> {ok, Dir} | {error, Reason}</name> + <fsummary>Get the current working directory</fsummary> + <type> + <v>Dir = string()</v> + <v>Reason = posix()</v> + </type> + <desc> + <p>Returns <c>{ok, Dir}</c>, where <c>Dir</c> is the current + working directory of the file server.</p> + <note> + <p>In rare circumstances, this function can fail on Unix. + It may happen if read permission does not exist for + the parent directories of the current directory.</p> + </note> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>eacces</c></tag> + <item> + <p>Missing read permission for one of the parents of + the current directory.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>get_cwd(Drive) -> {ok, Dir} | {error, Reason}</name> + <fsummary>Get the current working directory for the drive specified</fsummary> + <type> + <v>Drive = string() -- see below</v> + <v>Dir = string()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p><c>Drive</c> should be of the form "<c>Letter</c><c>:</c>", + for example "c:". Returns <c>{ok, Dir}</c> or + <c>{error, Reason}</c>, where <c>Dir</c> is the current + working directory of the drive specified.</p> + <p>This function returns <c>{error, enotsup}</c> on platforms + which have no concept of current drive (Unix, for example).</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>enotsup</c></tag> + <item> + <p>The operating system have no concept of drives.</p> + </item> + <tag><c>eacces</c></tag> + <item> + <p>The drive does not exist.</p> + </item> + <tag><c>einval</c></tag> + <item> + <p>The format of <c>Drive</c> is invalid.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>list_dir(Dir) -> {ok, Filenames} | {error, Reason}</name> + <fsummary>List files in a directory</fsummary> + <type> + <v>Dir = name()</v> + <v>Filenames = [Filename]</v> + <v> Filename = string()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Lists all the files in a directory. Returns + <c>{ok, Filenames}</c> if successful. Otherwise, it returns + <c>{error, Reason}</c>. <c>Filenames</c> is a list of + the names of all the files in the directory. The names are + not sorted.</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>eacces</c></tag> + <item> + <p>Missing search or write permissions for <c>Dir</c> or + one of its parent directories.</p> + </item> + <tag><c>enoent</c></tag> + <item> + <p>The directory does not exist.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>make_dir(Dir) -> ok | {error, Reason}</name> + <fsummary>Make a directory</fsummary> + <type> + <v>Dir = name()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Tries to create the directory <c>Dir</c>. Missing parent + directories are <em>not</em> created. Returns <c>ok</c> if + successful.</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>eacces</c></tag> + <item> + <p>Missing search or write permissions for the parent + directories of <c>Dir</c>.</p> + </item> + <tag><c>eexist</c></tag> + <item> + <p>There is already a file or directory named <c>Dir</c>.</p> + </item> + <tag><c>enoent</c></tag> + <item> + <p>A component of <c>Dir</c> does not exist.</p> + </item> + <tag><c>enospc</c></tag> + <item> + <p>There is a no space left on the device.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p>A component of <c>Dir</c> is not a directory. On some + platforms, <c>enoent</c> is returned instead.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>make_link(Existing, New) -> ok | {error, Reason}</name> + <fsummary>Make a hard link to a file</fsummary> + <type> + <v>Existing = New = name()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Makes a hard link from <c>Existing</c> to <c>New</c>, on + platforms that support links (Unix). This function returns + <c>ok</c> if the link was successfully created, or + <c>{error, Reason}</c>. On platforms that do not support + links, <c>{error,enotsup}</c> is returned.</p> + <p>Typical error reasons:</p> + <taglist> + <tag><c>eacces</c></tag> + <item> + <p>Missing read or write permissions for the parent + directories of <c>Existing</c> or <c>New</c>.</p> + </item> + <tag><c>eexist</c></tag> + <item> + <p><c>New</c> already exists.</p> + </item> + <tag><c>enotsup</c></tag> + <item> + <p>Hard links are not supported on this platform.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>make_symlink(Name1, Name2) -> ok | {error, Reason}</name> + <fsummary>Make a symbolic link to a file or directory</fsummary> + <type> + <v>Name1 = Name2 = name()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>This function creates a symbolic link <c>Name2</c> to + the file or directory <c>Name1</c>, on platforms that support + symbolic links (most Unix systems). <c>Name1</c> need not + exist. This function returns <c>ok</c> if the link was + successfully created, or <c>{error, Reason}</c>. On platforms + that do not support symbolic links, <c>{error, enotsup}</c> + is returned.</p> + <p>Typical error reasons:</p> + <taglist> + <tag><c>eacces</c></tag> + <item> + <p>Missing read or write permissions for the parent + directories of <c>Name1</c> or <c>Name2</c>.</p> + </item> + <tag><c>eexist</c></tag> + <item> + <p><c>Name2</c> already exists.</p> + </item> + <tag><c>enotsup</c></tag> + <item> + <p>Symbolic links are not supported on this platform.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>open(Filename, Modes) -> {ok, IoDevice} | {error, Reason}</name> + <fsummary>Open a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Modes = [Mode]</v> + <v> Mode = read | write | append | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed</v> + <v> Size = Delay = int()</v> + <v>IoDevice = io_device()</v> + <v>Reason = ext_posix() | system_limit</v> + </type> + <desc> + <p>Opens the file <c>Filename</c> in the mode determined by + <c>Modes</c>, which may contain one or more of the following + items:</p> + <taglist> + <tag><c>read</c></tag> + <item> + <p>The file, which must exist, is opened for reading.</p> + </item> + <tag><c>write</c></tag> + <item> + <p>The file is opened for writing. It is created if it does + not exist. If the file exists, and if <c>write</c> is not + combined with <c>read</c>, the file will be truncated.</p> + </item> + <tag><c>append</c></tag> + <item> + <p>The file will be opened for writing, and it will be + created if it does not exist. Every write operation to a + file opened with <c>append</c> will take place at + the end of the file.</p> + </item> + <tag><c>raw</c></tag> + <item> + <p>The <c>raw</c> option allows faster access to a file, + because no Erlang process is needed to handle the file. + However, a file opened in this way has the following + limitations:</p> + <list type="bulleted"> + <item>The functions in the <c>io</c> module cannot be used, + because they can only talk to an Erlang process. + Instead, use the <c>read/2</c>, <c>read_line/1</c> and + <c>write/2</c> + functions.</item> + <item>Especially if <c>read_line/1</c> is to be used on a <c>raw</c> file, it is recommended to combine this option with the <c>{read_ahead, Size}</c> option as line oriented I/O is inefficient without buffering.</item> + <item>Only the Erlang process which opened the file can use + it.</item> + <item>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).</item> + </list> + </item> + <tag><c>binary</c></tag> + <item> + <p>When this option has been given, read operations on the file + will return binaries rather than lists.</p> + </item> + <tag><c>{delayed_write, Size, Delay}</c></tag> + <item> + <p>If this option is used, the data in subsequent + <c>write/2</c> calls is buffered until there are at least + <c>Size</c> bytes buffered, or until the oldest buffered + data is <c>Delay</c> 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 <c>write/2</c> is executed.</p> + <p>The purpose of this option is to increase performance + by reducing the number of operating system calls, so the + <c>write/2</c> calls should be for sizes significantly + less than <c>Size</c>, and not interspersed by to many + other file operations, for this to happen.</p> + <p>When this option is used, the result of <c>write/2</c> + calls may prematurely be reported as successful, and if + a write error should actually occur the error is + reported as the result of the next file operation, which + is not executed.</p> + <p>For example, when <c>delayed_write</c> is used, after a + number of <c>write/2</c> calls, <c>close/1</c> might + return <c>{error, enospc}</c> because there was not enough + space on the disc for previously written data, and + <c>close/1</c> should probably be called again since the + file is still open.</p> + </item> + <tag><c>delayed_write</c></tag> + <item> + <p>The same as <c>{delayed_write, Size, Delay}</c> with + reasonable default values for <c>Size</c> and + <c>Delay</c>. (Roughly some 64 KBytes, 2 seconds)</p> + </item> + <tag><c>{read_ahead, Size}</c></tag> + <item> + <p>This option activates read data buffering. If + <c>read/2</c> calls are for significantly less than + <c>Size</c> bytes, read operations towards the operating + system are still performed for blocks of <c>Size</c> + bytes. The extra data is buffered and returned in + subsequent <c>read/2</c> calls, giving a performance gain + since the number of operating system calls is reduced.</p> + <p>The <c>read_ahead</c> buffer is also highly utilized + by the <c>read_line/1</c> function in <c>raw</c> mode, + why this option is recommended (for performance reasons) + when accessing raw files using that function.</p> + <p>If <c>read/2</c> calls are for sizes not significantly + less than, or even greater than <c>Size</c> bytes, no + performance gain can be expected.</p> + </item> + <tag><c>read_ahead</c></tag> + <item> + <p>The same as <c>{read_ahead, Size}</c> with a reasonable + default value for <c>Size</c>. (Roughly some 64 KBytes)</p> + </item> + <tag><c>compressed</c></tag> + <item> + <p>Makes it possible to read or write gzip compressed + files. The <c>compressed</c> option must be combined + with either <c>read</c> or <c>write</c>, but not both. + Note that the file size obtained with + <c>read_file_info/1</c> will most probably not match the + number of bytes that can be read from a compressed file.</p> + </item> + <tag><c>{encoding, Encoding}</c></tag> + <item> + <p>Makes the file perform automatic translation of characters to and from a specific (Unicode) encoding. Note that the data supplied to file:write or returned by file:read still is byte oriented, this option only denotes how data is actually stored in the disk file.</p> + <p>Depending on the encoding, different methods of reading and writing data is preferred. The default encoding of <c>latin1</c> implies using this (the file) module for reading and writing data, as the interfaces provided here work with byte-oriented data, while using other (Unicode) encodings makes the <seealso marker="stdlib:io">io(3)</seealso> module's <c>get_chars</c>, <c>get_line</c> and <c>put_chars</c> functions more suitable, as they can work with the full Unicode range.</p> + <p>If data is sent to an <c>io_device()</c> 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 will be closed.</p> + <p>The allowed values for <c>Encoding</c> are:</p> + <taglist> + <tag><c>latin1</c></tag> + <item> + <p>The default encoding. Bytes supplied to i.e. file:write are written as is on the file, likewise bytes read from the file are returned to i.e. file:read as is. If the <seealso marker="stdlib:io">io(3)</seealso> module is used for writing, the file can only cope with Unicode characters up to codepoint 255 (the ISO-latin-1 range).</p> + </item> + <tag><c>unicode</c> or <c>utf8</c></tag> + <item> + <p>Characters are translated to and from the UTF-8 encoding before being written to or read from the file. A file opened in this way might be readable using the file:read function, as long as no data stored on the file lies beyond the ISO-latin-1 range (0..255), but failure will occur if the data contains Unicode codepoints beyond that range. The file is best read with the functions in the Unicode aware <seealso marker="stdlib:io">io(3)</seealso> module.</p> + <p>Bytes written to the file by any means are translated to UTF-8 encoding before actually being stored on the disk file.</p> + </item> + <tag><c>utf16</c> or <c>{utf16,big}</c></tag> + <item> + <p>Works like <c>unicode</c>, but translation is done to and from big endian UTF-16 instead of UTF-8.</p> + </item> + <tag><c>{utf16,little}</c></tag> + <item> + <p>Works like <c>unicode</c>, but translation is done to and from little endian UTF-16 instead of UTF-8.</p> + </item> + <tag><c>utf32</c> or <c>{utf32,big}</c></tag> + <item> + <p>Works like <c>unicode</c>, but translation is done to and from big endian UTF-32 instead of UTF-8.</p> + </item> + <tag><c>{utf32,little}</c></tag> + <item> + <p>Works like <c>unicode</c>, but translation is done to and from little endian UTF-32 instead of UTF-8.</p> + </item> + </taglist> + <p>The Encoding can be changed for a file "on the fly" by using the <seealso marker="stdlib:io#setopts/2">io:setopts/2</seealso> function, why a file can be analyzed in latin1 encoding for i.e. a BOM, positioned beyond the BOM and then be set for the right encoding before further reading.See the <seealso marker="stdlib:unicode">unicode(3)</seealso> module for functions identifying BOM's.</p> + <p>This option is not allowed on <c>raw</c> files.</p> + </item> + </taglist> + <p>Returns:</p> + <taglist> + <tag><c>{ok, IoDevice}</c></tag> + <item> + <p>The file has been opened in the requested mode. + <c>IoDevice</c> is a reference to the file.</p> + </item> + <tag><c>{error, Reason}</c></tag> + <item> + <p>The file could not be opened.</p> + </item> + </taglist> + <p><c>IoDevice</c> is really the pid of the process which + handles the file. This process is linked to the process + which originally opened the file. If any process to which + the <c>IoDevice</c> is linked terminates, the file will be + closed and the process itself will be terminated. + An <c>IoDevice</c> returned from this call can be used as an + argument to the IO functions (see + <seealso marker="stdlib:io">io(3)</seealso>).</p> + <note> + <p>In previous versions of <c>file</c>, modes were given + as one of the atoms <c>read</c>, <c>write</c>, or + <c>read_write</c> instead of a list. This is still allowed + for reasons of backwards compatibility, but should not be + used for new code. Also note that <c>read_write</c> is not + allowed in a mode list.</p> + </note> + <p>Typical error reasons:</p> + <taglist> + <tag><c>enoent</c></tag> + <item> + <p>The file does not exist.</p> + </item> + <tag><c>eacces</c></tag> + <item> + <p>Missing permission for reading the file or searching one + of the parent directories.</p> + </item> + <tag><c>eisdir</c></tag> + <item> + <p>The named file is not a regular file. It may be a + directory, a fifo, or a device.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p>A component of the file name is not a directory. On some + platforms, <c>enoent</c> is returned instead.</p> + </item> + <tag><c>enospc</c></tag> + <item> + <p>There is a no space left on the device (if <c>write</c> + access was specified).</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>path_consult(Path, Filename) -> {ok, Terms, FullName} | {error, Reason}</name> + <fsummary>Read Erlang terms from a file</fsummary> + <type> + <v>Path = [Dir]</v> + <v> Dir = name()</v> + <v>Filename = name()</v> + <v>Terms = [term()]</v> + <v>FullName = string()</v> + <v>Reason = ext_posix() | terminated | system_limit + | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see below</v> + </type> + <desc> + <p>Searches the path <c>Path</c> (a list of directory names) + until the file <c>Filename</c> is found. If <c>Filename</c> + is an absolute filename, <c>Path</c> is ignored. + Then reads Erlang terms, separated by '.', from the file. + Returns one of the following:</p> + <taglist> + <tag><c>{ok, Terms, FullName}</c></tag> + <item> + <p>The file was successfully read. <c>FullName</c> is + the full name of the file.</p> + </item> + <tag><c>{error, enoent}</c></tag> + <item> + <p>The file could not be found in any of the directories in + <c>Path</c>.</p> + </item> + <tag><c>{error, atom()}</c></tag> + <item> + <p>An error occurred when opening the file or reading it. + See <seealso marker="#open/2">open/2</seealso> for a list + of typical error codes.</p> + </item> + <tag><c>{error, {Line, Mod, Term}}</c></tag> + <item> + <p>An error occurred when interpreting the Erlang terms in + the file. Use <c>format_error/1</c> to convert + the three-element tuple to an English description of + the error.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>path_eval(Path, Filename) -> {ok, FullName} | {error, Reason}</name> + <fsummary>Evaluate Erlang expressions in a file</fsummary> + <type> + <v>Path = [Dir]</v> + <v> Dir = name()</v> + <v>Filename = name()</v> + <v>FullName = string()</v> + <v>Reason = ext_posix() | terminated | system_limit + | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see below</v> + </type> + <desc> + <p>Searches the path <c>Path</c> (a list of directory names) + until the file <c>Filename</c> is found. If <c>Filename</c> + is an absolute file name, <c>Path</c> is ignored. Then reads + and evaluates Erlang expressions, separated by '.' (or ',', a + sequence of expressions is also an expression), from the file. + The actual result of evaluation is not returned; any + expression sequence in the file must be there for its side + effect. Returns one of the following:</p> + <taglist> + <tag><c>{ok, FullName}</c></tag> + <item> + <p>The file was read and evaluated. <c>FullName</c> is + the full name of the file.</p> + </item> + <tag><c>{error, enoent}</c></tag> + <item> + <p>The file could not be found in any of the directories in + <c>Path</c>.</p> + </item> + <tag><c>{error, atom()}</c></tag> + <item> + <p>An error occurred when opening the file or reading it. + See <seealso marker="#open/2">open/2</seealso> for a list + of typical error codes.</p> + </item> + <tag><c>{error, {Line, Mod, Term}}</c></tag> + <item> + <p>An error occurred when interpreting the Erlang + expressions in the file. Use <c>format_error/1</c> to + convert the three-element tuple to an English description + of the error.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>path_open(Path, Filename, Modes) -> {ok, IoDevice, FullName} | {error, Reason}</name> + <fsummary>Open a file</fsummary> + <type> + <v>Path = [Dir]</v> + <v> Dir = name()</v> + <v>Filename = name()</v> + <v>Modes = [Mode] -- see open/2</v> + <v>IoDevice = io_device()</v> + <v>FullName = string()</v> + <v>Reason = ext_posix() | system_limit</v> + </type> + <desc> + <p>Searches the path <c>Path</c> (a list of directory names) + until the file <c>Filename</c> is found. If <c>Filename</c> + is an absolute file name, <c>Path</c> is ignored. + Then opens the file in the mode determined by <c>Modes</c>. + Returns one of the following:</p> + <taglist> + <tag><c>{ok, IoDevice, FullName}</c></tag> + <item> + <p>The file has been opened in the requested mode. + <c>IoDevice</c> is a reference to the file and + <c>FullName</c> is the full name of the file.</p> + </item> + <tag><c>{error, enoent}</c></tag> + <item> + <p>The file could not be found in any of the directories in + <c>Path</c>.</p> + </item> + <tag><c>{error, atom()}</c></tag> + <item> + <p>The file could not be opened.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>path_script(Path, Filename) -> {ok, Value, FullName} | {error, Reason}</name> + <fsummary>Evaluate and return the value of Erlang expressions in a file</fsummary> + <type> + <v>Path = [Dir]</v> + <v> Dir = name()</v> + <v>Filename = name()</v> + <v>Value = term()</v> + <v>FullName = string()</v> + <v>Reason = ext_posix() | terminated | system_limit + | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see below</v> + </type> + <desc> + <p>Searches the path <c>Path</c> (a list of directory names) + until the file <c>Filename</c> is found. If <c>Filename</c> + is an absolute file name, <c>Path</c> 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:</p> + <taglist> + <tag><c>{ok, Value, FullName}</c></tag> + <item> + <p>The file was read and evaluated. <c>FullName</c> is + the full name of the file and <c>Value</c> the value of + the last expression.</p> + </item> + <tag><c>{error, enoent}</c></tag> + <item> + <p>The file could not be found in any of the directories in + <c>Path</c>.</p> + </item> + <tag><c>{error, atom()}</c></tag> + <item> + <p>An error occurred when opening the file or reading it. + See <seealso marker="#open/2">open/2</seealso> for a list + of typical error codes.</p> + </item> + <tag><c>{error, {Line, Mod, Term}}</c></tag> + <item> + <p>An error occurred when interpreting the Erlang + expressions in the file. Use <c>format_error/1</c> to + convert the three-element tuple to an English description + of the error.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>path_script(Path, Filename, Bindings) -> {ok, Value, FullName} | {error, Reason}</name> + <fsummary>Evaluate and return the value of Erlang expressions in a file</fsummary> + <type> + <v>Path = [Dir]</v> + <v> Dir = name()</v> + <v>Filename = name()</v> + <v>Bindings -- see erl_eval(3)</v> + <v>Value = term()</v> + <v>FullName = string()</v> + <v>Reason = posix() | terminated | system_limit + | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see path_script/2</v> + </type> + <desc> + <p>The same as <c>path_script/2</c> but the variable bindings + <c>Bindings</c> are used in the evaluation. See + <seealso marker="stdlib:erl_eval">erl_eval(3)</seealso> about + variable bindings.</p> + </desc> + </func> + <func> + <name>pid2name(Pid) -> string() | undefined</name> + <fsummary>Return the name of the file handled by a pid</fsummary> + <type> + <v>Pid = pid()</v> + </type> + <desc> + <p>If <c>Pid</c> is an IO device, that is, a pid returned from + <c>open/2</c>, this function returns the filename, or rather:</p> + <taglist> + <tag><c>{ok, Filename}</c></tag> + <item> + <p>If this node's file server is not a slave, the file was + opened by this node's file server, (this implies that + <c>Pid</c> must be a local pid) and the file is not + closed. <c>Filename</c> is the filename in flat string + format.</p> + </item> + <tag><c>undefined</c></tag> + <item> + <p>In all other cases.</p> + </item> + </taglist> + <warning> + <p>This function is intended for debugging only.</p> + </warning> + </desc> + </func> + <func> + <name>position(IoDevice, Location) -> {ok, NewPosition} | {error, Reason}</name> + <fsummary>Set position in a file</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Location = Offset | {bof, Offset} | {cur, Offset} | {eof, Offset} | bof | cur | eof</v> + <v> Offset = int()</v> + <v>NewPosition = int()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Sets the position of the file referenced by <c>IoDevice</c> + to <c>Location</c>. Returns <c>{ok, NewPosition}</c> (as + absolute offset) if successful, otherwise + <c>{error, Reason}</c>. <c>Location</c> is one of + the following:</p> + <taglist> + <tag><c>Offset</c></tag> + <item> + <p>The same as <c>{bof, Offset}</c>.</p> + </item> + <tag><c>{bof, Offset}</c></tag> + <item> + <p>Absolute offset.</p> + </item> + <tag><c>{cur, Offset}</c></tag> + <item> + <p>Offset from the current position.</p> + </item> + <tag><c>{eof, Offset}</c></tag> + <item> + <p>Offset from the end of file.</p> + </item> + <tag><c>bof | cur | eof</c></tag> + <item> + <p>The same as above with <c>Offset</c> 0.</p> + </item> + </taglist> + <p>Note that offsets are counted in bytes, not in characters. If the file is opened using some other <c>encoding</c> than <c>latin1</c>, one byte does not correspond to one character. Positioning in such a file can only be done to known character boundaries, i.e. to a position earlier retrieved by getting a current position, to the beginning/end of the file or to some other position <em>known</em> 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).</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>einval</c></tag> + <item> + <p>Either <c>Location</c> was illegal, or it evaluated to a + negative offset in the file. Note that if the resulting + position is a negative value, the result is an error, and + after the call the file position is undefined.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>pread(IoDevice, LocNums) -> {ok, DataL} | eof | {error, Reason}</name> + <fsummary>Read from a file at certain positions</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>LocNums = [{Location, Number}]</v> + <v> Location -- see position/2</v> + <v> Number = int()</v> + <v>DataL = [Data]</v> + <v> Data = [char()] | binary()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Performs a sequence of <c>pread/3</c> in one operation, + which is more efficient than calling them one at a time. + Returns <c>{ok, [Data, ...]}</c> or <c>{error, Reason}</c>, + where each <c>Data</c>, the result of the corresponding + <c>pread</c>, is either a list or a binary depending on + the mode of the file, or <c>eof</c> if the requested position + was beyond end of file.</p> + <p>As the position is given as a byte-offset, special caution has to be taken when working with files where <c>encoding</c> is set to something else than <c>latin1</c>, as not every byte position will be a valid character boundary on such a file.</p> + </desc> + </func> + <func> + <name>pread(IoDevice, Location, Number) -> {ok, Data} | eof | {error, Reason}</name> + <fsummary>Read from a file at a certain position</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Location -- see position/2</v> + <v>Number = int()</v> + <v>Data = [char()] | binary()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Combines <c>position/2</c> and <c>read/2</c> in one + operation, which is more efficient than calling them one at a + time. If <c>IoDevice</c> has been opened in raw mode, some + restrictions apply: <c>Location</c> is only allowed to be an + integer; and the current position of the file is undefined + after the operation.</p> + <p>As the position is given as a byte-offset, special caution has to be taken when working with files where <c>encoding</c> is set to something else than <c>latin1</c>, as not every byte position will be a valid character boundary on such a file.</p> + </desc> + </func> + <func> + <name>pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}}</name> + <fsummary>Write to a file at certain positions</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>LocBytes = [{Location, Bytes}]</v> + <v> Location -- see position/2</v> + <v> Bytes = iodata()</v> + <v>N = int()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Performs a sequence of <c>pwrite/3</c> in one operation, + which is more efficient than calling them one at a time. + Returns <c>ok</c> or <c>{error, {N, Reason}}</c>, where + <c>N</c> is the number of successful writes that was done + before the failure.</p> + <p>When positioning in a file with other <c>encoding</c> than <c>latin1</c>, caution must be taken to set the position on a correct character boundary, see <seealso marker="#position/2">position/2</seealso> for details.</p> + </desc> + </func> + <func> + <name>pwrite(IoDevice, Location, Bytes) -> ok | {error, Reason}</name> + <fsummary>Write to a file at a certain position</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Location -- see position/2</v> + <v>Bytes = iodata()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Combines <c>position/2</c> and <c>write/2</c> in one + operation, which is more efficient than calling them one at a + time. If <c>IoDevice</c> has been opened in raw mode, some + restrictions apply: <c>Location</c> is only allowed to be an + integer; and the current position of the file is undefined + after the operation.</p> + <p>When positioning in a file with other <c>encoding</c> than <c>latin1</c>, caution must be taken to set the position on a correct character boundary, see <seealso marker="#position/2">position/2</seealso> for details.</p> + </desc> + </func> + <func> + <name>read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason}</name> + <fsummary>Read from a file</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Number = int()</v> + <v>Data = [char()] | binary()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Reads <c>Number</c> bytes/characters from the file referenced by + <c>IoDevice</c>. The functions <c>read/2</c>, <c>pread/3</c> + and <c>read_line/1</c> are the only ways to read from a file + opened in raw mode (although they work for normally opened + files, too).</p> + <p>For files where <c>encoding</c> is set to something else than <c>latin1</c>, one character might be represented by more than one byte on the file. The parameter <c>Number</c> always denotes the number of <em>characters</em> read from the file, why the position in the file might be moved a lot more than this number when reading a Unicode file.</p> + <p>Also if <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read/3</c> call will fail if the data contains characters larger than 255, why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p> + <p>The function returns:</p> + <taglist> + <tag><c>{ok, Data}</c></tag> + <item> + <p>If the file was opened in binary mode, the read bytes are + returned in a binary, otherwise in a list. The list or + binary will be shorter than the number of bytes requested + if end of file was reached.</p> + </item> + <tag><c>eof</c></tag> + <item> + <p>Returned if <c>Number>0</c> and end of file was reached + before anything at all could be read.</p> + </item> + <tag><c>{error, Reason}</c></tag> + <item> + <p>An error occurred.</p> + </item> + </taglist> + <p>Typical error reasons:</p> + <taglist> + <tag><c>ebadf</c></tag> + <item> + <p>The file is not opened for reading.</p> + </item> + <tag><c>{no_translation, unicode, latin1}</c></tag> + <item> + <p>The file is was opened with another <c>encoding</c> than <c>latin1</c> and the data on the file can not be translated to the byte-oriented data that this function returns.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>read_file(Filename) -> {ok, Binary} | {error, Reason}</name> + <fsummary>Read a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Binary = binary()</v> + <v>Reason = ext_posix() | terminated | system_limit</v> + </type> + <desc> + <p>Returns <c>{ok, Binary}</c>, where <c>Binary</c> is a binary + data object that contains the contents of <c>Filename</c>, or + <c>{error, Reason}</c> if an error occurs.</p> + <p>Typical error reasons:</p> + <taglist> + <tag><c>enoent</c></tag> + <item> + <p>The file does not exist.</p> + </item> + <tag><c>eacces</c></tag> + <item> + <p>Missing permission for reading the file, or for + searching one of the parent directories.</p> + </item> + <tag><c>eisdir</c></tag> + <item> + <p>The named file is a directory.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p>A component of the file name is not a directory. On some + platforms, <c>enoent</c> is returned instead.</p> + </item> + <tag><c>enomem</c></tag> + <item> + <p>There is not enough memory for the contents of the file.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>read_file_info(Filename) -> {ok, FileInfo} | {error, Reason}</name> + <fsummary>Get information about a file</fsummary> + <type> + <v>Filename = name()</v> + <v>FileInfo = #file_info{}</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Retrieves information about a file. Returns + <c>{ok, FileInfo}</c> if successful, otherwise + <c>{error, Reason}</c>. <c>FileInfo</c> is a record + <c>file_info</c>, defined in the Kernel include file + <c>file.hrl</c>. Include the following directive in the module + from which the function is called:</p> + <code type="none"> +-include_lib("kernel/include/file.hrl").</code> + <p>The record <c>file_info</c> contains the following fields.</p> + <taglist> + <tag><c>size = int()</c></tag> + <item> + <p>Size of file in bytes.</p> + </item> + <tag><c>type = device | directory | regular | other</c></tag> + <item> + <p>The type of the file.</p> + </item> + <tag><c>access = read | write | read_write | none</c></tag> + <item> + <p>The current system access to the file.</p> + </item> + <tag><c>atime = time()</c></tag> + <item> + <p>The last (local) time the file was read.</p> + </item> + <tag><c>mtime = time()</c></tag> + <item> + <p>The last (local) time the file was written.</p> + </item> + <tag><c>ctime = time()</c></tag> + <item> + <p>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.</p> + </item> + <tag><c>mode = int()</c></tag> + <item> + <p>The file permissions as the sum of the following bit + values:</p> + <taglist> + <tag>8#00400</tag> + <item>read permission: owner</item> + <tag>8#00200</tag> + <item>write permission: owner</item> + <tag>8#00100</tag> + <item>execute permission: owner</item> + <tag>8#00040</tag> + <item>read permission: group</item> + <tag>8#00020</tag> + <item>write permission: group</item> + <tag>8#00010</tag> + <item>execute permission: group</item> + <tag>8#00004</tag> + <item>read permission: other</item> + <tag>8#00002</tag> + <item>write permission: other</item> + <tag>8#00001</tag> + <item>execute permission: other</item> + <tag>16#800</tag> + <item>set user id on execution</item> + <tag>16#400</tag> + <item>set group id on execution</item> + </taglist> + <p>On Unix platforms, other bits than those listed above + may be set.</p> + </item> + <tag><c>links = int()</c></tag> + <item> + <p>Number of links to the file (this will always be 1 for + file systems which have no concept of links).</p> + </item> + <tag><c>major_device = int()</c></tag> + <item> + <p>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.</p> + </item> + <tag><c>minor_device = int()</c></tag> + <item> + <p>Only valid for character devices on Unix. In all other + cases, this field is zero.</p> + </item> + <tag><c>inode = int()</c></tag> + <item> + <p>Gives the <c>inode</c> number. On non-Unix file systems, + this field will be zero.</p> + </item> + <tag><c>uid = int()</c></tag> + <item> + <p>Indicates the owner of the file. Will be zero for + non-Unix file systems.</p> + </item> + <tag><c>gid = int()</c></tag> + <item> + <p>Gives the group that the owner of the file belongs to. + Will be zero for non-Unix file systems.</p> + </item> + </taglist> + <p>Typical error reasons:</p> + <taglist> + <tag><c>eacces</c></tag> + <item> + <p>Missing search permission for one of the parent + directories of the file.</p> + </item> + <tag><c>enoent</c></tag> + <item> + <p>The file does not exist.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p>A component of the file name is not a directory. On some + platforms, <c>enoent</c> is returned instead.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>read_line(IoDevice) -> {ok, Data} | eof | {error, Reason}</name> + <fsummary>Read a line from a file</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Data = [char()] | binary()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Reads a line of bytes/characters from the file referenced by + <c>IoDevice</c>. Lines are defined to be delimited by the linefeed (LF, <c>\\n</c>) character, but any carriage return (CR, <c>\\r</c>) followed by a newline is also treated as a single LF character (the carriage return is silently ignored). The line is returned <em>including</em> the LF, but excluding any CR immediately followed by a LF. This behaviour is consistent with the behaviour of <seealso marker="stdlib:io#get_line/2">io:get_line/2</seealso>. If end of file is reached without any LF ending the last line, a line with no trailing LF is returned.</p> + <p>The function can be used on files opened in <c>raw</c> mode. It is however inefficient to use it on <c>raw</c> files if the file is not opened with the option <c>{read_ahead, Size}</c> specified, why combining <c>raw</c> and <c>{read_ahead, Size}</c> is highly recommended when opening a text file for raw line oriented reading.</p> + <p>If <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read_line/1</c> call will fail if the data contains characters larger than 255, why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p> + <p>The function returns:</p> + <taglist> + <tag><c>{ok, Data}</c></tag> + <item> + <p>One line from the file is returned, including the trailing LF, but with CRLF sequences replaced by a single LF (see above).</p> + <p>If the file was opened in binary mode, the read bytes are + returned in a binary, otherwise in a list.</p> + </item> + <tag><c>eof</c></tag> + <item> + <p>Returned if end of file was reached + before anything at all could be read.</p> + </item> + <tag><c>{error, Reason}</c></tag> + <item> + <p>An error occurred.</p> + </item> + </taglist> + <p>Typical error reasons:</p> + <taglist> + <tag><c>ebadf</c></tag> + <item> + <p>The file is not opened for reading.</p> + </item> + <tag><c>{no_translation, unicode, latin1}</c></tag> + <item> + <p>The file is was opened with another <c>encoding</c> than <c>latin1</c> and the data on the file can not be translated to the byte-oriented data that this function returns.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>read_link(Name) -> {ok, Filename} | {error, Reason}</name> + <fsummary>See what a link is pointing to</fsummary> + <type> + <v>Name = name()</v> + <v>Filename = string()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>This function returns <c>{ok, Filename}</c> if <c>Name</c> + refers to a symbolic link or <c>{error, Reason}</c> otherwise. + On platforms that do not support symbolic links, the return + value will be <c>{error,enotsup}</c>.</p> + <p>Typical error reasons:</p> + <taglist> + <tag><c>einval</c></tag> + <item> + <p><c>Linkname</c> does not refer to a symbolic link.</p> + </item> + <tag><c>enoent</c></tag> + <item> + <p>The file does not exist.</p> + </item> + <tag><c>enotsup</c></tag> + <item> + <p>Symbolic links are not supported on this platform.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>read_link_info(Name) -> {ok, FileInfo} | {error, Reason}</name> + <fsummary>Get information about a link or file</fsummary> + <type> + <v>Name = name()</v> + <v>FileInfo = #file_info{}, see read_file_info/1</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>This function works like <c>read_file_info/1</c>, except that + if <c>Name</c> is a symbolic link, information about the link + will be returned in the <c>file_info</c> record and + the <c>type</c> field of the record will be set to + <c>symlink</c>.</p> + <p>If <c>Name</c> is not a symbolic link, this function returns + exactly the same result as <c>read_file_info/1</c>. + On platforms that do not support symbolic links, this function + is always equivalent to <c>read_file_info/1</c>.</p> + </desc> + </func> + <func> + <name>rename(Source, Destination) -> ok | {error, Reason}</name> + <fsummary>Rename a file</fsummary> + <type> + <v>Source = Destination = name()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Tries to rename the file <c>Source</c> to <c>Destination</c>. + It can be used to move files (and directories) between + directories, but it is not sufficient to specify + the destination only. The destination file name must also be + specified. For example, if <c>bar</c> is a normal file and + <c>foo</c> and <c>baz</c> are directories, + <c>rename("foo/bar", "baz")</c> returns an error, but + <c>rename("foo/bar", "baz/bar")</c> succeeds. Returns + <c>ok</c> if it is successful.</p> + <note> + <p>Renaming of open files is not allowed on most platforms + (see <c>eacces</c> below).</p> + </note> + <p>Typical error reasons:</p> + <taglist> + <tag><c>eacces</c></tag> + <item> + <p>Missing read or write permissions for the parent + directories of <c>Source</c> or <c>Destination</c>. On + some platforms, this error is given if either + <c>Source</c> or <c>Destination</c> is open.</p> + </item> + <tag><c>eexist</c></tag> + <item> + <p><c>Destination</c> is not an empty directory. On some + platforms, also given when <c>Source</c> and + <c>Destination</c> are not of the same type.</p> + </item> + <tag><c>einval</c></tag> + <item> + <p><c>Source</c> is a root directory, or <c>Destination</c> + is a sub-directory of <c>Source</c>.</p> + </item> + <tag><c>eisdir</c></tag> + <item> + <p><c>Destination</c> is a directory, but <c>Source</c> is + not.</p> + </item> + <tag><c>enoent</c></tag> + <item> + <p><c>Source</c> does not exist.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p><c>Source</c> is a directory, but <c>Destination</c> is + not.</p> + </item> + <tag><c>exdev</c></tag> + <item> + <p><c>Source</c> and <c>Destination</c> are on different + file systems.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>script(Filename) -> {ok, Value} | {error, Reason}</name> + <fsummary>Evaluate and return the value of Erlang expressions in a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Value = term()</v> + <v>Reason = ext_posix() | terminated | system_limit + | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see below</v> + </type> + <desc> + <p>Reads and evaluates Erlang expressions, separated by '.' (or + ',', a sequence of expressions is also an expression), from + the file. Returns one of the following:</p> + <taglist> + <tag><c>{ok, Value}</c></tag> + <item> + <p>The file was read and evaluated. <c>Value</c> is + the value of the last expression.</p> + </item> + <tag><c>{error, atom()}</c></tag> + <item> + <p>An error occurred when opening the file or reading it. + See <seealso marker="#open/2">open/2</seealso> for a list + of typical error codes.</p> + </item> + <tag><c>{error, {Line, Mod, Term}}</c></tag> + <item> + <p>An error occurred when interpreting the Erlang + expressions in the file. Use <c>format_error/1</c> to + convert the three-element tuple to an English description + of the error.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>script(Filename, Bindings) -> {ok, Value} | {error, Reason}</name> + <fsummary>Evaluate and return the value of Erlang expressions in a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Bindings -- see erl_eval(3)</v> + <v>Value = term()</v> + <v>Reason = ext_posix() | terminated | system_limit + | {Line, Mod, Term}</v> + <v> Line, Mod, Term -- see below</v> + </type> + <desc> + <p>The same as <c>script/1</c> but the variable bindings + <c>Bindings</c> are used in the evaluation. See + <seealso marker="stdlib:erl_eval">erl_eval(3)</seealso> about + variable bindings.</p> + </desc> + </func> + <func> + <name>set_cwd(Dir) -> ok | {error,Reason}</name> + <fsummary>Set the current working directory</fsummary> + <type> + <v>Dir = name()</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Sets the current working directory of the file server to + <c>Dir</c>. Returns <c>ok</c> if successful.</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>enoent</c></tag> + <item> + <p>The directory does not exist.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p>A component of <c>Dir</c> is not a directory. On some + platforms, <c>enoent</c> is returned.</p> + </item> + <tag><c>eacces</c></tag> + <item> + <p>Missing permission for the directory or one of its + parents.</p> + </item> + <tag><c>badarg</c></tag> + <item> + <p><c>Filename</c> had an improper type, such as tuple.</p> + </item> + </taglist> + <warning> + <p>In a future release, a bad type for the <c>Filename</c> + argument will probably generate an exception.</p> + <p></p> + </warning> + </desc> + </func> + <func> + <name>sync(IoDevice) -> ok | {error, Reason}</name> + <fsummary>Synchronizes the in-memory state of a file with that on the physical medium</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Makes sure 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.</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>enospc</c></tag> + <item> + <p>Not enough space left to write the file.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>truncate(IoDevice) -> ok | {error, Reason}</name> + <fsummary>Truncate a file</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Truncates the file referenced by <c>IoDevice</c> at + the current position. Returns <c>ok</c> if successful, + otherwise <c>{error, Reason}</c>.</p> + </desc> + </func> + <func> + <name>write(IoDevice, Bytes) -> ok | {error, Reason}</name> + <fsummary>Write to a file</fsummary> + <type> + <v>IoDevice = io_device()</v> + <v>Bytes = iodata()</v> + <v>Reason = ext_posix() | terminated</v> + </type> + <desc> + <p>Writes <c>Bytes</c> to the file referenced by + <c>IoDevice</c>. This function is the only way to write to a + file opened in raw mode (although it works for normally + opened files, too). Returns <c>ok</c> if successful, and + <c>{error, Reason}</c> otherwise.</p> + <p>If the file is opened with <c>encoding</c> set to something else than <c>latin1</c>, each byte written might result in several bytes actually being written to the file, as the byte range 0..255 might represent anything between one and four bytes depending on value and UTF encoding type.</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>ebadf</c></tag> + <item> + <p>The file is not opened for writing.</p> + </item> + <tag><c>enospc</c></tag> + <item> + <p>There is a no space left on the device.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>write_file(Filename, Bytes) -> ok | {error, Reason}</name> + <fsummary>Write a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Bytes = iodata()</v> + <v>Reason = ext_posix() | terminated | system_limit</v> + </type> + <desc> + <p>Writes the contents of the iodata term <c>Bytes</c> to the + file <c>Filename</c>. The file is created if it does not + exist. If it exists, the previous contents are + overwritten. Returns <c>ok</c>, or <c>{error, Reason}</c>.</p> + <p>Typical error reasons are:</p> + <taglist> + <tag><c>enoent</c></tag> + <item> + <p>A component of the file name does not exist.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p>A component of the file name is not a directory. On some + platforms, <c>enoent</c> is returned instead.</p> + </item> + <tag><c>enospc</c></tag> + <item> + <p>There is a no space left on the device.</p> + </item> + <tag><c>eacces</c></tag> + <item> + <p>Missing permission for writing the file or searching one + of the parent directories.</p> + </item> + <tag><c>eisdir</c></tag> + <item> + <p>The named file is a directory.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>write_file(Filename, Bytes, Modes) -> ok | {error, Reason}</name> + <fsummary>Write a file</fsummary> + <type> + <v>Filename = name()</v> + <v>Bytes = iodata()</v> + <v>Modes = [Mode] -- see open/2</v> + <v>Reason = ext_posix() | terminated | system_limit</v> + </type> + <desc> + <p>Same as <c>write_file/2</c>, but takes a third argument + <c>Modes</c>, a list of possible modes, see + <seealso marker="#open/2">open/2</seealso>. The mode flags + <c>binary</c> and <c>write</c> are implicit, so they should + not be used.</p> + </desc> + </func> + <func> + <name>write_file_info(Filename, FileInfo) -> ok | {error, Reason}</name> + <fsummary>Change information about a file</fsummary> + <type> + <v>Filename = name()</v> + <v>FileInfo = #file_info{} -- see also read_file_info/1</v> + <v>Reason = ext_posix()</v> + </type> + <desc> + <p>Change file information. Returns <c>ok</c> if successful, + otherwise <c>{error, Reason}</c>. <c>FileInfo</c> is a record + <c>file_info</c>, defined in the Kernel include file + <c>file.hrl</c>. Include the following directive in the module + from which the function is called:</p> + <code type="none"> +-include_lib("kernel/include/file.hrl").</code> + <p>The following fields are used from the record, if they are + given.</p> + <taglist> + <tag><c>atime = time()</c></tag> + <item> + <p>The last (local) time the file was read.</p> + </item> + <tag><c>mtime = time()</c></tag> + <item> + <p>The last (local) time the file was written.</p> + </item> + <tag><c>ctime = time()</c></tag> + <item> + <p>On Unix, any value give for this field will be ignored + (the "ctime" for the file will be set to the current + time). On Windows, this field is the new creation time to + set for the file.</p> + </item> + <tag><c>mode = int()</c></tag> + <item> + <p>The file permissions as the sum of the following bit + values:</p> + <taglist> + <tag>8#00400</tag> + <item>read permission: owner</item> + <tag>8#00200</tag> + <item>write permission: owner</item> + <tag>8#00100</tag> + <item>execute permission: owner</item> + <tag>8#00040</tag> + <item>read permission: group</item> + <tag>8#00020</tag> + <item>write permission: group</item> + <tag>8#00010</tag> + <item>execute permission: group</item> + <tag>8#00004</tag> + <item>read permission: other</item> + <tag>8#00002</tag> + <item>write permission: other</item> + <tag>8#00001</tag> + <item>execute permission: other</item> + <tag>16#800</tag> + <item>set user id on execution</item> + <tag>16#400</tag> + <item>set group id on execution</item> + </taglist> + <p>On Unix platforms, other bits than those listed above + may be set.</p> + </item> + <tag><c>uid = int()</c></tag> + <item> + <p>Indicates the owner of the file. Ignored for non-Unix + file systems.</p> + </item> + <tag><c>gid = int()</c></tag> + <item> + <p>Gives the group that the owner of the file belongs to. + Ignored non-Unix file systems.</p> + </item> + </taglist> + <p>Typical error reasons:</p> + <taglist> + <tag><c>eacces</c></tag> + <item> + <p>Missing search permission for one of the parent + directories of the file.</p> + </item> + <tag><c>enoent</c></tag> + <item> + <p>The file does not exist.</p> + </item> + <tag><c>enotdir</c></tag> + <item> + <p>A component of the file name is not a directory. On some + platforms, <c>enoent</c> is returned instead.</p> + </item> + </taglist> + </desc> + </func> + </funcs> + + <section> + <title>POSIX Error Codes</title> + <list type="bulleted"> + <item><c>eacces</c> - permission denied</item> + <item><c>eagain</c> - resource temporarily unavailable</item> + <item><c>ebadf</c> - bad file number</item> + <item><c>ebusy</c> - file busy</item> + <item><c>edquot</c> - disk quota exceeded</item> + <item><c>eexist</c> - file already exists</item> + <item><c>efault</c> - bad address in system call argument</item> + <item><c>efbig</c> - file too large</item> + <item><c>eintr</c> - interrupted system call</item> + <item><c>einval</c> - invalid argument</item> + <item><c>eio</c> - IO error</item> + <item><c>eisdir</c> - illegal operation on a directory</item> + <item><c>eloop</c> - too many levels of symbolic links</item> + <item><c>emfile</c> - too many open files</item> + <item><c>emlink</c> - too many links</item> + <item><c>enametoolong</c> - file name too long</item> + <item><c>enfile</c> - file table overflow</item> + <item><c>enodev</c> - no such device</item> + <item><c>enoent</c> - no such file or directory</item> + <item><c>enomem</c> - not enough memory</item> + <item><c>enospc</c> - no space left on device</item> + <item><c>enotblk</c> - block device required</item> + <item><c>enotdir</c> - not a directory</item> + <item><c>enotsup</c> - operation not supported</item> + <item><c>enxio</c> - no such device or address</item> + <item><c>eperm</c> - not owner</item> + <item><c>epipe</c> - broken pipe</item> + <item><c>erofs</c> - read-only file system</item> + <item><c>espipe</c> - invalid seek</item> + <item><c>esrch</c> - no such process</item> + <item><c>estale</c> - stale remote file handle</item> + <item><c>exdev</c> - cross-domain link</item> + </list> + </section> + + <section> + <title>Performance</title> + <p>Some operating system file operations, for example a + <c>sync/1</c> or <c>close/1</c> on a huge file, may block their + calling thread for seconds. If this befalls the emulator main + thread, the response time is no longer in the order of + milliseconds, depending on the definition of "soft" in soft + real-time system.</p> + <p>If the device driver thread pool is active, file operations are + done through those threads instead, so the emulator can go on + executing Erlang processes. Unfortunately, the time for serving a + file operation increases due to the extra scheduling required + from the operating system.</p> + <p>If the device driver thread pool is disabled or of size 0, large + file reads and writes are segmented into several smaller, which + enables the emulator so server other processes during the file + operation. This gives the same effect as when using the thread + pool, but with larger overhead. Other file operations, for + example <c>sync/1</c> or <c>close/1</c> on a huge file, still are + a problem.</p> + <p>For increased performance, raw files are recommended. Raw files + uses the file system of the node's host machine. 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 another node's, + and the other node runs on some other host machine, they may have + different file systems. This is seldom a problem, but you have + now been warned.</p> + <p>A normal file is really a process so it can be used as an IO + device (see <c>io</c>). 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 + another node's, also binaries are copied.</p> + <p>Caching data to reduce the number of file operations, or rather + the number of calls to the file driver, will generally increase + performance. The following function writes 4 MBytes in 23 + seconds when tested:</p> + <code type="none"><![CDATA[ +create_file_slow(Name, N) when integer(N), N >= 0 -> + {ok, FD} = file:open(Name, [raw, write, delayed_write, binary]), + ok = create_file_slow(FD, 0, N), + ok = ?FILE_MODULE:close(FD), + ok. + +create_file_slow(FD, M, M) -> + ok; +create_file_slow(FD, M, N) -> + ok = file:write(FD, <<M:32/unsigned>>), + create_file_slow(FD, M+1, N).]]></code> + <p>The following, functionally equivalent, function collects 1024 + entries into a list of 128 32-byte binaries before each call to + <c>file:write/2</c> and so does the same work in 0.52 seconds, + which is 44 times faster.</p> + <code type="none"><![CDATA[ +create_file(Name, N) when integer(N), N >= 0 -> + {ok, FD} = file:open(Name, [raw, write, delayed_write, binary]), + ok = create_file(FD, 0, N), + ok = ?FILE_MODULE:close(FD), + ok. + +create_file(FD, M, M) -> + ok; +create_file(FD, M, N) when M + 1024 =< N -> + create_file(FD, M, M + 1024, []), + create_file(FD, M + 1024, N); +create_file(FD, M, N) -> + create_file(FD, M, N, []). + +create_file(FD, M, M, R) -> + ok = file:write(FD, R); +create_file(FD, M, N0, R) when M + 8 =< N0 -> + N1 = N0-1, N2 = N0-2, N3 = N0-3, N4 = N0-4, + N5 = N0-5, N6 = N0-6, N7 = N0-7, N8 = N0-8, + create_file(FD, M, N8, + [<<N8:32/unsigned, N7:32/unsigned, + N6:32/unsigned, N5:32/unsigned, + N4:32/unsigned, N3:32/unsigned, + N2:32/unsigned, N1:32/unsigned>> | R]); +create_file(FD, M, N0, R) -> + N1 = N0-1, + create_file(FD, M, N1, [<<N1:32/unsigned>> | R]).]]></code> + <note> + <p>Trust only your own benchmarks. If the list length in + <c>create_file/2</c> above is increased, it will run slightly + faster, but consume more memory and cause more memory + fragmentation. How much this affects your application is + something that this simple benchmark can not predict.</p> + <p>If the size of each binary is increased to 64 bytes, it will + also run slightly faster, but the code will be twice as clumsy. + In the current implementation are binaries larger than 64 bytes + stored in memory common to all processes and not copied when + sent between processes, while these smaller binaries are stored + on the process heap and copied when sent like any other term.</p> + <p>So, with a binary size of 68 bytes <c>create_file/2</c> runs + 30 percent slower then with 64 bytes, and will cause much more + memory fragmentation. Note that if the binaries were to be sent + between processes (for example a non-raw file) the results + would probably be completely different.</p> + </note> + <p>A raw file is really a port. When writing data to a port, it is + efficient to write a list of binaries. There is no need 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 <c>file:write(FD, [Bin1, Bin2 | Bin3])</c> + will write the contents of the binaries without copying the data + at all except for perhaps deep down in the operating system + kernel.</p> + <p>For raw files, <c>pwrite/2</c> and <c>pread/2</c> are + efficiently implemented. The file driver is called only once for + the whole operation, and the list iteration is done in the file + driver.</p> + <p>The options <c>delayed_write</c> and <c>read_ahead</c> to + <c>file:open/2</c> makes the file driver cache data to reduce + the number of operating system calls. The function + <c>create_file/2</c> in the example above takes 60 seconds + seconds without the <c>delayed_write</c> option, which is 2.6 + times slower.</p> + <p>And, as a really bad example, <c>create_file_slow/2</c> above + without the <c>raw</c>, <c>binary</c> and <c>delayed_write</c> + options, that is it calls <c>file:open(Name, [write])</c>, needs + 1 min 20 seconds for the job, which is 3.5 times slower than + the first example, and 150 times slower than the optimized + <c>create_file/2</c>. </p> + </section> + + <section> + <title>Warnings</title> + <p>If an error occurs when accessing an open file with the <c>io</c> + module, the process which handles the file will exit. The dead + file process might hang if a process tries to access it later. + This will be fixed in a future release.</p> + </section> + + <section> + <title>SEE ALSO</title> + <p><seealso marker="stdlib:filename">filename(3)</seealso></p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml new file mode 100644 index 0000000000..de41178a17 --- /dev/null +++ b/lib/kernel/doc/src/gen_sctp.xml @@ -0,0 +1,1075 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2007</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>gen_sctp</title> + <prepared>[email protected]</prepared> + <responsible></responsible> + <docno>1</docno> + <approved></approved> + <checked></checked> + <date>2007-03-21</date> + <rev>A</rev> + <file>gen_sctp.sgml</file> + </header> + <module>gen_sctp</module> + <modulesummary>The gen_sctp module provides functions for communicating with sockets using the SCTP protocol.</modulesummary> + <description> + <p>The <c>gen_sctp</c> module provides functions for communicating with + sockets using the SCTP protocol. The implementation assumes that + the OS kernel supports SCTP + <url href="http://www.rfc-archive.org/getrfc.php?rfc=2960">(RFC2960)</url> through the user-level + <url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">Sockets API Extensions.</url> + During development this implementation was tested on + Linux Fedora Core 5.0 (kernel 2.6.15-2054 or later is needed), + and on 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, and later on + 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.</p> + <p>Record definitions for the <c>gen_sctp</c> module can be found using:</p> + <pre> + -include_lib("kernel/include/inet_sctp.hrl"). </pre> + <p>These record definitions use the "new" spelling 'adaptation', + not the deprecated 'adaption', regardless of which + spelling the underlying C API uses.</p> + </description> + + <section> + <marker id="contents"></marker> + <title>CONTENTS</title> + <list type="bulleted"> + <item><seealso marker="#types">DATA TYPES</seealso></item> + <item><seealso marker="#exports">EXPORTS</seealso></item> + <item><seealso marker="#options">SCTP SOCKET OPTIONS</seealso></item> + <item><seealso marker="#examples">SCTP EXAMPLES</seealso></item> + <item><seealso marker="#seealso">SEE ALSO</seealso></item> + <item><seealso marker="#authors">AUTHORS</seealso></item> + </list> + </section> + + <section> + <marker id="types"></marker> + <title>DATA TYPES</title> + <marker id="type-assoc_id"></marker> + <taglist> + <tag><c>assoc_id()</c></tag> + <item> + <p>An opaque term returned in for example #sctp_paddr_change{} + that identifies an association for an SCTP socket. The term + is opaque except for the special value <c>0</c> that has a + meaning such as "the whole endpoint" or "all future associations".</p> + <marker id="type-charlist"></marker> + </item> + <tag><c>charlist() = [char()]</c></tag> + <item> <marker id="type-iolist"></marker> +</item> + <tag><c>iolist() = [char() | binary()]</c></tag> + <item> <marker id="type-ip_address"></marker> +</item> + <tag><c>ip_address()</c></tag> + <item> + <p>Represents an address of an SCTP socket. + It is a tuple as explained in + <seealso marker="inet">inet(3)</seealso>.</p> + <marker id="type-port_number"></marker> + </item> + <tag><c>port_number() = 0 .. 65535</c></tag> + <item> <marker id="type-posix"></marker> +</item> + <tag><c>posix()</c></tag> + <item> + <p>See + <seealso marker="inet#error_codes">inet(3); POSIX Error Codes.</seealso></p> + <marker id="type-sctp_option"></marker> + </item> + <tag><c>sctp_option()</c></tag> + <item> + <p>One of the + <seealso marker="#options">SCTP Socket Options.</seealso></p> + <marker id="type-sctp_socket"></marker> + </item> + <tag><c>sctp_socket()</c></tag> + <item> + <p>Socket identifier returned from <c>open/*</c>.</p> + <marker id="type-timeout"></marker> + </item> + <tag><c>timeout() = int() | infinity</c></tag> + <item> + <p>Timeout used in SCTP connect and receive calls.</p> + </item> + </taglist> + <marker id="exports"></marker> + </section> + <funcs> + <func> + <name>abort(sctp_socket(), Assoc) -> ok | {error, posix()}</name> + <fsummary>Abnormally terminate the association given by Assoc, without flushing of unsent data</fsummary> + <type> + <v>Assoc = #sctp_assoc_change{}</v> + </type> + <desc> + <p>Abnormally terminates the association given by <c>Assoc</c>, without + flushing of unsent data. The socket itself remains open. Other + associations opened on this socket are still valid, and it can be + used in new associations.</p> + </desc> + </func> + <func> + <name>close(sctp_socket()) -> ok | {error, posix()}</name> + <fsummary>Completely close the socket and all associations on it</fsummary> + <desc> + <p>Completely closes the socket and all associations on it. The unsent + data is flushed as in <c>eof/2</c>. The <c>close/1</c> call + is blocking or otherwise depending of the value of + the <seealso marker="#option-linger">linger</seealso> socket + <seealso marker="#options">option</seealso>. + If <c>close</c> does not linger or linger timeout expires, + the call returns and the data is flushed in the background.</p> + </desc> + </func> + <func> + <name>connect(Socket, Addr, Port, Opts) -> {ok,Assoc} | {error, posix()}</name> + <fsummary>Same as <c>connect(Socket, Addr, Port, Opts, infinity)</c>.</fsummary> + <desc> + <p>Same as <c>connect(Socket, Addr, Port, Opts, infinity)</c>.</p> + </desc> + </func> + <func> + <name>connect(Socket, Addr, Port, [Opt], Timeout) -> {ok, Assoc} | {error, posix()}</name> + <fsummary>Establish a new association for the socket <c>Socket</c>, with a peer (SCTP server socket)</fsummary> + <type> + <v>Socket = sctp_socket()</v> + <v>Addr = ip_address() | Host</v> + <v>Port = port_number()</v> + <v>Opt = sctp_option()</v> + <v>Timeout = timeout()</v> + <v>Host = atom() | string()</v> + <v>Assoc = #sctp_assoc_change{}</v> + </type> + <desc> + <p>Establishes a new association for the socket <c>Socket</c>, + with the peer (SCTP server socket) given by + <c>Addr</c> and <c>Port</c>. The <c>Timeout</c>, + is expressed in milliseconds.</p> + <p>A socket can be associated with multiple peers. + <marker id="record-sctp_assoc_change"></marker> + + The result of <c>connect/*</c> is an <c>#sctp_assoc_change{}</c> + event which contains, in particular, the new + <seealso marker="#type-assoc_id">Association ID:</seealso></p> + <pre> + #sctp_assoc_change{ + state = atom(), + error = atom(), + outbound_streams = int(), + inbound_streams = int(), + assoc_id = assoc_id() + } </pre> + <p>The number of outbound and inbound streams can be set by + giving an <c>sctp_initmsg</c> option to <c>connect</c> + as in:</p> + <pre> + connect(Socket, Ip, Port, + [{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams, + max_instreams=MaxInStreams}}]) </pre> + <p>All options <c>Opt</c> are set on the socket before the + association is attempted. If an option record has got undefined + field values, the options record is first read from the socket + for those values. In effect, <c>Opt</c> option records only + define field values to change before connecting.</p> + <p>The returned <c>outbound_streams</c> and <c>inbound_streams</c> + are the actual stream numbers on the socket, which may be different + from the requested values (<c>OutStreams</c> and <c>MaxInStreams</c> + respectively) if the peer requires lower values.</p> + <p>The following values of <c>state</c> are possible:</p> + <list type="bulleted"> + <item> + <p><c>comm_up</c>: association successfully established. This + indicates a successful completion of <c>connect</c>.</p> + </item> + <item> + <p><c>cant_assoc</c>: association cannot be established + (<c>connect/*</c> failure).</p> + </item> + </list> + <p>All other states do not normally occur in the output from + <c>connect/*</c>. Rather, they may occur in + <c>#sctp_assoc_change{}</c> events received instead of data in + <seealso marker="#recv/1">recv/*</seealso> calls. + All of them indicate losing the association due to various + error conditions, and are listed here for the sake of completeness. + The <c>error</c> field may provide more detailed diagnostics.</p> + <list type="bulleted"> + <item> + <p><c>comm_lost</c>;</p> + </item> + <item> + <p><c>restart</c>;</p> + </item> + <item> + <p><c>shutdown_comp</c>.</p> + </item> + </list> + </desc> + </func> + <func> + <name>controlling_process(sctp_socket(), pid()) -> ok</name> + <fsummary>Assign a new controlling process pid to the socket</fsummary> + <desc> + <p>Assigns a new controlling process Pid to Socket. Same implementation + as <c>gen_udp:controlling_process/2</c>.</p> + </desc> + </func> + <func> + <name>eof(Socket, Assoc) -> ok | {error, Reason}</name> + <fsummary>Gracefully terminate the association given by Assoc, with flushing of all unsent data</fsummary> + <type> + <v>Socket = sctp_socket()</v> + <v>Assoc = #sctp_assoc_change{}</v> + </type> + <desc> + <p>Gracefully terminates the association given by <c>Assoc</c>, with + flushing of all unsent data. The socket itself remains open. Other + associations opened on this socket are still valid, and it can be + used in new associations.</p> + </desc> + </func> + <func> + <name>listen(Socket, IsServer) -> ok | {error, Reason}</name> + <fsummary>Set up a socket to listen.</fsummary> + <type> + <v>Socket = sctp_socket()</v> + <v>IsServer = bool()</v> + </type> + <desc> + <p>Sets up a socket to listen on the IP address and port number + it is bound to. IsServer must be 'true' or 'false'. + In the contrast to TCP, in SCTP there is no listening queue length. + If IsServer is 'true' the socket accepts new associations, i.e. + it will become an SCTP server socket.</p> + </desc> + </func> + <func> + <name>open() -> {ok, Socket} | {error, posix()}</name> + <name>open(Port) -> {ok, Socket} | {error, posix()}</name> + <name>open([Opt]) -> {ok, Socket} | {error, posix()}</name> + <name>open(Port, [Opt]) -> {ok, Socket} | {error, posix()}</name> + <fsummary>Create an SCTP socket and bind it to local addresses</fsummary> + <type> + <v>Opt = {ip,IP} | {ifaddr,IP} | {port,Port} | sctp_option()</v> + <v>IP = ip_address() | any | loopback</v> + <v>Port = port_number()</v> + </type> + <desc> + <p>Creates an SCTP socket and binds it to the local addresses + specified by all <c>{ip,IP}</c> (or synonymously <c>{ifaddr,IP}</c>) + options (this feature is called SCTP multi-homing). + The default <c>IP</c> and <c>Port</c> are <c>any</c> + and <c>0</c>, meaning bind to all local addresses on any + one free port.</p> + <p>A default set of socket <seealso marker="#options">options</seealso> + is used. In particular, the socket is opened in + <seealso marker="#option-binary">binary</seealso> and + <seealso marker="#option-active">passive</seealso> mode, + and with reasonably large + <seealso marker="#option-sndbuf">kernel</seealso> and driver + <seealso marker="#option-buffer">buffers.</seealso></p> + </desc> + </func> + <func> + <name>recv(sctp_socket()) -> {ok, {FromIP, FromPort, AncData, BinMsg}} | {error, Reason}</name> + <name>recv(sctp_socket(), timeout()) -> {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}</name> + <fsummary>Receive a message from a socket</fsummary> + <type> + <v>FromIP = ip_address()</v> + <v>FromPort = port_number()</v> + <v>AncData = [#sctp_sndrcvinfo{}]</v> + <v>Data = binary() | charlist() | #sctp_sndrcvinfo{} | + #sctp_assoc_change{} | #sctp_paddr_change{} | + #sctp_adaptation_event{} </v> + <v>Reason = posix() | #sctp_send_failed{} | #scpt_paddr_change{} | + #sctp_pdapi_event{} | #sctp_remote_error{} | + #sctp_shutdown_event{}</v> + </type> + <desc> + <p>Receives the <c>Data</c> message from any association of the socket. + If the receive times out <c>{error,timeout</c> is returned. + The default timeout is <c>infinity</c>. + <c>FromIP</c> and <c>FromPort</c> indicate the sender's address.</p> + <p><c>AncData</c> is a list of Ancillary Data items which + may be received along with the main <c>Data</c>. + This list can be empty, or contain a single + <seealso marker="#record-sctp_sndrcvinfo">#sctp_sndrcvinfo{}</seealso> + record, if receiving of such ancillary data is enabled + (see option + <seealso marker="#option-sctp_events">sctp_events</seealso>). + It is enabled by default, since such ancillary data + provide an easy way of determining the association and stream + over which the message has been received. + (An alternative way would be to get the Association ID from the + <c>FromIP</c> and <c>FromPort</c> using the + <seealso marker="#option-sctp_get_peer_addr_info">sctp_get_peer_addr_info</seealso> socket option, + but this would still not produce the Stream number).</p> + <p>The actual <c>Data</c> received may be a <c>binary()</c>, + or <c>list()</c> of bytes (integers in the range 0 through 255) + depending on the socket mode, or an SCTP Event. + <marker id="sctp_events"></marker> + + The following SCTP Events are possible:</p> + <list type="bulleted"> + <item> + <p><seealso marker="#record-sctp_sndrcvinfo">#sctp_sndrcvinfo{}</seealso></p> + </item> + <item> + <p><seealso marker="#record-sctp_assoc_change">#sctp_assoc_change{}</seealso>;</p> + </item> + <item> + <pre> + #sctp_paddr_change{ + addr = {ip_address(),port()}, + state = atom(), + error = int(), + assoc_id = assoc_id() + } </pre> + <p>Indicates change of the status of the peer's IP address given by + <c>addr</c> within the association <c>assoc_id</c>. + Possible values of <c>state</c> (mostly self-explanatory) include:</p> + <list type="bulleted"> + <item> + <p><c>addr_unreachable</c>;</p> + </item> + <item> + <p><c>addr_available</c>;</p> + </item> + <item> + <p><c>addr_removed</c>;</p> + </item> + <item> + <p><c>addr_added</c>;</p> + </item> + <item> + <p><c>addr_made_prim</c>.</p> + </item> + <item> + <p><c>addr_confirmed</c>.</p> + </item> + </list> + <p>In case of an error (e.g. <c>addr_unreachable</c>), the + <c>error</c> field provides additional diagnostics. In such cases, + the <c>#sctp_paddr_change{}</c> Event is automatically + converted into an <c>error</c> term returned by + <c>gen_sctp:recv</c>. The <c>error</c> field value can be + converted into a string using <c>error_string/1</c>.</p> + </item> + <item> + <pre> + #sctp_send_failed{ + flags = true | false, + error = int(), + info = #sctp_sndrcvinfo{}, + assoc_id = assoc_id() + data = binary() + } </pre> + <p>The sender may receive this event if a send operation fails. + The <c>flags</c> is a Boolean specifying whether the data have + actually been transmitted over the wire; <c>error</c> provides + extended diagnostics, use <c>error_string/1</c>; + <c>info</c> is the original + <seealso marker="#record-sctp_sndrcvinfo">#sctp_sndrcvinfo{}</seealso> record used in the failed + <seealso marker="#send/3">send/*,</seealso> and <c>data</c> + is the whole original data chunk attempted to be sent.</p> + <p>In the current implementation of the Erlang/SCTP binding, + this Event is internally converted into an <c>error</c> term + returned by <c>recv/*</c>.</p> + </item> + <item> + <pre> + #sctp_adaptation_event{ + adaptation_ind = int(), + assoc_id = assoc_id() + } </pre> + <p>Delivered when a peer sends an Adaptation Layer Indication + parameter (configured through the option + <seealso marker="#option-sctp_adaptation_layer">sctp_adaptation_layer</seealso>). + Note that with the current implementation of + the Erlang/SCTP binding, this event is disabled by default.</p> + </item> + <item> + <pre> + #sctp_pdapi_event{ + indication = sctp_partial_delivery_aborted, + assoc_id = assoc_id() + } </pre> + <p>A partial delivery failure. In the current implementation of + the Erlang/SCTP binding, this Event is internally converted + into an <c>error</c> term returned by <c>recv/*</c>.</p> + </item> + </list> + </desc> + </func> + <func> + <name>send(Socket, SndRcvInfo, Data) -> ok | {error, Reason}</name> + <fsummary>Send a message using an <c>#sctp_sndrcvinfo{}</c>record</fsummary> + <type> + <v>Socket = sctp_socket()</v> + <v>SndRcvInfo = #sctp_sndrcvinfo{}</v> + <v>Data = binary() | iolist()</v> + </type> + <desc> + <p>Sends the <c>Data</c> message with all sending parameters from a + <seealso marker="#record-sctp_sndrcvinfo">#sctp_sndrcvinfo{}</seealso> 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 level of user control is rarely required. + The send/4 function is sufficient for most applications.</p> + </desc> + </func> + <func> + <name>send(Socket, Assoc, Stream, Data) -> ok | {error, Reason}</name> + <fsummary>Send a message over an existing association and given stream</fsummary> + <type> + <v>Socket = sctp_socket()</v> + <v>Assoc = #sctp_assoc_change{} | assoc_id()</v> + <v>Stream = integer()</v> + <v>Data = binary() | iolist()</v> + </type> + <desc> + <p>Sends <c>Data</c> message over an existing association and given + stream.</p> + </desc> + </func> + <func> + <name>error_string(integer()) -> ok | string() | undefined</name> + <fsummary>Translate an SCTP error number into a string</fsummary> + <desc> + <p>Translates an SCTP error number from for example + <c>#sctp_remote_error{}</c> or <c>#sctp_send_failed{}</c> into + an explanatory string, or one of the atoms <c>ok</c> for no + error and <c>undefined</c> for an unrecognized error.</p> + </desc> + </func> + </funcs> + + <section> + <marker id="options"></marker> + <title>SCTP SOCKET OPTIONS</title> + <p>The set of admissible SCTP socket options is by construction + orthogonal to the sets of TCP, UDP and generic INET options: + only those options which are explicitly listed below are allowed + for SCTP sockets. Options can be set on the socket using + <c>gen_sctp:open/1,2</c> or <c>inet:setopts/2</c>, + retrieved using <c>inet:getopts/2</c>, and when calling + <c>gen_sctp:connect/4,5</c> options can be changed.</p> + <marker id="option-binary"></marker> + <marker id="option-list"></marker> + <taglist> + <tag><c>{mode, list|binary}</c>or just <c>list</c> or <c>binary</c>.</tag> + <item> + <p>Determines the type of data returned from <c>gen_sctp:recv/1,2</c>.</p> + <marker id="option-active"></marker> + </item> + <tag><c>{active, true|false|once}</c></tag> + <item> + <list type="bulleted"> + <item> + <p>If <c>false</c> (passive mode, the default), + the caller needs to do an explicit <c>gen_sctp:recv</c> call + in order to retrieve the available data from the socket.</p> + </item> + <item> + <p>If <c>true</c> (full active mode), the pending data or events are + sent to the owning process.</p> + <p><em>NB:</em> This can cause the message queue to overflow, + as there is no way to throttle the sender in this case + (no flow control!).</p> + </item> + <item> + <p>If <c>once</c>, only one message is automatically placed + in the message queue, after that the mode is automatically + re-set to passive. This provides flow control as well as + the possibility for the receiver to listen for its incoming + SCTP data interleaved with other inter-process messages.</p> + </item> + </list> + <marker id="option-buffer"></marker> + </item> + <tag><c>{buffer, int()}</c></tag> + <item> + <p>Determines the size of the user-level software buffer used by + the SCTP driver. Not to be confused with <c>sndbuf</c> + and <c>recbuf</c> options which correspond to + the kernel socket buffers. It is recommended + to have <c>val(buffer) >= max(val(sndbuf),val(recbuf))</c>. + In fact, the <c>val(buffer)</c> is automatically set to + the above maximum when <c>sndbuf</c> or <c>recbuf</c> values are set.</p> + </item> + <tag><c>{tos, int()}</c></tag> + <item> + <p>Sets the Type-Of-Service field on the IP datagrams being sent, + to the given value, which effectively determines a prioritization + policy for the outbound packets. The acceptable values + are system-dependent. TODO: we do not provide + symbolic names for these values yet.</p> + </item> + <tag><c>{priority, int()}</c></tag> + <item> + <p>A protocol-independent equivalent of <c>tos</c> above. Setting + priority implies setting tos as well.</p> + </item> + <tag><c>{dontroute, true|false}</c></tag> + <item> + <p>By default <c>false</c>. If <c>true</c>, the kernel does not + send packets via any gateway, only sends them to directly + connected hosts.</p> + </item> + <tag><c>{reuseaddr, true|false}</c></tag> + <item> + <p>By default <c>false</c>. If true, the local binding address + <c>{IP,Port}</c> of the socket can be re-used immediately: + no waiting in the CLOSE_WAIT state is performed (may be + required for high-throughput servers).</p> + <marker id="option-linger"></marker> + </item> + <tag><c>{linger, {true|false, int()}</c></tag> + <item> + <p>Determines the timeout in seconds for flushing unsent data in the + <c>gen_sctp:close/1</c> socket call. If the 1st component of the value + tuple is <c>false</c>, the 2nd one is ignored, which means that + <c>gen_sctp:close/1</c> returns immediately not waiting + for data to be flushed. Otherwise, the 2nd component is + the flushing time-out in seconds.</p> + <marker id="option-sndbuf"></marker> + </item> + <tag><c>{sndbuf, int()}</c></tag> + <item> + <p>The size, in bytes, of the *kernel* send buffer for this socket. + Sending errors would occur for datagrams larger than + <c>val(sndbuf)</c>. Setting this option also adjusts + the size of the driver buffer (see <c>buffer</c> above).</p> + </item> + <tag><c>{recbuf, int()}</c></tag> + <item> + <p>The size, in bytes, of the *kernel* recv buffer for this socket. + Sending errors would occur for datagrams larger than + <c>val(sndbuf)</c>. Setting this option also adjusts + the size of the driver buffer (see <c>buffer</c> above).</p> + </item> + <tag><c>{sctp_rtoinfo, #sctp_rtoinfo{}}</c></tag> + <item> + <pre> + #sctp_rtoinfo{ + assoc_id = assoc_id(), + initial = int(), + max = int(), + min = int() + } </pre> + <p>Determines re-transmission time-out parameters, in milliseconds, + for the association(s) given by <c>assoc_id</c>. + If <c>assoc_id = 0</c> (default) indicates the whole endpoint. See + <url href="http://www.rfc-archive.org/getrfc.php?rfc=2960">RFC2960</url> and + <url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">Sockets API Extensions for SCTP</url> for the exact semantics of the fields values.</p> + </item> + <tag><c>{sctp_associnfo, #sctp_assocparams{}}</c></tag> + <item> + <pre> + #sctp_assocparams{ + assoc_id = assoc_id(), + asocmaxrxt = int(), + number_peer_destinations = int(), + peer_rwnd = int(), + local_rwnd = int(), + cookie_life = int() + } </pre> + <p>Determines association parameters for the association(s) given by + <c>assoc_id</c>. <c>assoc_id = 0</c> (default) indicates + the whole endpoint. See + <url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">Sockets API Extensions for SCTP</url> for the discussion of their semantics. Rarely used.</p> + </item> + <tag><c>{sctp_initmsg, #sctp_initmsg{}}</c></tag> + <item> + <pre> + #sctp_initmsg{ + num_ostreams = int(), + max_instreams = int(), + max_attempts = int(), + max_init_timeo = int() + } </pre> + <p>Determines the default parameters which this socket attempts + to negotiate with its peer while establishing an association with it. + Should be set after <c>open/*</c> but before the first + <c>connect/*</c>. <c>#sctp_initmsg{}</c> can also be used + as ancillary data with the first call of <c>send/*</c> to + a new peer (when a new association is created).</p> + <list type="bulleted"> + <item> + <p><c>num_ostreams</c>: number of outbound streams;</p> + </item> + <item> + <p><c>max_instreams</c>: max number of in-bound streams;</p> + </item> + <item> + <p><c>max_attempts</c>: max re-transmissions while + establishing an association;</p> + </item> + <item> + <p><c>max_init_timeo</c>: time-out in milliseconds + for establishing an association.</p> + </item> + </list> + <p></p> + </item> + <tag><c>{sctp_autoclose, int()|infinity}</c></tag> + <item> + <p>Determines the time (in seconds) after which an idle association is + automatically closed.</p> + </item> + <tag><c>{sctp_nodelay, true|false}</c></tag> + <item> + <p>Turns on|off the Nagle algorithm for merging small packets + into larger ones (which improves throughput at the expense + of latency).</p> + </item> + <tag><c>{sctp_disable_fragments, true|false}</c></tag> + <item> + <p>If <c>true</c>, induces an error on an attempt to send + a message which is larger than the current PMTU size + (which would require fragmentation/re-assembling). + Note that message fragmentation does not affect + the logical atomicity of its delivery; this option + is provided for performance reasons only.</p> + </item> + <tag><c>{sctp_i_want_mapped_v4_addr, true|false}</c></tag> + <item> + <p>Turns on|off automatic mapping of IPv4 addresses into IPv6 ones + (if the socket address family is AF_INET6).</p> + </item> + <tag><c>{sctp_maxseg, int()}</c></tag> + <item> + <p>Determines the maximum chunk size if message fragmentation is used. + If <c>0</c>, the chunk size is limited by the Path MTU only.</p> + </item> + <tag><c>{sctp_primary_addr, #sctp_prim{}}</c></tag> + <item> + <pre> + #sctp_prim{ + assoc_id = assoc_id(), + addr = {IP, Port} + } + IP = ip_address() + Port = port_number() </pre> + <p>For the association given by <c>assoc_id</c>, + <c>{IP,Port}</c> must be one of the peer's addresses. + This option determines that the given address is + treated by the local SCTP stack as the peer's primary address.</p> + </item> + <tag><c>{sctp_set_peer_primary_addr, #sctp_setpeerprim{}}</c></tag> + <item> + <pre> + #sctp_setpeerprim{ + assoc_id = assoc_id(), + addr = {IP, Port} + } + IP = ip_address() + Port = port_number() </pre> + <p>When set, informs the peer that it should use <c>{IP, Port}</c> + as the primary address of the local endpoint for the association + given by <c>assoc_id</c>.</p> + <marker id="option-sctp_adaptation_layer"></marker> + </item> + <tag><c>{sctp_adaptation_layer, #sctp_setadaptation{}}</c></tag> + <item> + <marker id="record-sctp_setadaptation"></marker> + <pre> + #sctp_setadaptation{ + adaptation_ind = int() + } </pre> + <p>When set, requests that the local endpoint uses the value given by + <c>adaptation_ind</c> as the Adaptation Indication parameter for + establishing new associations. See + <url href="http://www.rfc-archive.org/getrfc.php?rfc=2960">RFC2960</url> and + <url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">Sockets API Extenstions for SCTP</url> for more details.</p> + </item> + <tag><c>{sctp_peer_addr_params, #sctp_paddrparams{}}</c></tag> + <item> + <pre> + #sctp_paddrparams{ + assoc_id = assoc_id(), + address = {IP, Port}, + hbinterval = int(), + pathmaxrxt = int(), + pathmtu = int(), + sackdelay = int(), + flags = list() + } + IP = ip_address() + Port = port_number() </pre> + <p>This option determines various per-address parameters for + the association given by <c>assoc_id</c> and the peer address + <c>address</c> (the SCTP protocol supports multi-homing, + so more than 1 address can correspond to a given association).</p> + <list type="bulleted"> + <item> + <p><c>hbinterval</c>: heartbeat interval, in milliseconds;</p> + </item> + <item> + <p><c>pathmaxrxt</c>: max number of retransmissions + before this address is considered unreachable (and an + alternative address is selected);</p> + </item> + <item> + <p><c>pathmtu</c>: fixed Path MTU, if automatic discovery is + disabled (see <c>flags</c> below);</p> + </item> + <item> + <p><c>sackdelay</c>: delay in milliseconds for SAC messages + (if the delay is enabled, see <c>flags</c> below);</p> + </item> + <item> + <p><c>flags</c>: the following flags are available:</p> + <list type="bulleted"> + <item> + <p><c>hb_enable</c>: enable heartbeat; </p> + </item> + <item> + <p><c>hb_disable</c>: disable heartbeat;</p> + </item> + <item> + <p><c>hb_demand</c>: initiate heartbeat immediately;</p> + </item> + <item> + <p><c>pmtud_enable</c>: enable automatic Path MTU discovery;</p> + </item> + <item> + <p><c>pmtud_disable</c>: disable automatic Path MTU discovery;</p> + </item> + <item> + <p><c>sackdelay_enable</c>: enable SAC delay;</p> + </item> + <item> + <p><c>sackdelay_disable</c>: disable SAC delay.</p> + </item> + </list> + <p></p> + </item> + </list> + <p></p> + </item> + <tag><c>{sctp_default_send_param, #sctp_sndrcvinfo{}}</c></tag> + <item> + <marker id="record-sctp_sndrcvinfo"></marker> + <pre> + #sctp_sndrcvinfo{ + stream = int(), + ssn = int(), + flags = list(), + ppid = int(), + context = int(), + timetolive = int(), + tsn = int(), + cumtsn = int(), + assoc_id = assoc_id() + } </pre> + <p><c>#sctp_sndrcvinfo{}</c> is used both in this socket option, and as + ancillary data while sending or receiving SCTP messages. When + set as an option, it provides a default values for subsequent + <c>gen_sctp:send</c>calls on the association given by + <c>assoc_id</c>. <c>assoc_id = 0</c> (default) indicates + the whole endpoint. The following fields typically need + to be specified by the sender:</p> + <list type="bulleted"> + <item> + <p><c>sinfo_stream</c>: stream number (0-base) within the association + to send the messages through;</p> + </item> + <item> + <p><c>sinfo_flags</c>: the following flags are recognised:</p> + <list type="bulleted"> + <item> + <p><c>unordered</c>: the message is to be sent unordered;</p> + </item> + <item> + <p><c>addr_over</c>: the address specified in + <c>gen_sctp:send</c> overwrites the primary peer address;</p> + </item> + <item> + <p><c>abort</c>: abort the current association without + flushing any unsent data;</p> + </item> + <item> + <p><c>eof</c>: gracefully shut down the current + association, with flushing of unsent data.</p> + </item> + </list> + <p></p> + <p>Other fields are rarely used. See + <url href="http://www.rfc-archive.org/getrfc.php?rfc=2960">RFC2960</url> and + <url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">Sockets API Extensions for SCTP</url> for full information.</p> + </item> + </list> + <p></p> + <marker id="option-sctp_events"></marker> + </item> + <tag><c>{sctp_events, #sctp_event_subscribe{}}</c></tag> + <item> + <marker id="record-sctp_event_subscribe"></marker> + <pre> + #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 + } </pre> + <p>This option determines which + <seealso marker="#sctp_events">SCTP Events</seealso> are to be + received (via <seealso marker="#recv/1">recv/*</seealso>) + along with the data. The only + exception is <c>data_io_event</c> which enables or disables + receiving of + <seealso marker="#record-sctp_sndrcvinfo">#sctp_sndrcvinfo{}</seealso> + ancillary data, not events. + By default, all flags except <c>adaptation_layer_event</c> are + enabled, although <c>sctp_data_io_event</c> and + <c>association_event</c> are used by the driver itself and not + exported to the user level.</p> + </item> + <tag><c>{sctp_delayed_ack_time, #sctp_assoc_value{}}</c></tag> + <item> + <pre> + #sctp_assoc_value{ + assoc_id = assoc_id(), + assoc_value = int() + } </pre> + <p>Rarely used. Determines the ACK time + (given by <c>assoc_value</c> in milliseconds) for + the given association or the whole endpoint + if <c>assoc_value = 0</c> (default).</p> + </item> + <tag><c>{sctp_status, #sctp_status{}}</c></tag> + <item> + <pre> + #sctp_status{ + assoc_id = assoc_id(), + state = atom(), + rwnd = int(), + unackdata = int(), + penddata = int(), + instrms = int(), + outstrms = int(), + fragmentation_point = int(), + primary = #sctp_paddrinfo{} + } </pre> + <p>This option is read-only. It determines the status of + the SCTP association given by <c>assoc_id</c>. Possible values of + <c>state</c> follows. The state designations are mostly + self-explanatory. <c>state_empty</c> is the default which means + that no other state is active:</p> + <list type="bulleted"> + <item> + <p><c>sctp_state_empty</c></p> + </item> + <item> + <p><c>sctp_state_closed</c></p> + </item> + <item> + <p><c>sctp_state_cookie_wait</c></p> + </item> + <item> + <p><c>sctp_state_cookie_echoed</c></p> + </item> + <item> + <p><c>sctp_state_established</c></p> + </item> + <item> + <p><c>sctp_state_shutdown_pending</c></p> + </item> + <item> + <p><c>sctp_state_shutdown_sent</c></p> + </item> + <item> + <p><c>sctp_state_shutdown_received</c></p> + </item> + <item> + <p><c>sctp_state_shutdown_ack_sent</c></p> + </item> + </list> + <p>The semantics of other fields is the following:</p> + <list type="bulleted"> + <item> + <p><c>sstat_rwnd</c>: the association peer's current receiver + window size;</p> + </item> + <item> + <p><c>sstat_unackdata</c>: number of unacked data chunks;</p> + </item> + <item> + <p><c>sstat_penddata</c>: number of data chunks pending receipt;</p> + </item> + <item> + <p><c>sstat_instrms</c>: number of inbound streams;</p> + </item> + <item> + <p><c>sstat_outstrms</c>: number of outbound streams;</p> + </item> + <item> + <p><c>sstat_fragmentation_point</c>: message size at which SCTP + fragmentation will occur;</p> + </item> + <item> + <p><c>sstat_primary</c>: information on the current primary peer + address (see below for the format of <c>#sctp_paddrinfo{}</c>).</p> + </item> + </list> + <p></p> + <marker id="option-sctp_get_peer_addr_info"></marker> + </item> + <tag><c>{sctp_get_peer_addr_info, #sctp_paddrinfo{}}</c></tag> + <item> + <marker id="record-sctp_paddrinfo"></marker> + <pre> + #sctp_paddrinfo{ + assoc_id = assoc_id(), + address = {IP, Port}, + state = inactive | active, + cwnd = int(), + srtt = int(), + rto = int(), + mtu = int() + } + IP = ip_address() + Port = port_number() </pre> + <p>This option is read-only. It determines the parameters specific to + the peer's address given by <c>address</c> within the association + given by <c>assoc_id</c>. The <c>address</c> field must be set by the + caller; all other fields are filled in on return. + If <c>assoc_id = 0</c> (default), the <c>address</c> + is automatically translated into the corresponding + association ID. This option is rarely used; see + <url href="http://www.rfc-archive.org/getrfc.php?rfc=2960">RFC2960</url> and + <url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">Sockets API Extensions for SCTP</url> for the semantics of all fields.</p> + </item> + </taglist> + </section> + + <section> + <marker id="examples"></marker> + <title>SCTP EXAMPLES</title> + <list type="bulleted"> + <item> + <p>Example of an Erlang SCTP Server which receives SCTP messages and + prints them on the standard output:</p> + <pre> + -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([{ip,IP},{port,Port}],[{recbuf,65536}]), + 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). </pre> + <p></p> + </item> + <item> + <p>Example of an Erlang SCTP Client which interacts with the above Server. + Note that in this example, the Client creates an association with + the Server with 5 outbound streams. For this reason, sending of + "Test 0" over Stream 0 succeeds, but sending of "Test 5" + over Stream 5 fails. The client then <c>abort</c>s the association, + which results in the corresponding Event being received on + the Server side.</p> + <pre> + -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). </pre> + <p></p> + </item> + </list> + </section> + + <section> + <marker id="seealso"></marker> + <title>SEE ALSO</title> + <p><seealso marker="inet">inet(3)</seealso>, + <seealso marker="gen_tcp">gen_tcp(3)</seealso>, + <seealso marker="gen_udp">gen_upd(3)</seealso>, + <url href="http://www.rfc-archive.org/getrfc.php?rfc=2960">RFC2960</url> (Stream Control Transmission Protocol), + <url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">Sockets API Extensions for SCTP.</url></p> + <marker id="authors"></marker> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml new file mode 100644 index 0000000000..032dcc5251 --- /dev/null +++ b/lib/kernel/doc/src/gen_tcp.xml @@ -0,0 +1,464 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>gen_tcp</title> + <prepared>[email protected]</prepared> + <docno></docno> + <date>1997-10-24</date> + <rev>A</rev> + </header> + <module>gen_tcp</module> + <modulesummary>Interface to TCP/IP sockets</modulesummary> + <description> + <p>The <c>gen_tcp</c> module provides functions for communicating + with sockets using the TCP/IP protocol.</p> + <p>The following code fragment provides a simple example of + a client connecting to a server at port 5678, transferring a + binary and closing the connection:</p> + <code type="none"> +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).</code> + <p>At the other end a server is listening on port 5678, accepts + the connection and receives the binary:</p> + <code type="none"> +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), + 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.</code> + <p>For more examples, see the <seealso marker="#examples">examples</seealso> section.</p> + </description> + + <section> + <title>DATA TYPES</title> + <code type="none"> +ip_address() + see inet(3) + +posix() + see inet(3) + +socket() + as returned by accept/1,2 and connect/3,4</code> + </section> + <funcs> + <func> + <name>connect(Address, Port, Options) -> {ok, Socket} | {error, Reason}</name> + <name>connect(Address, Port, Options, Timeout) -> {ok, Socket} | {error, Reason}</name> + <fsummary>Connect to a TCP port</fsummary> + <type> + <v>Address = string() | atom() | ip_address()</v> + <v>Port = 0..65535</v> + <v>Options = [Opt]</v> + <v> Opt -- see below</v> + <v>Timeout = int() | infinity</v> + <v>Socket = socket()</v> + <v>Reason = posix()</v> + </type> + <desc> + <p>Connects to a server on TCP port <c>Port</c> on the host + with IP address <c>Address</c>. The <c>Address</c> argument + can be either a hostname, or an IP address.</p> + <p>The available options are:</p> + <taglist> + <tag><c>list</c></tag> + <item> + <p>Received <c>Packet</c> is delivered as a list.</p> + </item> + <tag><c>binary</c></tag> + <item> + <p>Received <c>Packet</c> is delivered as a binary.</p> + </item> + <tag><c>{ip, ip_address()}</c></tag> + <item> + <p>If the host has several network interfaces, this option + specifies which one to use.</p> + </item> + <tag><c>{port, Port}</c></tag> + <item> + <p>Specify which local port number to use.</p> + </item> + <tag><c>{fd, int()}</c></tag> + <item> + <p>If a socket has somehow been connected without using + <c>gen_tcp</c>, use this option to pass the file + descriptor for it.</p> + </item> + <tag><c>inet6</c></tag> + <item> + <p>Set up the socket for IPv6.</p> + </item> + <tag><c>inet</c></tag> + <item> + <p>Set up the socket for IPv4.</p> + </item> + <tag>Opt</tag> + <item> + <p>See + <seealso marker="inet#setopts/2">inet:setopts/2</seealso>.</p> + </item> + </taglist> + <p>Packets can be sent to the returned socket <c>Socket</c> + using <c>send/2</c>. Packets sent from the peer are delivered + as messages:</p> + <code type="none"> +{tcp, Socket, Data}</code> + <p>If the socket is closed, the following message is delivered:</p> + <code type="none"> +{tcp_closed, Socket}</code> + <p>If an error occurs on the socket, the following message is + delivered:</p> + <code type="none"> +{tcp_error, Socket, Reason}</code> + <p>unless <c>{active, false}</c> is specified in the option list + for the socket, in which case packets are retrieved by + calling <c>recv/2</c>.</p> + <p>The optional <c>Timeout</c> parameter specifies a timeout in + milliseconds. The default value is <c>infinity</c>.</p> + <note> + <p>The default values for options given to <c>connect</c> can + be affected by the Kernel configuration parameter + <c>inet_default_connect_options</c>. See + <seealso marker="inet">inet(3)</seealso> for details.</p> + </note> + </desc> + </func> + <func> + <name>listen(Port, Options) -> {ok, ListenSocket} | {error, Reason}</name> + <fsummary>Set up a socket to listen on a port</fsummary> + <type> + <v>Port = 0..65535</v> + <v>Options = [Opt]</v> + <v> Opt -- see below</v> + <v>ListenSocket -- see below</v> + <v>Reason = posix()</v> + </type> + <desc> + <p>Sets up a socket to listen on the port <c>Port</c> on + the local host.</p> + <p>If <c>Port == 0</c>, the underlying OS assigns an available + port number, use <c>inet:port/1</c> to retrieve it.</p> + <p>The available options are:</p> + <taglist> + <tag><c>list</c></tag> + <item> + <p>Received <c>Packet</c> is delivered as a list.</p> + </item> + <tag><c>binary</c></tag> + <item> + <p>Received <c>Packet</c> is delivered as a binary.</p> + </item> + <tag><c>{backlog, B}</c></tag> + <item> + <p><c>B</c> is an integer >= 0. The backlog value defaults + to 5. The backlog value defines the maximum length that + the queue of pending connections may grow to.</p> + </item> + <tag><c>{ip, ip_address()}</c></tag> + <item> + <p>If the host has several network interfaces, this option + specifies which one to listen on.</p> + </item> + <tag><c>{fd, Fd}</c></tag> + <item> + <p>If a socket has somehow been connected without using + <c>gen_tcp</c>, use this option to pass the file + descriptor for it.</p> + </item> + <tag><c>inet6</c></tag> + <item> + <p>Set up the socket for IPv6.</p> + </item> + <tag><c>inet</c></tag> + <item> + <p>Set up the socket for IPv4.</p> + </item> + <tag><c>Opt</c></tag> + <item> + <p>See + <seealso marker="inet#setopts/2">inet:setopts/2</seealso>.</p> + </item> + </taglist> + <p>The returned socket <c>ListenSocket</c> can only be used in + calls to <c>accept/1,2</c>.</p> + <note> + <p>The default values for options given to <c>listen</c> can + be affected by the Kernel configuration parameter + <c>inet_default_listen_options</c>. See + <seealso marker="inet">inet(3)</seealso> for details.</p> + </note> + </desc> + </func> + <func> + <name>accept(ListenSocket) -> {ok, Socket} | {error, Reason}</name> + <name>accept(ListenSocket, Timeout) -> {ok, Socket} | {error, Reason}</name> + <fsummary>Accept an incoming connection request on a listen socket</fsummary> + <type> + <v>ListenSocket -- see listen/2</v> + <v>Timeout = int() | infinity</v> + <v>Socket = socket()</v> + <v>Reason = closed | timeout | posix()</v> + </type> + <desc> + <p>Accepts an incoming connection request on a listen socket. + <c>Socket</c> must be a socket returned from <c>listen/2</c>. + <c>Timeout</c> specifies a timeout value in ms, defaults to + <c>infinity</c>.</p> + <p>Returns <c>{ok, Socket}</c> if a connection is established, + or <c>{error, closed}</c> if <c>ListenSocket</c> is closed, + or <c>{error, timeout}</c> if no connection is established + within the specified time. May also return a POSIX error + value if something else goes wrong, see inet(3) for possible + error values.</p> + <p>Packets can be sent to the returned socket <c>Socket</c> + using <c>send/2</c>. Packets sent from the peer are delivered + as messages:</p> + <code type="none"> +{tcp, Socket, Data}</code> + <p>unless <c>{active, false}</c> was specified in the option + list for the listen socket, in which case packets are + retrieved by calling <c>recv/2</c>.</p> + <note> + <p>It is worth noting that the <c>accept</c> call does + <em>not</em> 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.</p> + </note> + </desc> + </func> + <func> + <name>send(Socket, Packet) -> ok | {error, Reason}</name> + <fsummary>Send a packet</fsummary> + <type> + <v>Socket = socket()</v> + <v>Packet = [char()] | binary()</v> + <v>Reason = posix()</v> + </type> + <desc> + <p>Sends a packet on a socket. </p> + <p>There is no <c>send</c> call with timeout option, you use the + <c>send_timeout</c> socket option if timeouts are + desired. See the <seealso marker="#examples">examples</seealso> section.</p> + </desc> + </func> + <func> + <name>recv(Socket, Length) -> {ok, Packet} | {error, Reason}</name> + <name>recv(Socket, Length, Timeout) -> {ok, Packet} | {error, Reason}</name> + <fsummary>Receive a packet from a passive socket</fsummary> + <type> + <v>Socket = socket()</v> + <v>Length = int()</v> + <v>Packet = [char()] | binary()</v> + <v>Timeout = int() | infinity</v> + <v>Reason = closed | posix()</v> + </type> + <desc> + <p>This function receives a packet from a socket in passive + mode. A closed socket is indicated by a return value + <c>{error, closed}</c>.</p> + <p>The <c>Length</c> argument is only meaningful when + the socket is in <c>raw</c> mode and denotes the number of + bytes to read. If <c>Length</c> = 0, all available bytes are + returned. If <c>Length</c> > 0, exactly <c>Length</c> + bytes are returned, or an error; possibly discarding less + than <c>Length</c> bytes of data when the socket gets closed + from the other side.</p> + <p>The optional <c>Timeout</c> parameter specifies a timeout in + milliseconds. The default value is <c>infinity</c>.</p> + </desc> + </func> + <func> + <name>controlling_process(Socket, Pid) -> ok | {error, Reason}</name> + <fsummary>Change controlling process of a socket</fsummary> + <type> + <v>Socket = socket()</v> + <v>Pid = pid()</v> + <v>Reason = closed | not_owner | posix()</v> + </type> + <desc> + <p>Assigns a new controlling process <c>Pid</c> to + <c>Socket</c>. The controlling process is the process which + receives messages from the socket. If called by any other + process than the current controlling process, + <c>{error, eperm}</c> is returned.</p> + </desc> + </func> + <func> + <name>close(Socket) -> ok | {error, Reason}</name> + <fsummary>Close a TCP socket</fsummary> + <type> + <v>Socket = socket()</v> + <v>Reason = posix()</v> + </type> + <desc> + <p>Closes a TCP socket.</p> + </desc> + </func> + <func> + <name>shutdown(Socket, How) -> ok | {error, Reason}</name> + <fsummary>Immediately close a socket</fsummary> + <type> + <v>Socket = socket()</v> + <v>How = read | write | read_write</v> + <v>Reason = posix()</v> + </type> + <desc> + <p>Immediately close a socket in one or two directions.</p> + <p><c>How == write</c> means closing the socket for writing, + reading from it is still possible.</p> + <p>To be able to handle that the peer has done a shutdown on + the write side, the <c>{exit_on_close, false}</c> option + is useful.</p> + </desc> + </func> + </funcs> + + <section> + <title>Examples</title> + <marker id="examples"></marker> + <p>The following example illustrates usage of the {active,once} + option and multiple accepts by implementing a server as a + number of worker processes doing accept on one single listen + socket. The start/2 function takes the number of worker + processes as well as a port number to listen for incoming + connections on. If <c>LPort</c> is specified as <c>0</c>, an + ephemeral portnumber is used, why the start function returns + the actual portnumber allocated:</p> + <code type="none"> +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.</code> + <p>A simple client could look like this:</p> + <code type="none"> +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.</code> + <p>The fact that the <c>send</c> call does not accept a timeout + option, is because timeouts on send is handled through the socket + option <c>send_timeout</c>. The behavior of a send operation with + no receiver is in a very high degree defined by the underlying TCP + stack, as well as the network infrastructure. If one wants to write + code that handles a hanging receiver that might eventually cause + the sender to hang on a <c>send</c> call, one writes code like + the following.</p> + <p>Consider a process that receives data from a client process that + is to be forwarded to a server on the network. The process has + connected to the server via TCP/IP and does not get any acknowledge + for each message it sends, but has to rely on the send timeout + option to detect that the other end is unresponsive. We could use + the <c>send_timeout</c> option when connecting:</p> + <code type="none"> + ... + {ok,Sock} = gen_tcp:connect(HostAddress, Port, + [{active,false}, + {send_timeout, 5000}, + {packet,2}]), + loop(Sock), % See below + ... </code> + <p>In the loop where requests are handled, we can now detect send + timeouts:</p> + <code type="none"> +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. </code> + <p>Usually it would suffice to detect timeouts on receive, as most + protocols include some sort of acknowledgment from the server, + but if the protocol is strictly one way, the <c>send_timeout</c> + option comes in handy!</p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml new file mode 100644 index 0000000000..71f2e9bd83 --- /dev/null +++ b/lib/kernel/doc/src/gen_udp.xml @@ -0,0 +1,179 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>gen_udp</title> + <prepared>[email protected]</prepared> + <docno></docno> + <date>1997-12-03</date> + <rev>A</rev> + </header> + <module>gen_udp</module> + <modulesummary>Interface to UDP sockets</modulesummary> + <description> + <p>The <c>gen_udp</c> module provides functions for communicating + with sockets using the UDP protocol.</p> + </description> + + <section> + <title>DATA TYPES</title> + <code type="none"> +ip_address() + see inet(3) + +posix() + see inet(3) + +socket() + as returned by open/1,2</code> + </section> + <funcs> + <func> + <name>open(Port) -> {ok, Socket} | {error, Reason}</name> + <name>open(Port, Options) -> {ok, Socket} | {error, Reason}</name> + <fsummary>Associate a UDP port number with the process calling it</fsummary> + <type> + <v>Port = 0..65535</v> + <v>Options = [Opt]</v> + <v> Opt -- see below</v> + <v>Socket = socket()</v> + <v>Reason = posix()</v> + </type> + <desc> + <p>Associates a UDP port number (<c>Port</c>) with the calling + process.</p> + <p>The available options are:</p> + <taglist> + <tag><c>list</c></tag> + <item> + <p>Received <c>Packet</c> is delivered as a list.</p> + </item> + <tag><c>binary</c></tag> + <item> + <p>Received <c>Packet</c> is delivered as a binary.</p> + </item> + <tag><c>{ip, ip_address()}</c></tag> + <item> + <p>If the host has several network interfaces, this option + specifies which one to use.</p> + </item> + <tag><c>{fd, int()}</c></tag> + <item> + <p>If a socket has somehow been opened without using + <c>gen_udp</c>, use this option to pass the file + descriptor for it.</p> + </item> + <tag><c>inet6</c></tag> + <item> + <p>Set up the socket for IPv6.</p> + </item> + <tag><c>inet</c></tag> + <item> + <p>Set up the socket for IPv4.</p> + </item> + <tag><c>Opt</c></tag> + <item> + <p>See + <seealso marker="inet#setopts/2">inet:setopts/2</seealso>.</p> + </item> + </taglist> + <p>The returned socket <c>Socket</c> is used to send packets + from this port with <c>send/4</c>. When UDP packets arrive at + the opened port, they are delivered as messages:</p> + <code type="none"> +{udp, Socket, IP, InPortNo, Packet}</code> + <p>Note that arriving UDP packets that are longer than + the receive buffer option specifies, might be truncated + without warning.</p> + <p><c>IP</c> and <c>InPortNo</c> define the address from which + <c>Packet</c> came. <c>Packet</c> is a list of bytes if + the option <c>list</c> was specified. <c>Packet</c> is a + binary if the option <c>binary</c> was specified.</p> + <p>Default value for the receive buffer option is + <c>{recbuf, 8192}</c>.</p> + <p>If <c>Port == 0</c>, the underlying OS assigns a free UDP + port, use <c>inet:port/1</c> to retrieve it.</p> + </desc> + </func> + <func> + <name>send(Socket, Address, Port, Packet) -> ok | {error, Reason}</name> + <fsummary>Send a packet</fsummary> + <type> + <v>Socket = socket()</v> + <v>Address = string() | atom() | ip_address()</v> + <v>Port = 0..65535</v> + <v>Packet = [char()] | binary()</v> + <v>Reason = not_owner | posix()</v> + </type> + <desc> + <p>Sends a packet to the specified address and port. + The <c>Address</c> argument can be either a hostname, or an + IP address.</p> + </desc> + </func> + <func> + <name>recv(Socket, Length) -> {ok, {Address, Port, Packet}} | {error, Reason}</name> + <name>recv(Socket, Length, Timeout) -> {ok, {Address, Port, Packet}} | {error, Reason}</name> + <fsummary>Receive a packet from a passive socket</fsummary> + <type> + <v>Socket = socket()</v> + <v>Length = int()</v> + <v>Address = ip_address()</v> + <v>Port = 0..65535</v> + <v>Packet = [char()] | binary()</v> + <v>Timeout = int() | infinity</v> + <v>Reason = not_owner | posix()</v> + </type> + <desc> + <p>This function receives a packet from a socket in passive + mode.</p> + <p>The optional <c>Timeout</c> parameter specifies a timeout in + milliseconds. The default value is <c>infinity</c>.</p> + </desc> + </func> + <func> + <name>controlling_process(Socket, Pid) -> ok</name> + <fsummary>Change controlling process of a socket</fsummary> + <type> + <v>Socket = socket()</v> + <v>Pid = pid()</v> + </type> + <desc> + <p>Assigns a new controlling process <c>Pid</c> to + <c>Socket</c>. The controlling process is the process which + receives messages from the socket.</p> + </desc> + </func> + <func> + <name>close(Socket) -> ok | {error, Reason}</name> + <fsummary>Close a UDP socket</fsummary> + <type> + <v>Socket = socket()</v> + <v>Reason = not_owner | posix()</v> + </type> + <desc> + <p>Closes a UDP socket.</p> + </desc> + </func> + </funcs> +</erlref> + diff --git a/lib/kernel/doc/src/global.xml b/lib/kernel/doc/src/global.xml new file mode 100644 index 0000000000..077109d6c9 --- /dev/null +++ b/lib/kernel/doc/src/global.xml @@ -0,0 +1,399 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>global</title> + <prepared>Martin Björklund</prepared> + <docno></docno> + <date>1997-11-17</date> + <rev></rev> + </header> + <module>global</module> + <modulesummary>A Global Name Registration Facility</modulesummary> + <description> + <p>This documentation describes the Global module which consists + of the following functionalities:</p> + + <list type="bulleted"> + <item>registration of global names;</item> + <item>global locks;</item> + <item>maintenance of the fully connected network.</item> + </list> + + <p>These services are controlled via the process + <c>global_name_server</c> which exists on every node. The global + name server is started automatically when a node is started. + With the term <em>global</em> is meant over a system consisting + of several Erlang nodes.</p> + + <p>The ability to globally register names is a central concept in + the programming of distributed Erlang systems. In this module, + the equivalent of the <c>register/2</c> and <c>whereis/1</c> + BIFs (for local name registration) are implemented, 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 will + also be globally unregistered.</p> + + <p>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. When any action in taken which results in a change to + the global name table, all tables on other nodes are automatically + updated.</p> + + <p>Global locks have lock identities and are set on a specific + resource. For instance, the specified resource could be a pid. + When a global lock is set, access to the locked resource is + denied for all other resources other than the lock requester.</p> + + <p>Both the registration and lock functionalities are atomic. All + nodes involved in these actions will have the same view of + the information.</p> + + <p>The global name server also performs the critical task of + continuously monitoring changes in node configuration: if a node + which runs a globally registered process goes down, the name + will be globally unregistered. To this end the global name + server subscribes to <c>nodeup</c> and <c>nodedown</c> messages + sent from the <c>net_kernel</c> module. Relevant Kernel + application variables in this context are <c>net_setuptime</c>, + <c>net_ticktime</c>, and <c>dist_auto_connect</c>. See also + <seealso marker="kernel_app#net_setuptime">kernel(6)</seealso>.</p> + + <p>The name server will also maintain a fully connected network. For + example, if node <c>N1</c> connects to node <c>N2</c> (which is + already connected to <c>N3</c>), the global name servers on the + nodes <c>N1</c> and <c>N3</c> will make sure that also <c>N1</c> + and <c>N3</c> are connected. If this is not desired, the command + line flag <c>-connect_all false</c> can be used (see also + <seealso marker="erts:erl#connect_all">erl(1)</seealso>). In + this case the name registration facility cannot be used, but the + lock mechanism will still work.</p> + + <p>If the global name server fails to connect nodes (<c>N1</c> and + <c>N3</c> in the example above) a warning event is sent to the + error logger. The presence of such an event does not exclude the + possibility that the nodes will later connect--one can for + example try the command <c>rpc:call(N1, net_adm, ping, [N2])</c> in + the Erlang shell--but it indicates some kind of problem with + the network.</p> + + <note> + <p>If the fully connected network is not set up properly, the + first thing to try is to increase the value of + <c>net_setuptime</c>.</p> + </note> + + </description> + + <funcs> + <func> + <name>del_lock(Id)</name> + <name>del_lock(Id, Nodes) -> void()</name> + <fsummary>Delete a lock</fsummary> + <type> + <v>Id = {ResourceId, LockRequesterId}</v> + <v> ResourceId = term()</v> + <v> LockRequesterId = term()</v> + <v>Nodes = [node()]</v> + </type> + <desc> + <p>Deletes the lock <c>Id</c> synchronously.</p> + </desc> + </func> + + <func> + <name>notify_all_name(Name, Pid1, Pid2) -> none</name> + <fsummary>Name resolving function that notifies both pids</fsummary> + <type> + <v>Name = term()</v> + <v>Pid1 = Pid2 = pid()</v> + </type> + <desc> + <p>This function can be used as a name resolving function for + <c>register_name/3</c> and <c>re_register_name/3</c>. It + unregisters both pids, and sends the message + <c>{global_name_conflict, Name, OtherPid}</c> to both + processes.</p> + </desc> + </func> + + <func> + <name>random_exit_name(Name, Pid1, Pid2) -> Pid1 | Pid2</name> + <fsummary>Name resolving function that kills one pid</fsummary> + <type> + <v>Name = term()</v> + <v>Pid1 = Pid2 = pid()</v> + </type> + <desc> + <p>This function can be used as a name resolving function for + <c>register_name/3</c> and <c>re_register_name/3</c>. It + randomly chooses one of the pids for registration and kills + the other one.</p> + </desc> + </func> + + <func> + <name>random_notify_name(Name, Pid1, Pid2) -> Pid1 | Pid2</name> + <fsummary>Name resolving function that notifies one pid</fsummary> + <type> + <v>Name = term()</v> + <v>Pid1 = Pid2 = pid()</v> + </type> + <desc> + <p>This function can be used as a name resolving function for + <c>register_name/3</c> and <c>re_register_name/3</c>. It + randomly chooses one of the pids for registration, and sends + the message <c>{global_name_conflict, Name}</c> to the other + pid.</p> + </desc> + </func> + + <func> + <name>register_name(Name, Pid)</name> + <name>register_name(Name, Pid, Resolve) -> yes | no</name> + <fsummary>Globally register a name for a pid</fsummary> + <type> + <v>Name = term()</v> + <v>Pid = pid()</v> + <v>Resolve = fun() or {Module, Function} where</v> + <v> Resolve(Name, Pid, Pid2) -> Pid | Pid2 | none</v> + </type> + <desc> + <p>Globally associates the name <c>Name</c> with a pid, that is, + Globally notifies all nodes of a new global name in a network + of Erlang nodes.</p> + + <p>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, + the <c>Resolve</c> function 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.</p> + + <p>There are three pre-defined resolve functions: + <c>random_exit_name/3</c>, <c>random_notify_name/3</c>, and + <c>notify_all_name/3</c>. If no <c>Resolve</c> function is + defined, <c>random_exit_name</c> is used. This means that one + of the two registered processes will be selected as correct + while the other is killed.</p> + + <p>This function is completely synchronous. This means that + when this function returns, the name is either registered on + all nodes or none.</p> + + <p>The function returns <c>yes</c> if successful, <c>no</c> if + it fails. For example, <c>no</c> 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.</p> + + <note> + <p>Releases up to and including OTP R10 did not check if the + process was already registered. As a consequence the + global name table could become inconsistent. The old + (buggy) behavior can be chosen by giving the Kernel + application variable <c>global_multi_name_action</c> the + value <c>allow</c>.</p> + </note> + + <p>If a process with a registered name dies, or the node goes + down, the name is unregistered on all nodes.</p> + </desc> + </func> + + <func> + <name>registered_names() -> [Name]</name> + <fsummary>All globally registered names</fsummary> + <type> + <v>Name = term()</v> + </type> + <desc> + <p>Returns a lists of all globally registered names.</p> + </desc> + </func> + + <func> + <name>re_register_name(Name, Pid)</name> + <name>re_register_name(Name, Pid, Resolve) -> void()</name> + <fsummary>Atomically re-register a name</fsummary> + <type> + <v>Name = term()</v> + <v>Pid = pid()</v> + <v>Resolve = fun() or {Module, Function} where</v> + <v> Resolve(Name, Pid, Pid2) -> Pid | Pid2 | none</v> + </type> + <desc> + <p>Atomically changes the registered name <c>Name</c> on all + nodes to refer to <c>Pid</c>.</p> + + <p>The <c>Resolve</c> function has the same behavior as in + <c>register_name/2,3</c>.</p> + </desc> + </func> + + <func> + <name>send(Name, Msg) -> Pid</name> + <fsummary>Send a message to a globally registered pid</fsummary> + <type> + <v>Name = term()</v> + <v>Msg = term()</v> + <v>Pid = pid()</v> + </type> + <desc> + <p>Sends the message <c>Msg</c> to the pid globally registered + as <c>Name</c>.</p> + + <p>Failure: If <c>Name</c> is not a globally registered + name, the calling function will exit with reason + <c>{badarg, {Name, Msg}}</c>.</p> + </desc> + </func> + + <func> + <name>set_lock(Id)</name> + <name>set_lock(Id, Nodes)</name> + <name>set_lock(Id, Nodes, Retries) -> boolean()</name> + <fsummary>Set a lock on the specified nodes</fsummary> + <type> + <v>Id = {ResourceId, LockRequesterId}</v> + <v> ResourceId = term()</v> + <v> LockRequesterId = term()</v> + <v>Nodes = [node()]</v> + <v>Retries = int() >= 0 | infinity</v> + </type> + <desc> + <p>Sets a lock on the specified nodes (or on all nodes if none + are specified) on <c>ResourceId</c> for + <c>LockRequesterId</c>. If a lock already exists on + <c>ResourceId</c> for another requester than + <c>LockRequesterId</c>, and <c>Retries</c> is not equal to 0, + the process sleeps for a while and will try to execute + the action later. When <c>Retries</c> attempts have been made, + <c>false</c> is returned, otherwise <c>true</c>. If + <c>Retries</c> is <c>infinity</c>, <c>true</c> is eventually + returned (unless the lock is never released).</p> + + <p>If no value for <c>Retries</c> is given, <c>infinity</c> is + used.</p> + + <p>This function is completely synchronous.</p> + + <p>If a process which holds a lock dies, or the node goes + down, the locks held by the process are deleted.</p> + + <p>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.</p> + + <p>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. But if some processes try to lock two or + more resources, a deadlock may occur. It is up to the + application to detect and rectify a deadlock.</p> + + <note> + <p>Some values of <c>ResourceId</c> should be avoided or + Erlang/OTP will not work properly. A list of resources to + avoid: <c>global</c>, <c>dist_ac</c>, + <c>mnesia_table_lock</c>, <c>mnesia_adjust_log_writes</c>, + <c>pg2</c>.</p> + </note> + + </desc> + </func> + + <func> + <name>sync() -> void()</name> + <fsummary>Synchronize the global name server</fsummary> + <desc> + <p>Synchronizes the global name server with all nodes known to + this node. These are the nodes which are returned from + <c>erlang:nodes()</c>. When this function returns, + the global name server will receive global information from + all nodes. This function can be called when new nodes are + added to the network.</p> + </desc> + </func> + + <func> + <name>trans(Id, Fun)</name> + <name>trans(Id, Fun, Nodes)</name> + <name>trans(Id, Fun, Nodes, Retries) -> Res | aborted</name> + <fsummary>Micro transaction facility</fsummary> + <type> + <v>Id = {ResourceId, LockRequesterId}</v> + <v> ResourceId = term()</v> + <v> LockRequesterId = term()</v> + <v>Fun = fun() | {M, F}</v> + <v>Nodes = [node()]</v> + <v>Retries = int() >= 0 | infinity</v> + <v>Res = term()</v> + </type> + <desc> + <p>Sets a lock on <c>Id</c> (using <c>set_lock/3</c>). If this + succeeds, <c>Fun()</c> is evaluated and the result <c>Res</c> + is returned. Returns <c>aborted</c> if the lock attempt + failed. If <c>Retries</c> is set to <c>infinity</c>, + the transaction will not abort.</p> + + <p><c>infinity</c> is the default setting and will be used if + no value is given for <c>Retries</c>.</p> + </desc> + </func> + + <func> + <name>unregister_name(Name) -> void()</name> + <fsummary>Remove a globally registered name for a pid</fsummary> + <type> + <v>Name = term()</v> + </type> + <desc> + <p>Removes the globally registered name <c>Name</c> from + the network of Erlang nodes.</p> + </desc> + </func> + + <func> + <name>whereis_name(Name) -> pid() | undefined</name> + <fsummary>Get the pid with a given globally registered name</fsummary> + <type> + <v>Name = term()</v> + </type> + <desc> + <p>Returns the pid with the globally registered name + <c>Name</c>. Returns <c>undefined</c> if the name is not + globally registered.</p> + </desc> + </func> + </funcs> + + <section> + <title>See Also</title> + <p><seealso marker="global_group">global_group(3)</seealso>, + <seealso marker="net_kernel">net_kernel(3)</seealso></p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/global_group.xml b/lib/kernel/doc/src/global_group.xml new file mode 100644 index 0000000000..4facf4a4aa --- /dev/null +++ b/lib/kernel/doc/src/global_group.xml @@ -0,0 +1,284 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1998</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>global_group</title> + <prepared>Esko Vierumäki</prepared> + <docno></docno> + <date>1998-12-18</date> + <rev>b</rev> + </header> + <module>global_group</module> + <modulesummary>Grouping Nodes to Global Name Registration Groups</modulesummary> + <description> + <p>The global group function makes it possible to group the nodes + in a system into partitions, each partition having its own global + name space, refer to <c>global(3)</c>. These partitions are + called global groups.</p> + <p>The main advantage of dividing systems to global groups is that + the background load decreases while the number of nodes to be + updated is reduced when manipulating globally registered names.</p> + <p>The Kernel configuration parameter <c>global_groups</c> defines + the global groups (see also + <seealso marker="kernel_app">kernel(6)</seealso>, + <seealso marker="config">config(4)</seealso>:</p> + <code type="none"> +{global_groups, [GroupTuple]}</code> + <p>Types:</p> + <list type="bulleted"> + <item><c>GroupTuple = {GroupName, [Node]} | {GroupName, PublishType, [Node]}</c></item> + <item><c>GroupName = atom()</c> (naming a global group)</item> + <item><c>PublishType = normal | hidden</c></item> + <item><c>Node = atom()</c> (naming a node)</item> + </list> + <p>A <c>GroupTuple</c> without <c>PublishType</c> is the same as a + <c>GroupTuple</c> with <c>PublishType == normal</c>.</p> + <p>A node started with the command line flag <c>-hidden</c>, see + <seealso marker="erts:erl">erl(1)</seealso>, is said to be a + <em>hidden</em> node. A hidden node will establish hidden + connections to nodes not part of the same global group, but + normal (visible) connections to nodes part of the same global + group.</p> + <p>A global group defined with <c>PublishType == hidden</c>, is + said to be a hidden global group. All nodes in a hidden global + group are hidden nodes, regardless if they are started with + the <c>-hidden</c> command line flag or not.</p> + <p>For the processes and nodes to run smoothly using the global + group functionality, the following criteria must be met:</p> + <list type="bulleted"> + <item> + <p>An instance of the global group server, <c>global_group</c>, + must be running on each node. The processes are automatically + started and synchronized when a node is started.</p> + </item> + <item> + <p>All involved nodes must agree on the global group definition, + or the behavior of the system is undefined.</p> + </item> + <item> + <p><em>All</em> nodes in the system should belong to exactly + one global group.</p> + </item> + </list> + <p>In the following description, a <em>group node</em> is a node + belonging to the same global group as the local node.</p> + </description> + <funcs> + <func> + <name>global_groups() -> {GroupName, GroupNames} | undefined</name> + <fsummary>Return the global group names</fsummary> + <type> + <v>GroupName = atom()</v> + <v>GroupNames = [GroupName]</v> + </type> + <desc> + <p>Returns a tuple containing the name of the global group + the local node belongs to, and the list of all other known + group names. Returns <c>undefined</c> if no global groups are + defined.</p> + </desc> + </func> + <func> + <name>info() -> [{Item, Info}]</name> + <fsummary>Information about global groups</fsummary> + <type> + <v>Item, Info -- see below</v> + </type> + <desc> + <p>Returns a list containing information about the global + groups. Each element of the list is a tuple. The order of + the tuples is not defined.</p> + <taglist> + <tag><c>{state, State}</c></tag> + <item> + <p>If the local node is part of a global group, + <c>State == synced</c>. If no global groups are defined, + <c>State == no_conf</c>.</p> + </item> + <tag><c>{own_group_name, GroupName}</c></tag> + <item> + <p>The name (atom) of the group that the local node belongs + to.</p> + </item> + <tag><c>{own_group_nodes, Nodes}</c></tag> + <item> + <p>A list of node names (atoms), the group nodes.</p> + </item> + <tag><c>{synced_nodes, Nodes}</c></tag> + <item> + <p>A list of node names, the group nodes currently + synchronized with the local node.</p> + </item> + <tag><c>{sync_error, Nodes}</c></tag> + <item> + <p>A list of node names, the group nodes with which + the local node has failed to synchronize.</p> + </item> + <tag><c>{no_contact, Nodes}</c></tag> + <item> + <p>A list of node names, the group nodes to which there are + currently no connections.</p> + </item> + <tag><c>{other_groups, Groups}</c></tag> + <item> + <p><c>Groups</c> is a list of tuples + <c>{GroupName, Nodes}</c>, specifying the name and nodes + of the other global groups.</p> + </item> + <tag><c>{monitoring, Pids}</c></tag> + <item> + <p>A list of pids, specifying the processes which have + subscribed to <c>nodeup</c> and <c>nodedown</c> messages.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>monitor_nodes(Flag) -> ok </name> + <fsummary>Subscribe to node status changes</fsummary> + <type> + <v>Flag = bool()</v> + </type> + <desc> + <p>Depending on <c>Flag</c>, the calling process starts + subscribing (<c>Flag == true</c>) or stops subscribing + (<c>Flag == false</c>) to node status change messages.</p> + <p>A process which has subscribed will receive the messages + <c>{nodeup, Node}</c> and <c>{nodedown, Node}</c> when a + group node connects or disconnects, respectively.</p> + </desc> + </func> + <func> + <name>own_nodes() -> Nodes</name> + <fsummary>Return the group nodes</fsummary> + <type> + <v>Nodes = [Node]</v> + <v> Node = node()</v> + </type> + <desc> + <p>Returns the names of all group nodes, regardless of their + current status.</p> + </desc> + </func> + <func> + <name>registered_names(Where) -> Names</name> + <fsummary>Return globally registered names</fsummary> + <type> + <v>Where = {node, Node} | {group, GroupName}</v> + <v> Node = node()</v> + <v> GroupName = atom()</v> + <v>Names = [Name]</v> + <v> Name = atom()</v> + </type> + <desc> + <p>Returns a list of all names which are globally registered + on the specified node or in the specified global group.</p> + </desc> + </func> + <func> + <name>send(Name, Msg) -> pid() | {badarg, {Name, Msg}}</name> + <name>send(Where, Name, Msg) -> pid() | {badarg, {Name, Msg}}</name> + <fsummary>Send a message to a globally registered pid</fsummary> + <type> + <v>Where = {node, Node} | {group, GroupName}</v> + <v> Node = node()</v> + <v> GroupName = atom()</v> + <v>Name = atom()</v> + <v>Msg = term()</v> + </type> + <desc> + <p>Searches for <c>Name</c>, globally registered on + the specified node or in the specified global group, or -- + if the <c>Where</c> argument is not provided -- in any global + group. The global groups are searched in the order in which + they appear in the value of the <c>global_groups</c> + configuration parameter.</p> + <p>If <c>Name</c> is found, the message <c>Msg</c> 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 + <c>{badarg, {Name, Msg}}</c>.</p> + </desc> + </func> + <func> + <name>sync() -> ok</name> + <fsummary>Synchronize the group nodes</fsummary> + <desc> + <p>Synchronizes the group nodes, that is, the global name + servers on the group nodes. Also check the names globally + registered in the current global group and unregisters them + on any known node not part of the group.</p> + <p>If synchronization is not possible, an error report is sent + to the error logger (see also <c>error_logger(3)</c>).</p> + <p>Failure: + <c>{error, {'invalid global_groups definition', Bad}}</c> if + the <c>global_groups</c> configuration parameter has an + invalid value <c>Bad</c>.</p> + </desc> + </func> + <func> + <name>whereis_name(Name) -> pid() | undefined</name> + <name>whereis_name(Where, Name) -> pid() | undefined</name> + <fsummary>Get the pid with a given globally registered name</fsummary> + <type> + <v>Where = {node, Node} | {group, GroupName}</v> + <v> Node = node()</v> + <v> GroupName = atom()</v> + <v>Name = atom()</v> + </type> + <desc> + <p>Searches for <c>Name</c>, globally registered on + the specified node or in the specified global group, or -- if + the <c>Where</c> argument is not provided -- in any global + group. The global groups are searched in the order in which + they appear in the value of the <c>global_groups</c> + configuration parameter.</p> + <p>If <c>Name</c> is found, the corresponding pid is returned. + If the name is not found, the function returns + <c>undefined</c>.</p> + </desc> + </func> + </funcs> + + <section> + <title>NOTE</title> + <p>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 may produce an + incorrect or misleading result. For example, the isolated node may + not have accurate information about registered names in its + global group.</p> + <p>Note also that the <c>send/2,3</c> function is not secure.</p> + <p>Distribution of applications is highly dependent of the global + group definitions. It is not recommended that an application is + distributed over several global groups of the obvious reason that + the registered names may be moved to another global group at + failover/takeover. There is nothing preventing doing this, but + the application code must in such case handle the situation.</p> + </section> + + <section> + <title>SEE ALSO</title> + <p><seealso marker="erts:erl">erl(1)</seealso>, + <seealso marker="global">global(3)</seealso></p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/heart.xml b/lib/kernel/doc/src/heart.xml new file mode 100644 index 0000000000..0df699572d --- /dev/null +++ b/lib/kernel/doc/src/heart.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>heart</title> + <prepared>Magnus Fröberg</prepared> + <docno></docno> + <date>1998-01-28</date> + <rev>A</rev> + </header> + <module>heart</module> + <modulesummary>Heartbeat Monitoring of an Erlang Runtime System</modulesummary> + <description> + <p>This modules contains the interface to the <c>heart</c> process. + <c>heart</c> sends periodic heartbeats to an external port + program, which is also named <c>heart</c>. 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 <c>HEART_BEAT_TIMEOUT</c> seconds + (default is 60 seconds), the system can be rebooted. Also, if + the system is equipped with a hardware watchdog timer and is + running Solaris, the watchdog can be used to supervise the entire + system.</p> + <p>An Erlang runtime system to be monitored by a heart program, + should be started with the command line flag <c>-heart</c> (see + also <seealso marker="erts:erl">erl(1)</seealso>. The <c>heart</c> + process is then started automatically:</p> + <pre> +% <input>erl -heart ...</input></pre> + <p>If the system should be rebooted because of missing heart-beats, + or a terminated Erlang runtime system, the environment variable + <c>HEART_COMMAND</c> has to be set before the system is started. + If this variable is not set, a warning text will be printed but + the system will not reboot. However, if the hardware watchdog is + used, it will trigger a reboot <c>HEART_BEAT_BOOT_DELAY</c> + seconds later nevertheless (default is 60).</p> + <p>To reboot on the WINDOWS platform <c>HEART_COMMAND</c> can be + set to <c>heart -shutdown</c> (included in the Erlang delivery) + or of course to any other suitable program which can activate a + reboot.</p> + <p>The hardware watchdog will not be started under Solaris if + the environment variable <c>HW_WD_DISABLE</c> is set.</p> + <p>The <c>HEART_BEAT_TIMEOUT</c> and <c>HEART_BEAT_BOOT_DELAY</c> + environment variables can be used to configure the heart timeouts, + they can be set in the operating system shell before Erlang is + started or be specified at the command line:</p> + <pre> +% <input>erl -heart -env HEART_BEAT_TIMEOUT 30 ...</input></pre> + <p>The value (in seconds) must be in the range 10 < X <= 65535.</p> + <p>It should be noted that if the system clock is adjusted with + more than <c>HEART_BEAT_TIMEOUT</c> seconds, <c>heart</c> will + timeout and try to reboot the system. This can happen, for + example, if the system clock is adjusted automatically by use of + NTP (Network Time Protocol).</p> + <p>In the following descriptions, all function fails with reason + <c>badarg</c> if <c>heart</c> is not started.</p> + </description> + <funcs> + <func> + <name>set_cmd(Cmd) -> ok | {error, {bad_cmd, Cmd}}</name> + <fsummary>Set a temporary reboot command</fsummary> + <type> + <v>Cmd = string()</v> + </type> + <desc> + <p>Sets a temporary reboot command. This command is used if + a <c>HEART_COMMAND</c> other than the one specified with + the environment variable should be used in order to reboot + the system. The new Erlang runtime system will (if it + misbehaves) use the environment variable + <c>HEART_COMMAND</c> to reboot.</p> + <p>Limitations: The length of the <c>Cmd</c> command string + must be less than 2047 characters.</p> + </desc> + </func> + <func> + <name>clear_cmd() -> ok</name> + <fsummary>Clear the temporary boot command</fsummary> + <desc> + <p>Clears the temporary boot command. If the system terminates, + the normal <c>HEART_COMMAND</c> is used to reboot.</p> + </desc> + </func> + <func> + <name>get_cmd() -> {ok, Cmd}</name> + <fsummary>Get the temporary reboot command</fsummary> + <type> + <v>Cmd = string()</v> + </type> + <desc> + <p>Get the temporary reboot command. If the command is cleared, + the empty string will be returned.</p> + </desc> + </func> + </funcs> +</erlref> + diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml new file mode 100644 index 0000000000..cae5fef2f8 --- /dev/null +++ b/lib/kernel/doc/src/inet.xml @@ -0,0 +1,827 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>inet</title> + <prepared>[email protected]</prepared> + <docno></docno> + <date>1998-02-04</date> + <rev>A</rev> + </header> + <module>inet</module> + <modulesummary>Access to TCP/IP Protocols</modulesummary> + <description> + <p>Provides access to TCP/IP protocols.</p> + <p>See also <em>ERTS User's Guide, Inet configuration</em> for more + information on how to configure an Erlang runtime system for IP + communication.</p> + <p>Two Kernel configuration parameters affect the behaviour of all + sockets opened on an Erlang node: + <c>inet_default_connect_options</c> can contain a list of default + options used for all sockets returned when doing <c>connect</c>, + and <c>inet_default_listen_options</c> can contain a list of + default options used when issuing a <c>listen</c> call. When + <c>accept</c> is issued, the values of the listensocket options + are inherited, why no such application variable is needed for + <c>accept</c>.</p> + <p>Using the Kernel configuration parameters mentioned above, one + can set default options for all TCP sockets on a node. This should + be used with care, but options like <c>{delay_send,true}</c> + might be specified in this way. An example of starting an Erlang + node with all sockets using delayed send could look like this:</p> + <pre> +$ <input>erl -sname test -kernel \\</input> +<input>inet_default_connect_options '[{delay_send,true}]' \\</input> +<input>inet_default_listen_options '[{delay_send,true}]'</input></pre> + <p>Note that the default option <c>{active, true}</c> currently + cannot be changed, for internal reasons.</p> + </description> + + <section> + <title>DATA TYPES</title> + <code type="none"> +#hostent{h_addr_list = [ip_address()] % list of addresses for this host + h_addrtype = inet | inet6 + h_aliases = [hostname()] % list of aliases + h_length = int() % length of address in bytes + h_name = hostname() % official name for host + 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() = atom() | string() + +ip_address() = {N1,N2,N3,N4} % IPv4 + | {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6 + Ni = 0..255 + Ki = 0..65535 + +posix() + an atom which is named from the Posix error codes used in + Unix, and in the runtime libraries of most C compilers + +socket() + see gen_tcp(3), gen_udp(3)</code> + <p>Addresses as inputs to functions can be either a string or a + tuple. For instance, the IP address 150.236.20.73 can be passed to + <c>gethostbyaddr/1</c> either as the string "150.236.20.73" + or as the tuple <c>{150, 236, 20, 73}</c>.</p> + <p>IPv4 address examples:</p> + <code type="none"> +Address ip_address() +------- ------------ +127.0.0.1 {127,0,0,1} +192.168.42.2 {192,168,42,2}</code> + <p>IPv6 address examples:</p> + <code type="none"> +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 + {16#FFFF,0,0,0,0,0,(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,0,16#204,16#acff,16#fe17,16#bf38}</code> + <p>A function that may be useful is <c>inet_parse:address/1</c>:</p> + <pre> +1> <input>inet_parse:address("192.168.42.2").</input> +{ok,{192,168,42,2}} +2> <input>inet_parse:address("FFFF::192.168.42.2").</input> +{ok,{65535,0,0,0,0,0,49320,10754}}</pre> + </section> + <funcs> + <func> + <name>close(Socket) -> ok</name> + <fsummary>Close a socket of any type</fsummary> + <type> + <v>Socket = socket()</v> + </type> + <desc> + <p>Closes a socket of any type.</p> + </desc> + </func> + <func> + <name>get_rc() -> [{Par, Val}]</name> + <fsummary>Return a list of IP configuration parameters</fsummary> + <type> + <v>Par, Val -- see below</v> + </type> + <desc> + <p>Returns the state of the Inet configuration database in + form of a list of recorded configuration parameters. (See the + ERTS User's Guide, Inet configuration, for more information). + Only parameters with other than default values are returned.</p> + </desc> + </func> + <func> + <name>format_error(Posix) -> string()</name> + <fsummary>Return a descriptive string for an error reason</fsummary> + <type> + <v>Posix = posix()</v> + </type> + <desc> + <p>Returns a diagnostic error string. See the section below + for possible <c>Posix</c> values and the corresponding + strings.</p> + </desc> + </func> + <func> + <name>getaddr(Host, Family) -> {ok, Address} | {error, posix()}</name> + <fsummary>Return the IP-address for a host</fsummary> + <type> + <v>Host = ip_address() | string() | atom()</v> + <v>Family = inet | inet6</v> + <v>Address = ip_address()</v> + <v>posix() = term()</v> + </type> + <desc> + <p>Returns the IP-address for <c>Host</c> as a tuple of + integers. <c>Host</c> can be an IP-address, a single hostname + or a fully qualified hostname.</p> + </desc> + </func> + <func> + <name>getaddrs(Host, Family) -> {ok, Addresses} | {error, posix()}</name> + <fsummary>Return the IP-addresses for a host</fsummary> + <type> + <v>Host = ip_address() | string() | atom()</v> + <v>Addresses = [ip_address()]</v> + <v>Family = inet | inet6</v> + </type> + <desc> + <p>Returns a list of all IP-addresses for <c>Host</c>. + <c>Host</c> can be an IP-address, a single hostname or a fully + qualified hostname.</p> + </desc> + </func> + <func> + <name>gethostbyaddr(Address) -> {ok, Hostent} | {error, posix()}</name> + <fsummary>Return a hostent record for the host with the given address</fsummary> + <type> + <v>Address = string() | ip_address()</v> + <v>Hostent = #hostent{}</v> + </type> + <desc> + <p>Returns a <c>hostent</c> record given an address.</p> + </desc> + </func> + <func> + <name>gethostbyname(Name) -> {ok, Hostent} | {error, posix()}</name> + <fsummary>Return a hostent record for the host with the given name</fsummary> + <type> + <v>Hostname = hostname()</v> + <v>Hostent = #hostent{}</v> + </type> + <desc> + <p>Returns a <c>hostent</c> record given a hostname.</p> + </desc> + </func> + <func> + <name>gethostbyname(Name, Family) -> {ok, Hostent} | {error, posix()}</name> + <fsummary>Return a hostent record for the host with the given name</fsummary> + <type> + <v>Hostname = hostname()</v> + <v>Family = inet | inet6</v> + <v>Hostent = #hostent{}</v> + </type> + <desc> + <p>Returns a <c>hostent</c> record given a hostname, restricted + to the given address family.</p> + </desc> + </func> + <func> + <name>gethostname() -> {ok, Hostname}</name> + <fsummary>Return the local hostname</fsummary> + <type> + <v>Hostname = string()</v> + </type> + <desc> + <p>Returns the local hostname. Will never fail.</p> + </desc> + </func> + <func> + <name>getopts(Socket, Options) -> OptionValues | {error, posix()}</name> + <fsummary>Get one or more options for a socket</fsummary> + <type> + <v>Socket = term()</v> + <v>Options = [Opt | RawOptReq]</v> + <v>Opt = atom()</v> + <v>RawOptReq = {raw, Protocol, OptionNum, ValueSpec}</v> + <v>Protocol = int()</v> + <v>OptionNum = int()</v> + <v>ValueSpec = ValueSize | ValueBin</v> + <v>ValueSize = int()</v> + <v>ValueBin = binary()</v> + <v>OptionValues = [{Opt, Val} | {raw, Protocol, OptionNum, ValueBin}]</v> + </type> + <desc> + <p>Gets one or more options for a socket. + See <seealso marker="#setopts/2">setopts/2</seealso> + for a list of available options.</p> + <p>The number of elements in the returned <c>OptionValues</c> + list does not necessarily correspond to the number of options + asked for. If the operating system fails to support an option, + it is simply left out in the returned list. An error tuple is only + returned when getting options for the socket is impossible + (i.e. the socket is closed or the buffer size in a raw request + is too large). This behavior is kept for backward + compatibility reasons.</p> + <p>A <c>RawOptReq</c> 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 the current platform.</p> + <p>The <c>RawOptReq</c> consists of the tag <c>raw</c> 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 + should be used when the underlying <c>getsockopt</c> requires + <em>input</em> + in the argument field, in which case the size of the binary + should correspond to the required buffer + size of the return value. The supplied values in a <c>RawOptReq</c> + correspond to the second, third and fourth/fifth parameters to the + <c>getsockopt</c> call in the C socket API. The value stored + in the buffer is returned as a binary <c>ValueBin</c> + where all values are coded in the native endianess.</p> + <p>Asking for and inspecting raw socket options require low + level information about the current operating system and TCP + stack.</p> + <p>As an example, consider a Linux machine where the + <c>TCP_INFO</c> option could be used to collect TCP statistics + for a socket. Lets say we're interested in the + <c>tcpi_sacked</c> field of the <c>struct tcp_info</c> + filled in when asking for <c>TCP_INFO</c>. To + be able to access this information, we need to know both the + numeric value of the protocol level <c>IPPROTO_TCP</c>, the + numeric value of the option <c>TCP_INFO</c>, the size of the + <c>struct tcp_info</c> and the size and offset of + the specific field. By inspecting the headers or writing a small C + program, we found <c>IPPROTO_TCP</c> to be 6, + <c>TCP_INFO</c> to be 11, the structure size to be 92 (bytes), + the offset of <c>tcpi_sacked</c> to be 28 bytes and the actual + value to be a 32 bit integer. We could use the following + code to retrieve the value:</p> + <code type="none"><![CDATA[ + get_tcpi_sacked(Sock) -> + {ok,[{raw,_,_,Info}]} = inet:getopts(Sock,[{raw,6,11,92}]), + <<_:28/binary,TcpiSacked:32/native,_/binary>> = Info, + TcpiSacked.]]></code> + <p>Preferably, you would check the machine type, the OS + and the kernel version prior to executing anything similar to the + code above.</p> + </desc> + </func> + + <func> + <name>getstat(Socket)</name> + <name>getstat(Socket, Options) -> {ok, OptionValues} | {error, posix()}</name> + <fsummary>Get one or more statistic options for a socket</fsummary> + <type> + <v>Socket = term()</v> + <v>Options = [Opt]</v> + <v>OptionValues = [{Opt, Val}]</v> + <v> Opt, Val -- see below</v> + </type> + <desc> + <p>Gets one or more statistic options for a socket.</p> + <p><c>getstat(Socket)</c> is equivalent to + <c>getstat(Socket, [recv_avg, recv_cnt, recv_dvi, recv_max, recv_oct, send_avg, send_cnt, send_dvi, send_max, send_oct])</c></p> + <p>The following options are available:</p> + <taglist> + <tag><c>recv_avg</c></tag> + <item> + <p>Average size of packets in bytes received to the socket.</p> + </item> + <tag><c>recv_cnt</c></tag> + <item> + <p>Number of packets received to the socket.</p> + </item> + <tag><c>recv_dvi</c></tag> + <item> + <p>Average packet size deviation in bytes received to the socket.</p> + </item> + <tag><c>recv_max</c></tag> + <item> + <p>The size of the largest packet in bytes received to the socket.</p> + </item> + <tag><c>recv_oct</c></tag> + <item> + <p>Number of bytes received to the socket.</p> + </item> + + <tag><c>send_avg</c></tag> + <item> + <p>Average size of packets in bytes sent from the socket.</p> + </item> + <tag><c>send_cnt</c></tag> + <item> + <p>Number of packets sent from the socket.</p> + </item> + <tag><c>send_dvi</c></tag> + <item> + <p>Average packet size deviation in bytes received sent from the socket.</p> + </item> + <tag><c>send_max</c></tag> + <item> + <p>The size of the largest packet in bytes sent from the socket.</p> + </item> + <tag><c>send_oct</c></tag> + <item> + <p>Number of bytes sent from the socket.</p> + </item> + </taglist> + </desc> + </func> + + <func> + <name>peername(Socket) -> {ok, {Address, Port}} | {error, posix()}</name> + <fsummary>Return the address and port for the other end of a connection</fsummary> + <type> + <v>Socket = socket()</v> + <v>Address = ip_address()</v> + <v>Port = int()</v> + </type> + <desc> + <p>Returns the address and port for the other end of a + connection.</p> + </desc> + </func> + <func> + <name>port(Socket) -> {ok, Port}</name> + <fsummary>Return the local port number for a socket</fsummary> + <type> + <v>Socket = socket()</v> + <v>Port = int()</v> + </type> + <desc> + <p>Returns the local port number for a socket.</p> + </desc> + </func> + <func> + <name>sockname(Socket) -> {ok, {Address, Port}} | {error, posix()}</name> + <fsummary>Return the local address and port number for a socket</fsummary> + <type> + <v>Socket = socket()</v> + <v>Address = ip_address()</v> + <v>Port = int()</v> + </type> + <desc> + <p>Returns the local address and port number for a socket.</p> + </desc> + </func> + <func> + <name>setopts(Socket, Options) -> ok | {error, posix()}</name> + <fsummary>Set one or more options for a socket</fsummary> + <type> + <v>Socket = term()</v> + <v>Options = [{Opt, Val} | {raw, Protocol, Option, ValueBin}]</v> + <v>Protocol = int()</v> + <v>OptionNum = int()</v> + <v>ValueBin = binary()</v> + <v> Opt, Val -- see below</v> + </type> + <desc> + <p>Sets one or more options for a socket. The following options + are available:</p> + <taglist> + <tag><c>{active, true | false | once}</c></tag> + <item> + <p>If the value is <c>true</c>, which is the default, + everything received from the socket will be sent as + messages to the receiving process. If the value is + <c>false</c> (passive mode), the process must explicitly + receive incoming data by calling <c>gen_tcp:recv/2,3</c> + or <c>gen_udp:recv/2,3</c> (depending on the type of + socket).</p> + <p>If the value is <c>once</c> (<c>{active, once}</c>), + <em>one</em> data message from the socket will be sent + to the process. To receive one more message, + <c>setopts/2</c> must be called again with the + <c>{active, once}</c> option.</p> + <p>When using <c>{active, once}</c>, the socket changes + behaviour automatically when data is received. This can + sometimes be confusing in combination with connection + oriented sockets (i.e. <c>gen_tcp</c>) as a socket with + <c>{active, false}</c> behaviour reports closing + differently than a socket with <c>{active, true}</c> + behaviour. To make programming easier, a socket where + the peer closed and this was detected while in + <c>{active, false}</c> mode, will still generate the + message + <c>{tcp_closed,Socket}</c> when set to <c>{active, once}</c> or <c>{active, true}</c> mode. It is therefore + safe to assume that the message + <c>{tcp_closed,Socket}</c>, possibly followed by socket + port termination (depending on the <c>exit_on_close</c> + option) will eventually appear when a socket changes + back and forth between <c>{active, true}</c> and + <c>{active, false}</c> mode. However, + <em>when</em> peer closing is detected is all up to the + underlying TCP/IP stack and protocol.</p> + <p>Note that <c>{active,true}</c> mode provides no flow + control; a fast sender could easily overflow the + receiver with incoming messages. Use active mode only if + your high-level protocol provides its own flow control + (for instance, acknowledging received messages) or the + amount of data exchanged is small. <c>{active,false}</c> + mode or use of the <c>{active, once}</c> mode provides + flow control; the other side will not be able send + faster than the receiver can read.</p> + </item> + <tag><c>{broadcast, Boolean}</c>(UDP sockets)</tag> + <item> + <p>Enable/disable permission to send broadcasts.</p> + </item> + <tag><c>{delay_send, Boolean}</c></tag> + <item> + <p>Normally, when an Erlang process sends to a socket, + the driver will try to immediately send the data. If that + fails, the driver will use any means available to queue + up the message to be sent whenever the operating system + says it can handle it. Setting <c>{delay_send, true}</c> + will make <em>all</em> messages queue up. This makes + the messages actually sent onto the network be larger but + fewer. The option actually affects the scheduling of send + requests versus Erlang processes instead of changing any + real property of the socket. Needless to say it is an + implementation specific option. Default is <c>false</c>.</p> + </item> + <tag><c>{dontroute, Boolean}</c></tag> + <item> + <p>Enable/disable routing bypass for outgoing messages.</p> + </item> + <tag><c>{exit_on_close, Boolean}</c></tag> + <item> + <p>By default this option is set to <c>true</c>.</p> + <p>The only reason to set it to <c>false</c> is if you want + to continue sending data to the socket after a close has + been detected, for instance if the peer has used + <seealso marker="gen_tcp#shutdown/2">gen_tcp:shutdown/2</seealso> + to shutdown the write side.</p> + </item> + <tag><c>{header, Size}</c></tag> + <item> + <p>This option is only meaningful if the <c>binary</c> + option was specified when the socket was created. If + the <c>header</c> option is specified, the first + <c>Size</c> number bytes of data received from the socket + will be elements of a list, and the rest of the data will + be a binary given as the tail of the same list. If for + example <c>Size == 2</c>, the data received will match + <c>[Byte1,Byte2|Binary]</c>.</p> + </item> + <tag><c>{keepalive, Boolean}</c>(TCP/IP sockets)</tag> + <item> + <p>Enables/disables periodic transmission on a connected + socket, when no other data is being exchanged. If + the other end does not respond, the connection is + considered broken and an error message will be sent to + the controlling process. Default disabled.</p> + </item> + <tag><c>{nodelay, Boolean}</c>(TCP/IP sockets)</tag> + <item> + <p>If <c>Boolean == true</c>, the <c>TCP_NODELAY</c> option + is turned on for the socket, which means that even small + amounts of data will be sent immediately.</p> + </item> + <tag><c>{packet, PacketType}</c>(TCP/IP sockets)</tag> + <item> + <p>Defines the type of packets to use for a socket. + The following values are valid:</p> + <taglist> + <tag><c>raw | 0</c></tag> + <item> + <p>No packaging is done.</p> + </item> + <tag><c>1 | 2 | 4</c></tag> + <item> + <p>Packets consist of a header specifying the number of + bytes in the packet, followed by that number of bytes. + The length of header can be one, two, or four bytes; + containing an unsigned integer in big-endian byte order. + Each send operation will generate the header, and the header + will be stripped off on each receive operation.</p> + <p>In current implementation the 4-byte header is limited to 2Gb.</p> + </item> + <tag><c>asn1 | cdr | sunrm | fcgi | tpkt | line</c></tag> + <item> + <p>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, there will be one message sent to + the controlling process for each complete packet + received, and, similarly, each call to + <c>gen_tcp:recv/2,3</c> returns one complete packet. + The header is <em>not</em> stripped off.</p> + <p>The meanings of the packet types are as follows: + <br></br> +<c>asn1</c> - ASN.1 BER, + <br></br> +<c>sunrm</c> - Sun's RPC encoding, + <br></br> +<c>cdr</c> - CORBA (GIOP 1.1), + <br></br> +<c>fcgi</c> - Fast CGI, + <br></br> +<c>tpkt</c> - TPKT format [RFC1006], + <br></br> +<c>line</c> - Line mode, a packet is a line + terminated with newline, lines longer than + the receive buffer are truncated.</p> + </item> + <tag><c>http | http_bin</c></tag> + <item> + <p>The Hypertext Transfer Protocol. The packets + are returned with the format according to <c>HttpPacket</c> + described in <seealso marker="erts:erlang#decode_packet/3"> + erlang:decode_packet/3</seealso>. A socket in passive + mode will return <c>{ok, HttpPacket}</c> from <c>gen_tcp:recv</c> + while an active socket will send messages like <c>{http, + Socket, HttpPacket}</c>.</p> + <p>Note that the packet type <c>httph</c> is not + needed when reading from a socket.</p> + </item> + </taglist> + </item> + <tag><c>{packet_size, Integer}</c>(TCP/IP sockets)</tag> + <item> + <p>Sets the max allowed length of the packet body. If + the packet header indicates that the length of the packet + is longer than the max allowed length, the packet is + considered invalid. The same happens if the packet header + is too big for the socket receive buffer.</p> + </item> + <tag><c>{read_packets, Integer}</c>(UDP sockets)</tag> + <item> + <p>Sets the max 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. + The default is 5, and if this parameter is set too + high the system can become unresponsive due to + UDP packet flooding.</p> + </item> + <tag><c>{recbuf, Integer}</c></tag> + <item> + <p>Gives the size of the receive buffer to use for + the socket.</p> + </item> + <tag><c>{reuseaddr, Boolean}</c></tag> + <item> + <p>Allows or disallows local reuse of port numbers. By + default, reuse is disallowed.</p> + </item> + <tag><c>{send_timeout, Integer}</c></tag> + <item> + <p>Only allowed for connection oriented sockets.</p> + <p>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 will return + <c>{error,timeout}</c>. How much of a packet that actually + got sent is unknown, why the socket should be closed + whenever a timeout has occurred (see <c>send_timeout_close</c>). + Default is <c>infinity</c>.</p> + </item> + <tag><c>{send_timeout_close, Boolean}</c></tag> + <item> + <p>Only allowed for connection oriented sockets.</p> + <p>Used together with <c>send_timeout</c> to specify whether + the socket will be automatically closed when the send operation + returns <c>{error,timeout}</c>. The recommended setting is + <c>true</c> which will automatically close the socket. + Default is <c>false</c> due to backward compatibility.</p> + </item> + + <tag><c>{sndbuf, Integer}</c></tag> + <item> + <p>Gives the size of the send buffer to use for the socket.</p> + </item> + <tag><c>{priority, Integer}</c></tag> + <item> + <p>Sets the SO_PRIORITY socket level option on platforms where + this is implemented. The behaviour and allowed range varies on + different systems. The option is ignored on platforms where the + option is not implemented. Use with caution.</p> + </item> + <tag><c>{tos, Integer}</c></tag> + <item> + <p>Sets IP_TOS IP level options on platforms where this is + implemented. The behaviour and allowed range varies on different + systems. The option is ignored on platforms where the option is + not implemented. Use with caution.</p> + </item> + </taglist> + <p>In addition to the options mentioned above, <em>raw</em> + option specifications can be used. The raw options are + specified as a tuple of arity four, beginning with the tag + <c>raw</c>, followed by the protocol level, the option number + and the actual option value specified as a binary. This + corresponds to the second, third and fourth argument to the + <c>setsockopt</c> call in the C socket API. The option value + needs to be coded in the native endianess of the platform and, + if a structure is required, needs to follow the struct + alignment conventions on the specific platform.</p> + <p>Using raw socket options require detailed knowledge about + the current operating system and TCP stack.</p> + <p>As an example of the usage of raw options, consider a Linux + system where you want to set the <c>TCP_LINGER2</c> option on + the <c>IPPROTO_TCP</c> protocol level in the stack. You know + that on this particular system it defaults to 60 (seconds), + but you would like to lower it to 30 for a particular + socket. The <c>TCP_LINGER2</c> option is not explicitly + supported by inet, but you know that the protocol level + translates to the number 6, the option number to the number 8 + and the value is to be given as a 32 bit integer. You can use + this line of code to set the option for the socket named + <c>Sock</c>:</p> + <code type="none"><![CDATA[ + inet:setopts(Sock,[{raw,6,8,<<30:32/native>>}]),]]></code> + <p>As many options are silently discarded by the stack if they + are given out of range, it could be a good idea to check that + a raw option really got accepted. This code places the value + in the variable TcpLinger2:</p> + <code type="none"><![CDATA[ + {ok,[{raw,6,8,<<TcpLinger2:32/native>>}]}=inet:getopts(Sock,[{raw,6,8,4}]),]]></code> + <p>Code such as the examples above is inherently non portable, + even different versions of the same OS on the same platform + may respond differently to this kind of option + manipulation. Use with care.</p> + <p>Note that the default options for TCP/IP sockets can be + changed with the Kernel configuration parameters mentioned in + the beginning of this document.</p> + </desc> + </func> + </funcs> + + <section> + <marker id="error_codes"></marker> + <title>POSIX Error Codes</title> + <list type="bulleted"> + <item><c>e2big</c> - argument list too long</item> + <item><c>eacces</c> - permission denied</item> + <item><c>eaddrinuse</c> - address already in use</item> + <item><c>eaddrnotavail</c> - cannot assign requested address</item> + <item><c>eadv</c> - advertise error</item> + <item><c>eafnosupport</c> - address family not supported by + protocol family</item> + <item><c>eagain</c> - resource temporarily unavailable</item> + <item><c>ealign</c> - EALIGN</item> + <item><c>ealready</c> - operation already in progress</item> + <item><c>ebade</c> - bad exchange descriptor</item> + <item><c>ebadf</c> - bad file number</item> + <item><c>ebadfd</c> - file descriptor in bad state</item> + <item><c>ebadmsg</c> - not a data message</item> + <item><c>ebadr</c> - bad request descriptor</item> + <item><c>ebadrpc</c> - RPC structure is bad</item> + <item><c>ebadrqc</c> - bad request code</item> + <item><c>ebadslt</c> - invalid slot</item> + <item><c>ebfont</c> - bad font file format</item> + <item><c>ebusy</c> - file busy</item> + <item><c>echild</c> - no children</item> + <item><c>echrng</c> - channel number out of range</item> + <item><c>ecomm</c> - communication error on send</item> + <item><c>econnaborted</c> - software caused connection abort</item> + <item><c>econnrefused</c> - connection refused</item> + <item><c>econnreset</c> - connection reset by peer</item> + <item><c>edeadlk</c> - resource deadlock avoided</item> + <item><c>edeadlock</c> - resource deadlock avoided</item> + <item><c>edestaddrreq</c> - destination address required</item> + <item><c>edirty</c> - mounting a dirty fs w/o force</item> + <item><c>edom</c> - math argument out of range</item> + <item><c>edotdot</c> - cross mount point</item> + <item><c>edquot</c> - disk quota exceeded</item> + <item><c>eduppkg</c> - duplicate package name</item> + <item><c>eexist</c> - file already exists</item> + <item><c>efault</c> - bad address in system call argument</item> + <item><c>efbig</c> - file too large</item> + <item><c>ehostdown</c> - host is down</item> + <item><c>ehostunreach</c> - host is unreachable</item> + <item><c>eidrm</c> - identifier removed</item> + <item><c>einit</c> - initialization error</item> + <item><c>einprogress</c> - operation now in progress</item> + <item><c>eintr</c> - interrupted system call</item> + <item><c>einval</c> - invalid argument</item> + <item><c>eio</c> - I/O error</item> + <item><c>eisconn</c> - socket is already connected</item> + <item><c>eisdir</c> - illegal operation on a directory</item> + <item><c>eisnam</c> - is a named file</item> + <item><c>el2hlt</c> - level 2 halted</item> + <item><c>el2nsync</c> - level 2 not synchronized</item> + <item><c>el3hlt</c> - level 3 halted</item> + <item><c>el3rst</c> - level 3 reset</item> + <item><c>elbin</c> - ELBIN</item> + <item><c>elibacc</c> - cannot access a needed shared library</item> + <item><c>elibbad</c> - accessing a corrupted shared library</item> + <item><c>elibexec</c> - cannot exec a shared library directly</item> + <item><c>elibmax</c> - attempting to link in more shared + libraries than system limit</item> + <item><c>elibscn</c> - .lib section in a.out corrupted</item> + <item><c>elnrng</c> - link number out of range</item> + <item><c>eloop</c> - too many levels of symbolic links</item> + <item><c>emfile</c> - too many open files</item> + <item><c>emlink</c> - too many links</item> + <item><c>emsgsize</c> - message too long</item> + <item><c>emultihop</c> - multihop attempted</item> + <item><c>enametoolong</c> - file name too long</item> + <item><c>enavail</c> - not available</item> + <item><c>enet</c> - ENET</item> + <item><c>enetdown</c> - network is down</item> + <item><c>enetreset</c> - network dropped connection on reset</item> + <item><c>enetunreach</c> - network is unreachable</item> + <item><c>enfile</c> - file table overflow</item> + <item><c>enoano</c> - anode table overflow</item> + <item><c>enobufs</c> - no buffer space available</item> + <item><c>enocsi</c> - no CSI structure available</item> + <item><c>enodata</c> - no data available</item> + <item><c>enodev</c> - no such device</item> + <item><c>enoent</c> - no such file or directory</item> + <item><c>enoexec</c> - exec format error</item> + <item><c>enolck</c> - no locks available</item> + <item><c>enolink</c> - link has be severed</item> + <item><c>enomem</c> - not enough memory</item> + <item><c>enomsg</c> - no message of desired type</item> + <item><c>enonet</c> - machine is not on the network</item> + <item><c>enopkg</c> - package not installed</item> + <item><c>enoprotoopt</c> - bad protocol option</item> + <item><c>enospc</c> - no space left on device</item> + <item><c>enosr</c> - out of stream resources or not a stream + device</item> + <item><c>enosym</c> - unresolved symbol name</item> + <item><c>enosys</c> - function not implemented</item> + <item><c>enotblk</c> - block device required</item> + <item><c>enotconn</c> - socket is not connected</item> + <item><c>enotdir</c> - not a directory</item> + <item><c>enotempty</c> - directory not empty</item> + <item><c>enotnam</c> - not a named file</item> + <item><c>enotsock</c> - socket operation on non-socket</item> + <item><c>enotsup</c> - operation not supported</item> + <item><c>enotty</c> - inappropriate device for ioctl</item> + <item><c>enotuniq</c> - name not unique on network</item> + <item><c>enxio</c> - no such device or address</item> + <item><c>eopnotsupp</c> - operation not supported on socket</item> + <item><c>eperm</c> - not owner</item> + <item><c>epfnosupport</c> - protocol family not supported</item> + <item><c>epipe</c> - broken pipe</item> + <item><c>eproclim</c> - too many processes</item> + <item><c>eprocunavail</c> - bad procedure for program</item> + <item><c>eprogmismatch</c> - program version wrong</item> + <item><c>eprogunavail</c> - RPC program not available</item> + <item><c>eproto</c> - protocol error</item> + <item><c>eprotonosupport</c> - protocol not supported</item> + <item><c>eprototype</c> - protocol wrong type for socket</item> + <item><c>erange</c> - math result unrepresentable</item> + <item><c>erefused</c> - EREFUSED</item> + <item><c>eremchg</c> - remote address changed</item> + <item><c>eremdev</c> - remote device</item> + <item><c>eremote</c> - pathname hit remote file system</item> + <item><c>eremoteio</c> - remote i/o error</item> + <item><c>eremoterelease</c> - EREMOTERELEASE</item> + <item><c>erofs</c> - read-only file system</item> + <item><c>erpcmismatch</c> - RPC version is wrong</item> + <item><c>erremote</c> - object is remote</item> + <item><c>eshutdown</c> - cannot send after socket shutdown</item> + <item><c>esocktnosupport</c> - socket type not supported</item> + <item><c>espipe</c> - invalid seek</item> + <item><c>esrch</c> - no such process</item> + <item><c>esrmnt</c> - srmount error</item> + <item><c>estale</c> - stale remote file handle</item> + <item><c>esuccess</c> - Error 0</item> + <item><c>etime</c> - timer expired</item> + <item><c>etimedout</c> - connection timed out</item> + <item><c>etoomanyrefs</c> - too many references</item> + <item><c>etxtbsy</c> - text file or pseudo-device busy</item> + <item><c>euclean</c> - structure needs cleaning</item> + <item><c>eunatch</c> - protocol driver not attached</item> + <item><c>eusers</c> - too many users</item> + <item><c>eversion</c> - version mismatch</item> + <item><c>ewouldblock</c> - operation would block</item> + <item><c>exdev</c> - cross-domain link</item> + <item><c>exfull</c> - message tables full</item> + <item><c>nxdomain</c> - the hostname or domain name could not be + found</item> + </list> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/inet_res.xml b/lib/kernel/doc/src/inet_res.xml new file mode 100644 index 0000000000..d8fe23544b --- /dev/null +++ b/lib/kernel/doc/src/inet_res.xml @@ -0,0 +1,482 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2009</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>inet_res</title> + <prepared>[email protected]</prepared> + <docno></docno> + <date>2009-09-11</date> + <rev>A</rev> + </header> + <module>inet_res</module> + <modulesummary>A Rudimentary DNS Client</modulesummary> + <description> + <p>Performs DNS name resolving towards recursive name servers</p> + <p>See also + <seealso marker="erts:inet_cfg"> + ERTS User's Guide: Inet configuration + </seealso> for more + information on how to configure an Erlang runtime system for IP + communication and how to enable this DNS client by defining + <c><![CDATA['dns']]></c> as a lookup method. It then acts + as a backend for the resolving functions in + <seealso marker="kernel:inet">inet</seealso>.</p> + <p>This DNS client can resolve DNS records even if it + is not used for normal name resolving in the node.</p> + <p>This is not a full-fledged resolver. It is just a + DNS client that relies on asking trusted recursive nameservers.</p> + </description> + + <section> + <title>Name Resolving</title> + <p>UDP queries are used unless resolver option + <c>usevc</c> is <c>true</c>, which forces TCP queries. + If the query is to large for UDP, TCP is used instead. + For regular DNS queries 512 bytes is the size limit. + When EDNS is enabled (resolver option + <c>edns</c> is set to the EDNS version i.e <c>0</c> + instead of <c>false</c>), resolver option + <c>udp_payload_size</c> sets the limit. If a nameserver + replies with the TC bit set (truncation), indicating + the answer is incomplete, the query is retried + to that nameserver using TCP. The resolver option + <c>udp_payload_size</c> also sets the advertised + size for the max allowed reply size, if EDNS is + enabled, otherwise the nameserver uses the limit + 512 byte. If the reply is larger it gets truncated, + forcing a TCP re-query.</p> + <p>For UDP queries, the resolver options <c>timeout</c> + and <c>retry</c> control retransmission. + Each nameserver in the <c>nameservers</c> list is + tried with a timeout of <c>timeout</c> / <c>retry</c>. + Then all nameservers are tried again doubling the + timeout, for a total of <c>retry</c> times.</p> + <p>For queries that not use the <c>search</c> list, + if the query to all <c>nameservers</c> results in + <c>{error,nxdomain}</c>or an empty answer, the same + query is tried for the <c>alt_nameservers</c>.</p> + </section> + + + + + <section> + <title>DATA TYPES</title> + <p>As defined in the module + <seealso marker="kernel:inet">inet</seealso>:</p> + <code type="none"> +hostent() = #hostent{} +posix() = some atom()s +ip_address() = tuple of integers of arity 4 or 8</code> + + <p>Resolver types:</p> + <code type="none">These correspond to resolver options: + +res_option() = + [ {alt_nameservers, [ nameserver() ]} + | {edns, 0 | false} % Use EDNS + | {inet6, bool()} % Return IPv6 addresses + | {nameservers, [ nameserver() ]} % List of nameservers + | {recurse, bool()} % Request server recursion + | {retry, integer()} % UDP retries + | {timeout, integer()} % UDP query timeout + | {udp_payload_size, integer()} % EDNS payload size + | {usevc, bool()} ] % Use TCP (Virtual Circuit) + +nameserver() = {ip_address(),Port} + Port = integer(1..65535) + +res_error() = + formerr | + qfmterror | + servfail | + nxdomain | + notimp | + refused | + badvers | + timeout +</code> + + <p>DNS types:</p> + <marker id="dns_types"/> + <code type="none">dns_name() = string() with no adjacent dots + +rr_type() = a | aaaa | cname | gid | hinfo | ns | mb | md | mg | mf + | minfo | mx | naptr | null | ptr | soa | spf | srv | txt + | uid | uinfo | unspec | wks + +query_type() = axfr | mailb | maila | any | rr_type() + +dns_class() = in | chaos | hs | any + +dns_msg() = DnsMsg + This is the start of a hiearchy of opaque data structures + that can be examined with access functions in inet_dns + that return lists of {Field,Value} tuples. The arity 2 + functions just return the value for a given field. + + 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 + +dhs_header() = DnsHeader + inet_dns:header(DnsHeader) -> + [ {id, integer()} + | {qr, bool()} + | {opcode, 'query' | iquery | status | integer()} + | {aa, bool()} + | {tc, bool()} + | {rd, bool()} + | {ra, bool()} + | {pr, bool()} + | {rcode, integer(0..16)} ] + inet_dns:header(DnsHeader, Field) -> Value + +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, 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 + +dns_data() = % for dns_type() + [ dns_name() % ns, md, mf, cname, mb, mg, mr, ptr + | ip_address(v4) % a + | ip_address(v6) % aaaa + | {MName,RName,Serial,Refresh,Retry,Expiry,Minimum} % soa + | {ip_address(v4),Proto,BitMap} % wks + | {CpuString,OsString} % hinfo + | {RM,EM} % minfo + | {Prio,dns_name()} % mx + | {Prio,Weight,Port,dns_name()} % srv + | {Order,Preference,Flags,Services,Regexp,dns_name()} % naptr + | [ string() ] % txt, spf + | binary() ] % null, integer() +MName, RName = dns_name() +Serial, Refresh, Retry, Expiry, Minimum = integer(), +Proto = integer() +BitMap = binary() +CpuString, OsString = string() +RM = EM = dns_name() +Prio, Weight, Port = integer() +Order, Preference = integer() +Flags, Services = string(), +Regexp = string(utf8) + + + +There is an info 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) will convert +any of these data structures into a {Field,Value} list.</code> + </section> + + + + <funcs> + + <func> + <name>getbyname(Name, Type) -> {ok,hostent()} | {error,Reason}</name> + <name>getbyname(Name, Type, Timeout) -> + {ok,hostent()} | {error,Reason} + </name> + <fsummary>Resolve a DNS record of the given type for the given host + </fsummary> + <type> + <v>Name = dns_name()</v> + <v>Type = rr_type()</v> + <v>Timeout = integer() >= 0 | infinity</v> + <v>Reason = posix() | res_error()</v> + </type> + <desc> + <p>Resolve a DNS record of the given type for the given host, + of class <c>in</c>. On success returns a <c>hostent()</c> record with + <c>dns_data()</c> elements in the address list field. + </p><p> + This function uses the resolver option <c>search</c> 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 simply supposed to be + an absolute name and the search list is not used. + </p> + </desc> + </func> + + <func> + <name>gethostbyaddr(Address) -> {ok,hostent()} | {error,Reason}</name> + <name>gethostbyaddr(Address, Timeout) -> + {ok,hostent()} | {error,Reason} + </name> + <fsummary>Return a hostent record for the host with the given address + </fsummary> + <type> + <v>Address = ip_address()</v> + <v>Timeout = integer() >= 0 | infinity</v> + <v>Reason = posix() | res_error()</v> + </type> + <desc> + <p>Backend functions used by + <seealso marker="kernel:inet#gethostbyaddr/1"> + inet:gethostbyaddr/1 + </seealso>. + </p> + </desc> + </func> + + <func> + <name>gethostbyname(Name) -> {ok,hostent()} | Reason}</name> + <name>gethostbyname(Name, Family) -> + {ok,hostent()} | {error,Reason}} + </name> + <name>gethostbyname(Name, Family, Timeout) -> + {ok,hostent()} | {error,Reason} + </name> + <fsummary>Return a hostent record for the host with the given name + </fsummary> + <type> + <v>Name = dns_name()</v> + <v>Timeout = integer() >= 0 | infinity</v> + <v>Reason = posix() | res_error()</v> + </type> + <desc> + <p>Backend functions used by + <seealso marker="kernel:inet#gethostbyname/1"> + inet:gethostbyname/1,2 + </seealso>. + </p><p> + This function uses the resolver option <c>search</c> just like + <seealso marker="#getbyname/2">getbyname/2,3</seealso>. + </p><p> + If the resolver option <c>inet6</c> is <c>true</c>, + an IPv6 address is looked up, and if that fails + the IPv4 address is looked up and returned on + IPv6 mapped IPv4 format. + </p> + </desc> + </func> + + <func> + <name>lookup(Name, Class, Type) -> [ dns_data() ] + </name> + <name>lookup(Name, Class, Type, Opts) -> [ dns_data() ] + </name> + <name>lookup(Name, Class, Type, Opts, Timeout) -> [ dns_data() ] + </name> + <fsummary>Resolve the DNS data for the record of the given type and class + for the given name + </fsummary> + <type> + <v>Name = dns_name() | ip_address()</v> + <v>Type = rr_type()</v> + <v>Opts = res_option() | verbose</v> + <v>Timeout = integer() >= 0 | infinity</v> + <v>Reason = posix() | res_error()</v> + </type> + <desc> + <p>Resolve the DNS data for the record of the given type and class + for the given name. On success filters out the answer records + with the correct <c>Class</c> and <c>Type</c> and returns + a list of their data fields. So a lookup for type <c>any</c> + will give an empty answer since the answer records have + specific types that are not <c>any</c>. An empty answer + as well as a failed lookup returns an empty list. + </p><p> + Calls <seealso marker="#resolve/3">resolve/2..4</seealso> + with the same arguments and filters the result, so + <c>Opts</c> is explained there. + </p> + </desc> + </func> + + <func> + <name>resolve(Name, Class, Type) -> {ok,dns_msg()} | Error + </name> + <name>resolve(Name, Class, Type, Opts) -> {ok,dns_msg()} | Error + </name> + <name>resolve(Name, Class, Type, Opts, Timeout) -> {ok,dns_msg()} | Error + </name> + <fsummary>Resolve a DNS record of the given type and class + for the given name + </fsummary> + <type> + <v>Name = dns_name() | ip_address()</v> + <v>Type = rr_type()</v> + <v>Opts = res_option() | verbose | atom()</v> + <v>Timeout = integer() >= 0 | infinity</v> + <v>Error = {error,Reason} | {error,{Reason,dns_msg()}}</v> + <v>Reason = posix() | res_error()</v> + </type> + <desc> + <p>Resolve a DNS record of the given type and class for the given name. + The returned <c>dns_msg()</c> can be examined using + access functions in <c>inet_db</c> as described + in <seealso marker="#dns_types">DNS types</seealso>. + </p><p> + If <c>Name</c> is an <c>ip_address()</c>, the domain name + to query for 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 + <c>Class = in</c> and <c>Type = ptr</c> but it + is not done automatically. + </p><p> + <c>Opts</c> override the corresponding resolver options. + If the option <c>nameservers</c> is given, it is + also assumed that it is the complete list of nameserves, + so the resolver option <c>alt_nameserves</c> is ignored. + Of course, if that option is also given to this function, + it is used. + </p><p> + The <c>verbose</c> option (or rather <c>{verbose,true}</c>), + causes diagnostics printout through + <seealso marker="stdlib:io#format/3">io:format/2</seealso> + of queries, replies retransmissions, etc, similar + to from utilities like <c>dig</c>, <c>nslookup</c> et.al. + </p><p> + If <c>Opt</c> is an arbitrary atom it is interpreted + as <c>{Opt,true}</c> unless the atom string starts with + <c>"no"</c> making the interpretation <c>{Opt,false}</c>. + For example: <c>usevc</c> is an alias for <c>{usevc,true}</c>, + and <c>nousevc</c> an alias for <c>{usevc,false}</c>. + </p><p> + The <c>inet6</c> option currently has no effect on this function. + You probably want to use <c>Type = a | aaaa</c> instead. + </p> + </desc> + </func> + + </funcs> + + + + <section> + <title>Examples</title> + <p>Access functions example: how + <seealso marker="#lookup/3">lookup/3</seealso> + could have been implemented using + <seealso marker="#resolve/3">resolve/3</seealso> + from outside the module. + </p><code type="none"> + 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.</code> + </section> + + + + <section> + <title>Legacy Functions</title> + <p>These have been deprecated due to the annoying double + meaning of the nameservers/timeout argument, and + because they had no decent place for a resolver options list.</p> + </section> + + <funcs> + + <func> + <name>nslookup(Name, Class, Type) -> {ok,dns_msg()} | {error,Reason} + </name> + <name>nslookup(Name, Class, Type, Timeout) -> + {ok,dns_msg()} | {error,Reason} + </name> + <name>nslookup(Name, Class, Type, Nameservers) -> + {ok,dns_msg()} | {error,Reason} + </name> + <fsummary>Resolve a DNS record of the given type and class + for the given name + </fsummary> + <type> + <v>Name = dns_name() | ip_address()</v> + <v>Type = rr_type()</v> + <v>Nameservers = [ nameserver() ]</v> + <v>Timeout = integer() >= 0 | infinity</v> + <v>Reason = posix() | res_error()</v> + </type> + <desc> + <p>Resolve a DNS record of the given type and class for the given name. + </p> + </desc> + </func> + + <func> + <name>nnslookup(Name, Class, Type, Nameservers) -> + {ok,dns_msg()} | {error,posix()} + </name> + <name>nnslookup(Name, Class, Type, Nameservers, Timeout) -> + {ok,dns_msg()} | {error,posix()} + </name> + <fsummary>Resolve a DNS record of the given type and class + for the given name + </fsummary> + <type> + <v>Name = dns_name() | ip_address()</v> + <v>Type = rr_type()</v> + <v>Nameservers = [ nameserver() ]</v> + <v>Timeout = integer() >= 0 | infinity</v> + <v>Reason = posix() | res_error()</v> + </type> + <desc> + <p>Resolve a DNS record of the given type and class for the given name. + </p> + </desc> + </func> + + </funcs> + +</erlref> diff --git a/lib/kernel/doc/src/init_stub.xml b/lib/kernel/doc/src/init_stub.xml new file mode 100644 index 0000000000..e8645458e4 --- /dev/null +++ b/lib/kernel/doc/src/init_stub.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year> + <year>2009</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>init</title> + <prepared>[email protected]</prepared> + <docno></docno> + <date>2008-12-16</date> + <rev>A</rev> + </header> + <module>init</module> + <modulesummary>Coordination of System Startup</modulesummary> + <description><p> + + The module init is moved to the runtime system + application. Please see <seealso + marker="erts:init">init(3)</seealso> in the + erts reference manual instead. + + </p></description> +</erlref> diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml new file mode 100644 index 0000000000..bf513b7815 --- /dev/null +++ b/lib/kernel/doc/src/kernel_app.xml @@ -0,0 +1,348 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE appref SYSTEM "appref.dtd"> + +<appref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>kernel</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <app>kernel</app> + <appsummary>The Kernel Application</appsummary> + <description> + <p>The Kernel application is the first application started. It is + mandatory in the sense that the minimal system based on + Erlang/OTP consists of Kernel and STDLIB. The Kernel application + contains the following services:</p> + <list type="bulleted"> + <item>application controller, see <c>application(3)</c></item> + <item><c>code</c></item> + <item><c>disk_log</c></item> + <item><c>dist_ac</c>, distributed application controller</item> + <item><c>erl_boot_server</c></item> + <item><c>erl_ddll</c></item> + <item><c>error_logger</c></item> + <item><c>file</c></item> + <item><c>global</c></item> + <item><c>global_group</c></item> + <item><c>heart</c></item> + <item><c>inet</c></item> + <item><c>net_kernel</c></item> + <item><c>os</c></item> + <item><c>pg2</c></item> + <item><c>rpc</c></item> + <item><c>seq_trace</c></item> + <item><c>user</c></item> + </list> + </description> + + <section> + <title>Error Logger Event Handlers</title> + <p>Two standard error logger event handlers are defined in + the Kernel application. These are described in + <seealso marker="error_logger">error_logger(3)</seealso>.</p> + </section> + + <section> + <title>Configuration</title> + <p>The following configuration parameters are defined for the Kernel + application. See <c>app(3)</c> for more information about + configuration parameters.</p> + <taglist> + <tag><c>browser_cmd = string() | {M,F,A}</c></tag> + <item> + <p>When pressing the Help button in a tool such as Debugger or + TV, the help text (an HTML file <c>File</c>) is by default + displayed in a Netscape browser which is required to be up and + running. This parameter can be used to change the command for + how to display the help text if another browser than Netscape + is preferred, or another platform than Unix or Windows is + used.</p> + <p>If set to a string <c>Command</c>, the command + <c>"Command File"</c> will be evaluated using <c>os:cmd/1</c>.</p> + <p>If set to a module-function-args tuple <c>{M,F,A}</c>, + the call <c>apply(M,F,[File|A])</c> will be evaluated.</p> + </item> + <tag><c>distributed = [Distrib]</c></tag> + <item> + <p>Specifies which applications are distributed and on which + nodes they may execute. In this parameter:</p> + <list type="bulleted"> + <item><c>Distrib = {App,Nodes} | {App,Time,Nodes}</c></item> + <item><c>App = atom()</c></item> + <item><c>Time = integer()>0</c></item> + <item><c>Nodes = [node() | {node(),...,node()}]</c></item> + </list> + <p>The parameter is described in <c>application(3)</c>, function + <c>load/2</c>.</p> + </item> + <tag><c>dist_auto_connect = Value</c></tag> + <item> + <p>Specifies when nodes will be automatically connected. If + this parameter is not specified, a node is always + automatically connected, e.g when a message is to be sent to + that node. <c>Value</c> is one of:</p> + <taglist> + <tag><c>never</c></tag> + <item>Connections are never automatically connected, they + must be explicitly connected. See <c>net_kernel(3)</c>.</item> + <tag><c>once</c></tag> + <item>Connections will be established automatically, but only + once per node. If a node goes down, it must thereafter be + explicitly connected. See <c>net_kernel(3)</c>.</item> + </taglist> + </item> + <tag><c>permissions = [Perm]</c></tag> + <item> + <p>Specifies the default permission for applications when they + are started. In this parameter:</p> + <list type="bulleted"> + <item><c>Perm = {ApplName,Bool}</c></item> + <item><c>ApplName = atom()</c></item> + <item><c>Bool = boolean()</c></item> + </list> + <p>Permissions are described in <c>application(3)</c>, function + <c>permit/2</c>.</p> + </item> + <tag><c>error_logger = Value</c></tag> + <item> + <p><c>Value</c> is one of:</p> + <taglist> + <tag><c>tty</c></tag> + <item>Installs the standard event handler which prints error + reports to <c>stdio</c>. This is the default option.</item> + <tag><c>{file, FileName}</c></tag> + <item>Installs the standard event handler which prints error + reports to the file <c>FileName</c>, where <c>FileName</c> + is a string.</item> + <tag><c>false</c></tag> + <item> + <p>No standard event handler is installed, but + the initial, primitive event handler is kept, printing + raw event messages to tty.</p> + </item> + <tag><c>silent</c></tag> + <item> + <p>Error logging is turned off.</p> + </item> + </taglist> + </item> + <tag><c>global_groups = [GroupTuple]</c></tag> + <item> + <p>Defines global groups, see <c>global_group(3)</c>.</p> + <list type="bulleted"> + <item><c>GroupTuple = {GroupName, [Node]} | {GroupName, PublishType, [Node]}</c></item> + <item><c>GroupName = atom()</c></item> + <item><c>PublishType = normal | hidden</c></item> + <item><c>Node = node()</c></item> + </list> + </item> + <tag><c>inet_default_connect_options = [{Opt, Val}]</c></tag> + <item> + <p>Specifies default options for <c>connect</c> sockets, + see <c>inet(3)</c>.</p> + </item> + <tag><c>inet_default_listen_options = [{Opt, Val}]</c></tag> + <item> + <p>Specifies default options for <c>listen</c> (and + <c>accept</c>) sockets, see <c>inet(3)</c>.</p> + </item> + <tag><c>{inet_dist_use_interface, ip_address()}</c></tag> + <item> + <p>If the host of an Erlang node has several network interfaces, + this parameter specifies which one to listen on. See + <c>inet(3)</c> for the type definition of <c>ip_address()</c>.</p> + </item> + <tag><c>{inet_dist_listen_min, First}</c></tag> + <item> + <p>See below.</p> + </item> + <tag><c>{inet_dist_listen_max, Last}</c></tag> + <item> + <p>Define the <c>First..Last</c> port range for the listener + socket of a distributed Erlang node.</p> + </item> + <tag><c>inet_parse_error_log = silent</c></tag> + <item> + <p>If this configuration parameter is set, no + <c>error_logger</c> messages are generated when erroneous + lines are found and skipped in the various Inet configuration + files.</p> + </item> + <tag><c>inetrc = Filename</c></tag> + <item> + <p>The name (string) of an Inet user configuration file. See + ERTS User's Guide, Inet configuration.</p> + </item> + <tag><c>net_setuptime = SetupTime</c></tag> + <item> + <marker id="net_setuptime"></marker> + <p><c>SetupTime</c> must be a positive integer or floating point + number, and will be interpreted as the maximally allowed time + for each network operation during connection setup to another + Erlang node. The maximum allowed value is 120; if higher values + are given, 120 will be used. The default value if the variable + is not given, or if the value is incorrect (e.g. not a number), + is 7 seconds.</p> + <p>Note that this value does not limit the total connection + setup time, but rather each individual network operation during + the connection setup and handshake.</p> + </item> + <tag><c>net_ticktime = TickTime</c></tag> + <item> + <marker id="net_ticktime"></marker> + <p>Specifies the <c>net_kernel</c> tick time. <c>TickTime</c> + is given in seconds. Once every <c>TickTime/4</c> second, all + connected nodes are ticked (if anything else has been written + to a node) and if nothing has been received from another node + within the last four (4) tick times that node is considered + to be down. This ensures that nodes which are not responding, + for reasons such as hardware errors, are considered to be + down.</p> + <p>The time <c>T</c>, in which a node that is not responding is + detected, is calculated as: <c><![CDATA[MinT < T < MaxT]]></c> where:</p> + <code type="none"> +MinT = TickTime - TickTime / 4 +MaxT = TickTime + TickTime / 4</code> + <p><c>TickTime</c> is by default 60 (seconds). Thus, + <c><![CDATA[45 < T < 75]]></c> seconds.</p> + <p><em>Note:</em> All communicating nodes should have the same + <c>TickTime</c> value specified.</p> + <p><em>Note:</em> Normally, a terminating node is detected + immediately.</p> + </item> + <tag><c>sync_nodes_mandatory = [NodeName]</c></tag> + <item> + <p>Specifies which other nodes <em>must</em> be alive in order + for this node to start properly. If some node in the list + does not start within the specified time, this node will not + start either. If this parameter is undefined, it defaults to + [].</p> + </item> + <tag><c>sync_nodes_optional = [NodeName]</c></tag> + <item> + <p>Specifies which other nodes <em>can</em> be alive in order + for this node to start properly. If some node in this list + does not start within the specified time, this node starts + anyway. If this parameter is undefined, it defaults to + the empty list.</p> + </item> + <tag><c>sync_nodes_timeout = integer() | infinity</c></tag> + <item> + <p>Specifies the amount of time (in milliseconds) this node + will wait for the mandatory and optional nodes to start. If + this parameter is undefined, no node synchronization is + performed. This option also makes sure that <c>global</c> is + synchronized.</p> + </item> + <tag><c>start_dist_ac = true | false</c></tag> + <item> + <p>Starts the <c>dist_ac</c> server if the parameter is + <c>true</c>. This parameter should be set to <c>true</c> for + systems that use distributed applications.</p> + <p>The default value is <c>false</c>. If this parameter is + undefined, the server is started if the parameter + <c>distributed</c> is set.</p> + </item> + <tag><c>start_boot_server = true | false</c></tag> + <item> + <p>Starts the <c>boot_server</c> if the parameter is <c>true</c> + (see <c>erl_boot_server(3)</c>). This parameter should be + set to <c>true</c> in an embedded system which uses this + service.</p> + <p>The default value is <c>false</c>.</p> + </item> + <tag><c>boot_server_slaves = [SlaveIP]</c></tag> + <item> + <p>If the <c>start_boot_server</c> configuration parameter is + <c>true</c>, this parameter can be used to initialize + <c>boot_server</c> with a list of slave IP addresses. + <c>SlaveIP = string() | atom | {integer(),integer(),integer(),integer()}</c></p> + <p>where <c><![CDATA[0 <= integer() <=255]]></c>.</p> + <p>Examples of <c>SlaveIP</c> in atom, string and tuple form + are: <br></br> +<c>'150.236.16.70', "150,236,16,70", {150,236,16,70}</c>.</p> + <p>The default value is <c>[]</c>.</p> + </item> + <tag><c>start_disk_log = true | false</c></tag> + <item> + <p>Starts the <c>disk_log_server</c> if the parameter is + <c>true</c> (see <c>disk_log(3)</c>). This parameter should be + set to true in an embedded system which uses this service.</p> + <p>The default value is <c>false</c>.</p> + </item> + <tag><c>start_pg2 = true | false</c></tag> + <item> + <p>Starts the <c>pg2</c> server (see <c>pg2(3)</c>) if + the parameter is <c>true</c>. This parameter should be set to + <c>true</c> in an embedded system which uses this service.</p> + <p>The default value is <c>false</c>.</p> + </item> + <tag><c>start_timer = true | false</c></tag> + <item> + <p>Starts the <c>timer_server</c> if the parameter is + <c>true</c> (see <c>timer(3)</c>). This parameter should be + set to <c>true</c> in an embedded system which uses this + service.</p> + <p>The default value is <c>false</c>.</p> + </item> + <tag><c>shutdown_func = {Mod, Func}</c></tag> + <item> + <p>Where:</p> + <list type="bulleted"> + <item><c>Mod = atom()</c></item> + <item><c>Func = atom()</c></item> + </list> + <p>Sets a function that <c>application_controller</c> calls + when it starts to terminate. The function is called as: + <c>Mod:Func(Reason)</c>, where <c>Reason</c> is the terminate + reason for <c>application_controller</c>, and it must + return as soon as possible for <c>application_controller</c> + to terminate properly.</p> + </item> + </taglist> + </section> + + <section> + <title>See Also</title> + <p><seealso marker="app">app(4)</seealso>, + <seealso marker="application">application(3)</seealso>, + <seealso marker="code">code(3)</seealso>, + <seealso marker="disk_log">disk_log(3)</seealso>, + <seealso marker="erl_boot_server">erl_boot_server(3)</seealso>, + <seealso marker="erl_ddll">erl_ddll(3)</seealso>, + <seealso marker="error_logger">error_logger(3)</seealso>, + <seealso marker="file">file(3)</seealso>, + <seealso marker="global">global(3)</seealso>, + <seealso marker="global_group">global_group(3)</seealso>, + <seealso marker="heart">heart(3)</seealso>, + <seealso marker="inet">inet(3)</seealso>, + <seealso marker="net_kernel">net_kernel(3)</seealso>, + <seealso marker="os">os(3)</seealso>, + <seealso marker="pg2">pg2(3)</seealso>, + <seealso marker="rpc">rpc(3)</seealso>, + <seealso marker="seq_trace">seq_trace(3)</seealso>, + <seealso marker="user">user(3)</seealso></p> + </section> +</appref> + diff --git a/lib/kernel/doc/src/make.dep b/lib/kernel/doc/src/make.dep new file mode 100644 index 0000000000..f79d1c6367 --- /dev/null +++ b/lib/kernel/doc/src/make.dep @@ -0,0 +1,28 @@ +# ---------------------------------------------------- +# >>>> Do not edit this file <<<< +# This file was automaticly generated by +# /home/otp/bin/docdepend +# ---------------------------------------------------- + + +# ---------------------------------------------------- +# TeX files that the DVI file depend on +# ---------------------------------------------------- + +book.dvi: app.tex application.tex auth.tex book.tex \ + code.tex config.tex disk_log.tex erl_boot_server.tex \ + erl_ddll.tex erl_prim_loader_stub.tex erlang_stub.tex \ + error_handler.tex error_logger.tex file.tex \ + gen_sctp.tex gen_tcp.tex gen_udp.tex global.tex \ + global_group.tex heart.tex inet.tex inet_res.tex \ + init_stub.tex kernel_app.tex net_adm.tex net_kernel.tex \ + os.tex packages.tex pg2.tex ref_man.tex rpc.tex \ + seq_trace.tex user.tex wrap_log_reader.tex \ + zlib_stub.tex + +# ---------------------------------------------------- +# Source inlined when transforming from source to LaTeX +# ---------------------------------------------------- + +book.tex: ref_man.xml + diff --git a/lib/kernel/doc/src/net_adm.xml b/lib/kernel/doc/src/net_adm.xml new file mode 100644 index 0000000000..7ec4f7f0e7 --- /dev/null +++ b/lib/kernel/doc/src/net_adm.xml @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>net_adm</title> + <prepared>Claes Wikstrom</prepared> + <docno>1</docno> + <date>96-09-10</date> + <rev>A</rev> + </header> + <module>net_adm</module> + <modulesummary>Various Erlang Net Administration Routines</modulesummary> + <description> + <p>This module contains various network utility functions.</p> + </description> + <funcs> + <func> + <name>dns_hostname(Host) -> {ok, Name} | {error, Host}</name> + <fsummary>Official name of a host</fsummary> + <type> + <v>Host = atom() | string()</v> + <v>Name = string()</v> + </type> + <desc> + <p>Returns the official name of <c>Host</c>, or + <c>{error, Host}</c> if no such name is found. See also + <c>inet(3)</c>.</p> + </desc> + </func> + <func> + <name>host_file() -> Hosts | {error, Reason}</name> + <fsummary>Read the <c>.hosts.erlang</c>file</fsummary> + <type> + <v>Hosts = [Host]</v> + <v> Host = atom()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Reads the <c>.hosts.erlang</c> file, see the section + <em>Files</em> below. Returns the hosts in this file as a + list, or returns <c>{error, Reason}</c> if the file could not + be read. See <c>file(3)</c> for possible values of + <c>Reason</c>.</p> + </desc> + </func> + <func> + <name>localhost() -> Name</name> + <fsummary>Name of the local host</fsummary> + <type> + <v>Name = string()</v> + </type> + <desc> + <p>Returns the name of the local host. If Erlang was started + with the <c>-name</c> command line flag, <c>Name</c> is + the fully qualified name.</p> + </desc> + </func> + <func> + <name>names() -> {ok, [{Name, Port}]} | {error, Reason}</name> + <name>names(Host) -> {ok, [{Name, Port}]} | {error, Reason}</name> + <fsummary>Names of Erlang nodes at a host</fsummary> + <type> + <v>Name = string()</v> + <v>Port = int()</v> + <v>Reason = address | term()</v> + </type> + <desc> + <p>Similar to <c>epmd -names</c>, see <c>epmd(1)</c>. + <c>Host</c> defaults to the local host. Returns the names and + associated port numbers of the Erlang nodes that <c>epmd</c> + at the specified host has registered.</p> + <p>Returns <c>{error, address}</c> if <c>epmd</c> is not + running. See <c>inet(3)</c> for other possible values of + <c>Reason</c>.</p> + <pre> +(arne@dunn)1> <input>net_adm:names().</input> +{ok,[{"arne",40262}]}</pre> + </desc> + </func> + <func> + <name>ping(Node) -> pong | pang</name> + <fsummary>Set up a connection to a node</fsummary> + <type> + <v>Node = node()</v> + </type> + <desc> + <p>Tries to set up a connection to <c>Node</c>. Returns + <c>pang</c> if it fails, or <c>pong</c> if it is successful.</p> + </desc> + </func> + <func> + <name>world() -> [node()]</name> + <name>world(Arg) -> [node()]</name> + <fsummary>Lookup and connect to all nodes at all hosts in <c>.hosts.erlang</c></fsummary> + <type> + <v>Arg = silent | verbose</v> + </type> + <desc> + <p>This function calls <c>names(Host)</c> for all hosts which + are specified in the Erlang host file <c>.hosts.erlang</c>, + collects the replies and then evaluates <c>ping(Node)</c> on + all those nodes. Returns the list of all nodes that were, + successfully pinged.</p> + <p><c>Arg</c> defaults to <c>silent</c>. + If <c>Arg == verbose</c>, the function writes information about which + nodes it is pinging to stdout.</p> + <p>This function can be useful when a node is started, and + the names of the other nodes in the network are not initially + known.</p> + <p>Failure: <c>{error, Reason}</c> if <c>host_file()</c> + returns <c>{error, Reason}</c>.</p> + </desc> + </func> + <func> + <name>world_list(Hosts) -> [node()]</name> + <name>world_list(Hosts, Arg) -> [node()]</name> + <fsummary>Lookup and connect to all nodes at specified hosts</fsummary> + <type> + <v>Hosts = [Host]</v> + <v> Host = atom()</v> + <v>Arg = silent | verbose</v> + </type> + <desc> + <p>As <c>world/0,1</c>, but the hosts are given as argument + instead of being read from <c>.hosts.erlang</c>.</p> + </desc> + </func> + </funcs> + + <section> + <title>Files</title> + <p>The <c>.hosts.erlang</c> file 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 <c>$OTP_ROOT</c> + (the root directory of Erlang/OTP), in that order.</p> + <p>The format of the <c>.hosts.erlang</c> file must be one host + name per line. The host names must be within quotes as shown in + the following example:</p> + <pre> +'super.eua.ericsson.se'. +'renat.eua.ericsson.se'. +'grouse.eua.ericsson.se'. +'gauffin1.eua.ericsson.se'. +^ (new line)</pre> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/net_kernel.xml b/lib/kernel/doc/src/net_kernel.xml new file mode 100644 index 0000000000..a18226e779 --- /dev/null +++ b/lib/kernel/doc/src/net_kernel.xml @@ -0,0 +1,331 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>net_kernel</title> + <prepared>Claes Wikstrom</prepared> + <docno>1</docno> + <date>96-09-10</date> + <rev>A</rev> + </header> + <module>net_kernel</module> + <modulesummary>Erlang Networking Kernel</modulesummary> + <description> + <p>The net kernel is a system process, registered as + <c>net_kernel</c>, which must be running for distributed Erlang + to work. The purpose of this process is to implement parts of + the BIFs <c>spawn/4</c> and <c>spawn_link/4</c>, and to provide + monitoring of the network.</p> + <p>An Erlang node is started using the command line flag + <c>-name</c> or <c>-sname</c>:</p> + <pre> +$ <input>erl -sname foobar</input></pre> + <p>It is also possible to call <c>net_kernel:start([foobar])</c> + directly from the normal Erlang shell prompt:</p> + <p></p> + <pre> +1> <input>net_kernel:start([foobar, shortnames]).</input> +{ok,<0.64.0>} +(foobar@gringotts)2></pre> + <p>If the node is started with the command line flag <c>-sname</c>, + the node name will be <c>foobar@Host</c>, where <c>Host</c> is + the short name of the host (not the fully qualified domain name). + If started with the <c>-name</c> flag, <c>Host</c> is the fully + qualified domain name. See <c>erl(1)</c>.</p> + <p>Normally, connections are established automatically when + another node is referenced. This functionality can be disabled + by setting the Kernel configuration parameter + <c>dist_auto_connect</c> to <c>false</c>, see + <seealso marker="kernel_app">kernel(6)</seealso>. In this case, + connections must be established explicitly by calling + <c>net_kernel:connect_node/1</c>.</p> + <p>Which nodes are allowed to communicate with each other is handled + by the magic cookie system, see + <seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso> in the Erlang Reference Manual.</p> + </description> + <funcs> + <func> + <name>allow(Nodes) -> ok | error</name> + <fsummary>Limit access to a specified set of nodes</fsummary> + <type> + <v>Nodes = [node()]</v> + </type> + <desc> + <p>Limits access to the specified set of nodes. Any access + attempts made from (or to) nodes not in <c>Nodes</c> will be + rejected.</p> + <p>Returns <c>error</c> if any element in <c>Nodes</c> is not + an atom.</p> + </desc> + </func> + <func> + <name>connect_node(Node) -> true | false | ignored</name> + <fsummary>Establish a connection to a node</fsummary> + <type> + <v>Node = node()</v> + </type> + <desc> + <p>Establishes a connection to <c>Node</c>. Returns <c>true</c> + if successful, <c>false</c> if not, and <c>ignored</c> if + the local node is not alive.</p> + </desc> + </func> + <func> + <name>monitor_nodes(Flag) -> ok | Error</name> + <name>monitor_nodes(Flag, Options) -> ok | Error</name> + <fsummary>Subscribe to node status change messages</fsummary> + <type> + <v>Flag = true | false</v> + <v>Options = [Option]</v> + <v> Option -- see below</v> + <v>Error = error | {error, term()}</v> + </type> + <desc> + <p>The calling process subscribes or unsubscribes to node + status change messages. A <c>nodeup</c> message is delivered + to all subscribing process when a new node is connected, and + a <c>nodedown</c> message is delivered when a node is + disconnected.</p> + <p>If <c>Flag</c> is <c>true</c>, a new subscription is started. + If <c>Flag</c> is <c>false</c>, all previous subscriptions -- + started with the same <c>Options</c> -- are stopped. Two + option lists are considered the same if they contain the same + set of options.</p> + <p>As of <c>kernel</c> version 2.11.4, and <c>erts</c> version + 5.5.4, the following is guaranteed:</p> + <list type="bulleted"> + <item><c>nodeup</c> messages will be delivered before delivery + of any message from the remote node passed through the + newly established connection.</item> + <item><c>nodedown</c> messages will not be delivered until all + messages from the remote node that have been passed + through the connection have been delivered.</item> + </list> + <p>Note, that this is <em>not</em> guaranteed for <c>kernel</c> + versions before 2.11.4.</p> + <p>As of <c>kernel</c> version 2.11.4 subscriptions can also be + made before the <c>net_kernel</c> server has been started, + i.e., <c>net_kernel:monitor_nodes/[1,2]</c> does not return + <c>ignored</c>.</p> + <p>As of <c>kernel</c> version 2.13, and <c>erts</c> version + 5.7, the following is guaranteed:</p> + <list type="bulleted"> + <item><c>nodeup</c> messages will be delivered after the + corresponding node appears in results from + <c>erlang:nodes/X</c>.</item> + <item><c>nodedown</c> messages will be delivered after the + corresponding node has disappeared in results from + <c>erlang:nodes/X</c>.</item> + </list> + <p>Note, that this is <em>not</em> guaranteed for <c>kernel</c> + versions before 2.13.</p> + <p>The format of the node status change messages depends on + <c>Options</c>. If <c>Options</c> is [], which is the default, + the format is:</p> + <code type="none"> +{nodeup, Node} | {nodedown, Node} + Node = node()</code> + <p>If <c>Options /= []</c>, the format is:</p> + <code type="none"> +{nodeup, Node, InfoList} | {nodedown, Node, InfoList} + Node = node() + InfoList = [{Tag, Val}]</code> + <p><c>InfoList</c> is a list of tuples. Its contents depends on + <c>Options</c>, see below.</p> + <p>Also, when <c>OptionList == []</c> only visible nodes, that + is, nodes that appear in the result of + <seealso marker="erts:erlang#nodes/0">nodes/0</seealso>, are + monitored.</p> + <p><c>Option</c> can be any of the following:</p> + <taglist> + <tag><c>{node_type, NodeType}</c></tag> + <item> + <p>Currently valid values for <c>NodeType</c> are:</p> + <taglist> + <tag><c>visible</c></tag> + <item>Subscribe to node status change messages for visible + nodes only. The tuple <c>{node_type, visible}</c> is + included in <c>InfoList</c>.</item> + <tag><c>hidden</c></tag> + <item>Subscribe to node status change messages for hidden + nodes only. The tuple <c>{node_type, hidden}</c> is + included in <c>InfoList</c>.</item> + <tag><c>all</c></tag> + <item>Subscribe to node status change messages for both + visible and hidden nodes. The tuple + <c>{node_type, visible | hidden}</c> is included in + <c>InfoList</c>.</item> + </taglist> + </item> + <tag><c>nodedown_reason</c></tag> + <item> + <p>The tuple <c>{nodedown_reason, Reason}</c> is included in + <c>InfoList</c> in <c>nodedown</c> messages. <c>Reason</c> + can be:</p> + <taglist> + <tag><c>connection_setup_failed</c></tag> + <item>The connection setup failed (after <c>nodeup</c> + messages had been sent).</item> + <tag><c>no_network</c></tag> + <item>No network available.</item> + <tag><c>net_kernel_terminated</c></tag> + <item>The <c>net_kernel</c> process terminated.</item> + <tag><c>shutdown</c></tag> + <item>Unspecified connection shutdown.</item> + <tag><c>connection_closed</c></tag> + <item>The connection was closed.</item> + <tag><c>disconnect</c></tag> + <item>The connection was disconnected (forced from the + current node).</item> + <tag><c>net_tick_timeout</c></tag> + <item>Net tick timeout.</item> + <tag><c>send_net_tick_failed</c></tag> + <item>Failed to send net tick over the connection.</item> + <tag><c>get_status_failed</c></tag> + <item>Status information retrieval from the <c>Port</c> + holding the connection failed.</item> + </taglist> + </item> + </taglist> + </desc> + </func> + <func> + <name>get_net_ticktime() -> Res</name> + <fsummary>Get <c>net_ticktime</c></fsummary> + <type> + <v>Res = NetTicktime | {ongoing_change_to, NetTicktime}</v> + <v> NetTicktime = int()</v> + </type> + <desc> + <p>Gets <c>net_ticktime</c> (see + <seealso marker="kernel_app">kernel(6)</seealso>).</p> + <p>Currently defined return values (<c>Res</c>):</p> + <taglist> + <tag><c>NetTicktime</c></tag> + <item> + <p><c>net_ticktime</c> is <c>NetTicktime</c> seconds.</p> + </item> + <tag><c>{ongoing_change_to, NetTicktime}</c></tag> + <item> + <p><c>net_kernel</c> is currently changing + <c>net_ticktime</c> to <c>NetTicktime</c> seconds.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>set_net_ticktime(NetTicktime) -> Res</name> + <name>set_net_ticktime(NetTicktime, TransitionPeriod) -> Res</name> + <fsummary>Set <c>net_ticktime</c></fsummary> + <type> + <v>NetTicktime = int() > 0</v> + <v>TransitionPeriod = int() >= 0</v> + <v>Res = unchanged | change_initiated | {ongoing_change_to, NewNetTicktime}</v> + <v> NewNetTicktime = int() > 0</v> + </type> + <desc> + <p>Sets <c>net_ticktime</c> (see + <seealso marker="kernel_app">kernel(6)</seealso>) to + <c>NetTicktime</c> seconds. <c>TransitionPeriod</c> defaults + to 60.</p> + <p>Some definitions:</p> + <p></p> + <taglist> + <tag>The minimum transition traffic interval (<c>MTTI</c>)</tag> + <item> + <p><c>minimum(NetTicktime, PreviousNetTicktime)*1000 div 4</c> milliseconds.</p> + </item> + <tag>The transition period</tag> + <item> + <p>The time of the least number of consecutive <c>MTTI</c>s + to cover <c>TransitionPeriod</c> seconds following + the call to <c>set_net_ticktime/2</c> (i.e. + ((<c>TransitionPeriod*1000 - 1) div MTTI + 1)*MTTI</c> + milliseconds).</p> + </item> + </taglist> + <p>If <c><![CDATA[NetTicktime < PreviousNetTicktime]]></c>, the actual + <c>net_ticktime</c> change will be done at the end of + the transition period; otherwise, at the beginning. During + the transition period, <c>net_kernel</c> will ensure that + there will be outgoing traffic on all connections at least + every <c>MTTI</c> millisecond.</p> + <note> + <p>The <c>net_ticktime</c> changes have to be initiated on all + nodes in the network (with the same <c>NetTicktime</c>) + before the end of any transition period on any node; + otherwise, connections may erroneously be disconnected.</p> + </note> + <p>Returns one of the following:</p> + <taglist> + <tag><c>unchanged</c></tag> + <item> + <p><c>net_ticktime</c> already had the value of + <c>NetTicktime</c> and was left unchanged.</p> + </item> + <tag><c>change_initiated</c></tag> + <item> + <p><c>net_kernel</c> has initiated the change of + <c>net_ticktime</c> to <c>NetTicktime</c> seconds.</p> + </item> + <tag><c>{ongoing_change_to, NewNetTicktime}</c></tag> + <item> + <p>The request was <em>ignored</em>; because, + <c>net_kernel</c> was busy changing <c>net_ticktime</c> to + <c>NewTicktime</c> seconds.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>start([Name]) -> {ok, pid()} | {error, Reason}</name> + <name>start([Name, NameType]) -> {ok, pid()} | {error, Reason}</name> + <name>start([Name, NameType, Ticktime]) -> {ok, pid()} | {error, Reason}</name> + <fsummary>Turn an Erlang runtime system into a distributed node</fsummary> + <type> + <v>Name = atom()</v> + <v>NameType = shortnames | longnames</v> + <v>Reason = {already_started, pid()} | term()</v> + </type> + <desc> + <p>Note that the argument is a list with exactly one, two or + three arguments. <c>NameType</c> defaults to <c>longnames</c> + and <c>Ticktime</c> to 15000.</p> + <p>Turns a non-distributed node into a distributed node by + starting <c>net_kernel</c> and other necessary processes.</p> + </desc> + </func> + <func> + <name>stop() -> ok | {error, not_allowed | not_found}</name> + <fsummary>Turn a node into a non-distributed Erlang runtime system</fsummary> + <desc> + <p>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 <c>start/1</c>, otherwise returns + <c>{error, not_allowed}</c>. Returns <c>{error, not_found}</c> + if the local node is not alive.</p> + </desc> + </func> + </funcs> +</erlref> + diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml new file mode 100644 index 0000000000..5bac964535 --- /dev/null +++ b/lib/kernel/doc/src/notes.xml @@ -0,0 +1,2273 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2004</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>Kernel Release Notes</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>notes.xml</file> + </header> + <p>This document describes the changes made to the Kernel application.</p> + +<section><title>Kernel 2.13.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>A link in <c>pg2(3)</c> has been fixed. (Thanks to + Christophe Romain.)</p> + <p> + Own Id: OTP-8198</p> + </item> + <item> + <p> + A ticker process could potentially be blocked + indefinitely trying to send a tick to a node not + responding. If this happened, the connection would not be + brought down as it should.</p> + <p> + Own Id: OTP-8218</p> + </item> + <item> + <p>A bug in <c>pg2</c> when members who died did not + leave process groups has been fixed. (Thanks to Matthew + Dempsky.)</p> + <p> + Own Id: OTP-8259</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The documentation is now built with open source tools + (xsltproc and fop) that exists on most platforms. One + visible change is that the frames are removed.</p> + <p> + Own Id: OTP-8201</p> + </item> + <item> + <p> + The top directory in archive files does not need to have + a <c>-vsn</c> suffix anymore. For example if the archive + file has the name like <c>mnesia-4.4.7.ez</c> the top + directory in the archive can either be named + <c>mnesia</c> or <c>mnesia-4.4.7</c>. If the archive file + has a name like <c>mnesia.ez</c> the top directory in the + archive must be named <c>mnesia</c> as earlier.</p> + <p> + Own Id: OTP-8266</p> + </item> + <item> + <p>The -on_load() directive can be used to run a function + when a module is loaded. It is documented in the section + about code loading in the Reference Manual.</p> + <p> + Own Id: OTP-8295</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.13.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> The DNS resolver client inet_res has been rewritten, + documented and released. See inet_res(3) and Erts User's + Guide: Inet configuration. </p><p> It can formally not be + incompatible with respect to earlier versions since there + was no earlier official version. However it was used + before and some details have changed. </p><p> + Configuration now initializes from /etc/resolv.conf and + /etc/hosts on all unix platforms regardless of which + distribution mode the node is started in. The directory + (/etc) these files are supposed to reside in can be + changed via an environment variable. These configuration + file locations can also be changed in the inet + configuration. The files are monitored for change and + re-read, which makes a few resolver configuration + variables out of application control. The /etc/hosts + entries have now their own cache table that is shadowed + (with lookup method 'file' is used) by the application + configured host entries. This problem (that inet_res + configuration only worked for distribution mode long + names) was among other reported by Matthew O'Gorman many + moons ago. </p><p> The lookup methods are still 'native' + only per default. Resolver configuration is done on all + Unix platforms just to get a usable configuration for + direct calls to inet_res. </p><p> The functions + <c>inet_res:nslookup/3..5</c> and + <c>inet_res:nnslookup/4..4</c> are no longer recommended + to use, instead use <c>inet_res:lookup/3..5</c> and + <c>inet_res:resolve/3..5</c> which provide clearer + argument types and the possibility to override options in + the call. </p><p> Users of previous unsupported versions + of inet_res have included internal header files to get to + the internal record definitions in order to examine DNS + replies. This is still unsupported and there are access + functions in inet_dns to use instead. These are + documented in inet_res(3). </p><p> Bug fix: a compression + reference loop would make DNS message decoding loop + forever. Problem reported by Florian Weimer. </p><p> Bug + fix and patch suggestion by Sergei Golovan: configuring + IPv6 nameservers did not work. His patch (as he warned) + created many UDP sockets; one per nameserver. This has + been fixed in the released version. </p><p> Improvement: + <c>inet_res</c> is now EDNS0 capable. The current + implementation is simple and does not probe and cache + EDNS info for nameservers, which a fully capable + implementation probably should do. EDNS has to be enabled + via resolver configuration, and if a nameserver replies + that it does not support EDNS, <c>inet_res</c> falls back + to a regular DNS query. </p><p> Improvement: now + <c>inet_res</c> automatically falls back to TCP if it + gets a truncated answer from a nameserver. </p><p> + Warning: some of the ancient and exotic record types + handled by <c>inet_res</c> and <c>inet_dns</c> are not + supported by current versions of BIND, so they could not + be tested after the rewrite, with reasonable effort, e.g + MD, MF, NULL, and SPF. The risk for bugs in these + particular records is still low since their code is + mostly shared with other tested record types. </p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-7955 Aux Id: OTP-7107 OTP-6852 </p> + </item> + <item> + <p> + A TCP socket with option <c>{packet,4}</c> could crash + the emulator if it received a packet header with a very + large size value (>2Gb). The same bug caused + <c>erlang:decode_packet/3</c> to return faulty values. + (Thanks to Georgos Seganos.)</p> + <p> + Own Id: OTP-8102</p> + </item> + <item> + <p> + The file module has now a read_line/1 function similar to + the io:get_line/2, but with byte oriented semantics. The + function file:read_line/1 works for raw files as well, + but for good performance it is recommended to use it + together with the 'read_ahead' option for raw file + access.</p> + <p> + Own Id: OTP-8108</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.13.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A bug when doing io:get_line (among other calls) from a + file opened with encoding other than latin1, causing + false unicode errors to occur, is now corrected.</p> + <p> + Own Id: OTP-7974</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added functionality to get higher resolution timestamp + from system. The erlang:now function returns a timestamp + that's not always consistent with the actual operating + system time (due to resilience against large time changes + in the operating system). The function os:timestamp/0 is + added to get a similar timestamp as the one being + returned by erlang:now, but untouched by Erlangs time + correcting and smoothing algorithms. The timestamp + returned by os:timestamp is always consistent with the + operating systems view of time, like the calendar + functions for getting wall clock time, but with higher + resolution. Example of usage can be found in the os + manual page.</p> + <p> + Own Id: OTP-7971</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.13.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Many concurrent calls to <c>os:cmd/1</c> will only block + one scheduler thread at a time, making an smp emulator + more responsive if the OS is slow forking processes.</p> + <p> + Own Id: OTP-7890 Aux Id: seq11219 </p> + </item> + <item> + <p> + Fixed hanging early RPC that did IO operation during node + start.</p> + <p> + Own Id: OTP-7903 Aux Id: seq11224 </p> + </item> + <item> + <p> + The error behavior of gen_tcp and gen_udp has been + corrected. gen_tcp:connect/3,4 and gen_udp:send/4 now + returns {error,eafnosupport} for conflicting destination + address versus socket address family. Other corner cases + for IP address string host names combined with not using + the native (OS) resolver (which is not default) has also + been changed to return {error,nxdomain} instead of + {error,einval}. Those changes just may surprise old + existing code. gen_tcp:listen/2 and gen_udp:open/2 now + fails for conflicting local address versus socket address + family instead of trying to use an erroneous address. + Problem reported by Per Hedeland.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-7929</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Several glitches and performance issues in the Unicode + and I/O-system implementation of R13A have been + corrected.</p> + <p> + Own Id: OTP-7896 Aux Id: OTP-7648 OTP-7887 </p> + </item> + <item> + <p> + The unsupported DNS resolver client inet_res has now been + improved to handle NAPTR queries.</p> + <p> + Own Id: OTP-7925 Aux Id: seq11231 </p> + </item> + </list> + </section> + +</section> + + +<section><title>Kernel 2.13</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The old Erlang DNS resolver inet_res has been corrected + to handle TXT records with more than one character + string. Patch courtesy of Geoff Cant.</p> + <p> + Own Id: OTP-7588</p> + </item> + <item> + <p>When chunk reading a disk log opened in read_only + mode, bad terms could crash the disk log process.</p> + <p> + Own Id: OTP-7641 Aux Id: seq11090 </p> + </item> + <item> + <p> + <c>gen_tcp:send()</c> did sometimes (only observed on + Solaris) return <c>{error,enotconn}</c> instead of the + expected <c>{error,closed}</c> as the peer socket had + been explicitly closed.</p> + <p> + Own Id: OTP-7647</p> + </item> + <item> + <p> + The gen_sctp option sctp_peer_addr_params, + #sctp_paddrparams{address={IP,Port} was erroneously + decoded in the inet driver. This bug has now been + corrected.</p> + <p> + Own Id: OTP-7755</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Erlang programs can now access STDERR on platforms where + such a file descriptor is available by using the + io_server 'standard_error', i.e. + io:format(standard_error,"~s~n",[ErrorMessage]),</p> + <p> + Own Id: OTP-6688</p> + </item> + <item> + <p> + The format of the string returned by + <c>erlang:system_info(system_version)</c> (as well as the + first message when Erlang is started) has changed. The + string now contains the both the OTP version number as + well as the erts version number.</p> + <p> + Own Id: OTP-7649</p> + </item> + <item> + <p>As of this version, the global name server no longer + supports nodes running Erlang/OTP R10B.</p> + <p> + Own Id: OTP-7661</p> + </item> + <item> + <p> + A <c>{nodedown, Node}</c> message passed by the + <c>net_kernel:monitor_nodes/X</c> functionality is now + guaranteed to be sent after <c>Node</c> has been removed + from the result returned by <c>erlang:nodes/Y</c>.</p> + <p> + Own Id: OTP-7725</p> + </item> + <item> + <p>The deprecated functions <c>erlang:fault/1</c>, + <c>erlang:fault/2</c>, and <c>file:rawopen/2</c> have + been removed.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-7812</p> + </item> + <item> + <p> + Nodes belonging to different independent clusters can now + co-exist on the same host with the help of a new + environment variable setting ERL_EPMD_PORT.</p> + <p> + Own Id: OTP-7826</p> + </item> + <item> + <p>The copyright notices have been updated.</p> + <p> + Own Id: OTP-7851</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.12.5.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>When chunk reading a disk log opened in read_only + mode, bad terms could crash the disk log process.</p> + <p> + Own Id: OTP-7641 Aux Id: seq11090 </p> + </item> + <item> + <p> + Calling <c>gen_tcp:send()</c> from several processes on + socket with option <c>send_timeout</c> could lead to much + longer timeout than specified. The solution is a new + socket option <c>{send_timeout_close,true}</c> that will + do automatic close on timeout. Subsequent calls to send + will then immediately fail due to the closed connection.</p> + <p> + Own Id: OTP-7731 Aux Id: seq11161 </p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.12.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>The documentation of <c>rpc:pmap/3</c> has been + corrected. (Thanks to Kirill Zaborski.)</p> + <p> + Own Id: OTP-7537</p> + </item> + <item> + <p> + The listen socket used for the distributed Erlang + protocol now uses the socket option 'reuseaddr', which is + useful when you force the listen port number using kernel + options 'inet_dist_listen_min' and 'inet_dist_listen_max' + and restarts a node with open connections.</p> + <p> + Own Id: OTP-7563</p> + </item> + <item> + <p> + Fixed memory leak of unclosed TCP-ports. A gen_tcp:send() + followed by a failing gen_tcp:recv() could in some cases + cause the port to linger after being closed.</p> + <p> + Own Id: OTP-7615</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Processes spawned using <c>proc_lib</c> (including + <c>gen_server</c> and other library modules that use + <c>proc_lib</c>) no longer keep the entire argument list + for the initial call, but only the arity.</p> + <p>Also, if <c>proc_lib:spawn/1</c> is used to spawn a + fun, the actual fun is not kept, but only module, + function name, and arity of the function that implements + the fun.</p> + <p>The reason for the change is that keeping the initial + fun (or a fun in an argument list), would prevent + upgrading the code for the module. A secondary reason is + that keeping the fun and function arguments could waste a + significant amount of memory.</p> + <p>The drawback with the change is that the crash reports + will provide less precise information about the initial + call (only <c>Module:Function/Arity</c> instead of + <c>Module:Function(Arguments)</c>). The function + <c>proc_lib:initial_call/1</c> still returns a list, but + each argument has been replaced with a dummy atom.</p> + <p> + Own Id: OTP-7531 Aux Id: seq11036 </p> + </item> + <item> + <p> + <c>io:get_line/1</c> when reading from standard input is + now substantially faster. There are also some minor + performance improvements in <c>io:get_line/1</c> when + reading from any file opened in binary mode. (Thanks to + Fredrik Svahn.)</p> + <p> + Own Id: OTP-7542</p> + </item> + <item> + <p> + There is now experimental support for loading of code + from archive files. See the documentation of <c>code</c>, + <c>init</c>, <c>erl_prim_loader </c> and <c>escript</c> + for more info.</p> + <p> + The error handling of <c>escripts</c> has been improved.</p> + <p> + An <c>escript</c> may now set explicit arguments to the + emulator, such as <c>-smp enabled</c>.</p> + <p> + An <c>escript</c> may now contain a precompiled beam + file.</p> + <p> + An <c>escript</c> may now contain an archive file + containing one or more applications (experimental).</p> + <p> + The internal module <c>code_aux</c> has been removed.</p> + <p> + Own Id: OTP-7548 Aux Id: otp-6622 </p> + </item> + <item> + <p> + <c>code:is_sticky/1</c> is now documented. (Thanks to + Vlad Dumitrescu.)</p> + <p> + Own Id: OTP-7561</p> + </item> + <item> + <p> + In the job control mode, the "s" and "r" commands now + take an optional argument to specify which shell to + start. (Thanks to Robert Virding.)</p> + <p> + Own Id: OTP-7617</p> + </item> + <item> + <p> + <c>net_adm:world/0,1</c> could crash if called in an + emulator that has not been started with either the + <c>-sname</c> or <c>-name</c> option; now it will return + an empty list. (Thanks to Edwin Fine.)</p> + <p> + Own Id: OTP-7618</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.12.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Large files are now handled on Windows, where the + filesystem supports it.</p> + <p> + Own Id: OTP-7410</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + New BIF <c>erlang:decode_packet/3</c> that extracts a + protocol packet from a binary. Similar to the socket + option <c>{packet, Type}</c>. Also documented the socket + packet type <c>http</c> and made it official. + <em>NOTE</em>: The tuple format for <c>http</c> packets + sent from an active socket has been changed in an + incompatible way.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-7404</p> + </item> + <item> + <p> + Setting the <c>{active,once}</c> for a socket (using + inets:setopts/2) is now specially optimized (because the + <c>{active,once}</c> option is typically used much more + frequently than other options).</p> + <p> + Own Id: OTP-7520</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.12.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + SCTP_ADDR_CONFIRMED events are now handled by gen_sctp.</p> + <p> + Own Id: OTP-7276</p> + </item> + <item> + <p>When leaving a process group with <c>pg2:leave/2</c> + the process was falsely assumed to be a member of the + group. This bug has been fixed.</p> + <p> + Own Id: OTP-7277</p> + </item> + <item> + <p> + In the Erlang shell, using up and down arrow keys, the + wrong previous command could sometimes be retrieved.</p> + <p> + Own Id: OTP-7278</p> + </item> + <item> + <p> + The documentation for <c>erlang:trace/3</c> has been + corrected.</p> + <p> + Own Id: OTP-7279 Aux Id: seq10927 </p> + </item> + <item> + <p> + In the SMP emulator, there was small risk that + <c>code:purge(Mod)</c> would kill a process that was + running code in <c>Mod</c> and unload the module + <c>Mod</c> before the process had terminated. + <c>code:purge(Mod)</c> now waits for confirmation (using + <c>erlang:monitor/2</c>) that the process has been killed + before proceeding.</p> + <p> + Own Id: OTP-7282</p> + </item> + <item> + <p> + <c>zlib:inflate</c> failed when the size of the inflated + data was an exact multiple of the internal buffer size + (4000 bytes by default).</p> + <p> + Own Id: OTP-7359</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Additional library directories can now be specified in + the environment variable ERL_LIBS. See the manual page + for the <c>code</c> module. (Thanks to Serge Aleynikov.)</p> + <p> + Own Id: OTP-6940</p> + </item> + <item> + <p> + crypto and zlib drivers improved to allow concurrent smp + access.</p> + <p> + Own Id: OTP-7262</p> + </item> + <item> + <p> + There is a new function <c>init:stop/1</c> which can be + used to shutdown the system cleanly AND generate a + non-zero exit status or crash dump. (Thanks to Magnus + Froberg.)</p> + <p> + Own Id: OTP-7308</p> + </item> + <item> + <p> + The <c>hide</c> option for <c>open_port/2</c> is now + documented. (Thanks to Richard Carlsson.)</p> + <p> + Own Id: OTP-7358</p> + </item> + </list> + </section> + +</section> + + +<section><title>Kernel 2.12.2.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + <c>os:cmd/1</c> on unix platforms now use <c>/bin/sh</c> + as shell instead of looking for <c>sh</c> in the + <c>PATH</c> environment.</p> + <p> + Own Id: OTP-7283</p> + </item> + </list> + </section> + +</section> +<section><title>Kernel 2.12.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>A bug caused by a race condition involving + <c>disk_log</c> and <c>pg2</c> has been fixed.</p> + <p> + Own Id: OTP-7209 Aux Id: seq10890 </p> + </item> + <item> + <p>The beta testing module <c>gen_sctp</c> now supports + active mode as stated in the documentation. Active mode + is still rather untested, and there are some issues about + what should be the right semantics for + <c>gen_sctp:connect/5</c>. In particular: should it be + blocking or non-blocking or choosable. There is a high + probability it will change semantics in a (near) future + patch.</p> <p>Try it, give comments and send in bug + reports!</p> + <p> + Own Id: OTP-7225</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p><c>erlang:system_info/1</c> now accepts the + <c>logical_processors</c>, and <c>debug_compiled</c> + arguments. For more info see the, <c>erlang(3)</c> + documentation.</p> <p>The scale factor returned by + <c>test_server:timetrap_scale_factor/0</c> is now also + effected if the emulator uses a larger amount of + scheduler threads than the amount of logical processors + on the system. </p> + <p> + Own Id: OTP-7175</p> + </item> + <item> + <p> + Updated the documentation for + <c>erlang:function_exported/3</c> and <c>io:format/2</c> + functions to no longer state that those functions are + kept mainly for backwards compatibility.</p> + <p> + Own Id: OTP-7186</p> + </item> + <item> + <p> + A process executing the <c>processes/0</c> BIF can now be + preempted by other processes during its execution. This + in order to disturb the rest of the system as little as + possible. The returned result is, of course, still a + consistent snapshot of existing processes at a time + during the call to <c>processes/0</c>.</p> + <p> + The documentation of the <c>processes/0</c> BIF and the + <c>is_process_alive/1</c> BIF have been updated in order + to clarify the difference between an existing process and + a process that is alive.</p> + <p> + Own Id: OTP-7213</p> + </item> + <item> + <p><c>tuple_size/1</c> and <c>byte_size/1</c> have been + substituted for <c>size/1</c> in the documentation.</p> + <p> + Own Id: OTP-7244</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.12.1.2</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The <c>{allocator_sizes, Alloc}</c> and + <c>alloc_util_allocators</c> arguments are now accepted + by <c>erlang:system_info/1</c>. For more information see + the <c>erlang(3)</c> documentation.</p> + <p> + Own Id: OTP-7167</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.12.1.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed a problem in group that could cause the ssh server + to lose answers or hang.</p> + <p> + Own Id: OTP-7185 Aux Id: seq10871 </p> + </item> + </list> + </section> +</section> +<section><title>Kernel 2.12.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + file:read/2 and file:consult_stream/1,3 did not use an + empty prompt on I/O devices. This bug has now been + corrected.</p> + <p> + Own Id: OTP-7013</p> + </item> + <item> + <p> + The sctp driver has been updated to work against newer + lksctp packages e.g 1.0.7 that uses the API spelling + change adaption -> adaptation. Older lksctp (1.0.6) still + work. The erlang API in gen_sctp.erl and inet_sctp.hrl + now spells 'adaptation' regardless of the underlying C + API.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-7120</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The documentation has been updated so as to reflect + the last updates of the Erlang shell as well as the minor + modifications of the control sequence <c>p</c> of the + <c>io_lib</c> module.</p> <p>Superfluous empty lines have + been removed from code examples and from Erlang shell + examples.</p> + <p> + Own Id: OTP-6944 Aux Id: OTP-6554, OTP-6911 </p> + </item> + <item> + <p><c>tuple_size/1</c> and <c>byte_size/1</c> have been + substituted for <c>size/1</c>.</p> + <p> + Own Id: OTP-7009</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.12</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A bug for raw files when reading 0 bytes returning 'eof' + instead of empty data has been corrected.</p> + <p> + Own Id: OTP-6291 Aux Id: OTP-6967 </p> + </item> + <item> + <p> + A bug in gen_udp:fdopen reported by David Baird and also + found by Dialyzer has been fixed.</p> + <p> + Own Id: OTP-6836 Aux Id: OTP-6594 </p> + </item> + <item> + <p> + Calling <c>error_logger:tty(true)</c> multiple times does + not give multiple error log printouts.</p> + <p> + Own Id: OTP-6884 Aux Id: seq10767 </p> + </item> + <item> + <p>The global name server now ignores <c>nodeup</c> + messages when the command line flag <c>-connect_all + false</c> has been used. (Thanks to Trevor + Woollacott.)</p> + <p> + Own Id: OTP-6931</p> + </item> + <item> + <p>file:write_file/3, file:write/2 and file:read/2 could + crash (contrary to documentation) for odd enough file + system problems, e.g write to full file system. This bug + has now been corrected.</p> <p>In this process the file + module has been rewritten to produce better error codes. + Posix error codes now originate from the OS file system + calls or are generated only for very similar causes (for + example 'enomem' is generated if a memory allocation + fails, and 'einval' is generated if the file handle in + Erlang is a file handle but currently invalid).</p> + <p>More Erlang-ish error codes are now generated. For + example <c>{error,badarg}</c> is now returned from + <c>file:close/1</c> if the argument is not of a file + handle type. See file(3).</p> <p>The possibility to write + a single byte using <c>file:write/2</c> instead of a list + or binary of one byte, contradictory to the + documentation, has been removed.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-6967 Aux Id: OTP-6597 OTP-6291 </p> + </item> + <item> + <p> + Monitor messages produced by the system monitor + functionality, and garbage collect trace messages could + contain erroneous heap and/or stack sizes when the actual + heaps and/or stacks were huge.</p> + <p> + As of erts version 5.6 the <c>large_heap</c> option to + <c>erlang:system_monitor/[1,2]</c> has been modified. The + monitor message is sent if the sum of the sizes of all + memory blocks allocated for all heap generations is equal + to or larger than the specified size. Previously the + monitor message was sent if the memory block allocated + for the youngest generation was equal to or larger than + the specified size.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-6974 Aux Id: seq10796 </p> + </item> + <item> + <p> + <c>inet:getopts/2</c> returned random values on Windows + Vista.</p> + <p> + Own Id: OTP-7003</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Minor documentation corrections for file:pread/2 and + file:pread/3.</p> + <p> + Own Id: OTP-6853</p> + </item> + <item> + <p> + The deprecated functions <c>file:file_info/1</c>, + <c>init:get_flag/1</c>, <c>init:get_flags/0</c>, and + <c>init:get_args/0</c> have been removed.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-6886</p> + </item> + <item> + <p> + Contract directives for modules in Kernel and STDLIB.</p> + <p> + Own Id: OTP-6895</p> + </item> + <item> + <p>The functions io:columns/0, io:columns/1, io:rows/0 + and io:rows/1 are added to allow the user to get + information about the terminal geometry. The shell takes + some advantage of this when formatting output. For + regular files and other io-devices where height and width + are not applicable, the functions return + {error,enotsup}.</p> + <p>Potential incompatibility: If one has written a custom + io-handler, the handler has to either return an error or + take care of io-requests regarding terminal height and + width. Usually that is no problem as io-handlers, as a + rule of thumb, should give an error reply when receiving + unknown io-requests, instead of crashing.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-6933</p> + </item> + <item> + <p> + The undocumented and unsupported functions + <c>inet:ip_to_bytes/1</c>, <c>inet:ip4_to_bytes/1</c>, + <c>inet:ip6_to_bytes/1</c>, and + <c>inet:bytes_to_ip6/16</c> have been removed.</p> + <p> + Own Id: OTP-6938</p> + </item> + <item> + <p> + Added new checksum combine functions to <c>zlib</c>. And + fixed a bug in <c>zlib:deflate</c>. Thanks Matthew + Dempsky.</p> + <p> + Own Id: OTP-6970</p> + </item> + <item> + <p> + The <c>spawn_monitor/1</c> and <c>spawn_monitor/3</c> BIFs + are now auto-imported (i.e. they no longer need an + <c>erlang:</c> prefix).</p> + <p> + Own Id: OTP-6975</p> + </item> + <item> + <p>All functions in the <c>code</c> module now fail with + an exception if they are called with obviously bad + arguments, such as a tuple when an atom was expected. + Some functions now also fail for undocumented argument + types (for instance, <c>ensure_loaded/1</c> now only + accepts an atom as documented; it used to accept a string + too).</p> + <p><c>Dialyzer</c> will generally emit warnings for any + calls that use undocumented argument types. Even if the + call happens to still work in R12B, you should correct + your code. A future release will adhere to the + documentation.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-6983</p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.11.5.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The kernel parameter dist_auto_connect once could fail to + block a node if massive parallel sends were issued + during a transient failure of network communication</p> + <p> + Own Id: OTP-6893 Aux Id: seq10753 </p> + </item> + </list> + </section> + +</section> + +<section><title>Kernel 2.11.5.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The internal (rarely used) DNS resolver has been modified + to not use the domain search list when asked to resolve + an absolute name; a name with a terminating dot. There + was also a bug causing it to create malformed DNS queries + for absolute names that has been corrected, correction + suggested by Scott Lystig Fritchie. The code has also + been corrected to look up cached RRs in the same search + order as non-cached, now allows having the root domain + among the search domains, and can now actually do a zone + transfer request.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-6806 Aux Id: seq10714 EABln35459 </p> + </item> + <item> + <p> + zlib:close/1 would leave an EXIT message in the message + queue if the calling process had the trap_exit flag + enabled.</p> + <p> + Own Id: OTP-6811</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The documentation of <c>process_flag(priority, + Level)</c> has been updated, see the <c>erlang(3)</c> + documentation. </p> + <p> + Own Id: OTP-6745 Aux Id: OTP-6715 </p> + </item> + </list> + </section> + +</section> + + <section> + <title>Kernel 2.11.5</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>The shell has been updated to fix the following flaws: + Shell process exit left you with an unresponsive initial + shell if not using oldshell. Starting a restricted shell + with a nonexisting callback module resulted in a shell + where no commands could be used, not even init:stop/0. + Fun's could not be used as parameters to local shell + functions (in shell_default or user_default) when + restricted_shell was active.</p> + <p>Own Id: OTP-6537</p> + </item> + <item> + <p>The undocumented feature gen_tcp:fdopen/2 was broken + in R11B-4. It is now fixed again.</p> + <p>Own Id: OTP-6615</p> + </item> + <item> + <p>Corrected cancellation of timers in three places in the + inet_res module. (Problem found by Dialyzer.)</p> + <p>Own Id: OTP-6676</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Corrected protocol layer flue for socket options + SO_LINGER, SO_SNDBUF and SO_RCVBUF, for SCTP.</p> + <p>Own Id: OTP-6625 Aux Id: OTP-6336 </p> + </item> + <item> + <p>The behaviour of the inet option {active,once} on peer + close is improved and documented.</p> + <p>Own Id: OTP-6681</p> + </item> + <item> + <p>The inet option send_timeout for connection oriented + sockets is added to allow for timeouts in communicating + send requests to the underlying TCP stack.</p> + <p>Own Id: OTP-6684 Aux Id: seq10637 OTP-6681 </p> + </item> + <item> + <p>Minor Makefile changes.</p> + <p>Own Id: OTP-6689 Aux Id: OTP-6742 </p> + </item> + <item> + <p>The documentation of <c>process_flag(priority, Level)</c> has been updated, see the <c>erlang(3)</c> + documentation. </p> + <p>Own Id: OTP-6715</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.11.4.2</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>process_flag/2 accepts the new flag <c>sensitive</c>.</p> + <p>Own Id: OTP-6592 Aux Id: seq10555 </p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.11.4.1</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>A bug in gen_udp:open that broke the 'fd' option has been + fixed.</p> + <p>Own Id: OTP-6594 Aux Id: seq10619 </p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.11.4</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Added a warning to the documentation for the + <c>error_logger</c> functions <c>error_msg/1,2</c>, + <c>warning_msg/1,2</c> and <c>info_msg/1,2</c> that + calling these function with bad arguments can crash the + standard event handler.</p> + <p>Own Id: OTP-4575 Aux Id: seq7693 </p> + </item> + <item> + <p>A bug in <c>inet_db</c> concerning getting the resolver + option <c>retry</c> has been corrected.</p> + <p>Own Id: OTP-6380 Aux Id: seq10534 </p> + </item> + <item> + <p>Names registered by calling + <c>global:register_name()</c> or + <c>global:re_register_name()</c> were not always + unregistered when the registering or registered process + died. This bug has been fixed.</p> + <p>Own Id: OTP-6428</p> + </item> + <item> + <p>When setting the kernel configuration parameter + <c>error_logger</c> to <c>false</c>, the documentation + stated that "No error logger handler is installed". This + is true, but error logging is not turned off, as the + initial, primitive error logger event handler is kept, + printing raw event messages to tty.</p> + <p>Changing this behavior can be viewed as a backward + incompatible change. Instead a new value <c>silent</c> + for the configuration parameter has been added, which + ensures that error logging is completely turned off.</p> + <p>Own Id: OTP-6445</p> + </item> + <item> + <p>Clarified the documentation for <c>code:lib_dir/1</c> and + <c>code:priv_dir/1</c>. The functions traverse the names + of the code path, they do not search the actual + directories.</p> + <p>Own Id: OTP-6466</p> + </item> + <item> + <p><c>io:setopts</c> returned <c>{error,badarg}</c>, when + called with only an <c>expand_fun</c> argument. (Thanks to + igwan.)</p> + <p>Own Id: OTP-6508</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>An interface towards the SCTP Socket API Extensions + has been implemented.It is an Open Source patch courtesy + of Serge Aleynikov and Leonid Timochouk. The Erlang code + parts has been adapted by the OTP team, changing the + Erlang API somewhat.</p> + <p>The Erlang interface consists of the module + <c>gen_sctp</c> and an include file + <c>-include_lib("kernel/include/inet_sctp.hrl").</c> for + option record definitions. The <c>gen_sctp</c> module is + documented.</p> + <p>The delivered Open Source patch, before the OTP team + rewrites, was written according to + <url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13</url> + and was claimed to work fine, tested on Linux Fedora Core + 5.0 (kernel 2.6.15-2054 or later) and on Solaris 10 and + 11. The OTP team rewrites used the same standard document + but might have accidentally broken some functionality. If + so, it will soon be patched to working state. The tricky + parts in C and the general design has essentially not + changed. During the rewrites the code was hand tested on + SuSE Linux Enterprise Server 10, and briefly on Solaris + 10. Feedbach on code and docs is very much + appreciated.</p> + <p>The SCTP interface is in beta state. It has only been + hand tested and has no automatic test suites in OTP + meaning everything is most certainly not tested. Socket + active mode is broken. IPv6 is not tested. The documentation + has been reworked due to the API changes, + but has not been proofread after this.</p> + <p>Thank you from the OTP team to Serge Aleynikov and + Leonid Timochouk for a valuable contribution. We hope we + have not messed it up too much.</p> + <p>Own Id: OTP-6336</p> + </item> + <item> + <p>A <c>{minor_version,Version}</c> option is now recognized + by <c>term_to_binary/2</c>. {minor_version,1} will cause + floats to be encoded in an exact and more space-efficient + way compared to the previous encoding.</p> + <p>Own Id: OTP-6434</p> + </item> + <item> + <p>Monitoring of nodes has been improved. Now the following + properties apply to + <c>net_kernel:monitor_nodes/[1,2]</c>:</p> + <list type="bulleted"> + <item><c>nodeup</c> messages will be delivered before delivery + of any message from the remote node passed through the + newly established connection. </item> + <item><c>nodedown</c> messages will not be delivered until all + messages from the remote node that have been passed + through the connection have been delivered. </item> + <item>Subscriptions can also be made before the + <c>net_kernel</c> server has been started. </item> + </list> + <p>Own Id: OTP-6481</p> + </item> + <item> + <p>Setting and getting socket options in a "raw" fashion is + now allowed. Using this feature will inevitably produce + non portable code, but will allow setting ang getting + arbitrary uncommon options on TCP stacks that do have + them.</p> + <p>Own Id: OTP-6519</p> + </item> + <item> + <p>Dialyzer warnings have been eliminated.</p> + <p>Own Id: OTP-6523</p> + </item> + <item> + <p>The documentation for <c>file:delete/1</c> and + <c>file:set_cwd/1</c> has been updated to clarify what + happens if the input arguments are of an incorrect type.</p> + <p>Own Id: OTP-6535</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.11.3.1</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>An erroneous packet size could be used for the first + messages passed through a newly established connection + between two Erlang nodes. This could cause messages to be + discarded, or termination of the connection.</p> + <p>Own Id: OTP-6473</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.11.3</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>On Unix, the <c>unix:cmd/1</c> function could leave an + 'EXIT' message in the message queue for the calling + process That problem was more likely to happen in an SMP + emulator.</p> + <p>Own Id: OTP-6368</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>More interfaces are added in erl_ddll, to support + different usage scenarios.</p> + <p>Own Id: OTP-6307 Aux Id: OTP-6234 </p> + </item> + <item> + <p>Locks set by calling <c>global:set_lock()</c> were not + always deleted when the locking process died. This bug + has been fixed.</p> + <p>Own Id: OTP-6341 Aux Id: seq10445 </p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.11.2</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Behavior in case of disappeared nodes when using he + dist_auto_connect once got changed in R11B-1. The + timeouts regarding normal distributed operations is now + reverted to the old (pre R11B-1).</p> + <p>Own Id: OTP-6258 Aux Id: OTP-6200, seq10449 </p> + </item> + <item> + <p>Start-up problems for the internal process used by the + <c>inet:gethostbyname()</c> functions were eliminated. If + the internal process (<c>inet_gethost_native</c>) had not + previously been started, and if several processes at the + same time called one of the <c>inet:gethostbyname()</c> + functions, the calls could fail.</p> + <p>Own Id: OTP-6286</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Code cleanup: the old internal obsolete file_server has + been removed. It was only used when communicating with R7 + and older nodes.</p> + <p>Own Id: OTP-6245</p> + </item> + <item> + <p>Trying to open a non-existent or badly formed disk log + no longer results in a crash report. In particular, + <c>ets:file2tab/1</c> reports no error when the argument + is not a well-formed disk log file. (The return value has + not been changed, it is still an error tuple.)</p> + <p>Own Id: OTP-6278 Aux Id: seq10421 </p> + </item> + <item> + <p>There are new BIFs <c>erlang:spawn_monitor/1,3</c>, + and the new option <c>monitor</c> for + <c>spawn_opt/2,3,4,5</c>.</p> + <p>The <c>observer_backend</c> module has been updated to + handle the new BIFs.</p> + <p>Own Id: OTP-6281</p> + </item> + <item> + <p>To help Dialyzer find more bugs, many functions in the + Kernel and STDLIB applications now only accept arguments + of the type that is documented.</p> + <p>For instance, the functions <c>lists:prefix/2</c> and + <c>lists:suffix/2</c> are documented to only accept lists + as their arguments, but they actually accepted anything + and returned <c>false</c>. That has been changed so that + the functions cause an exception if one or both arguments + are not lists.</p> + <p>Also, the <c>string:strip/3</c> function is documented + to take a character argument that is a character to strip + from one or both ends of the string. Given a list instead + of a character, it used to do nothing, but will now cause + an exception.</p> + <p>Dialyzer will find most cases where those functions + are passed arguments of the wrong type.</p> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> + <p>Own Id: OTP-6295</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.11.1.1</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>There is now an option read_packets for UDP sockets that + sets the maximum number of UDP packets that will be read + for each invocation of the socket driver.</p> + <p>Own Id: OTP-6249 Aux Id: seq10452 </p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.11.1</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>In R11B-0, the erl_ddll server process is always started. + Despite that, the configuration parameter + <c>start_ddll</c> for the Kernel application was still + obeyed, which would cause the erl_ddll server to be + started TWICE (and the system shutting down as a result). + In this release, <c>start_ddll</c> is no longer used and + its documentation has been removed.</p> + <p>Own Id: OTP-6163</p> + </item> + <item> + <p>The kernel option {dist_auto_connect,once} could block + out nodes that had never been connected, causing + persistent partitioning of networks. Furthermore, partial + restarts of networks could cause inconsistent global name + databases. Both problems are now solved.</p> + <p>Own Id: OTP-6200 Aux Id: seq10377 </p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Late arriving tcp_closed and udp_closed messages are now + removed from the message queue of a process calling + gen_tcp:close/1, gen_udp:close/1, and inet:close/1.</p> + <p>Own Id: OTP-6197</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.11</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>When repairing a disk log with a corrupt index file + (caused by for instance a hard disk failure) the old + contents of the index file is kept unmodified. This will + make repeated attempts to open the disk log fail every + time.</p> + <p>Own Id: OTP-5558 Aux Id: seq9823 </p> + </item> + <item> + <p>Previously <c>unlink/1</c> and <c>erlang:demonitor/2</c> + behaved completely asynchronous. This had one undesirable + effect, though. You could never know when you were + guaranteed <em>not</em> to be affected by a link that you + had unlinked or a monitor that you had demonitored.</p> + <p>The new behavior of <c>unlink/1</c> and + <c>erlang:demonitor/2</c> can be viewed as two operations + performed atomically. Asynchronously send an unlink + signal or a demonitor signal, and ignore any future + results of the link or monitor.</p> + <p><em>NOTE</em>: This change can cause some obscure code + to fail which previously did not. For example, the + following code might hang:</p> + <code type="none"> + Mon = erlang:monitor(process, Pid), + %% ... + exit(Pid, bang), + erlang:demonitor(Mon), + receive + {'DOWN', Mon, process, Pid, _} -> ok + %% We were previously guaranteed to get a down message + %% (since we exited the process ourself), so we could + %% in this case leave out: + %% after 0 -> ok + end, + </code> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> + <p>Own Id: OTP-5772</p> + </item> + <item> + <p>The behavior when an application fails to start and + possibly causes the runtime system to halt has been + cleaned up, including fixing some minor bugs.</p> + <p><c>application_controller</c> should now always terminate + with a non-nested string, meaning the slogan in an + <c>erl_crash.dump</c> should always be easy to read.</p> + <p><c>init</c> now makes sure that the slogan passed to + <c>erlang:halt/1</c> does not exceed the maximum allowed + length.</p> + <p>Redundant calls to <c>list_to_atom/1</c> has been removed + from the primitive <c>error_logger</c> event handler. + (Thanks Serge Aleynikov for pointing this out).</p> + <p>The changes only affects the contents of the error + messages and crashdump file slogan.</p> + <p>Own Id: OTP-5964</p> + </item> + <item> + <p>The <c>erl_ddll</c> server is now started when OTP is + started and placed under the Kernel supervisor. This + fixes several minor issues. It used to be started on + demand.</p> + <p>The documentation for the <c>start</c> and <c>stop</c> + functions in the <c>erl_ddll</c> module has been removed, + as those functions are not meant to be used by other + applications.</p> + <p>Furthermore, the <c>erl_ddll:stop/1</c> function no longer + terminates the <c>erl_ddll</c> server, as that would + terminate the entire runtime system.</p> + <p>Own Id: OTP-6033</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Removed some unused functions from + <c>application_master</c>.</p> + <p>Own Id: OTP-3889</p> + </item> + <item> + <p>Global no longer allows the registration of a process + under more than one name. If the old (buggy) behavior is + desired the Kernel application variable + <c>global_multi_name_action</c> can be given the value + <c>allow</c>.</p> + <p>Own Id: OTP-5640 Aux Id: OTP-5603</p> + </item> + <item> + <p>The (slightly misleading) warnings that was shown when + the <c>erlang.erl</c> file was compiled has been + eliminated.</p> + <p>Own Id: OTP-5947</p> + </item> + <item> + <p>The <c>auth</c> module API is deprecated.</p> + <p>Own Id: OTP-6037</p> + </item> + <item> + <p>Added <c>erlang:demonitor/2</c>, making it possible to at + the same time flush a received <c>'DOWN'</c> message, if + there is one. See <c>erlang(3)</c>.</p> + <p>Own Id: OTP-6100 Aux Id: OTP-5772 </p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.13</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Large files (more than 2 GBytes) are now handled on + Solaris 8.</p> + <p>Own Id: OTP-5849 Aux Id: seq10157</p> + </item> + <item> + <p>During startup, a garbage <c>{'DOWN', ...}</c> message was + left by <c>inet_gethost_native</c>, that caused problems + for the starting code server.</p> + <p>Own Id: OTP-5978 Aux Id: OTP-5974</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p><c>global</c> now makes several attempts to connect nodes + when maintaining the fully connected network. More than one + attempt is sometimes needed under very heavy load.</p> + <p>Own Id: OTP-5889</p> + </item> + <item> + <p><c>erl_epmd</c> now explicitly sets the timeout to + <c>infinity</c> when calling <c>gen_server:call</c>. The + old timeout of 15 seconds could time out under very heavy + load.</p> + <p>Own Id: OTP-5959</p> + </item> + <item> + <p>Corrected the start of code server to use reference-tagged + tuples to ensure that an unexpected message sent to + the parent process does not cause a halt of the system. + Also removed the useless <c>start/*</c> functions in both + <c>code.erl</c> and <c>code_server.erl</c> and no longer + exports the <c>init</c> function from + <c>code_server.erl</c>.</p> + <p>Own Id: OTP-5974 Aux Id: seq10243, OTP-5978</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.12</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>A bug in <c>global</c> has been fixed: the locker process + added <c>nonode@nohost</c> to the list of nodes to lock. + This could happen before any nodes got known to the global + name server. Depending on net configuration the symptom was + a delay.</p> + <p>Own Id: OTP-5792 Aux Id: OTP-5563</p> + </item> + <item> + <p>If an <c>.app</c> file is missing, the error reason + returned by <c>application:load/1</c> has been corrected + to <c>{"no such file or directory", "FILE.app"}</c>, + instead of the less informative <c>{"unknown POSIX error","FILE.app"}</c>.</p> + <p>Own Id: OTP-5809</p> + </item> + <item> + <p>Bug fixes: <c>disk_log:accessible_logs/0</c> no longer + reports all <c>pg2</c> process groups as distributed disk + logs; <c>disk_log:pid2name/1</c> did not recognize + processes of distributed disk logs.</p> + <p>Own Id: OTP-5810</p> + </item> + <item> + <p>The functions <c>file:consult/1</c>, + <c>file:path_consult/2</c>, <c>file:eval/1,2</c>, + <c>file:path_eval/2,3</c>, <c>file:script/1,2</c>, + <c>file:path_script/2,3</c> now return correct line + numbers in error tuples.</p> + <p>Own Id: OTP-5814</p> + </item> + <item> + <p>If there were user-defined variables in the boot script, + and their values were not provided using + the <c>-boot_var</c> option, the emulator would refuse to + start with a confusing error message. Corrected to show a + clear, understandable message.</p> + <p>The <c>prim_file</c> module was modified to not depend + on the <c>lists</c> module, to make it possible to start + the emulator using a user-defined loader. (Thanks to + Martin Bjorklund.)</p> + <p>Own Id: OTP-5828 Aux Id: seq10151</p> + </item> + <item> + <p>Minor corrections in the description of open modes. + (Thanks to Richard Carlsson.)</p> + <p>Own Id: OTP-5856</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p><c>application_controller</c> now terminates with the + actual error reason, instead of <c>shutdown</c>. This + means that the crash dump now should be somewhat more + informative, in the case where the runtime system is + terminated due to an error in an application.</p> + <p>Example: If the (permanent) application <c>app1</c> fails + to start, the slogan now will be: "<c>Kernel pid terminated (application_controller) ({application_start_failure,app1,{shutdown, {app1,start,[normal,[]]}}})</c>"</p> + <p>rather than the previous "<c>Kernel pid terminated (application_controller) (shutdown)</c>".</p> + <p>Own Id: OTP-5811</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.11.1</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Timers could sometimes timeout too early. This bug has + now been fixed.</p> + <p>Automatic cancellation of timers created by + <c>erlang:send_after(Time,</c> pid(), Msg), and + <c>erlang:start_timer(Time,</c> pid(), Msg) has been + introduced. + Timers created with the receiver specified by a pid, will + automatically be cancelled when the receiver exits. For + more information see the <c>erlang(3)</c> man page.</p> + <p>In order to be able to maintain a larger amount of timers + without increasing the maintenance cost, the internal + timer wheel and bif timer table have been enlarged.</p> + <p>Also a number of minor bif timer optimizations have been + implemented.</p> + <p>Own Id: OTP-5795 Aux Id: OTP-5090, seq8913, seq10139, + OTP-5782</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Documentation improvements:</p> + <p>- documentation for <c>erlang:link/1</c> corrected</p> + <p>- command line flag <c>-code_path_cache</c> added</p> + <p>- <c>erl</c> command line flags clarifications</p> + <p>- <c>net_kernel(3)</c> clarifications</p> + <p>Own Id: OTP-5847</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.11</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Several bug fixes and improvements in the global name + registration facility (see <c>global(3)</c>):</p> + <list type="bulleted"> + <item>the name resolving procedure did not always unlink no + longer registered processes;</item> + <item>the global name could sometimes hang when a + <c>nodedown</c> was immediately followed by a + <c>nodeup</c>;</item> + <item>global names were not always unregistered when a node + went down;</item> + <item>it is now possible to set and delete locks at + the same time as the global name server is resolving + names--the handling of global locks has been separated + from registration of global names;</item> + </list> + <p>As of this version, <c>global</c> no longer supports nodes + running Erlang/OTP R7B or earlier.</p> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> + <p>Own Id: OTP-5563</p> + </item> + <item> + <p>The functions <c>global:set_lock/3</c> and + <c>global:trans/4</c> now accept the value <c>0</c> + (zero) of the <c>Retries</c> argument.</p> + <p>Own Id: OTP-5737</p> + </item> + <item> + <p>The <c>inet:getaddr(Addr, Family)</c> no longer + validates the <c>Addr</c> argument if it is a 4 or 8 + tuple containing the IP address, except for the size of + the tuple and that it contains integers in the correct + range.</p> + <p>The reason for the change is that validation could + cause the following sequence of calls to fail:</p> + <p><c>{ok,Addr} = inet:getaddr(localhost, inet6), gen_tcp:connect(Addr, 7, [inet6])</c></p> + <p>Own Id: OTP-5743</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>The previously undocumented and UNSUPPORTED <c>zlib</c> + module has been updated in an incompatible way and many + bugs have been corrected. It is now also documented.</p> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> + <p>Own Id: OTP-5715</p> + </item> + <item> + <p>Added <c>application</c> interface functions + <c>which_applications/1</c>, <c>set_env/4</c> and + <c>unset_env/3</c>, which take an additional + <c>Timeout</c> argument. To be used in situations where + the standard gen_server timeout (5000ms) is not adequate.</p> + <p>Own Id: OTP-5724 Aux Id: seq10083</p> + </item> + <item> + <p>Improved documentation regarding synchronized start of + applications with included applications (using start + phases and <c>application_starter</c>).</p> + <p>Own Id: OTP-5754</p> + </item> + <item> + <p>New socket options <c>priority</c> and <c>tos</c> for + platforms that support them (currently only Linux).</p> + <p>Own Id: OTP-5756</p> + </item> + <item> + <p>The global name server has been optimized when it comes + to maintaining a fully connected network.</p> + <p>Own Id: OTP-5770</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.10.1</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>The native resolver has gotten an control API for + extended debugging and soft restart. It is: + <c>inet_gethost_native:control(Control)</c> <br></br> +<c>Control = {debug_level,Level} | soft_restart</c> <br></br> +<c>Level = integer() in the range 0-4</c>.</p> + <p>Own Id: OTP-5751 Aux Id: EABln25013</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.10</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>If several processes (at the same node) simultaneously + tried to start the same distributed application, this + could lead to <c>application:start</c> returning an + erroneous value, or even hang.</p> + <p>Own Id: OTP-5606 Aux Id: seq9838</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>The manual pages for most of the Kernel and some of + the STDLIB modules have been updated, in particular + regarding type definitions.</p> + <p>The documentation of the return value for + <c>erts:info/1</c> has been corrected.</p> + <p>The documentation for <c>erlang:statistics/1</c> now + lists all possible arguments.</p> + <p>Own Id: OTP-5360</p> + </item> + <item> + <p>When the native resolver fails a <c>gethostbyaddr</c> + lookup, <c>nxdomain</c> should be returned. There should be + no attempt to fallback on a routine that succeeds if only + the syntax of the IP address is valid. This has been fixed.</p> + <p>Own Id: OTP-5598 Aux Id: OTP-5576</p> + </item> + <item> + <p>Replaced some tuple funs with the new <c>fun M:F/A</c> + construct.</p> + <p>The high-order functions in the <c>lists</c> module no + longer accept bad funs under any circumstances. + '<c>lists:map(bad_fun, [])</c>' used to return + '<c>[]</c>' but now causes an exception.</p> + <p>Unused, broken compatibility code in the <c>ets</c> + module was removed. (Thanks to Dialyzer.)</p> + <p>Eliminated 5 discrepancies found by Dialyzer in the + Appmon application.</p> + <p>Own Id: OTP-5633</p> + </item> + <item> + <p>The possibility to have comments following the list of + tuples in a config file (file specified with + the <c>-config</c> flag) has been added.</p> + <p>Own Id: OTP-5661 Aux Id: seq10003</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.9</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>'<c>erl -config sys.config</c>' would fail to start if + the <c>sys.config</c> file did not contain any whitespace + at all after the dot. (Thanks to Anders Nygren.)</p> + <p>Own Id: OTP-5543</p> + </item> + <item> + <p>A bug regarding tcp sockets which results in hanging + <c>gen_tcp:send/2</c> has been corrected. To encounter + this bug you needed one process that read from a socket, + one that wrote more date than the reader read out so the + sender got suspended, and then the reader closed the + socket. (Reported and diagnosed by Alexey Shchepin.)</p> + <p>Corrected a bug in the (undocumented and unsupported) + option <c>{packet,http}</c> for <c>gen_tcp.</c> + (Thanks to Claes Wikstrom and Luke Gorrie.)</p> + <p>Updated the documentation regarding the second argument to + <c>gen_tcp:recv/2</c>, the <c>Length</c> to receive.</p> + <p>Own Id: OTP-5582 Aux Id: seq9839</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>At startup, the Erlang resolver hosts table was used to + look up the name of the local (and possibly stand alone) + host. This was incorrect. The configured resolver method + is now used for this purpose.</p> + <p>Own Id: OTP-5393</p> + </item> + <item> + <p>The <c>erlang:port_info/1</c> BIF is now documented. Minor + corrections of the documentation for + <c>erlang:port_info/2</c>.</p> + <p>Added a note to the documentation of the <c>math</c> module + that all functions are not available on all platforms.</p> + <p>Added more information about the <c>+c</c> option in + the <c>erl</c> man page in the ERTS documentation.</p> + <p>Own Id: OTP-5555</p> + </item> + <item> + <p>The new <c>fun M:F/A</c> construct creates a fun that + refers to the latest version of <c>M:F/A.</c> This syntax is + meant to replace tuple funs <c>{M,F}</c> which have many + problems.</p> + <p>The new type test <c>is_function(Fun,A)</c> (which may be + used in guards) test whether <c>Fun</c> is a fun that can be + applied with <c>A</c> arguments. (Currently, <c>Fun</c> can + also be a tuple fun.)</p> + <p>Own Id: OTP-5584</p> + </item> + <item> + <p>According to the documentation <c>global</c> implements + the equivalent of <c>register/2</c>, which returns + <c>badarg</c> if a process is already registered. As it + turns out there is no check in <c>global</c> if a process is + registered under more than one name. If some process is + accidentaly or by design given several names, it is + possible that the name registry becomes inconsistent due + to the way the resolve function is called when name + clashes are discovered (see <c>register_name/3</c> in + <c>global(3)</c>).</p> + <p>In OTP R11B <c>global</c> will not allow the registration of + a process under more than one name. To help finding code + where <c>no</c> will be returned, a Kernel application + variable, <c>global_multi_name_action</c>, is hereby + introduced. Depending on its value (<c>info</c>, + <c>warning</c>, or <c>error</c>), messages are sent to + the error logger when <c>global</c> discovers that some + process is given more than one name. The variable only + affects the node where it is defined.</p> + <p>Own Id: OTP-5603</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.8</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>In case of a DNS lookup loop, <c>inet_db:getbyname</c> ends + up building an infinite list. This has been fixed.</p> + <p>Own Id: OTP-5449</p> + </item> + <item> + <p>When doing an <c>inet6</c> name lookup on an IPv4 address + it was possible to get an address on IPv4 format back. This + has been corrected. Some other minor inconsistencies + regarding IPv6 name lookup have also been corrected.</p> + <p>Own Id: OTP-5576</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.7</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Under certain circumstances the <c>net_kernel</c> could + emit spurious nodedown messages. This bug has been fixed.</p> + <p>Own Id: OTP-5396</p> + </item> + <item> + <p>Removed description of the <c>keep_zombies</c> + configuration parameter in the <c>kernel</c> man page.</p> + <p>Own Id: OTP-5497</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Eliminated Dialyzer warnings (caused by dead code) in + the <c>init</c> and <c>prim_file</c> modules.</p> + <p>Own Id: OTP-5496</p> + </item> + <item> + <p><c>inet_config</c> now also checks the environment variable + <c>ERL_INETRC</c> for a possible user configuration file. + See the ERTS User's Guide for details.</p> + <p>Own Id: OTP-5512</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.6</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>The <c>c</c> option for the <c>+B</c> flag has been + introduced which makes it possible to use Ctrl-C + (Ctrl-Break on Windows) to interrupt the shell process + rather than to invoke the emulator break handler. All new + <c>+B</c> options are also supported on Windows (werl) as + of now. Furthermore, Ctrl-C on Windows has now been + reserved for copying text (what Ctrl-Ins was used for + previously). Ctrl-Break should be used for break handling. + Lastly, the documentation of the system flags has been + updated.</p> + <p>Own Id: OTP-5388</p> + </item> + <item> + <p>The possibility to start the Erlang shell in parallel + with the rest of the system was reintroduced for backwards + compatibility in STDLIB 1.13.1. The flag to be used for + this is now called <c>async_shell_start</c> and has + been documented. New shells started from the JCL menu are + not synchronized with <c>init</c> anymore. This makes it + possible to start a new shell (e.g. for debugging purposes) + even if the initial shell has not come up.</p> + <p>Own Id: OTP-5406 Aux Id: OTP-5218</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.5</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Documentation for <c>erlang:binary_to_float/1</c> deleted. + The BIF itself was removed several releases ago.</p> + <p>Updated documentation for <c>apply/2</c> and + <c>apply/3</c>.</p> + <p>Own Id: OTP-5391</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p><c>net_kernel:monitor_nodes/2</c> which takes a flag and an + option list has been added. By use of + <c>net_kernel:monitor_nodes/2</c> one can subscribe for + <c>nodeup/nodedown</c> messages with extra information. It + is now possible to monitor hidden nodes, and get + <c>nodedown</c> reason. See the <c>net_kernel(3)</c> + documentation for more information.</p> + <p>Own Id: OTP-5374</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.4</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>The application master for an application now terminates + the application faster, which reduces the risk for + timeouts in other parts of the system.</p> + <p>Own Id: OTP-5363 Aux Id: EABln19084</p> + </item> + <item> + <p>A BIF <c>erlang:raise/3</c> has been added. See the manual + for details. It is intended for internal system programming + only, advanced error handling.</p> + <p>Own Id: OTP-5376 Aux Id: OTP-5257</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.3</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>With the <c>-eval</c> flag (<c>erl -eval Expr</c>), an + arbitrary expression can be evaluated during system + initialization. This is documented in <c>init(3)</c>.</p> + <p>Own Id: OTP-5260</p> + </item> + <item> + <p>The unsupported and undocumented modules <c>socks5</c>, + <c>socks5_auth</c>, <c>socks5_tcp</c>, and <c>socks5_udp</c> + have been removed.</p> + <p>Own Id: OTP-5266</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.10.1</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>The Pman 'trace shell' functionality was broken and has + now been fixed. Furthermore, Pman could not correctly + find the pid of the active shell if more than one shell + process was running on the node. This has also been + corrected.</p> + <p>Own Id: OTP-5191</p> + </item> + <item> + <p>The documentation for the <c>auth:open/1</c> function + which no longer exists has been removed. (Thanks to + Miguel Barreiro.)</p> + <p>Own Id: OTP-5208</p> + </item> + <item> + <p>Corrected the <c>crc32/3</c> function in the undocumented + and unsupported <c>zlib</c> module.</p> + <p>Own Id: OTP-5227</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>You can now start Erlang with the <c>-rsh</c> flag which + gives you a remote initial shell instead of a local one. + Example:</p> + <pre> + erl -sname this_node -rsh other_node@other_host + </pre> + <p>Own Id: OTP-5210</p> + </item> + <item> + <p>If <c>/etc/hosts</c> specified two hosts with the same IP + address (on separate lines), only the last host would be + registered by inet_db during inet configuration. This has + been corrected now so that both aliases are registered + with the same IP address.</p> + <p>Own Id: OTP-5212 Aux Id: seq7128</p> + </item> + <item> + <p>The documentation for BIFs that take I/O lists have + been clarified. Those are <c>list_to_binary/1</c>, + <c>port_command/2</c>, <c>port_control/3</c>.</p> + <p>Documentation for all <c>is_*</c> BIFs (such as + <c>is_atom/1</c>) has been added.</p> + <p>Removed the documentation for + <c>erlang:float_to_binary/2</c> which was removed from + the run-time system several releases ago.</p> + <p>Own Id: OTP-5222</p> + </item> + </list> + </section> + </section> +</chapter> + diff --git a/lib/kernel/doc/src/notes_history.xml b/lib/kernel/doc/src/notes_history.xml new file mode 100644 index 0000000000..2f6ceb9d42 --- /dev/null +++ b/lib/kernel/doc/src/notes_history.xml @@ -0,0 +1,415 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2006</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>Kernel Release Notes History</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + + <section> + <title>Kernel 2.10</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Added documentation of configuration parameter + <c>net_setuptime</c>.</p> + <p>Own Id: OTP-5117 Aux Id: seq8908</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>The <c>disk_log</c> module has been slightly changed for + the purpose of reducing the risk of memory problems due + to corrupt files. The <c>chunk</c> commands have been + optimized by increasing the chunk size from 8 kilobytes + to 64 kilobytes.</p> + <p>Own Id: OTP-4530 Aux Id: seq7646</p> + </item> + <item> + <p>The code server used <c>prim_file</c> for its file + operations. This made it impossible to load code from a + boot server. Now the code server uses <c>erl_prim_loader</c> + for these operations instead.</p> + <p>Own Id: OTP-4819 Aux Id: OTP-4802, OTP-4846</p> + </item> + <item> + <p>New functions - <c>rpc:call/5</c> and + <c>rpc:block_call/5</c>. They have a timeout argument! See + the documentation for details.</p> + <p>Own Id: OTP-4849 Aux Id: seq8250</p> + </item> + <item> + <p>A new environment parameter <c>browser_cmd</c> has been + introduced which defines how to display help text (HTML + files).</p> + <p>Own Id: OTP-4852</p> + </item> + <item> + <p>The system configuration file <c>sys.config</c> can now + contain names of other configuration files as well as + application configuration data.</p> + <p>Thus, it is now possible to have several configuration + files in connection with release handling. See + <c>config(4)</c> and <em>OTP Design Principles</em> for + more information.</p> + <p>Own Id: OTP-4867 Aux Id: OTP-1968</p> + </item> + <item> + <p>It is now possible to compile files with <c>erlc</c> without + getting a lot of (for compilation) unnecessary code + loaded and executed (like distribution, inet config, + etc). <c>erlc</c> now also calls <c>erl</c> with <c>-boot start_clean</c> (so that SASL is not started even if + <c>start_sasl</c> is default boot script).</p> + <p>Own Id: OTP-4878</p> + </item> + <item> + <p>Disk logs can now be opened or closed in parallel. In + particular, if some log is being repaired, other logs can + still be opened or closed.</p> + <p>Own Id: OTP-4913</p> + </item> + <item> + <p>Native lookup (system calls) is now default resolver + method on all platforms. Also the user inet configuration + method has changed so that a Kernel variable, <c>inetrc</c>, + should now be used to specify the name of the user inet + config file (if it exists). This is all documented in the + ERTS User's Guide.</p> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> + <p>Own Id: OTP-4983</p> + </item> + <item> + <p>Previously missing documentation of + <c>erlang:system_info/1</c> and <c>erlang:system_flag/2</c> + have been added.</p> + <p>Own Id: OTP-5038 Aux Id: seq8708</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.6.8</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>The code server now caches <c>.app</c> files as well as + <c>.beam</c> files. Application controller calls + the function <c>code:where_is_file/1</c> to locate + the cached <c>.app</c> file so that <c>file:consult/1</c> + may be used instead of <c>file:path_consult/2</c> to read + the file. This is much more efficient.</p> + <p>Own Id: OTP-5097 Aux Id: seq8956</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.6.7</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Improved setup of connection between nodes to avoid that + some nodes get lower priority (and thus times out) when + many nodes are connected simultaneously.</p> + <p>Own Id: OTP-5116 Aux Id: seq8908</p> + </item> + <item> + <p>There is now a packet size limit option for <c>gen_tcp</c> + sockets. See the manual for <c>inet:setopts/2</c>.</p> + <p>The ASN.1 BER packet decoding for <c>gen_tcp</c> sockets + can now decode indefinite length packets.</p> + <p>Own Id: OTP-5128</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.6.6</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>A helper for <c>global</c> would terminate if it received + unknown types of messages, causing <c>global</c> to + terminate too. Changed so that the helper process logs and + ignore strange messages.</p> + <p>Own Id: OTP-5078 Aux Id: seq_8839</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>The ability to set system wide options for TCP sockets is + added through the Kernel application variables + <c>inet_default_listen_options</c> and + <c>inet_default_connect_options</c>, see the <c>inet</c> + manual page for details.</p> + <p>Own Id: OTP-5080</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.6.5</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Fixed error that made code server crash if invalid + directories were added to the path.</p> + <p>Own Id: OTP-5070 Aux Id: OTP-5060, EABln14115</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.6.4</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Speed improvements in <c>code:add_path(s)[az]/1</c> when + the cache is activated.</p> + <p>Own Id: OTP-5060 Aux Id: seq8315, EABln14115</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.6.2</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Remote spawn on a nonreachable node now gives warning + instead of error in the error_log.</p> + <p>Own Id: OTP-5030 Aux Id: seq8663]</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.6.1</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>An error that made the code server ignore version numbers + on <c>lib</c> directories has been corrected.</p> + <p>Own Id: OTP-5020</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.5</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>A possibility to make distribution messages be queued up + during running of Erlang code, so that larger packages is + sent over the network is added.</p> + <p>Own Id: OTP-4916</p> + </item> + <item> + <p>When code loading failed it was impossible to know + exactly what caused it, only <c>{undef,[{M,F,A}|...]}</c> + would be reported. Now the primitive loader lets the + <c>error_logger</c> print an error report if a file + operation fails. All file errors except <c>enoent</c> and + <c>enotdir</c> are reported this way.</p> + <p>Own Id: OTP-4925 Aux Id: OTP-4952</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.4</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Bugs have been fixed in the <c>disk_log</c> module: if + <c>reopen</c> failed to rename a file, a message could + erroneously be sent to the client; if requests were + queued while a log was blocked, no replies were sent to + the blocked processes should the log be closed.</p> + <p>Own Id: OTP-4880 Aux Id: seq7902</p> + </item> + <item> + <p>In rare cases, the <c>global</c> name registration could + hang during simultaneous startup of several nodes, due to a + cyclic deadlock in the <c>global:loop_the_locker</c> + processes.</p> + <p>Own Id: OTP-4902 Aux Id: seq8275</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>The Kernel variable <c>net_setuptime</c> can now be defined + in fractions of seconds (using a floating point number).</p> + <p>Own Id: OTP-4915</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.3</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>The driver for dynamically linked in drivers has been + fixed to delete loaded drivers when its Erlang server + dies. The Erlang server has also been updated to improve + the start-on-demand behaviour.</p> + <p>Own Id: OTP-4876 Aux Id: OTP-4855 seq8272</p> + </item> + </list> + </section> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p>Starting Erlang with the <c>+Bi</c> flag (to ignore ^C), now + also disables the quit ('q') option in the JCL menu.</p> + <p>Own Id: OTP-4897</p> + </item> + <item> + <p>A STDLIB application variable, <c>shell_esc</c>, has been + introduced that controls the behaviour of ^G. If + <c>shell_esc</c> is set to <c>abort</c>, ^G restarts the + shell. If set to <c>jcl</c>, ^G invokes the JCL menu. The + latter is default.</p> + <p>Own Id: OTP-4898 Aux Id: OTP-4897</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.2</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>The boot server had become broken. Now it works again.</p> + <p>Own Id: OTP-4846 Aux Id: OTP-4802, OTP-4819</p> + </item> + <item> + <p>When loading a dynamically linked in driver through + <c>erl_ddll</c>, the server <c>ddll_server</c> that held + the port for the driver handling shared libraries got + the group leader of the invoking application. Later, when + the application was terminated, it killed all processes in + its group, also the <c>ddll_server</c>, so the driver still + had some shared libraries loaded. Finally, when + the <c>ddll_server</c> was restarted it assumed that all + shared libraries its driver knew of was statically linked, + so the dynamically linked in drivers that was loaded when + <c>ddll_server</c> was killed could neither be loaded nor + unloaded. This bug has now been fixed by setting the group + leader of <c>ddll_server</c> to something harmless and more + eternal, and by unloading all remaining dynamically linked + in drivers when <c>ddll_server</c> starts. A race condition + when starting <c>ddll_server</c> has also been fixed.</p> + <p>Own Id: OTP-4855 Aux Id: OTP-4876 seq8272</p> + </item> + </list> + </section> + </section> + + <section> + <title>Kernel 2.9.1</title> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>When the emulator was started with command line arguments + <c>-run</c> or <c>-s</c> and the started code did an + uncatched <c>erlang:throw/1</c>, the emulator ignored + the throw which is rather strange. Now the init process + exits with <c>nocatch</c> as expected.</p> + <p>Own Id: OTP-4788 Aux Id: seq8129</p> + </item> + <item> + <p>The code server could hang if invoked early in the startup. + For example if the emulator was started with <c>"-s file eval Filename"</c> and <c>Filename</c> contained a + call to <c>code:add_patha/1</c> the code server accidentally + tried to execute code in an unloaded module from inside + the code that loaded a module - hence hangup. This bug has + now been fixed.</p> + <p>Note! Starting Erlang through code loading from a remote + Erlang boot server will not work after this patch. It will + be fixed in a later patch. Rumours has it that remote boot + server code loading did not work before this patch either. + It is not a commonly used feature.</p> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> + <p>Own Id: OTP-4802 Aux Id: seq8314</p> + </item> + </list> + </section> + </section> +</chapter> + diff --git a/lib/kernel/doc/src/os.xml b/lib/kernel/doc/src/os.xml new file mode 100644 index 0000000000..2c9cc33eb7 --- /dev/null +++ b/lib/kernel/doc/src/os.xml @@ -0,0 +1,212 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>os</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>os</module> + <modulesummary>Operating System Specific Functions</modulesummary> + <description> + <p>The functions in this module are operating system specific. + Careless use of these functions will result 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.</p> + </description> + <funcs> + <func> + <name>cmd(Command) -> string()</name> + <fsummary>Execute a command in a shell of the target OS</fsummary> + <type> + <v>Command = string() | atom()</v> + </type> + <desc> + <p>Executes <c>Command</c> in a command shell of the target OS, + captures the standard output of the command and returns this + result as a string. This function is a replacement of + the previous <c>unix:cmd/1</c>; on a Unix platform they are + equivalent.</p> + <p>Examples:</p> + <code type="none"> +LsOut = os:cmd("ls"), % on unix platform +DirOut = os:cmd("dir"), % on Win32 platform</code> + <p>Note that in some cases, standard output of a command when + called from another program (for example, <c>os:cmd/1</c>) + may differ, compared to the standard output of the command + when called directly from an OS command shell.</p> + </desc> + </func> + <func> + <name>find_executable(Name) -> Filename | false</name> + <name>find_executable(Name, Path) -> Filename | false</name> + <fsummary>Absolute filename of a program</fsummary> + <type> + <v>Name = string()</v> + <v>Path = string()</v> + <v>Filename = string()</v> + </type> + <desc> + <p>These two functions look up an executable program given its + name and a search path, in the same way as the underlying + operating system. <c>find_executable/1</c> uses the current + execution path (that is, the environment variable PATH on + Unix and Windows).</p> + <p><c>Path</c>, if given, should conform to the syntax of + execution paths on the operating system. The absolute + filename of the executable program <c>Name</c> is returned, + or <c>false</c> if the program was not found.</p> + </desc> + </func> + <func> + <name>getenv() -> [string()]</name> + <fsummary>List all environment variables</fsummary> + <desc> + <p>Returns a list of all environment variables. + Each environment variable is given as a single string on + the format <c>"VarName=Value"</c>, where <c>VarName</c> is + the name of the variable and <c>Value</c> its value.</p> + </desc> + </func> + <func> + <name>getenv(VarName) -> Value | false</name> + <fsummary>Get the value of an environment variable</fsummary> + <type> + <v>VarName = string() </v> + <v>Value = string()</v> + </type> + <desc> + <p>Returns the <c>Value</c> of the environment variable + <c>VarName</c>, or <c>false</c> if the environment variable + is undefined.</p> + </desc> + </func> + <func> + <name>getpid() -> Value </name> + <fsummary>Return the process identifier of the emulator process</fsummary> + <type> + <v>Value = string()</v> + </type> + <desc> + <p>Returns the process identifier of the current Erlang emulator + in the format most commonly used by the operating system + environment. <c>Value</c> is returned as a string containing + the (usually) numerical identifier for a process. On Unix, + this is typically the return value of the <c>getpid()</c> + system call. On VxWorks, <c>Value</c> contains the task id + (decimal notation) of the Erlang task. On Windows, + the process id as returned by the <c>GetCurrentProcessId()</c> + system call is used.</p> + </desc> + </func> + <func> + <name>putenv(VarName, Value) -> true</name> + <fsummary>Set a new value for an environment variable</fsummary> + <type> + <v>VarName = string() </v> + <v>Value = string()</v> + </type> + <desc> + <p>Sets a new <c>Value</c> for the environment variable + <c>VarName</c>.</p> + </desc> + </func> + <func> + <name>timestamp() -> {MegaSecs, Secs, MicroSecs}</name> + <fsummary>Returna a timestamp from the OS in the erlang:now/0 format</fsummary> + <type> + <v>MegaSecs = Secs = MicroSecs = int()</v> + </type> + <desc> + <p>Returns a tuple in the same format as <seealso marker="erts:erlang#now/0">erlang:now/0</seealso>. The difference is that this function returns what the operating system thinks (a.k.a. the wall clock time) without any attempts at time correction. The result of two different calls to this function is <em>not</em> guaranteed to be different.</p> + <p>The most obvious use for this function is logging. The tuple can be used together with the function <seealso marker="stdlib:calendar#now_to_universal_time/1">calendar:now_to_universal_time/1</seealso> +or <seealso marker="stdlib:calendar#now_to_local_time/1">calendar:now_to_local_time/1</seealso> to get calendar time. Using the calendar time together with the <c>MicroSecs</c> part of the return tuple from this function allows you to log timestamps in high resolution and consistent with the time in the rest of the operating system.</p> + <p>Example of code formatting a string in the 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:</p> +<code> +-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]). +</code> + + <p>The module above could be used in the following way:</p> +<pre> +1> <input>io:format("~s~n",[print_time:format_utc_timestamp()]).</input> +29 Apr 2009 9:55:30.051711 +</pre> + </desc> + </func> + <func> + <name>type() -> {Osfamily, Osname} | Osfamily</name> + <fsummary>Return the OS family and, in some cases, OS name of the current operating system</fsummary> + <type> + <v>Osfamily = win32 | unix | vxworks</v> + <v>Osname = atom()</v> + </type> + <desc> + <p>Returns the <c>Osfamily</c> and, in some cases, <c>Osname</c> + of the current operating system.</p> + <p>On Unix, <c>Osname</c> will have same value as + <c>uname -s</c> returns, but in lower case. For example, on + Solaris 1 and 2, it will be <c>sunos</c>.</p> + <p>In Windows, <c>Osname</c> will be either <c>nt</c> (on + Windows NT), or <c>windows</c> (on Windows 95).</p> + <p>On VxWorks the OS family alone is returned, that is + <c>vxworks</c>.</p> + <note> + <p>Think twice before using this function. Use the + <c>filename</c> module if you want to inspect or build + file names in a portable way. + Avoid matching on the <c>Osname</c> atom.</p> + </note> + </desc> + </func> + <func> + <name>version() -> {Major, Minor, Release} | VersionString</name> + <fsummary>Return the Operating System version</fsummary> + <type> + <v>Major = Minor = Release = integer()</v> + <v>VersionString = string()</v> + </type> + <desc> + <p>Returns the operating system version. + On most systems, this function returns a tuple, but a string + will be returned instead if the system has versions which + cannot be expressed as three numbers.</p> + <note> + <p>Think twice before using this function. If you still need + to use it, always <c>call os:type()</c> first.</p> + </note> + </desc> + </func> + </funcs> +</erlref> + diff --git a/lib/kernel/doc/src/packages.xml b/lib/kernel/doc/src/packages.xml new file mode 100644 index 0000000000..80de2e05fc --- /dev/null +++ b/lib/kernel/doc/src/packages.xml @@ -0,0 +1,214 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2004</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>packages</title> + <prepared>Kenneth Lundin</prepared> + <responsible>Kenneth Lundin</responsible> + <docno>1</docno> + <approved>Kenneth Lundin</approved> + <checked></checked> + <date>2004-09-07</date> + <rev>A</rev> + <file>packages.sgml</file> + </header> + <module>packages</module> + <modulesummary>Packages in Erlang</modulesummary> + <description> + <warning><p> + Packages has since it was introduced more than 5 years ago been an + experimental feature. Use it at your own risk, we do not + actively maintain and develop this feature. It might however be + supported some + day. + </p> + <p> + In spite of this packages work quite well, but there are some + known issues in tools and other parts where packages don't work well. + </p> + </warning> + <p><em>Introduction</em></p> + <p>Packages are simply namespaces for modules. + All old Erlang modules automatically belong to the top level + ("empty-string") namespace, and do not need any changes.</p> + <p>The full name of a packaged module is written as e.g. + "<c>fee.fie.foe.foo</c>", + i.e., as atoms separated by periods, + where the package name is the part up to + but not including the last period; + in this case "<c>fee.fie.foe</c>". + A more concrete example is the module <c>erl.lang.term</c>, + which is in the + package <c>erl.lang</c>. + Package names can have any number of segments, as in + <c>erl.lang.list.sort</c>. + The atoms in the name can be quoted, as in <c>foo.'Bar'.baz</c>, + or even the + whole name, as in <c>'foo.bar.baz'</c> but the concatenation of + atoms and + periods must not contain two consecutive period characters or + end with a period, + as in <c>'foo..bar'</c>, <c>foo.'.bar'</c>, or <c>foo.'bar.'</c>. + The periods must not be followed by whitespace.</p> + <p>The code loader maps module names onto the file system directory + structure. + E.g., the module <c>erl.lang.term</c> corresponds to a file + <c>.../erl/lang/term.beam</c> + in the search path. + Note that the name of the actual object file corresponds to + the last part only of the full module name. + (Thus, old existing modules such as <c>lists</c> + simply map to <c>.../lists.beam</c>, exactly as before.)</p> + <p>A packaged module in a file "<c>foo/bar/fred.erl</c>" is declared + as:</p> + <code type="none"> +-module(foo.bar.fred).</code> + <p>This can be compiled and loaded from the Erlang shell using + <c>c(fred)</c>, if + your current directory is the same as that of the file. + The object file will be named <c>fred.beam</c>.</p> + <p>The Erlang search path works exactly as before, + except that the package segments will be appended to each + directory in the path in order to find the + file. E.g., assume the path is <c>["/usr/lib/erl", "/usr/local/lib/otp/legacy/ebin", "/home/barney/erl"]</c>. + Then, the code for a module named <c>foo.bar.fred</c> will be + searched for + first as <c>"/usr/lib/erl/foo/bar/fred.beam"</c>, then + <c>"/usr/local/lib/otp/legacy/ebin/foo/bar/fred.beam"</c> + and lastly <c>"/home/barney/erl/foo/bar/fred.beam"</c>. + A module + like <c>lists</c>, which is in the top-level package, + will be looked for as <c>"/usr/lib/erl/lists.beam"</c>, + <c>"/usr/local/lib/otp/legacy/ebin/lists.beam"</c> and + <c>"/home/barney/erl/lists.beam"</c>.</p> + <p><em>Programming</em></p> + <p>Normally, if a call is made from one module to another, + it is assumed that the + called module belongs to the same package as the source module. + The compiler + automatically expands such calls. E.g., in:</p> + <code type="none"> +-module(foo.bar.m1). +-export([f/1]). + +f(X) -> m2:g(X).</code> + <p><c>m2:g(X)</c> becomes a call to <c>foo.bar.m2</c> + If this is not what was intended, the call can be written + explicitly, as in</p> + <code type="none"> +-module(foo.bar.m1). +-export([f/1]). + +f(X) -> fee.fie.foe.m2:g(X).</code> + <p>Because the called module is given with an explicit package name, + no expansion is done in this case.</p> + <p>If a module from another package is used repeatedly in a module, + an import declaration can make life easier:</p> + <code type="none"> +-module(foo.bar.m1). +-export([f/1, g/1]). +-import(fee.fie.foe.m2). + +f(X) -> m2:g(X). +g(X) -> m2:h(X).</code> + <p>will make the calls to <c>m2</c> refer to <c>fee.fie.foe.m2</c>. + More generally, a declaration <c>-import(Package.Module).</c> + will cause calls to <c>Module</c> + to be expanded to <c>Package.Module</c>.</p> + <p>Old-style function imports work as normal (but full module + names must be + used); e.g.:</p> + <code type="none"> +-import(fee.fie.foe.m2, [g/1, h/1]).</code> + <p>however, it is probably better to avoid this form of import + altogether in new + code, since it makes it hard to see what calls are really "remote".</p> + <p>If it is necessary to call a module in the top-level package + from within a + named package, the module name can be written either with an + initial period as + in e.g. "<c>.lists</c>", or with an empty initial atom, as in + "<c>''.lists</c>". + However, the best way is to use an import declaration - + this is most obvious to + the eye, and makes sure we don't forget adding a period somewhere:</p> + <code type="none"> +-module(foo.bar.fred). +-export([f/1]). +-import(lists). + +f(X) -> lists:reverse(X).</code> + <p>The dot-syntax for module names can be used in any expression. + All segments must + be constant atoms, and the result must be a well-formed + package/module name. + E.g.:</p> + <code type="none"> +spawn(foo.bar.fred, f, [X])</code> + <p>is equivalent to <c>spawn('foo.bar.fred', f, [X])</c>.</p> + <p><em>The Erlang Shell</em></p> + <p>The shell also automatically expands remote calls, + however currently no + expansions are made by default. + The user can change the behaviour by using the <c>import/1</c> + shell command (or its abbreviation <c>use/1</c>). E.g.:</p> + <pre> +1> <input>import(foo.bar.m).</input> +ok +2> <input>m:f().</input></pre> + <p>will evaluate <c>foo.bar.m:f()</c>. + If a new import is made of the same name, + this overrides any previous import. + (It is likely that in the future, some + system packages will be pre-imported.)</p> + <p>In addition, the shell command <c>import_all/1</c> + (and its alias <c>use_all/1</c>) + imports all modules currently found in the path for a given + package name. E.g., + assuming the files "<c>.../foo/bar/fred.beam</c>", + "<c>.../foo/bar/barney.beam</c>" + and "<c>.../foo/bar/bambam.beam</c>" can be found from our current + path,</p> + <pre> +1> <input>import_all(foo.bar).</input></pre> + <p>will make <c>fred</c>, <c>barney</c> and <c>bambam</c> + expand to <c>foo.bar.fred</c>, + <c>foo.bar.barney</c> and <c>foo.bar.bambam</c>, respectively.</p> + <p>Note: The compiler does not have an "import all" directive, for the + reason that Erlang has no compile time type checking. + E.g. if the wrong search + path is used at compile time, a call <c>m:f(...)</c> + could be expanded to <c>foo.bar.m:f(...)</c> + without any warning, instead of the intended + <c>frob.ozz.m:f(...)</c>, if + package <c>foo.bar</c> happens to be found first in the path. + Explicitly + declaring each use of a module makes for safe code.</p> + </description> + <funcs> + <func> + <name>no functions exported</name> + <fsummary>x</fsummary> + </func> + </funcs> +</erlref> + diff --git a/lib/kernel/doc/src/part_notes.xml b/lib/kernel/doc/src/part_notes.xml new file mode 100644 index 0000000000..ff43b9e007 --- /dev/null +++ b/lib/kernel/doc/src/part_notes.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE part SYSTEM "part.dtd"> + +<part xmlns:xi="http://www.w3.org/2001/XInclude"> + <header> + <copyright> + <year>2004</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>Kernel Release Notes</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <description> + <p>The <em>Kernel</em> application has all the code necessary to run + the Erlang runtime system itself; File servers and code servers + etc.</p> + <p>For information about older versions, see + <url href="part_notes_history_frame.html">Release Notes History</url>.</p> + </description> + <xi:include href="notes.xml"/> +</part> + diff --git a/lib/kernel/doc/src/part_notes_history.xml b/lib/kernel/doc/src/part_notes_history.xml new file mode 100644 index 0000000000..07c7e4abea --- /dev/null +++ b/lib/kernel/doc/src/part_notes_history.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE part SYSTEM "part.dtd"> + +<part> + <header> + <copyright> + <year>2006</year> + <year>2007</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>Kernel Release Notes History</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <description> + <p>The <em>Kernel</em> application has all the code necessary to run + the Erlang runtime system itself; File servers and code servers + etc.</p> + </description> + <include file="notes_history"></include> +</part> + diff --git a/lib/kernel/doc/src/pg2.xml b/lib/kernel/doc/src/pg2.xml new file mode 100644 index 0000000000..7463fd10f5 --- /dev/null +++ b/lib/kernel/doc/src/pg2.xml @@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>pg2</title> + <prepared>[email protected]</prepared> + <responsible>[email protected]</responsible> + <docno></docno> + <approved>Bjarne Däcker</approved> + <checked>[email protected]</checked> + <date>1997-08-18</date> + <rev>A2</rev> + <file>pg2.sgml</file> + </header> + <module>pg2</module> + <modulesummary>Distributed Named Process Groups</modulesummary> + <description> + <p>This module implements process groups. The groups in this + module differ from the groups in the module <c>pg</c> in several + ways. In <c>pg</c>, each message is sent to all members in the + group. In this module, each message may be sent to one, some, or + all members. + </p> + <p>A group of processes can be accessed by a common name. For + example, if there is a group named <c>foobar</c>, there can be a + set of processes (which can be located on different nodes) which + are all members of the group <c>foobar</c>. There are no special + functions for sending a message to the group. Instead, client + functions should be written with the functions + <c>get_members/1</c> and <c>get_local_members/1</c> to find out + which processes are members of the group. Then the message can be + sent to one or more members of the group. + </p> + <p>If a member terminates, it is automatically removed from the + group. + </p> + <warning> + <p>This module is used by the <c>disk_log</c> module for + managing distributed disk logs. The disk log names are used as + group names, which means that some action may need to be taken + to avoid name clashes.</p> + </warning> + </description> + <funcs> + <func> + <name>create(Name) -> void()</name> + <fsummary>Create a new, empty process group</fsummary> + <type> + <v>Name = term()</v> + </type> + <desc> + <p>Creates a new, empty process group. The group is globally + visible on all nodes. If the group exists, nothing happens. + </p> + </desc> + </func> + <func> + <name>delete(Name) -> void()</name> + <fsummary>Delete a process group</fsummary> + <type> + <v>Name = term()</v> + </type> + <desc> + <p>Deletes a process group. + </p> + </desc> + </func> + <func> + <name>get_closest_pid(Name) -> Pid | {error, Reason}</name> + <fsummary>Common dispatch function</fsummary> + <type> + <v>Name = term()</v> + <v>Pid = pid()</v> + <v>Reason = {no_process, Name} | {no_such_group, Name}</v> + </type> + <desc> + <p>This is a useful dispatch function which can be used from + client functions. It returns a process on the local node, if + such a process exist. Otherwise, it chooses one randomly. + </p> + </desc> + </func> + <func> + <name>get_members(Name) -> [Pid] | {error, Reason}</name> + <fsummary>Return all processes in a group</fsummary> + <type> + <v>Name = term()</v> + <v>Pid = pid()</v> + <v>Reason = {no_such_group, Name}</v> + </type> + <desc> + <p>Returns all processes in the group <c>Name</c>. This + function should be used from within a client function that + accesses the group. It is therefore optimized for speed. + </p> + </desc> + </func> + <func> + <name>get_local_members(Name) -> [Pid] | {error, Reason}</name> + <fsummary>Return all local processes in a group</fsummary> + <type> + <v>Name = term()</v> + <v>Pid = pid()</v> + <v>Reason = {no_such_group, Name}</v> + </type> + <desc> + <p>Returns all processes running on the local node in the + group <c>Name</c>. This function should to be used from + within a client function that accesses the group. It is therefore + optimized for speed. + </p> + </desc> + </func> + <func> + <name>join(Name, Pid) -> ok | {error, Reason}</name> + <fsummary>Join a process to a group</fsummary> + <type> + <v>Name = term()</v> + <v>Pid = pid()</v> + <v>Reason = {no_such_group, Name}</v> + </type> + <desc> + <p>Joins the process <c>Pid</c> to the group <c>Name</c>. + A process can join a group several times; it must then + leave the group the same number of times. + </p> + </desc> + </func> + <func> + <name>leave(Name, Pid) -> ok | {error, Reason}</name> + <fsummary>Make a process leave a group</fsummary> + <type> + <v>Name = term()</v> + <v>Pid = pid()</v> + <v>Reason = {no_such_group, Name}</v> + </type> + <desc> + <p>Makes the process <c>Pid</c> leave the group <c>Name</c>. + If the process is not a member of the group, <c>ok</c> is + returned. + </p> + </desc> + </func> + <func> + <name>which_groups() -> [Name]</name> + <fsummary>Return a list of all known groups</fsummary> + <type> + <v>Name = term()</v> + </type> + <desc> + <p>Returns a list of all known groups. + </p> + </desc> + </func> + <func> + <name>start()</name> + <name>start_link() -> {ok, Pid} | {error, Reason}</name> + <fsummary>Start the pg2 server</fsummary> + <type> + <v>Pid = pid()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Starts the pg2 server. Normally, the server does not need + to be started explicitly, as it is started dynamically if it + is needed. This is useful during development, but in a + target system the server should be started explicitly. Use + configuration parameters for <c>kernel</c> for this. + </p> + </desc> + </func> + </funcs> + + <section> + <title>See Also</title> + <p><seealso marker="kernel_app">kernel(6)</seealso>, + <seealso marker="stdlib:pg">pg(3)</seealso></p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml new file mode 100644 index 0000000000..9ef0959271 --- /dev/null +++ b/lib/kernel/doc/src/ref_man.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE application SYSTEM "application.dtd"> + +<application xmlns:xi="http://www.w3.org/2001/XInclude"> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>Kernel Reference Manual</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <description> + <p>The <em>Kernel</em> application has all the code necessary to run + the Erlang runtime system itself: file servers and code servers + and so on.</p> + </description> + <xi:include href="kernel_app.xml"/> + <xi:include href="application.xml"/> + <xi:include href="auth.xml"/> + <xi:include href="code.xml"/> + <xi:include href="disk_log.xml"/> + <xi:include href="erl_boot_server.xml"/> + <xi:include href="erl_ddll.xml"/> + <xi:include href="erl_prim_loader_stub.xml"/> + <xi:include href="erlang_stub.xml"/> + <xi:include href="error_handler.xml"/> + <xi:include href="error_logger.xml"/> + <xi:include href="file.xml"/> + <xi:include href="gen_tcp.xml"/> + <xi:include href="gen_udp.xml"/> + <xi:include href="gen_sctp.xml"/> + <xi:include href="global.xml"/> + <xi:include href="global_group.xml"/> + <xi:include href="heart.xml"/> + <xi:include href="inet.xml"/> + <xi:include href="inet_res.xml"/> + <xi:include href="init_stub.xml"/> + <xi:include href="net_adm.xml"/> + <xi:include href="net_kernel.xml"/> + <xi:include href="os.xml"/> + <xi:include href="pg2.xml"/> + <xi:include href="rpc.xml"/> + <xi:include href="seq_trace.xml"/> + <xi:include href="user.xml"/> + <xi:include href="wrap_log_reader.xml"/> + <xi:include href="zlib_stub.xml"/> + <xi:include href="app.xml"/> + <xi:include href="config.xml"/> + <xi:include href="packages.xml"/> +</application> + diff --git a/lib/kernel/doc/src/rpc.xml b/lib/kernel/doc/src/rpc.xml new file mode 100644 index 0000000000..86c6ea9178 --- /dev/null +++ b/lib/kernel/doc/src/rpc.xml @@ -0,0 +1,499 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>rpc</title> + <prepared>Claes Wikstrom</prepared> + <docno>1</docno> + <date>96-09-10</date> + <rev>A</rev> + </header> + <module>rpc</module> + <modulesummary>Remote Procedure Call Services</modulesummary> + <description> + <p>This module contains services which are 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.</p> + </description> + <funcs> + <func> + <name>call(Node, Module, Function, Args) -> Res | {badrpc, Reason}</name> + <fsummary>Evaluate a function call on a node</fsummary> + <type> + <v>Node = node()</v> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <v>Res = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Evaluates <c>apply(Module, Function, Args)</c> on the node + <c>Node</c> and returns the corresponding value <c>Res</c>, or + <c>{badrpc, Reason}</c> if the call fails.</p> + </desc> + </func> + <func> + <name>call(Node, Module, Function, Args, Timeout) -> Res | {badrpc, Reason}</name> + <fsummary>Evaluate a function call on a node</fsummary> + <type> + <v>Node = node()</v> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <v>Res = term()</v> + <v>Reason = timeout | term()</v> + <v>Timeout = int() | infinity</v> + </type> + <desc> + <p>Evaluates <c>apply(Module, Function, Args)</c> on the node + <c>Node</c> and returns the corresponding value <c>Res</c>, or + <c>{badrpc, Reason}</c> if the call fails. <c>Timeout</c> is + a timeout value in milliseconds. If the call times out, + <c>Reason</c> is <c>timeout</c>.</p> + <p>If the reply arrives after the call times out, no message + will contaminate the caller's message queue, since this + function spawns off a middleman process to act as (a void) + destination for such an orphan reply. This feature also makes + this function more expensive than <c>call/4</c> at + the caller's end.</p> + </desc> + </func> + <func> + <name>block_call(Node, Module, Function, Args) -> Res | {badrpc, Reason}</name> + <fsummary>Evaluate a function call on a node in the RPC server's context</fsummary> + <type> + <v>Node = node()</v> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <v>Res = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Like <c>call/4</c>, but the RPC server at <c>Node</c> does + not create a separate process to handle the call. Thus, + this function can be used if the intention of the call is to + block the RPC server from any other incoming requests until + the request has been handled. The function can also be used + for efficiency reasons when very small fast functions are + evaluated, for example BIFs that are guaranteed not to + suspend.</p> + </desc> + </func> + <func> + <name>block_call(Node, Module, Function, Args, Timeout) -> Res | {badrpc, Reason}</name> + <fsummary>Evaluate a function call on a node in the RPC server's context</fsummary> + <type> + <v>Node = node()</v> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <v>Timeout = int() | infinity</v> + <v>Res = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Like <c>block_call/4</c>, but with a timeout value in + the same manner as <c>call/5</c>.</p> + </desc> + </func> + <func> + <name>async_call(Node, Module, Function, Args) -> Key</name> + <fsummary>Evaluate a function call on a node, asynchronous version</fsummary> + <type> + <v>Node = node()</v> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <v>Key -- see below</v> + </type> + <desc> + <p>Implements <em>call streams with promises</em>, a type of + RPC which does not suspend the caller until the result is + finished. Instead, a key is returned which can be used at a + later stage to collect the value. The key can be viewed as a + promise to deliver the answer.</p> + <p>In this case, the key <c>Key</c> is returned, which can be + used in a subsequent call to <c>yield/1</c> or + <c>nb_yield/1,2</c> to retrieve the value of evaluating + <c>apply(Module, Function, Args)</c> on the node <c>Node</c>.</p> + </desc> + </func> + <func> + <name>yield(Key) -> Res | {badrpc, Reason}</name> + <fsummary>Deliver the result of evaluating a function call on a node (blocking)</fsummary> + <type> + <v>Key -- see async_call/4</v> + <v>Res = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Returns the promised answer from a previous + <c>async_call/4</c>. If the answer is available, it is + returned immediately. Otherwise, the calling process is + suspended until the answer arrives from <c>Node</c>.</p> + </desc> + </func> + <func> + <name>nb_yield(Key) -> {value, Val} | timeout</name> + <fsummary>Deliver the result of evaluating a function call on a node (non-blocking)</fsummary> + <type> + <v>Key -- see async_call/4</v> + <v>Val = Res | {badrpc, Reason}</v> + <v> Res = term()</v> + <v> Reason = term()</v> + </type> + <desc> + <p>Equivalent to <c>nb_yield(Key, 0)</c>.</p> + </desc> + </func> + <func> + <name>nb_yield(Key, Timeout) -> {value, Val} | timeout</name> + <fsummary>Deliver the result of evaluating a function call on a node (non-blocking)</fsummary> + <type> + <v>Key -- see async_call/4</v> + <v>Timeout = int() | infinity</v> + <v>Val = Res | {badrpc, Reason}</v> + <v> Res = term()</v> + <v> Reason = term()</v> + </type> + <desc> + <p>This is a non-blocking version of <c>yield/1</c>. It returns + the tuple <c>{value, Val}</c> when the computation has + finished, or <c>timeout</c> when <c>Timeout</c> milliseconds + has elapsed.</p> + </desc> + </func> + <func> + <name>multicall(Module, Function, Args) -> {ResL, BadNodes}</name> + <fsummary>Evaluate a function call on a number of nodes</fsummary> + <type> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <v>ResL = [term()]</v> + <v>BadNodes = [node()]</v> + </type> + <desc> + <p>Equivalent to <c>multicall([node()|nodes()], Module, Function, Args, infinity)</c>.</p> + </desc> + </func> + <func> + <name>multicall(Nodes, Module, Function, Args) -> {ResL, BadNodes}</name> + <fsummary>Evaluate a function call on a number of nodes</fsummary> + <type> + <v>Nodes = [node()]</v> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <v>ResL = [term()]</v> + <v>BadNodes = [node()]</v> + </type> + <desc> + <p>Equivalent to <c>multicall(Nodes, Module, Function, Args, infinity)</c>.</p> + </desc> + </func> + <func> + <name>multicall(Module, Function, Args, Timeout) -> {ResL, BadNodes}</name> + <fsummary>Evaluate a function call on a number of nodes</fsummary> + <type> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <v>Timeout = int() | infinity</v> + <v>ResL = [term()]</v> + <v>BadNodes = [node()]</v> + </type> + <desc> + <p>Equivalent to <c>multicall([node()|nodes()], Module, Function, Args, Timeout)</c>.</p> + </desc> + </func> + <func> + <name>multicall(Nodes, Module, Function, Args, Timeout) -> {ResL, BadNodes}</name> + <fsummary>Evaluate a function call on a number of nodes</fsummary> + <type> + <v>Nodes = [node()]</v> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + <v>Timeout = int() | infinity</v> + <v>ResL = [term()]</v> + <v>BadNodes = [node()]</v> + </type> + <desc> + <p>In contrast to an RPC, a multicall is an RPC which is sent + concurrently from one client to multiple servers. This is + useful for collecting some 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.</p> + <p>The function evaluates <c>apply(Module, Function, Args)</c> + on the specified nodes and collects the answers. It returns + <c>{ResL, Badnodes}</c>, where <c>Badnodes</c> is a list + of the nodes that terminated or timed out during computation, + and <c>ResL</c> is a list of the return values. + <c>Timeout</c> is a time (integer) in milliseconds, or + <c>infinity</c>.</p> + <p>The following example is useful when new object code is to + be loaded on all nodes in the network, and also indicates + some side effects RPCs may produce:</p> + <code type="none"> +%% 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, Bin, File,]), + +%% and then maybe check the ResL list.</code> + </desc> + </func> + <func> + <name>cast(Node, Module, Function, Args) -> void()</name> + <fsummary>Run a function on a node ignoring the result</fsummary> + <type> + <v>Node = node()</v> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + </type> + <desc> + <p>Evaluates <c>apply(Module, Function, Args)</c> on the node + <c>Node</c>. No response is delivered and the calling + process is not suspended until the evaluation is complete, as + is the case with <c>call/4,5</c>.</p> + </desc> + </func> + <func> + <name>eval_everywhere(Module, Funtion, Args) -> void()</name> + <fsummary>Run a function on all nodes, ignoring the result</fsummary> + <type> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + </type> + <desc> + <p>Equivalent to <c>eval_everywhere([node()|nodes()], Module, Function, Args)</c>.</p> + </desc> + </func> + <func> + <name>eval_everywhere(Nodes, Module, Function, Args) -> void()</name> + <fsummary>Run a function on specific nodes, ignoring the result</fsummary> + <type> + <v>Nodes = [node()]</v> + <v>Module = Function = atom()</v> + <v>Args = [term()]</v> + </type> + <desc> + <p>Evaluates <c>apply(Module, Function, Args)</c> on + the specified nodes. No answers are collected.</p> + </desc> + </func> + <func> + <name>abcast(Name, Msg) -> void()</name> + <fsummary>Broadcast a message asynchronously to a registered process on all nodes</fsummary> + <type> + <v>Name = atom()</v> + <v>Msg = term()</v> + </type> + <desc> + <p>Equivalent to <c>abcast([node()|nodes()], Name, Msg)</c>.</p> + </desc> + </func> + <func> + <name>abcast(Nodes, Name, Msg) -> void()</name> + <fsummary>Broadcast a message asynchronously to a registered process on specific nodes</fsummary> + <type> + <v>Nodes = [node()]</v> + <v>Name = atom()</v> + <v>Msg = term()</v> + </type> + <desc> + <p>Broadcasts the message <c>Msg</c> asynchronously to + the registered process <c>Name</c> on the specified nodes.</p> + </desc> + </func> + <func> + <name>sbcast(Name, Msg) -> {GoodNodes, BadNodes}</name> + <fsummary>Broadcast a message synchronously to a registered process on all nodes</fsummary> + <type> + <v>Name = atom()</v> + <v>Msg = term()</v> + <v>GoodNodes = BadNodes = [node()]</v> + </type> + <desc> + <p>Equivalent to <c>sbcast([node()|nodes()], Name, Msg)</c>.</p> + </desc> + </func> + <func> + <name>sbcast(Nodes, Name, Msg) -> {GoodNodes, BadNodes}</name> + <fsummary>Broadcast a message synchronously to a registered process on specific nodes</fsummary> + <type> + <v>Name = atom()</v> + <v>Msg = term()</v> + <v>Nodes = GoodNodes = BadNodes = [node()]</v> + </type> + <desc> + <p>Broadcasts the message <c>Msg</c> synchronously to + the registered process <c>Name</c> on the specified nodes.</p> + <p>Returns <c>{GoodNodes, BadNodes}</c>, where <c>GoodNodes</c> + is the list of nodes which have <c>Name</c> as a registered + process.</p> + <p>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 + actually processed the message.</p> + <p>Any further messages sent to the servers, after this + function has returned, will be received by all servers after + this message.</p> + </desc> + </func> + <func> + <name>server_call(Node, Name, ReplyWrapper, Msg) -> Reply | {error, Reason}</name> + <fsummary>Interact with a server on a node</fsummary> + <type> + <v>Node = node()</v> + <v>Name = atom()</v> + <v>ReplyWrapper = Msg = Reply = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>This function can be used when interacting with a server + called <c>Name</c> at node <c>Node</c>. It is assumed that + the server receives messages in the format + <c>{From, Msg}</c> and replies using <c>From ! {ReplyWrapper, Node, Reply}</c>. 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.</p> + <p>The function returns the answer <c>Reply</c> as produced by + the server <c>Name</c>, or <c>{error, Reason}</c>.</p> + </desc> + </func> + <func> + <name>multi_server_call(Name, Msg) -> {Replies, BadNodes}</name> + <fsummary>Interact with the servers on a number of nodes</fsummary> + <type> + <v>Name = atom()</v> + <v>Msg = term()</v> + <v>Replies = [Reply]</v> + <v> Reply = term()</v> + <v>BadNodes = [node()]</v> + </type> + <desc> + <p>Equivalent to <c>multi_server_call([node()|nodes()], Name, Msg)</c>.</p> + </desc> + </func> + <func> + <name>multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes}</name> + <fsummary>Interact with the servers on a number of nodes</fsummary> + <type> + <v>Nodes = [node()]</v> + <v>Name = atom()</v> + <v>Msg = term()</v> + <v>Replies = [Reply]</v> + <v> Reply = term()</v> + <v>BadNodes = [node()]</v> + </type> + <desc> + <p>This function can be used when interacting with servers + called <c>Name</c> on the specified nodes. It is assumed that + the servers receive messages in the format <c>{From, Msg}</c> + and reply using <c>From ! {Name, Node, Reply}</c>, where + <c>Node</c> is the name of the node where the server is + located. The function returns <c>{Replies, Badnodes}</c>, + where <c>Replies</c> is a list of all <c>Reply</c> values and + <c>BadNodes</c> is a list of the nodes which did not exist, or + where the server did not exist, or where the server terminated + before sending any reply.</p> + </desc> + </func> + <func> + <name>safe_multi_server_call(Name, Msg) -> {Replies, BadNodes}</name> + <name>safe_multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes}</name> + <fsummary>Interact with the servers on a number of nodes (deprecated)</fsummary> + <desc> + <warning> + <p>This function is deprecated. Use + <c>multi_server_call/2,3</c> instead.</p> + </warning> + <p>In Erlang/OTP R6B and earlier releases, + <c>multi_server_call/2,3</c> could not handle the case + where the remote node exists, but there is no server called + <c>Name</c>. Instead this function had to be used. In + Erlang/OTP R7B and later releases, however, the functions are + equivalent, except for this function being slightly slower.</p> + </desc> + </func> + <func> + <name>parallel_eval(FuncCalls) -> ResL</name> + <fsummary>Evaluate several function calls on all nodes in parallel</fsummary> + <type> + <v>FuncCalls = [{Module, Function, Args}]</v> + <v> Module = Function = atom()</v> + <v> Args = [term()]</v> + <v>ResL = [term()]</v> + </type> + <desc> + <p>For every tuple in <c>FuncCalls</c>, evaluates + <c>apply(Module, Function, Args)</c> on some node in + the network. Returns the list of return values, in the same + order as in <c>FuncCalls</c>.</p> + </desc> + </func> + <func> + <name>pmap({Module, Function}, ExtraArgs, List2) -> List1</name> + <fsummary>Parallell evaluation of mapping a function over a list </fsummary> + <type> + <v>Module = Function = atom()</v> + <v>ExtraArgs = [term()]</v> + <v>List1 = [Elem]</v> + <v> Elem = term()</v> + <v>List2 = [term()]</v> + </type> + <desc> + <p>Evaluates <c>apply(Module, Function, [Elem|ExtraArgs])</c>, + for every element <c>Elem</c> in <c>List1</c>, in parallel. + Returns the list of return values, in the same order as in + <c>List1</c>.</p> + </desc> + </func> + <func> + <name>pinfo(Pid) -> [{Item, Info}] | undefined</name> + <fsummary>Information about a process</fsummary> + <type> + <v>Pid = pid()</v> + <v>Item, Info -- see erlang:process_info/1</v> + </type> + <desc> + <p>Location transparent version of the BIF + <c>process_info/1</c>.</p> + </desc> + </func> + <func> + <name>pinfo(Pid, Item) -> {Item, Info} | undefined | []</name> + <fsummary>Information about a process</fsummary> + <type> + <v>Pid = pid()</v> + <v>Item, Info -- see erlang:process_info/1</v> + </type> + <desc> + <p>Location transparent version of the BIF + <c>process_info/2</c>.</p> + </desc> + </func> + </funcs> +</erlref> + diff --git a/lib/kernel/doc/src/seq_trace.xml b/lib/kernel/doc/src/seq_trace.xml new file mode 100644 index 0000000000..6c043dd767 --- /dev/null +++ b/lib/kernel/doc/src/seq_trace.xml @@ -0,0 +1,506 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1998</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>seq_trace</title> + <prepared>[email protected]</prepared> + <docno></docno> + <date>1998-04-16</date> + <rev>A</rev> + </header> + <module>seq_trace</module> + <modulesummary>Sequential Tracing of Messages</modulesummary> + <description> + <p>Sequential tracing makes it possible to trace all messages + resulting from one initial message. Sequential tracing is + completely independent of the ordinary tracing in Erlang, which + is controlled by the <c>erlang:trace/3</c> BIF. See the chapter + <seealso marker="#whatis">What is Sequential Tracing</seealso> + below for more information about what sequential tracing is and + how it can be used.</p> + <p><c>seq_trace</c> provides functions which control all aspects of + sequential tracing. There are functions for activation, + deactivation, inspection and for collection of the trace output.</p> + <note> + <p>The implementation of sequential tracing is in beta status. + This means that the programming interface still might undergo + minor adjustments (possibly incompatible) based on feedback + from users.</p> + </note> + </description> + <funcs> + <func> + <name>set_token(Token) -> PreviousToken</name> + <fsummary>Set the trace token</fsummary> + <type> + <v>Token = PreviousToken = term() | []</v> + </type> + <desc> + <p>Sets the trace token for the calling process to <c>Token</c>. + If <c>Token == []</c> then tracing is disabled, otherwise + <c>Token</c> should be an Erlang term returned from + <c>get_token/0</c> or <c>set_token/1</c>. <c>set_token/1</c> + can be used to temporarily exclude message passing from + the trace by setting the trace token to empty like this:</p> + <code type="none"> +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 +... </code> + <p>Returns the previous value of the trace token.</p> + </desc> + </func> + <func> + <name>set_token(Component, Val) -> {Component, OldVal}</name> + <fsummary>Set a component of the trace token</fsummary> + <type> + <v>Component = label | serial | Flag</v> + <v> Flag = send | 'receive' | print | timestamp </v> + <v>Val = OldVal -- see below</v> + </type> + <desc> + <p>Sets the individual <c>Component</c> of the trace token to + <c>Val</c>. Returns the previous value of the component.</p> + <taglist> + <tag><c>set_token(label, Int)</c></tag> + <item> + <p>The <c>label</c> component is an integer which + identifies all events belonging to the same sequential + trace. If several sequential traces can be active + simultaneously, <c>label</c> is used to identify + the separate traces. Default is 0.</p> + </item> + <tag><c>set_token(serial, SerialValue)</c></tag> + <item> + <p><c>SerialValue = {Previous, Current}</c>. + The <c>serial</c> 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 <c>{0, 0}</c>.</p> + </item> + <tag><c>set_token(send, Bool)</c></tag> + <item> + <p>A trace token flag (<c>true | false</c>) which + enables/disables tracing on message sending. Default is + <c>false</c>.</p> + </item> + <tag><c>set_token('receive', Bool)</c></tag> + <item> + <p>A trace token flag (<c>true | false</c>) which + enables/disables tracing on message reception. Default is + <c>false</c>.</p> + </item> + <tag><c>set_token(print, Bool)</c></tag> + <item> + <p>A trace token flag (<c>true | false</c>) which + enables/disables tracing on explicit calls to + <c>seq_trace:print/1</c>. Default is <c>false</c>.</p> + </item> + <tag><c>set_token(timestamp, Bool)</c></tag> + <item> + <p>A trace token flag (<c>true | false</c>) which + enables/disables a timestamp to be generated for each + traced event. Default is <c>false</c>.</p> + </item> + </taglist> + </desc> + </func> + <func> + <name>get_token() -> TraceToken</name> + <fsummary>Return the value of the trace token</fsummary> + <type> + <v>TraceToken = term() | []</v> + </type> + <desc> + <p>Returns the value of the trace token for the calling process. + If <c>[]</c> 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 <c>set_token/1</c> function.</p> + </desc> + </func> + <func> + <name>get_token(Component) -> {Component, Val}</name> + <fsummary>Return the value of a trace token component</fsummary> + <type> + <v>Component = label | serial | Flag</v> + <v> Flag = send | 'receive' | print | timestamp </v> + <v>Val -- see set_token/2</v> + </type> + <desc> + <p>Returns the value of the trace token component + <c>Component</c>. See + <seealso marker="#set_token/2">set_token/2</seealso> for + possible values of <c>Component</c> and <c>Val</c>.</p> + </desc> + </func> + <func> + <name>print(TraceInfo) -> void()</name> + <fsummary>Put the Erlang term <c>TraceInfo</c>into the sequential trace output</fsummary> + <type> + <v>TraceInfo = term()</v> + </type> + <desc> + <p>Puts the Erlang term <c>TraceInfo</c> into the sequential + trace output if the calling process currently is executing + within a sequential trace and the <c>print</c> flag of + the trace token is set.</p> + </desc> + </func> + <func> + <name>print(Label, TraceInfo) -> void()</name> + <fsummary>Put the Erlang term <c>TraceInfo</c>into the sequential trace output</fsummary> + <type> + <v>Label = int()</v> + <v>TraceInfo = term()</v> + </type> + <desc> + <p>Same as <c>print/1</c> with the additional condition that + <c>TraceInfo</c> is output only if <c>Label</c> is equal to + the label component of the trace token.</p> + </desc> + </func> + <func> + <name>reset_trace() -> void()</name> + <fsummary>Stop all sequential tracing on the local node</fsummary> + <desc> + <p>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.</p> + </desc> + </func> + <func> + <name>set_system_tracer(Tracer) -> OldTracer</name> + <fsummary>Set the system tracer</fsummary> + <type> + <v>Tracer = OldTracer = pid() | port() | false</v> + </type> + <desc> + <p>Sets the system tracer. The system tracer can be either a + process or port denoted by <c>Tracer</c>. Returns the previous + value (which can be <c>false</c> if no system tracer is + active).</p> + <p>Failure: <c>{badarg, Info}}</c> if <c>Pid</c> is not an + existing local pid.</p> + </desc> + </func> + <func> + <name>get_system_tracer() -> Tracer</name> + <fsummary>Return the pid() or port() of the current system tracer.</fsummary> + <type> + <v>Tracer = pid() | port() | false</v> + </type> + <desc> + <p>Returns the pid or port identifier of the current system + tracer or <c>false</c> if no system tracer is activated.</p> + </desc> + </func> + </funcs> + + <section> + <title>Trace Messages Sent To the System Tracer</title> + <p>The format of the messages are:</p> + <code type="none"> +{seq_trace, Label, SeqTraceInfo, TimeStamp}</code> + <p>or</p> + <code type="none"> +{seq_trace, Label, SeqTraceInfo}</code> + <p>depending on whether the <c>timestamp</c> flag of the trace + token is set to <c>true</c> or <c>false</c>. Where:</p> + <code type="none"> +Label = int() +TimeStamp = {Seconds, Milliseconds, Microseconds} + Seconds = Milliseconds = Microseconds = int()</code> + <p>The <c>SeqTraceInfo</c> can have the following formats:</p> + <taglist> + <tag><c>{send, Serial, From, To, Message}</c></tag> + <item> + <p>Used when a process <c>From</c> with its trace token flag + <c>print</c> set to <c>true</c> has sent a message.</p> + </item> + <tag><c>{'receive', Serial, From, To, Message}</c></tag> + <item> + <p>Used when a process <c>To</c> receives a message with a + trace token that has the <c>'receive'</c> flag set to + <c>true</c>.</p> + </item> + <tag><c>{print, Serial, From, _, Info}</c></tag> + <item> + <p>Used when a process <c>From</c> has called + <c>seq_trace:print(Label, TraceInfo)</c> and has a trace + token with the <c>print</c> flag set to <c>true</c> and + <c>label</c> set to <c>Label</c>.</p> + </item> + </taglist> + <p><c>Serial</c> is a tuple <c>{PreviousSerial, ThisSerial}</c>, + where the first integer <c>PreviousSerial</c> denotes the serial + counter passed in the last received message which carried a trace + token. If the process is the first one in a new sequential trace, + <c>PreviousSerial</c> is set to the value of the process internal + "trace clock". The second integer <c>ThisSerial</c> is the serial + counter that a process sets on outgoing messages and 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.</p> + </section> + + <section> + <marker id="whatis"></marker> + <title>What is Sequential Tracing</title> + <p>Sequential tracing is a way to trace a sequence of messages sent + between different local or remote processes, where the sequence + is initiated by one single message. In short it works like this:</p> + <p>Each process has a <em>trace token</em>, which can be empty or + not empty. When not empty the trace token can be seen as + the tuple <c>{Label, Flags, Serial, From}</c>. The trace token is + passed invisibly with each message.</p> + <p>In order to start a sequential trace the user must explicitly set + the trace token in the process that will send the first message + in a sequence.</p> + <p>The trace token of a process is set each time the process + matches a message in a receive statement, according to the trace + token carried by the received message, empty or not.</p> + <p>On each Erlang node a process can be set as the <em>system tracer</em>. This process will receive trace messages each time + a message with a trace token is sent or received (if the trace + token flag <c>send</c> or <c>'receive'</c> is set). The system + tracer can then print each trace event, write it to a file or + whatever suitable.</p> + <note> + <p>The system tracer will only receive those trace events that + occur locally within the Erlang node. To get the whole picture + of a sequential trace that involves processes on several Erlang + nodes, the output from the system tracer on each involved node + must be merged (off line).</p> + </note> + <p>In the following sections Sequential Tracing and its most + fundamental concepts are described.</p> + </section> + + <section> + <title>Trace Token</title> + <p>Each process has a current trace token. Initially the token is + empty. When the process sends a message to another process, a + copy of the current token will be sent "invisibly" along with + the message.</p> + <p>The current token of a process is set in two ways, either</p> + <list type="ordered"> + <item> + <p>explicitly by the process itself, through a call to + <c>seq_trace:set_token</c>, or</p> + </item> + <item> + <p>when a message is received.</p> + </item> + </list> + <p>In both cases the current token will be set. In particular, if + the token of a message received is empty, the current token of + the process is set to empty.</p> + <p>A trace token contains a label, and a set of flags. Both + the label and the flags are set in 1 and 2 above.</p> + </section> + + <section> + <title>Serial</title> + <p>The trace token contains a component which is called + <c>serial</c>. It consists of two integers <c>Previous</c> and + <c>Current</c>. The purpose is to uniquely identify each traced + event within a trace sequence and to order the messages + chronologically and in the different branches if any.</p> + <p>The algorithm for updating <c>Serial</c> can be described as + follows:</p> + <p>Let each process have two counters <c>prev_cnt</c> and + <c>curr_cnt</c> which both are set to 0 when a process is created. + The counters are updated at the following occasions:</p> + <list type="bulleted"> + <item> + <p><em>When the process is about to send a message and the trace token is not empty.</em></p> + <p>Let the serial of the trace token be <c>tprev</c> and + <c>tcurr</c>. <br></br> +<c>curr_cnt := curr_cnt + 1</c> <br></br> +<c>tprev := prev_cnt</c> <br></br> +<c>tcurr := curr_cnt</c></p> + <p>The trace token with <c>tprev</c> and <c>tcurr</c> is then + passed along with the message.</p> + </item> + <item> + <p><em>When the process calls</em><c>seq_trace:print(Label, Info)</c>, <em>Label matches the label part of the trace token and the trace token print flag is true.</em></p> + <p>The same algorithm as for send above.</p> + </item> + <item> + <p><em>When a message is received and contains a nonempty trace token.</em></p> + <p>The process trace token is set to the trace token from + the message.</p> + <p>Let the serial of the trace token be <c>tprev</c> and + <c>tcurr</c>. <br></br> +<c><![CDATA[if (curr_cnt < tcurr )]]></c> <br></br> + + <c>curr_cnt := tcurr</c> <br></br> +<c>prev_cnt := tcurr</c></p> + </item> + </list> + <p>The <c>curr_cnt</c> 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 it + will not be possible to use the serial for ordering of the trace + events. To prevent the counter from overflowing in the middle of + a sequential trace the function <c>seq_trace:reset_trace/0</c> + can be called to reset the <c>prev_cnt</c> and <c>curr_cnt</c> of + all processes in the Erlang node. This function will also set all + trace tokens in processes and their message queues to empty and + will thus stop all ongoing sequential tracing.</p> + </section> + + <section> + <title>Performance considerations</title> + <p>The performance degradation for a system which is enabled for + Sequential Tracing is negligible as long as no tracing is + activated. When tracing is activated there will of course be an + extra cost for each traced message but all other messages will be + unaffected.</p> + </section> + + <section> + <title>Ports</title> + <p>Sequential tracing is not performed across ports.</p> + <p>If the user for some reason wants to pass the trace token to a + port this has to 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 + <c>seq_trace:get_token/1</c> and include trace information in + the message data sent to their respective ports.</p> + <p>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 + <c>seq_trace:set_token/2</c>.</p> + </section> + + <section> + <title>Distribution</title> + <p>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 will appear as one process from + the sequential tracing point of view.</p> + <p>In order to be able to perform sequential tracing between + distributed Erlang nodes, the distribution protocol has been + extended (in a backward compatible way). An Erlang node which + supports sequential tracing can communicate with an older + (OTP R3B) node but messages passed within that node can of course + not be traced.</p> + </section> + + <section> + <title>Example of Usage</title> + <p>The example shown here will give rough idea of how the new + primitives can be used and what kind of output it will produce.</p> + <p>Assume that we have an initiating process with + <c><![CDATA[Pid == <0.30.0>]]></c> like this:</p> + <code type="none"> +-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).</code> + <p>And a registered process <c>call_server</c> with + <c><![CDATA[Pid == <0.31.0>]]></c> like this:</p> + <code type="none"> +loop() -> + receive + {PortController,Message} -> + Ack = {received, Message}, + seq_trace:print(17,"We are here now"), + PortController ! {ack,Ack} + end, + loop().</code> + <p>A possible output from the system's sequential_tracer (inspired + by AXE-10 and MD-110) could look like:</p> + <pre> +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}}</pre> + <p>The implementation of a system tracer process that produces + the printout above could look like this:</p> + <code type="none"> +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]).</code> + <p>The code that creates a process that runs the tracer function + above and sets that process as the system tracer could look like + this:</p> + <code type="none"> +start() -> + Pid = spawn(?MODULE,tracer,[]), + seq_trace:set_system_tracer(Pid), % set Pid as the system tracer + ok.</code> + <p>With a function like <c>test/0</c> below the whole example can be + started.</p> + <code type="none"> +test() -> + P = spawn(?MODULE, loop, [port]), + register(call_server, spawn(?MODULE, loop, [])), + start(), + P ! {port,message}.</code> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/user.xml b/lib/kernel/doc/src/user.xml new file mode 100644 index 0000000000..d9de2f4b04 --- /dev/null +++ b/lib/kernel/doc/src/user.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year> + <year>2007</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>user</title> + <prepared>Robert Virding</prepared> + <docno>1</docno> + <date>96-10-10</date> + <rev>A</rev> + </header> + <module>user</module> + <modulesummary>Standard I/O Server</modulesummary> + <description> + <p><c>user</c> is a server which responds to all the messages + defined in the I/O interface. The code in <c>user.erl</c> can be + used as a model for building alternative I/O servers.</p> + </description> +</erlref> + diff --git a/lib/kernel/doc/src/user_guide.gif b/lib/kernel/doc/src/user_guide.gif Binary files differnew file mode 100644 index 0000000000..e6275a803d --- /dev/null +++ b/lib/kernel/doc/src/user_guide.gif diff --git a/lib/kernel/doc/src/wrap_log_reader.xml b/lib/kernel/doc/src/wrap_log_reader.xml new file mode 100644 index 0000000000..18664a029f --- /dev/null +++ b/lib/kernel/doc/src/wrap_log_reader.xml @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1998</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>wrap_log_reader</title> + <prepared>Esko Vierumäki</prepared> + <responsible>Esko Vierumäki</responsible> + <docno></docno> + <approved>nobody</approved> + <checked>no</checked> + <date>98-09-21</date> + <rev>A</rev> + <file>wrap_log_reader.sgml</file> + </header> + <module>wrap_log_reader</module> + <modulesummary>A function to read internally formatted wrap disk logs</modulesummary> + <description> + <p><c>wrap_log_reader</c> is a function to read internally formatted + wrap disk logs, refer to disk_log(3). <c>wrap_log_reader</c> does not + interfere with disk_log activities; there is however a known bug in this + version of the <c>wrap_log_reader</c>, see chapter <c>bugs</c> below. + </p> + <p>A wrap disk log file consists of several files, called index files. + A log file can be opened and closed. It is also possible to open just one index file + separately. If an non-existent or a non-internally formatted file is opened, + an error message is returned. If the file is corrupt, no attempt to repair it + will be done but an error message is returned. + </p> + <p>If a log is configured to be distributed, there is a possibility that all items + are not loggen on all nodes. <c>wrap_log_reader</c> does only read the log on + the called node, it is entirely up to the user to be sure that all items are read. + </p> + </description> + <funcs> + <func> + <name>chunk(Continuation)</name> + <name>chunk(Continuation, N) -> {Continuation2, Terms} | {Continuation2, Terms, Badbytes} | {Continuation2, eof} | {error, Reason}</name> + <fsummary>Read a chunk of objects written to a wrap log.</fsummary> + <type> + <v>Continuation = continuation()</v> + <v>N = int() > 0 | infinity</v> + <v>Continuation2 = continuation()</v> + <v>Terms= [term()]</v> + <v>Badbytes = integer()</v> + </type> + <desc> + <p>This function makes it possible to efficiently read the + terms which have been appended to a log. It minimises disk + I/O by reading large 8K chunks from the file. + </p> + <p>The first time <c>chunk</c> is called an initial + continuation returned from the <c>open/1</c>, <c>open/2</c> must be provided. + </p> + <p>When <c>chunk/3</c> is called, <c>N</c> controls the + maximum number of terms that are read from the log in each + chunk. Default is <c>infinity</c>, which means that all the + terms contained in the 8K chunk are read. If less than + <c>N</c> terms are returned, this does not necessarily mean + that end of file is reached. + </p> + <p>The <c>chunk</c> function returns a tuple + <c>{Continuation2, Terms}</c>, where <c>Terms</c> is a list + of terms found in the log. <c>Continuation2</c> is yet + another continuation which must be passed on into any + subsequent calls to <c>chunk</c>. With a series of calls to + <c>chunk</c> it is then possible to extract all terms from a + log. + </p> + <p>The <c>chunk</c> function returns a tuple + <c>{Continuation2, Terms, Badbytes}</c> if the log is opened + in read only mode and the read chunk is corrupt. <c>Badbytes</c> + indicates the number of non-Erlang terms found in the chunk. + Note also that the log is not repaired. + </p> + <p><c>chunk</c> returns <c>{Continuation2, eof}</c> when the end of the log is + reached, and <c>{error, Reason}</c> if an error occurs. + </p> + <p>The returned continuation may or may not be valid in the next call to + <c>chunk</c>. This is because the log may wrap and delete + the file into which the continuation points. To make sure + this does not happen, the log can be blocked during the + search. + </p> + </desc> + </func> + <func> + <name>close(Continuation) -> ok </name> + <fsummary>Close a log</fsummary> + <type> + <v>Continuation = continuation()</v> + </type> + <desc> + <p>This function closes a log file properly. + </p> + </desc> + </func> + <func> + <name>open(Filename) -> OpenRet</name> + <name>open(Filename, N) -> OpenRet</name> + <fsummary>Open a log file</fsummary> + <type> + <v>File = string() | atom()</v> + <v>N = integer()</v> + <v>OpenRet = {ok, Continuation} | {error, Reason} </v> + <v>Continuation = continuation()</v> + </type> + <desc> + <p><c>Filename</c> specifies the name of the file which is to be read. </p> + <p><c>N</c> specifies the index of the file which is to be read. + If <c>N</c> is omitted the whole wrap log file will be read; if it + is specified only the specified index file will be read. + </p> + <p>The <c>open</c> function returns <c>{ok, Continuation}</c> if the + log/index file was successfully opened. The <c>Continuation</c> + is to be used when chunking or closing the file. + </p> + <p>The function returns <c>{error, Reason}</c> for all errors. + </p> + </desc> + </func> + </funcs> + + <section> + <title>Bugs</title> + <p>This version of the <c>wrap_log_reader</c> does not detect if the <c>disk_log</c> + wraps to a new index file between a <c>wrap_log_reader:open</c> and the first + <c>wrap_log_reader:chunk</c>. + In this case the chuck will actually read the last logged items in the log file, + because the opened index file was truncated by the <c>disk_log</c>. + </p> + </section> + + <section> + <title>See Also</title> + <p><seealso marker="disk_log">disk_log(3)</seealso></p> + </section> +</erlref> + diff --git a/lib/kernel/doc/src/zlib_stub.xml b/lib/kernel/doc/src/zlib_stub.xml new file mode 100644 index 0000000000..fa14262181 --- /dev/null +++ b/lib/kernel/doc/src/zlib_stub.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1997</year> + <year>2009</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>zlib</title> + <prepared>[email protected]</prepared> + <docno></docno> + <date>2008-12-16</date> + <rev>A</rev> + </header> + <module>zlib</module> + <modulesummary>Zlib Compression interface.</modulesummary> + <description><p> + + The module zlib is moved to the runtime system + application. Please see <seealso + marker="erts:zlib">zlib(3)</seealso> in the + erts reference manual instead. + + </p></description> +</erlref> |