aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/doc/src/erl_tracer.xml13
-rw-r--r--erts/doc/src/notes.xml555
-rw-r--r--erts/emulator/Makefile.in4
-rw-r--r--erts/emulator/beam/bif.c6
-rw-r--r--erts/emulator/beam/erl_alloc_util.c12
-rw-r--r--erts/emulator/beam/erl_alloc_util.h7
-rw-r--r--erts/emulator/beam/erl_bits.c2
-rw-r--r--erts/emulator/beam/erl_bits.h1
-rw-r--r--erts/emulator/beam/erl_cpu_topology.c57
-rw-r--r--erts/emulator/beam/erl_db_hash.c2
-rw-r--r--erts/emulator/beam/erl_process.c6
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c16
-rw-r--r--erts/emulator/test/Makefile1
-rw-r--r--erts/emulator/test/binary_SUITE.erl14
-rw-r--r--erts/emulator/test/bs_construct_SUITE.erl2
-rw-r--r--erts/emulator/test/call_trace_SUITE.erl2
-rw-r--r--erts/emulator/test/ddll_SUITE.erl2
-rw-r--r--erts/emulator/test/distribution_SUITE.erl132
-rw-r--r--erts/emulator/test/evil_SUITE.erl2
-rw-r--r--erts/emulator/test/exception_SUITE.erl2
-rw-r--r--erts/emulator/test/gc_SUITE.erl151
-rw-r--r--erts/emulator/test/lttng_SUITE.erl2
-rw-r--r--erts/emulator/test/match_spec_SUITE.erl2
-rw-r--r--erts/emulator/test/nested_SUITE.erl2
-rw-r--r--erts/emulator/test/old_scheduler_SUITE.erl384
-rw-r--r--erts/emulator/test/port_SUITE.erl2
-rw-r--r--erts/emulator/test/port_trace_SUITE.erl2
-rw-r--r--erts/emulator/test/process_SUITE.erl83
-rw-r--r--erts/emulator/test/receive_SUITE.erl55
-rw-r--r--erts/emulator/test/timer_bif_SUITE.erl24
-rw-r--r--erts/emulator/test/trace_SUITE.erl10
-rw-r--r--erts/emulator/test/trace_port_SUITE.erl2
-rw-r--r--lib/asn1/doc/src/notes.xml49
-rw-r--r--lib/asn1/vsn.mk2
-rw-r--r--lib/common_test/doc/src/notes.xml68
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/notes.xml174
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/crypto/c_src/crypto.c4
-rw-r--r--lib/crypto/doc/src/notes.xml128
-rw-r--r--lib/crypto/vsn.mk2
-rw-r--r--lib/debugger/doc/src/notes.xml36
-rw-r--r--lib/debugger/vsn.mk2
-rw-r--r--lib/dialyzer/doc/src/notes.xml63
-rw-r--r--lib/dialyzer/vsn.mk2
-rw-r--r--lib/edoc/doc/src/notes.xml22
-rw-r--r--lib/edoc/vsn.mk2
-rw-r--r--lib/eldap/test/eldap_basic_SUITE.erl5
-rw-r--r--lib/erl_docgen/doc/src/notes.xml37
-rw-r--r--lib/erl_interface/doc/src/notes.xml33
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/eunit/doc/src/notes.xml15
-rw-r--r--lib/eunit/vsn.mk2
-rw-r--r--lib/hipe/doc/src/notes.xml95
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/inets/doc/src/notes.xml44
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl43
-rw-r--r--lib/inets/vsn.mk2
-rw-r--r--lib/jinterface/doc/src/notes.xml20
-rw-r--r--lib/jinterface/vsn.mk2
-rw-r--r--lib/kernel/doc/src/notes.xml135
-rw-r--r--lib/kernel/test/os_SUITE.erl47
-rw-r--r--lib/kernel/test/sendfile_SUITE.erl4
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/megaco/doc/src/notes.xml16
-rw-r--r--lib/megaco/vsn.mk2
-rw-r--r--lib/mnesia/doc/src/notes.xml21
-rw-r--r--lib/mnesia/src/mnesia_controller.erl2
-rw-r--r--lib/mnesia/vsn.mk2
-rw-r--r--lib/observer/doc/src/notes.xml51
-rw-r--r--lib/observer/src/observer_lib.erl4
-rw-r--r--lib/observer/vsn.mk2
-rw-r--r--lib/parsetools/doc/src/notes.xml27
-rw-r--r--lib/parsetools/vsn.mk2
-rw-r--r--lib/public_key/doc/src/notes.xml35
-rw-r--r--lib/public_key/vsn.mk2
-rw-r--r--lib/reltool/doc/src/notes.xml19
-rw-r--r--lib/reltool/doc/src/reltool_examples.xml627
-rw-r--r--lib/reltool/vsn.mk2
-rw-r--r--lib/runtime_tools/doc/src/notes.xml35
-rw-r--r--lib/runtime_tools/vsn.mk2
-rw-r--r--lib/sasl/doc/src/notes.xml17
-rw-r--r--lib/sasl/vsn.mk2
-rw-r--r--lib/snmp/doc/src/notes.xml19
-rw-r--r--lib/snmp/vsn.mk2
-rw-r--r--lib/ssh/doc/src/notes.xml163
-rw-r--r--lib/ssh/src/ssh_auth.erl59
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl78
-rw-r--r--lib/ssh/src/ssh_dbg.erl93
-rw-r--r--lib/ssh/src/ssh_options.erl6
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE.erl77
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/vsn.mk2
-rw-r--r--lib/ssl/doc/src/notes.xml108
-rw-r--r--lib/ssl/src/dtls_connection.erl61
-rw-r--r--lib/ssl/src/tls_connection.erl13
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl44
-rw-r--r--lib/stdlib/doc/src/gen_statem.xml2
-rw-r--r--lib/stdlib/doc/src/notes.xml412
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/syntax_tools/doc/src/notes.xml15
-rw-r--r--lib/syntax_tools/vsn.mk2
-rw-r--r--lib/tools/doc/src/notes.xml29
-rw-r--r--lib/tools/vsn.mk2
-rw-r--r--lib/wx/doc/src/notes.xml15
-rw-r--r--lib/wx/vsn.mk2
-rw-r--r--lib/xmerl/doc/src/notes.xml18
-rw-r--r--lib/xmerl/src/xmerl_sax_old_dom.erl7
-rw-r--r--lib/xmerl/src/xmerl_sax_parser.erl171
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_base.erlsrc293
-rw-r--r--lib/xmerl/src/xmerl_sax_simple_dom.erl5
-rw-r--r--lib/xmerl/test/Makefile1
-rw-r--r--lib/xmerl/test/xmerl_sax_SUITE.erl76
-rw-r--r--lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml4
-rw-r--r--lib/xmerl/test/xmerl_sax_stream_SUITE.erl17
-rw-r--r--otp_versions.table2
123 files changed, 1534 insertions, 3771 deletions
diff --git a/erts/doc/src/erl_tracer.xml b/erts/doc/src/erl_tracer.xml
index 63feebb0b5..fd3c17f337 100644
--- a/erts/doc/src/erl_tracer.xml
+++ b/erts/doc/src/erl_tracer.xml
@@ -653,7 +653,7 @@ ok
<0.37.0>
3> erlang:trace(new, true, [send,{tracer, erl_msg_tracer, Tracer}]).
0
-{<0.39.0>,<0.27.0>}
+{trace,<0.39.0>,<0.27.0>}
4> {ok, D} = file:open("/tmp/tmp.data",[write]).
{trace,#Port<0.486>,<0.40.0>}
{trace,<0.40.0>,<0.21.0>}
@@ -758,18 +758,21 @@ static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/*
* argv[0]: TraceTag, should only be 'send'
- * argv[1]: TracerState, process to send {argv[2], argv[4]} to
+ * argv[1]: TracerState, process to send {Tracee, Recipient} to
* argv[2]: Tracee
- * argv[3]: Recipient
- * argv[4]: Options, ignored
+ * argv[3]: Message
+ * argv[4]: Options, map containing Recipient
*/
static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifPid to_pid;
+ ERL_NIF_TERM recipient, msg;
if (enif_get_local_pid(env, argv[1], &to_pid)) {
- ERL_NIF_TERM msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], argv[4]);
+ if (enif_get_map_value(env, argv[4], enif_make_atom(env, "extra"), &recipient)) {
+ msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], recipient);
enif_send(env, &to_pid, NULL, msg);
+ }
}
return enif_make_atom(env, "ok");
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index d0fa170e66..8ae87ac280 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -32,559 +32,20 @@
<p>This document describes the changes made to the ERTS application.</p>
-<section><title>Erts 9.0</title>
+<section><title>Erts 8.3.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
- <p>Fix various bugs regarding loading, upgrade and purge
- of HiPE compiled code:</p> <list> <item>The native code
- memory for a purged module was never deallocated.</item>
- <item>Wrong functions could in some cases be called after
- a module upgrade.</item>
- <item><c>erlang:check_process_code</c> did not check for
- recursive calls made from native code.</item> </list>
<p>
- Own Id: OTP-13968</p>
- </item>
- <item>
- <p>
- Hipe optional LLVM backend does require LLVM version 3.9
- or later as older versions forced strong dependencies on
- erts internals structures.</p>
- <p>
- Own Id: OTP-14238</p>
- </item>
- <item>
- <p>When an exception such as '<c>throw(HugeTerm)</c>' was
- caught, <c>HugeTerm</c> term would be kept in the process
- until the next exception occurred, potentially increasing
- the heap size for the process. That has been
- corrected.</p>
- <p>
- Own Id: OTP-14255 Aux Id: OTP-14400, OTP-14401 </p>
- </item>
- <item>
- <p>
- Slogans in crash dumps have been extended to print more
- complex terms.</p>
- <p>
- Own Id: OTP-14303</p>
- </item>
- <item>
- <p>
- Fixed bug when using <c>enif_inspect_binary</c> in
- combination with <c>enif_copy</c>. In some circumstances
- the inspected binary could be realloced by the
- <c>enif_copy</c> call when it shouldn't have been.</p>
- <p>
- Own Id: OTP-14304</p>
- </item>
- <item>
- <p>
- The address family <c>local</c> (AF_UNIX / AF_LOCAL) now
- does not ensure zero termination of Linux Abstract
- Addresses so they can use all bytes.</p>
- <p>
- Own Id: OTP-14305</p>
- </item>
- <item>
- <p>
- Use <c>-fno-PIE</c> for Gentoo Hardened and others that
- don't accept linker flag <c>-no-pie</c>.</p>
- <p>
- Own Id: OTP-14307 Aux Id: PR-1379 </p>
- </item>
- <item>
- <p>
- Disable hipe for <c>ppc64le</c> architecture (little
- endian) as it is not, and has never been, supported. It
- was earlier equated with <c>ppc64</c> (big endian) which
- lead to broken build without <c>--disable-hipe</c>.</p>
- <p>
- Own Id: OTP-14314 Aux Id: ERL-369, PR-1394 </p>
- </item>
- <item>
- <p>
- Fix 'epmd -kill' to return a failure exit status code if
- epmd was not killed because of some error.</p>
- <p>
- Own Id: OTP-14324</p>
- </item>
- <item>
- <p>Fixed the following dirty scheduler related bugs:</p>
- <list> <item><p>the <c>+SDPcpu</c> command line argument
- could cause the amount of dirty CPU schedulers to be set
- to zero</p></item>
- <item><p><c>erlang:system_flag(multi_scheduling, _)</c>
- failed when only one normal scheduler was used together
- with dirty scheduler support</p></item> </list>
- <p>
- Own Id: OTP-14335</p>
- </item>
- <item>
- <p>
- Fix erlexec to handle mismatch in sysconf and proc fs
- when figuring out the cpu topology. This behaviour has
- been seen when using docker together with
- <c>--cpuset-cpus</c>.</p>
- <p>
- Own Id: OTP-14352</p>
- </item>
- <item>
- <p>
- Fixed memory segment cache used for multiblock carriers.
- Huge (> 2GB) memory segments could cause a VM crash.
- Creation of such huge memory segments used for multiblock
- carriers is however very uncommon.</p>
- <p>
- Own Id: OTP-14360 Aux Id: ERL-401, PR-1417 </p>
- </item>
- <item>
- <p>
- Fix bug causing <c>code:is_module_native</c> to falsely
- return true when <c>local</c> call trace is enabled for
- the module.</p>
- <p>
- Own Id: OTP-14390</p>
- </item>
- <item>
- <p>
- Fix emulator crash when receive tracing on a
- <c>trace_delivered</c> message.</p>
- <p>
- Own Id: OTP-14411</p>
- </item>
- <item>
- <p>
- <c>escript</c> did not handle paths with spaces correct.</p>
- <p>
- Own Id: OTP-14433</p>
- </item>
- <item>
- <p>
- Fix erroneous lock check assertion when <c>wx</c> is run
- on MacOS X.</p>
- <p>
- Own Id: OTP-14437 Aux Id: ERL-360 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Added <c>erlang:garbage_collect/2</c> that takes an
- option list as the last argument that can be used to
- control whether a minor or a major garbage collection is
- to be done. Doing a minor collection only collects terms
- that have recently died, but is cheaper than a mjor
- collection.</p>
- <p>
- Own Id: OTP-11695</p>
- </item>
- <item>
- <p>
- Optimized test for tuples with an atom as first element.</p>
- <p>
- Own Id: OTP-12148</p>
- </item>
- <item>
- <p>
- Erlang literals are no longer copied during process to
- process messaging.</p>
- <p>
- Own Id: OTP-13529</p>
- </item>
- <item>
- <p>Add support in the <c>erl_nif</c> API for asynchronous
- message notifications when sockets or other file
- descriptors are ready to accept read or write operations.
- The following functions have been added:</p> <list>
- <item><p>enif_select</p></item>
- <item><p>enif_monitor_process</p></item>
- <item><p>enif_demonitor_process</p></item>
- <item><p>enif_compare_monitors</p></item>
- <item><p>enif_open_resource_type_x</p></item> </list>
- <p>
- Own Id: OTP-13684</p>
- </item>
- <item>
- <p>There are two new guard BIFs '<c>floor/1</c>' and
- '<c>ceil/1</c>'. They both return integers. In the
- '<c>math</c>' module, there are two new BIFs with the
- same names that return floating point values.</p>
- <p>
- Own Id: OTP-13692</p>
- </item>
- <item>
- <p>
- Remove deprecated <c>erlang:hash/2</c>.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-13827</p>
- </item>
- <item>
- <p>Replaced usage of deprecated symbolic <seealso
- marker="erts:erlang#type-time_unit"><c>time
- unit</c></seealso> representations.</p>
- <p>
- Own Id: OTP-13831 Aux Id: OTP-13735 </p>
- </item>
- <item>
- <p>
- Added support in zlib for extraction of the inflation
- dictionary.</p>
- <p>
- Own Id: OTP-13842</p>
- </item>
- <item>
- <p>
- The previously used purge strategy has been removed. The
- optional purge strategy introduced in ERTS version 8.1 is
- now the only strategy available.</p>
- <p>
- The new purge strategy is slightly incompatible with the
- old strategy. Previously processes holding <c>fun</c>s
- that referred to the module being purged either failed a
- soft purge, or was killed during a hard purge. The new
- strategy completely ignores <c>fun</c>s. If <c>fun</c>s
- referring to the code being purged exist, and are used
- after a purge, an exception will be raised upon usage.
- That is, the behavior will be exactly the same as the
- case when a <c>fun</c> is received by a process after the
- purge.</p>
- <p>
- For more information see the documentation of <seealso
- marker="erts:erlang#check_process_code/3"><c>erlang:check_process_code/3</c></seealso>.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-13844 Aux Id: OTP-13833 </p>
- </item>
- <item>
- <p>
- Dirty schedulers are now enabled by default when the
- runtime system is built with SMP support.</p>
- <p>
- Own Id: OTP-13860</p>
- </item>
- <item>
- <p>
- Improved ETS lookup/insert/delete speed for large
- <c>set</c>, <c>bag</c> and <c>duplicate_bag</c> by a
- significant reduction of the hash load factor. This speed
- improvement comes at the expense of less than one word
- per table entry. Tables with less than 256 entries are
- not affected at all.</p>
- <p>
- Own Id: OTP-13903</p>
- </item>
- <item>
- <p>
- The NIF library <c>reload</c> feature is not supported
- anymore. It has been marked as deprecated since OTP R15B.
- This means that you are only allowed to do one successful
- call to <c>erlang:load_nif/2</c> for each module
- instance. A second call to <c>erlang:load_nif/2</c> will
- return <c>{error, {reload, _}}</c> even if the NIF
- library imlements the <c>reload</c> callback.</p>
- <p>
- Runtime upgrade of a NIF library is still supported by
- using the Erlang module upgrade mechanics with a current
- and an old module instance existing at the same time with
- their corresponding NIF libraries.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-13908</p>
- </item>
- <item>
- <p>
- Add <c>erlang:system_info(atom_count)</c> and
- <c>erlang:system_info(atom_limit)</c> to provide a way to
- retrieve the current and maximum number of atoms.</p>
- <p>
- Own Id: OTP-13976</p>
- </item>
- <item>
- <p>The function <c>fmod/2</c> has been added to the
- <c>math</c> module.</p>
- <p>
- Own Id: OTP-14000</p>
- </item>
- <item>
- <p>
- <c>erlang:load_nif/2</c> returns new error type
- <c>notsup</c> when called for a HiPE compiled module,
- which is not supported.</p>
- <p>
- Own Id: OTP-14002</p>
- </item>
- <item>
- <p>
- Add driver and nif lock instrumentation to lcnt</p>
- <p>
- Own Id: OTP-14069</p>
- </item>
- <item>
- <p>
- Reduce memory pressure by converting sub-binaries to
- heap-binaries when possible. This is done during garbage
- collection.</p>
- <p>
- Own Id: OTP-14149</p>
- </item>
- <item>
- <p>
- Dirty schedulers are now enabled and supported on Erlang
- runtime systems with SMP support.</p>
- <p>
- Besides support for dirty NIFs also support for dirty
- BIFs and dirty garbage collection have been introduced.
- All garbage collections that potentially will take a long
- time to complete are now performed on dirty schedulers if
- enabled.</p>
- <p>
- <seealso
- marker="erts:erlang#statistics/1"><c>erlang:statistics/1</c></seealso>
- with arguments inspecting scheduler and run queue states
- have been changed due to the dirty scheduler support.
- Code using this functionality may have to be rewritten
- taking these incompatibilities into consideration.
- Examples of such uses are calls to <seealso
- marker="erts:erlang#statistics_scheduler_wall_time"><c>erlang:statistics(scheduler_wall_time)</c></seealso>,
- <seealso
- marker="erts:erlang#statistics_total_run_queue_lengths"><c>statistics(total_run_queue_lengths)</c></seealso>,
- <seealso
- marker="erts:erlang#statistics_total_active_tasks"><c>statistics(total_active_tasks)</c></seealso>,
- etc.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14152</p>
- </item>
- <item>
- <p>Atoms may now contain arbitrary Unicode
- characters.</p>
- <p>
- Own Id: OTP-14178</p>
- </item>
- <item>
- <p>
- Introduce an event manager in Erlang to handle OS
- signals. A subset of OS signals may be subscribed to and
- those are described in the Kernel application.</p>
- <p>
- Own Id: OTP-14186</p>
- </item>
- <item>
- <p>
- The <c>escript</c> program now handles symbolic links to
- escripts.</p>
- <p>
- This is useful for standalone systems with
- <c>escript</c>s residing on a bin directory not included
- in the execution path (as it may cause their <c>erl</c>
- program(s) to override the desired one). Instead the
- <c>escript</c>s can be referred to via symbolic links
- from a bin directory in the path.</p>
- <p>
- Own Id: OTP-14201 Aux Id: PR-1293 </p>
- </item>
- <item>
- <p>
- All uses of the magic binary kludge has been replaced by
- uses of erlang references.</p>
- <p>
- A magic binary was presented as an empty binary, but
- actually referred other data internally in the Erlang VM.
- Since they were presented as empty binaries, different
- magic binaries compared as equal, and also lost their
- internal data when passed out of an erlang node.</p>
- <p>
- The new usage of references has not got any of these
- strange semantic issues, and the usage of these
- references has been optimized to give the same
- performance benefits as well as memory usage benefits as
- magic binaries had.</p>
- <p>
- A couple of examples of previous uses of magic binaries
- are match specifications and NIF resources.</p>
- <p>
- Own Id: OTP-14205</p>
- </item>
- <item>
- <p>
- The non-smp emulators have been deprecated and are
- scheduled for removal in OTP-21.</p>
- <p>
- In preperations for this, the threaded non-smp emulator
- is no longer built by default and has to be enabled using
- the --enable-plain-emulator to configure.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14272</p>
- </item>
- <item>
- <p>
- Allow HiPE to run on VM built with
- <c>--enable-m32-build</c>.</p>
- <p>
- Own Id: OTP-14330 Aux Id: PR-1397 </p>
- </item>
- <item>
- <p>
- Upgraded the OTP internal PCRE library from version 8.33
- to version 8.40. This library is used for implementation
- of the <seealso marker="stdlib:re"><c>re</c></seealso>
- regular expressions module.</p>
- <p>
- Besides various bug fixes, the new version allows for
- better stack protection. In order to utilize this
- feature, the stack size of normal scheduler threads is
- now by default set to 128 kilo words on all platforms.
- The stack size of normal scheduler threads can be set
- upon system start by passing the <seealso
- marker="erts:erl#sched_thread_stack_size"><c>+sss</c></seealso>
- command line argument to the <seealso
- marker="erts:erl"><c>erl</c></seealso> command.</p>
- <p>
- See <url
- href="http://pcre.org/original/changelog.txt"><c>http://pcre.org/original/changelog.txt</c></url>
- for information about changes made to PCRE between the
- versions 8.33 and 8.40.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14331 Aux Id: ERL-208 </p>
- </item>
- <item>
- <p>
- Remove generation of atoms in old latin1 external format.
- The old latin1 format can still be decoded but is never
- generated by <c>term_to_binary</c> or sent on a
- distribution channel. The new utf8 format for atoms was
- introduced in OTP R16. An OTP 20 node can therefore not
- connect to nodes older than R16.</p>
- <p>
- Own Id: OTP-14337</p>
- </item>
- <item>
- <p>
- Added function <c>re:version/0</c> which returns
- information about the OTP internal PCRE version used for
- implementation of the <c>re</c> module.</p>
- <p>
- Own Id: OTP-14347 Aux Id: PR-1412 </p>
- </item>
- <item>
- <p>
- Added new debug bif <c>erlang:list_to_port/1</c>.</p>
- <p>
- Own Id: OTP-14348</p>
- </item>
- <item>
- <p>
- Various improvements of timer management internally in
- the VM. These improvements both reduced memory
- consumption of timer wheels as well as reduce the amount
- of work that has to be performed in order to handle
- timers.</p>
- <p>
- Own Id: OTP-14356</p>
- </item>
- <item>
- <p> Sockets can now be bound to device (SO_BINDTODEVICE)
- on platforms where it is supported. </p> <p> This has
- been implemented e.g to support VRF-Lite under Linux; see
- <url
- href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">
- VRF </url>, and GitHub pull request <url
- href="https://github.com/erlang/otp/pull/1326">#1326</url>.
- </p>
- <p>
- Own Id: OTP-14357 Aux Id: PR-1326 </p>
- </item>
- <item>
- <p>Added the following <seealso
- marker="erl"><c>erl</c></seealso> command line arguments
- with which you can set suggested stack for dirty
- schedulers:</p> <taglist> <tag><seealso
- marker="erl#dcpu_sched_thread_stack_size"><c>+sssdcpu</c></seealso></tag>
- <item><p>for dirty CPU schedulers</p></item>
- <tag><seealso
- marker="erl#dio_sched_thread_stack_size"><c>+sssdio</c></seealso></tag>
- <item><p>for dirty IO schedulers</p></item> </taglist>
- <p>The default suggested stack size for dirty schedulers
- is 40 kilo words.</p>
- <p>
- Own Id: OTP-14380</p>
- </item>
- <item>
- <p>
- Changed erts startup program name, argv 0, to use the
- environment variable <c>ESCRIPT_NAME</c> so that
- <c>erlc</c>, <c>dialyzer</c>, <c>typer</c>,
- <c>ct_run</c>, or the escript name can be seen with
- external programs, such as ps and htop (depending on
- options), on unix.</p>
- <p>
- Own Id: OTP-14381</p>
- </item>
- <item>
- <p>
- Improvements of <c>escript</c> documentation.</p>
- <p>
- Own Id: OTP-14384 Aux Id: OTP-14201 </p>
- </item>
- <item>
- <p>
- Add function <c>enif_hash</c> for NIFs to calculate hash
- values of arbitrary terms.</p>
- <p>
- Own Id: OTP-14385 Aux Id: PR-1413 </p>
- </item>
- <item>
- <p>'<c>./configure --enable-lock-counter</c>' will
- enabling building of an additional emulator that has
- support for lock counting. (The option previously
- existed, but would turn on lock counting in the default
- emulator being built.) To start the lock-counting
- emulator, use '<c>erl -emu_type lcnt</c>'.</p>
- <p>On Windows, <c>erl</c> recognized the undocumented
- option <c>-debug</c> for starting a debug-compiled
- emulator. That option has been removed. Use '<c>erl
- -emu_type debug</c>' instead.</p>
- <p>
- Own Id: OTP-14407</p>
- </item>
- <item>
- <p>
- Warnings have been added to the relevant documentation
- about not using un-secure distributed nodes in exposed
- environments.</p>
- <p>
- Own Id: OTP-14425</p>
- </item>
- <item>
- <p>
- Improvement of the documentation of the environment
- variable <c>ERL_CRASH_DUMP_SECONDS</c> as well as the
- default behavior when it is not set.</p>
- <p>
- Own Id: OTP-14434</p>
- </item>
- <item>
- <p>
- Enabled off-heap message queue for some system processes
- that might receive large amounts of messages.</p>
+ Add option to make SIGTERM trigger the OS default
+ behaviour instead of doing a gracefull shutdown. To
+ activate this bahviour the environment variable
+ ERL_ZZ_SIGTERM_KILL should be set to "true". This option
+ only works in OTP 19 as OTP 20 will have a different way
+ to deal with SIGTERM.</p>
<p>
- Own Id: OTP-14438</p>
+ Own Id: OTP-14418 Aux Id: ERIERL-15 </p>
</item>
</list>
</section>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index 254e59f2c7..61c1e14741 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -149,6 +149,8 @@ endif
LIBS += $(TYPE_LIBS)
+ORIG_LIBS:= $(LIBS)
+
comma:=,
space:=
space+=
@@ -965,7 +967,7 @@ $(OBJDIR)/%.o: hipe/%.c
$(V_CC) $(subst O2,O3, $(CFLAGS)) $(INCLUDES) -c $< -o $@
$(BINDIR)/hipe_mkliterals$(TF_MARKER): $(OBJDIR)/hipe_mkliterals.o
- $(ld_verbose)$(CC) $(LDFLAGS) -o $@ $< $(TYPE_LIBS)
+ $(ld_verbose)$(CC) $(LDFLAGS) -o $@ $< $(ORIG_LIBS)
$(OBJDIR)/hipe_mkliterals.o: $(HIPE_ASM) $(TTF_DIR)/erl_alloc_types.h $(DTRACE_HEADERS) \
$(TTF_DIR)/OPCODES-GENERATED $(TTF_DIR)/TABLES-GENERATED
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 7134d2da56..40dd4129d2 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -2047,8 +2047,6 @@ ebif_bang_2(BIF_ALIST_2)
#define SEND_YIELD_CONTINUE (-8)
-Sint do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext*);
-
static Sint remote_send(Process *p, DistEntry *dep,
Eterm to, Eterm full_to, Eterm msg,
ErtsSendContext* ctx)
@@ -2102,8 +2100,8 @@ static Sint remote_send(Process *p, DistEntry *dep,
return res;
}
-Sint
-do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext* ctx)
+static Sint
+do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext *ctx)
{
Eterm portid;
Port *pt;
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 4889fac923..6fddba4b34 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -821,7 +821,7 @@ static void clear_literal_range(void* start, Uint size)
#if HAVE_ERTS_MSEG
-void*
+static void*
erts_alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p, Uint flags)
{
void *res;
@@ -832,7 +832,7 @@ erts_alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p, Uint flags)
return res;
}
-void*
+static void*
erts_alcu_mseg_realloc(Allctr_t *allctr, void *seg,
Uint old_size, Uint *new_size_p)
{
@@ -845,7 +845,7 @@ erts_alcu_mseg_realloc(Allctr_t *allctr, void *seg,
return res;
}
-void
+static void
erts_alcu_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size, Uint flags)
{
erts_mseg_dealloc_opt(allctr->alloc_no, seg, (UWord) size, flags, &allctr->mseg_opt);
@@ -996,7 +996,7 @@ erts_alcu_exec_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size, Uint flags)
#endif /* HAVE_ERTS_MSEG */
-void*
+static void*
erts_alcu_sys_alloc(Allctr_t *allctr, Uint* size_p, int superalign)
{
void *res;
@@ -1013,7 +1013,7 @@ erts_alcu_sys_alloc(Allctr_t *allctr, Uint* size_p, int superalign)
return res;
}
-void*
+static void*
erts_alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint *size_p, Uint old_size, int superalign)
{
void *res;
@@ -1035,7 +1035,7 @@ erts_alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint *size_p, Uint old_size,
return res;
}
-void
+static void
erts_alcu_sys_dealloc(Allctr_t *allctr, void *ptr, Uint size, int superalign)
{
#if ERTS_SA_MB_CARRIERS && ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index f570703f25..7a96bd0319 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -195,10 +195,6 @@ extern UWord erts_literal_vspace_map[];
# define ERTS_VSPACE_WORD_BITS (sizeof(UWord)*8)
#endif
-void* erts_alcu_mseg_alloc(Allctr_t*, Uint *size_p, Uint flags);
-void* erts_alcu_mseg_realloc(Allctr_t*, void *seg, Uint old_size, Uint *new_size_p);
-void erts_alcu_mseg_dealloc(Allctr_t*, void *seg, Uint size, Uint flags);
-
#if HAVE_ERTS_MSEG
# if defined(ARCH_32)
void* erts_alcu_literal_32_mseg_alloc(Allctr_t*, Uint *size_p, Uint flags);
@@ -218,9 +214,6 @@ void erts_alcu_exec_mseg_dealloc(Allctr_t*, void *seg, Uint size, Uint flags);
# endif
#endif /* HAVE_ERTS_MSEG */
-void* erts_alcu_sys_alloc(Allctr_t*, Uint *size_p, int superalign);
-void* erts_alcu_sys_realloc(Allctr_t*, void *ptr, Uint *size_p, Uint old_size, int superalign);
-void erts_alcu_sys_dealloc(Allctr_t*, void *ptr, Uint size, int superalign);
#ifdef ARCH_32
void* erts_alcu_literal_32_sys_alloc(Allctr_t*, Uint *size_p, int superalign);
void* erts_alcu_literal_32_sys_realloc(Allctr_t*, void *ptr, Uint *size_p, Uint old_size, int superalign);
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index eea55b3239..71c64997c1 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -1636,7 +1636,7 @@ erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb)
return LSB[0] | (LSB[1]<<8) | (LSB[2]<<16) | (LSB[3]<<24);
}
-void
+static void
erts_align_utf8_bytes(ErlBinMatchBuffer* mb, byte* buf)
{
Uint bits = mb->size - mb->offset;
diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h
index 632855255e..5da2b28a89 100644
--- a/erts/emulator/beam/erl_bits.h
+++ b/erts/emulator/beam/erl_bits.h
@@ -202,7 +202,6 @@ void erts_new_bs_put_string(ERL_BITS_PROTO_2(byte* iptr, Uint num_bytes));
Uint erts_bits_bufs_size(void);
Uint32 erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb);
-void erts_align_utf8_bytes(ErlBinMatchBuffer* mb, byte* buf);
Eterm erts_bs_get_utf8(ErlBinMatchBuffer* mb);
Eterm erts_bs_get_utf16(ErlBinMatchBuffer* mb, Uint flags);
Eterm erts_bs_append(Process* p, Eterm* reg, Uint live, Eterm build_size_term,
diff --git a/erts/emulator/beam/erl_cpu_topology.c b/erts/emulator/beam/erl_cpu_topology.c
index 4347f9f2b7..d0fd763798 100644
--- a/erts/emulator/beam/erl_cpu_topology.c
+++ b/erts/emulator/beam/erl_cpu_topology.c
@@ -2243,45 +2243,6 @@ add_cpu_groups(int groups,
return cgm;
}
-static void
-remove_cpu_groups(erts_cpu_groups_callback_t callback, void *arg)
-{
- erts_cpu_groups_map_t *prev_cgm, *cgm;
- erts_cpu_groups_callback_list_t *prev_cgcl, *cgcl;
-
- ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
-
- no_cpu_groups_callbacks--;
-
- prev_cgm = NULL;
- for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) {
- prev_cgcl = NULL;
- for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) {
- if (cgcl->callback == callback && cgcl->arg == arg) {
- if (prev_cgcl)
- prev_cgcl->next = cgcl->next;
- else
- cgm->callback_list = cgcl->next;
- erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgcl);
- if (!cgm->callback_list) {
- if (prev_cgm)
- prev_cgm->next = cgm->next;
- else
- cpu_groups_maps = cgm->next;
- if (cgm->array)
- erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm->array);
- erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm);
- }
- return;
- }
- prev_cgcl = cgcl;
- }
- prev_cgm = cgm;
- }
-
- erts_exit(ERTS_ABORT_EXIT, "Cpu groups not found\n");
-}
-
static int
cpu_groups_lookup(erts_cpu_groups_map_t *map,
ErtsSchedulerData *esdp)
@@ -2321,21 +2282,3 @@ update_cpu_groups_maps(void)
for (cgm = cpu_groups_maps; cgm; cgm = cgm->next)
make_cpu_groups_map(cgm, 0);
}
-
-void
-erts_add_cpu_groups(int groups,
- erts_cpu_groups_callback_t callback,
- void *arg)
-{
- erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
- add_cpu_groups(groups, callback, arg);
- erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
-}
-
-void erts_remove_cpu_groups(erts_cpu_groups_callback_t callback,
- void *arg)
-{
- erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
- remove_cpu_groups(callback, arg);
- erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
-}
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index 08a0f0e83b..0addfaa3c7 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -676,7 +676,7 @@ int db_create_hash(Process *p, DbTable *tbl)
sizeof(DbTableHashFineLocks));
for (i=0; i<DB_HASH_LOCK_CNT; ++i) {
erts_smp_rwmtx_init_opt_x(&tb->locks->lck_vec[i].lck, &rwmtx_opt,
- "db_hash_slot", make_small(i));
+ "db_hash_slot", tb->common.the_name);
}
/* This important property is needed to guarantee the two buckets
* involved in a grow/shrink operation it protected by the same lock:
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 00fc6116e5..fc2b34e70f 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -13933,7 +13933,11 @@ erts_continue_exit_process(Process *p)
erts_set_gc_state(p, 1);
state = erts_smp_atomic32_read_acqb(&p->state);
- if (state & ERTS_PSFLG_ACTIVE_SYS) {
+ if (state & ERTS_PSFLG_ACTIVE_SYS
+#ifdef ERTS_DIRTY_SCHEDULERS
+ || p->dirty_sys_tasks
+#endif
+ ) {
if (cleanup_sys_tasks(p, state, CONTEXT_REDS) >= CONTEXT_REDS/2)
goto yield;
}
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index 0acc2432a7..f8341f788a 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -969,17 +969,21 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd,
fdrec.sfv_len = SENDFILE_CHUNK_SIZE;
else
fdrec.sfv_len = *nbytes;
+
retval = sendfilev(out_fd, &fdrec, 1, &len);
- /* Sometimes sendfilev can return -1 and still send data.
- When that happens we just pretend that no error happend. */
- if (retval != -1 || errno == EAGAIN || errno == EINTR ||
- len != 0) {
+ if (retval == -1 && errno == EINVAL) {
+ /* On some solaris versions (I've seen it on SunOS 5.10),
+ using a sfv_len larger then a filesize will result in
+ a -1 && errno == EINVAL return. We translate this so
+ a successful send of the data.*/
+ retval = len;
+ }
+
+ if (retval != -1 || errno == EAGAIN || errno == EINTR) {
*offset += len;
*nbytes -= len;
written += len;
- if (errno != EAGAIN && errno != EINTR && len != 0)
- retval = len;
}
} while (len == SENDFILE_CHUNK_SIZE);
#elif defined(__DARWIN__)
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index 2479ccc01f..fcd7244ae9 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -117,7 +117,6 @@ MODULES= \
tracer_SUITE \
tracer_test \
scheduler_SUITE \
- old_scheduler_SUITE \
port_trace_SUITE \
unique_SUITE \
z_SUITE \
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 355be7a36d..4d17276e5c 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -1358,17 +1358,19 @@ do_trapping(N, Bif, ArgFun) ->
io:format("N=~p: Do ~p ~s gc.\n", [N, Bif, case N rem 2 of 0 -> "with"; 1 -> "without" end]),
Pid = spawn(?MODULE,trapping_loop,[Bif, ArgFun, 1000, self()]),
receive ok -> ok end,
- receive after 100 -> ok end,
Ref = make_ref(),
case N rem 2 of
- 0 -> erlang:garbage_collect(Pid, [{async,Ref}]),
- receive after 100 -> ok end;
+ 0 ->
+ erlang:garbage_collect(Pid, [{async,Ref}]),
+ receive after 1 -> ok end;
1 -> void
end,
- exit(Pid,kill),
+ exit(Pid, kill),
case N rem 2 of
- 0 -> receive {garbage_collect, Ref, _} -> ok end;
- 1 -> void
+ 0 ->
+ receive {garbage_collect, Ref, _} -> ok end;
+ 1 ->
+ void
end,
receive after 1 -> ok end,
do_trapping(N-1, Bif, ArgFun).
diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl
index ed03284a5b..779d81daa5 100644
--- a/erts/emulator/test/bs_construct_SUITE.erl
+++ b/erts/emulator/test/bs_construct_SUITE.erl
@@ -35,7 +35,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[test1, test2, test3, test4, test5, testf, not_used,
diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl
index 95171d04ce..1251d644ae 100644
--- a/erts/emulator/test/call_trace_SUITE.erl
+++ b/erts/emulator/test/call_trace_SUITE.erl
@@ -43,7 +43,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 2}}].
all() ->
Common = [errors, on_load],
diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl
index 0b9f76a892..031b05790d 100644
--- a/erts/emulator/test/ddll_SUITE.erl
+++ b/erts/emulator/test/ddll_SUITE.erl
@@ -55,7 +55,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[ddll_test, errors, reference_count, kill_port,
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index 434e729310..dc7afa381b 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -62,8 +62,7 @@
-export([sender/3, receiver2/2, dummy_waiter/0, dead_process/0,
roundtrip/1, bounce/1, do_dist_auto_connect/1, inet_rpc_server/1,
dist_parallel_sender/3, dist_parallel_receiver/0,
- dist_evil_parallel_receiver/0,
- sendersender/4, sendersender2/4]).
+ dist_evil_parallel_receiver/0]).
%% epmd_module exports
-export([start_link/0, register_node/2, register_node/3, port_please/2]).
@@ -129,52 +128,53 @@ bulk_send_small(Config) when is_list(Config) ->
bulk_send_big(Config) when is_list(Config) ->
bulk_send(32, 64).
-bulk_send_bigbig(Config) when is_list(Config) ->
- bulk_sendsend(32*5, 4).
-
bulk_send(Terms, BinSize) ->
ct:timetrap({seconds, 30}),
io:format("Sending ~w binaries, each of size ~w K", [Terms, BinSize]),
{ok, Node} = start_node(bulk_receiver),
Recv = spawn(Node, erlang, apply, [fun receiver/2, [0, 0]]),
- Bin = list_to_binary(lists:duplicate(BinSize*1024, 253)),
+ Bin = binary:copy(<<253>>, BinSize*1024),
Size = Terms*size(Bin),
{Elapsed, {Terms, Size}} = test_server:timecall(?MODULE, sender,
[Recv, Bin, Terms]),
stop_node(Node),
- {comment, integer_to_list(trunc(Size/1024/max(1,Elapsed)+0.5)) ++ " K/s"}.
+ {comment, integer_to_list(round(Size/1024/max(1,Elapsed))) ++ " K/s"}.
-bulk_sendsend(Terms, BinSize) ->
+sender(To, _Bin, 0) ->
+ To ! {done, self()},
+ receive
+ Any ->
+ Any
+ end;
+sender(To, Bin, Left) ->
+ To ! {term, Bin},
+ sender(To, Bin, Left-1).
+
+bulk_send_bigbig(Config) when is_list(Config) ->
+ Terms = 32*5,
+ BinSize = 4,
{Rate1, MonitorCount1} = bulk_sendsend2(Terms, BinSize, 5),
{Rate2, MonitorCount2} = bulk_sendsend2(Terms, BinSize, 995),
Ratio = if MonitorCount2 == 0 -> MonitorCount1 / 1.0;
true -> MonitorCount1 / MonitorCount2
end,
- Comment = integer_to_list(Rate1) ++ " K/s, " ++
- integer_to_list(Rate2) ++ " K/s, " ++
- integer_to_list(MonitorCount1) ++ " monitor msgs, " ++
- integer_to_list(MonitorCount2) ++ " monitor msgs, " ++
- float_to_list(Ratio) ++ " monitor ratio",
- if
- %% A somewhat arbitrary ratio, but hopefully one that will
- %% accommodate a wide range of CPU speeds.
- Ratio > 8.0 ->
- {comment,Comment};
- true ->
- io:put_chars(Comment),
- ct:fail(ratio_too_low)
- end.
+ Comment0 = io_lib:format("~p K/s, ~p K/s, "
+ "~p monitor msgs, ~p monitor msgs, "
+ "~.1f monitor ratio",
+ [Rate1,Rate2,MonitorCount1,
+ MonitorCount2,Ratio]),
+ Comment = lists:flatten(Comment0),
+ {comment,Comment}.
bulk_sendsend2(Terms, BinSize, BusyBufSize) ->
ct:timetrap({seconds, 30}),
- io:format("Sending ~w binaries, each of size ~w K",
+ io:format("\nSending ~w binaries, each of size ~w K",
[Terms, BinSize]),
{ok, NodeRecv} = start_node(bulk_receiver),
Recv = spawn(NodeRecv, erlang, apply, [fun receiver/2, [0, 0]]),
- Bin = list_to_binary(lists:duplicate(BinSize*1024, 253)),
- %%Size = Terms*size(Bin),
+ Bin = binary:copy(<<253>>, BinSize*1024),
%% SLF LEFT OFF HERE.
%% When the caller uses small hunks, like 4k via
@@ -185,74 +185,62 @@ bulk_sendsend2(Terms, BinSize, BusyBufSize) ->
%% default busy size and "+zdbbl 5", and if the 5 case gets
%% "many many more" monitor messages, then we know we're working.
- {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++ integer_to_list(BusyBufSize)),
- _Send = spawn(NodeSend, erlang, apply, [fun sendersender/4, [self(), Recv, Bin, Terms]]),
+ {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++
+ integer_to_list(BusyBufSize)),
+ _Send = spawn(NodeSend, erlang, apply,
+ [fun sendersender/4, [self(), Recv, Bin, Terms]]),
{Elapsed, {_TermsN, SizeN}, MonitorCount} =
- receive
- %% On some platforms (windows), the time taken is 0 so we
- %% simulate that some little time has passed.
- {sendersender, {0.0,T,MC}} ->
- {0.0015, T, MC};
- {sendersender, BigRes} ->
- BigRes
- end,
+ receive
+ %% On some platforms (Windows), the time taken is 0 so we
+ %% simulate that some little time has passed.
+ {sendersender, {0.0,T,MC}} ->
+ {0.0015, T, MC};
+ {sendersender, BigRes} ->
+ BigRes
+ end,
stop_node(NodeRecv),
stop_node(NodeSend),
- {trunc(SizeN/1024/Elapsed+0.5), MonitorCount}.
-
-sender(To, _Bin, 0) ->
- To ! {done, self()},
- receive
- Any ->
- Any
- end;
-sender(To, Bin, Left) ->
- To ! {term, Bin},
- sender(To, Bin, Left-1).
+ {round(SizeN/1024/Elapsed), MonitorCount}.
%% Sender process to be run on a slave node
sendersender(Parent, To, Bin, Left) ->
erlang:system_monitor(self(), [busy_dist_port]),
- [spawn(fun() -> sendersender2(To, Bin, Left, false) end) ||
- _ <- lists:seq(1,1)],
+ _ = spawn(fun() ->
+ sendersender_send(To, Bin, Left),
+ exit(normal)
+ end),
{USec, {Res, MonitorCount}} =
- timer:tc(?MODULE, sendersender2, [To, Bin, Left, true]),
+ timer:tc(fun() ->
+ sendersender_send(To, Bin, Left),
+ To ! {done, self()},
+ count_monitors(0)
+ end),
Parent ! {sendersender, {USec/1000000, Res, MonitorCount}}.
-sendersender2(To, Bin, Left, SendDone) ->
- sendersender3(To, Bin, Left, SendDone, 0).
+sendersender_send(_To, _Bin, 0) ->
+ ok;
+sendersender_send(To, Bin, Left) ->
+ To ! {term, Bin},
+ sendersender_send(To, Bin, Left-1).
-sendersender3(To, _Bin, 0, SendDone, MonitorCount) ->
- if SendDone ->
- To ! {done, self()};
- true ->
- ok
- end,
+count_monitors(MonitorCount) ->
receive
{monitor, _Pid, _Type, _Info} ->
- sendersender3(To, _Bin, 0, SendDone, MonitorCount + 1)
+ count_monitors(MonitorCount + 1)
after 0 ->
- if SendDone ->
- receive
- Any when is_tuple(Any), size(Any) == 2 ->
- {Any, MonitorCount}
- end;
- true ->
- exit(normal)
- end
- end;
-sendersender3(To, Bin, Left, SendDone, MonitorCount) ->
- To ! {term, Bin},
- %%timer:sleep(50),
- sendersender3(To, Bin, Left-1, SendDone, MonitorCount).
+ receive
+ {_,_}=Any ->
+ {Any,MonitorCount}
+ end
+ end.
%% Receiver process to be run on a slave node.
receiver(Terms, Size) ->
receive
{term, Bin} ->
- receiver(Terms+1, Size+size(Bin));
+ receiver(Terms+1, Size+byte_size(Bin));
{done, ReplyTo} ->
ReplyTo ! {Terms, Size}
end.
diff --git a/erts/emulator/test/evil_SUITE.erl b/erts/emulator/test/evil_SUITE.erl
index 9416ac7a02..fb1954ce37 100644
--- a/erts/emulator/test/evil_SUITE.erl
+++ b/erts/emulator/test/evil_SUITE.erl
@@ -34,7 +34,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 1}}].
all() ->
[heap_frag, encode_decode_ext, decode_integer_ext,
diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl
index 76e3556bc4..ad6d8c890f 100644
--- a/erts/emulator/test/exception_SUITE.erl
+++ b/erts/emulator/test/exception_SUITE.erl
@@ -33,7 +33,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[badmatch, pending_errors, nil_arith, stacktrace,
diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl
index 35dd147550..2c2cb9c32d 100644
--- a/erts/emulator/test/gc_SUITE.erl
+++ b/erts/emulator/test/gc_SUITE.erl
@@ -203,89 +203,90 @@ long_receive() ->
end.
minor_major_gc_option_self(_Config) ->
- Endless = fun Endless() ->
- receive
- {gc, Type} -> erlang:garbage_collect(self(), [{type, Type}])
- after 100 -> ok end,
- Endless()
- end,
-
- %% Try as major, a test process will self-trigger GC
- P1 = spawn(Endless),
- erlang:garbage_collect(P1, []),
- erlang:trace(P1, true, [garbage_collection]),
- P1 ! {gc, major},
- expect_trace_messages(P1, [gc_major_start, gc_major_end]),
- erlang:trace(P1, false, [garbage_collection]),
- erlang:exit(P1, kill),
-
- %% Try as minor, a test process will self-trigger GC
- P2 = spawn(Endless),
- erlang:garbage_collect(P2, []),
- erlang:trace(P2, true, [garbage_collection]),
- P2 ! {gc, minor},
- expect_trace_messages(P2, [gc_minor_start, gc_minor_end]),
- erlang:trace(P2, false, [garbage_collection]),
- erlang:exit(P2, kill).
+ %% Try as major, the test process will self-trigger GC
+ check_gc_tracing_around(
+ fun(Pid, Ref) ->
+ Pid ! {gc, Ref, major}
+ end, [gc_major_start, gc_major_end]),
+
+ %% Try as minor, the test process will self-trigger GC
+ check_gc_tracing_around(
+ fun(Pid, Ref) ->
+ Pid ! {gc, Ref, minor}
+ end, [gc_minor_start, gc_minor_end]).
minor_major_gc_option_async(_Config) ->
- Endless = fun Endless() ->
- receive after 100 -> ok end,
- Endless()
- end,
-
- %% Try with default option, must be major gc
- P1 = spawn(Endless),
- erlang:garbage_collect(P1, []),
- erlang:trace(P1, true, [garbage_collection]),
- erlang:garbage_collect(P1, []),
- expect_trace_messages(P1, [gc_major_start, gc_major_end]),
- erlang:trace(P1, false, [garbage_collection]),
- erlang:exit(P1, kill),
+ %% Try with default option, must be major GC
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ erlang:garbage_collect(Pid, [])
+ end, [gc_major_start, gc_major_end]),
%% Try with the 'major' type
- P2 = spawn(Endless),
- erlang:garbage_collect(P2, []),
- erlang:trace(P2, true, [garbage_collection]),
- erlang:garbage_collect(P2, [{type, major}]),
- expect_trace_messages(P2, [gc_major_start, gc_major_end]),
- erlang:trace(P2, false, [garbage_collection]),
- erlang:exit(P2, kill),
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ erlang:garbage_collect(Pid, [{type, major}])
+ end, [gc_major_start, gc_major_end]),
%% Try with 'minor' option, once
- P3 = spawn(Endless),
- erlang:garbage_collect(P3, []),
- erlang:trace(P3, true, [garbage_collection]),
- erlang:garbage_collect(P3, [{type, minor}]),
- expect_trace_messages(P3, [gc_minor_start, gc_minor_end]),
- erlang:trace(P3, false, [garbage_collection]),
- erlang:exit(P3, kill),
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ erlang:garbage_collect(Pid, [{type, minor}])
+ end, [gc_minor_start, gc_minor_end]),
%% Try with 'minor' option, once, async
- P4 = spawn(Endless),
+ check_gc_tracing_around(
+ fun(Pid, Ref) ->
+ ?assertEqual(async,
+ erlang:garbage_collect(Pid, [{type, minor}, {async, Ref}])),
+
+ receive
+ {garbage_collect, Ref, true} ->
+ ok
+ after 10000 ->
+ ct:fail("Did not receive a completion notification on async GC")
+ end
+ end, [gc_minor_start, gc_minor_end]).
+
+%% Traces garbage collection around the given operation, and fails the test if
+%% it results in any unexpected messages or if the expected trace tags are not
+%% received.
+check_gc_tracing_around(Fun, ExpectedTraceTags) ->
Ref = erlang:make_ref(),
- erlang:garbage_collect(P4, []),
- erlang:trace(P4, true, [garbage_collection]),
- ?assertEqual(async,
- erlang:garbage_collect(P4, [{type, minor}, {async, Ref}])),
- expect_trace_messages(P4, [gc_minor_start, gc_minor_end]),
- erlang:trace(P4, false, [garbage_collection]),
- receive {garbage_collect, Ref, true} -> ok;
- Other4 -> ct:pal("Unexpected message: ~p~n"
- ++ "while waiting for async gc result", [Other4])
- after 2000 -> ?assert(false)
- end,
- erlang:exit(P4, kill).
-
-%% Given a list of atoms, trace tags - receives messages and checks if they are
-%% trace events, and if the tag matches. Else will crash failing the test.
-expect_trace_messages(_Pid, []) -> ok;
+ Pid = spawn(
+ fun Endless() ->
+ receive
+ {gc, Ref, Type} ->
+ erlang:garbage_collect(self(), [{type, Type}])
+ after 100 ->
+ ok
+ end,
+ Endless()
+ end),
+ erlang:garbage_collect(Pid, []),
+ erlang:trace(Pid, true, [garbage_collection]),
+ Fun(Pid, Ref),
+ expect_trace_messages(Pid, ExpectedTraceTags),
+ erlang:trace(Pid, false, [garbage_collection]),
+ erlang:exit(Pid, kill),
+ check_no_unexpected_messages().
+
+%% Ensures that trace messages with the provided tags have all been received
+%% within a reasonable timeframe.
+expect_trace_messages(_Pid, []) ->
+ ok;
expect_trace_messages(Pid, [Tag | TraceTags]) ->
receive
- {trace, Pid, Tag, _Data} -> ok;
- AnythingElse ->
- ct:pal("Unexpected message: ~p~nWhile expected {trace, _, ~p, _}",
- [AnythingElse, Tag]),
- ?assert(false)
- end,
- expect_trace_messages(Pid, TraceTags).
+ {trace, Pid, Tag, _Data} ->
+ expect_trace_messages(Pid, TraceTags)
+ after 4000 ->
+ ct:fail("Didn't receive tag ~p within 4000ms", [Tag])
+ end.
+
+check_no_unexpected_messages() ->
+ receive
+ Anything ->
+ ct:fail("Unexpected message: ~p", [Anything])
+ after 0 ->
+ ok
+ end.
diff --git a/erts/emulator/test/lttng_SUITE.erl b/erts/emulator/test/lttng_SUITE.erl
index c12f63706a..1c1952f912 100644
--- a/erts/emulator/test/lttng_SUITE.erl
+++ b/erts/emulator/test/lttng_SUITE.erl
@@ -40,7 +40,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[t_lttng_list,
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index eb189c2c33..92ddc23592 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -42,7 +42,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 1}}].
all() ->
case test_server:is_native(match_spec_SUITE) of
diff --git a/erts/emulator/test/nested_SUITE.erl b/erts/emulator/test/nested_SUITE.erl
index 7af2873ce2..5059317172 100644
--- a/erts/emulator/test/nested_SUITE.erl
+++ b/erts/emulator/test/nested_SUITE.erl
@@ -27,7 +27,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[case_in_case, case_in_after, catch_in_catch,
diff --git a/erts/emulator/test/old_scheduler_SUITE.erl b/erts/emulator/test/old_scheduler_SUITE.erl
deleted file mode 100644
index 8515a87df8..0000000000
--- a/erts/emulator/test/old_scheduler_SUITE.erl
+++ /dev/null
@@ -1,384 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--module(old_scheduler_SUITE).
-
--include_lib("common_test/include/ct.hrl").
-
--export([all/0, suite/0,
- init_per_testcase/2, end_per_testcase/2]).
--export([equal/1, many_low/1, few_low/1, max/1, high/1]).
-
-suite() ->
- [{ct_hooks,[ts_install_cth]},
- {timetrap, {minutes, 11}}].
-
-all() ->
- case catch erlang:system_info(modified_timing_level) of
- Level when is_integer(Level) ->
- {skipped,
- "Modified timing (level " ++
- integer_to_list(Level) ++
- ") is enabled. Testcases gets messed "
- "up by modfied timing."};
- _ -> [equal, many_low, few_low, max, high]
- end.
-
-
-%%-----------------------------------------------------------------------------------
-%% TEST SUITE DESCRIPTION
-%%
-%% The test case function spawns two controlling processes: Starter and Receiver.
-%% Starter spawns a number of prio A and a number of prio B test processes. Each
-%% test process loops for a number of times, sends a report to the Receiver, then
-%% loops again. For each report, the Receiver increases a counter that corresponds
-%% to the priority of the sender. After a certain amount of time, the Receiver
-%% sends the collected data to the main test process and waits for the test case
-%% to terminate. From this data, it's possible to calculate the average run time
-%% relationship between the prio A and B test processes.
-%%
-%% Note that in order to be able to run tests with high or max prio test processes,
-%% the main test process and the Receiver needs to run at max prio, or they will
-%% be starved by the test processes. The controlling processes must not wait for
-%% messages from a normal (or low) prio process while max or high prio test processes
-%% are running (which happens e.g. if an io function is called).
-%%-----------------------------------------------------------------------------------
-
-init_per_testcase(_Case, Config) ->
- %% main test process needs max prio
- Prio = process_flag(priority, max),
- MS = erlang:system_flag(multi_scheduling, block_normal),
- [{prio,Prio},{multi_scheduling, MS}|Config].
-
-end_per_testcase(_Case, Config) ->
- erlang:system_flag(multi_scheduling, unblock_normal),
- Prio=proplists:get_value(prio, Config),
- process_flag(priority, Prio),
- ok.
-
-ok(Config) when is_list(Config) ->
- case proplists:get_value(multi_scheduling, Config) of
- blocked ->
- {comment,
- "Multi-scheduling blocked during test. This testcase was not "
- "written to work with multiple schedulers."};
- _ -> ok
- end.
-
-%% Run equal number of low and normal prio processes.
-
-equal(Config) when is_list(Config) ->
- Self = self(),
-
- %% specify number of test processes to run
- Normal = {normal,500},
- Low = {low,500},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- %% start controllers
- Receiver =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end),
- Starter =
- spawn(fun() -> starter(Normal, Low, Receiver) end),
-
- %% receive test data from Receiver
- {NRs,NAvg,LRs,LAvg,Ratio} =
- receive
- {Receiver,Res} -> Res
- end,
-
- %% stop controllers and test processes
- exit(Starter, kill),
- exit(Receiver, kill),
-
- io:format("Reports: ~w normal (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [NRs,NAvg,LRs,LAvg,Ratio]),
-
- %% runtime ratio between normal and low should be ~8
- if Ratio < 7.5 ; Ratio > 8.5 ->
- ct:fail({bad_ratio,Ratio});
- true ->
- ok(Config)
- end.
-
-
-%% Run many low and few normal prio processes.
-
-many_low(Config) when is_list(Config) ->
- Self = self(),
- Normal = {normal,1},
- Low = {low,1000},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- Receiver =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end),
- Starter =
- spawn(fun() -> starter(Normal, Low, Receiver) end),
- {NRs,NAvg,LRs,LAvg,Ratio} =
- receive
- {Receiver,Res} -> Res
- end,
- exit(Starter, kill),
- exit(Receiver, kill),
- io:format("Reports: ~w normal (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [NRs,NAvg,LRs,LAvg,Ratio]),
- if Ratio < 7.5 ; Ratio > 8.5 ->
- ct:fail({bad_ratio,Ratio});
- true ->
- ok(Config)
- end.
-
-
-%% Run few low and many normal prio processes.
-
-few_low(Config) when is_list(Config) ->
- Self = self(),
- Normal = {normal,1000},
- Low = {low,1},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- Receiver =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end),
- Starter =
- spawn(fun() -> starter(Normal, Low, Receiver) end),
- {NRs,NAvg,LRs,LAvg,Ratio} =
- receive
- {Receiver,Res} -> Res
- end,
- exit(Starter, kill),
- exit(Receiver, kill),
- io:format("Reports: ~w normal (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [NRs,NAvg,LRs,LAvg,Ratio]),
- if Ratio < 7.0 ; Ratio > 8.5 ->
- ct:fail({bad_ratio,Ratio});
- true ->
- ok(Config)
- end.
-
-
-%% Run max prio processes and verify they get at least as much
-%% runtime as high, normal and low.
-
-max(Config) when is_list(Config) ->
- max = process_flag(priority, max), % should already be max (init_per_tc)
- Self = self(),
- Max = {max,2},
- High = {high,2},
- Normal = {normal,100},
- Low = {low,100},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- Receiver1 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, High) end),
- Starter1 =
- spawn(fun() -> starter(Max, High, Receiver1) end),
- {M1Rs,M1Avg,HRs,HAvg,Ratio1} =
- receive
- {Receiver1,Res1} -> Res1
- end,
- exit(Starter1, kill),
- exit(Receiver1, kill),
- io:format("Reports: ~w max (~w/proc), ~w high (~w/proc). Ratio: ~w~n",
- [M1Rs,M1Avg,HRs,HAvg,Ratio1]),
- if Ratio1 < 1.0 ->
- ct:fail({bad_ratio,Ratio1});
- true ->
- ok(Config)
- end,
-
- Receiver2 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, Normal) end),
- Starter2 =
- spawn(fun() -> starter(Max, Normal, Receiver2) end),
- {M2Rs,M2Avg,NRs,NAvg,Ratio2} =
- receive
- {Receiver2,Res2} -> Res2
- end,
- exit(Starter2, kill),
- exit(Receiver2, kill),
- io:format("Reports: ~w max (~w/proc), ~w normal (~w/proc). Ratio: ~w~n",
- [M2Rs,M2Avg,NRs,NAvg,Ratio2]),
- if Ratio2 < 1.0 ->
- ct:fail({bad_ratio,Ratio2});
- true ->
- ok
- end,
-
- Receiver3 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, Low) end),
- Starter3 =
- spawn(fun() -> starter(Max, Low, Receiver3) end),
- {M3Rs,M3Avg,LRs,LAvg,Ratio3} =
- receive
- {Receiver3,Res3} -> Res3
- end,
- exit(Starter3, kill),
- exit(Receiver3, kill),
- io:format("Reports: ~w max (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [M3Rs,M3Avg,LRs,LAvg,Ratio3]),
- if Ratio3 < 1.0 ->
- ct:fail({bad_ratio,Ratio3});
- true ->
- ok(Config)
- end.
-
-
-%% Run high prio processes and verify they get at least as much
-%% runtime as normal and low.
-
-high(Config) when is_list(Config) ->
- max = process_flag(priority, max), % should already be max (init_per_tc)
- Self = self(),
- High = {high,2},
- Normal = {normal,100},
- Low = {low,100},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- Receiver1 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, High, Normal) end),
- Starter1 =
- spawn(fun() -> starter(High, Normal, Receiver1) end),
- {H1Rs,H1Avg,NRs,NAvg,Ratio1} =
- receive
- {Receiver1,Res1} -> Res1
- end,
- exit(Starter1, kill),
- exit(Receiver1, kill),
- io:format("Reports: ~w high (~w/proc), ~w normal (~w/proc). Ratio: ~w~n",
- [H1Rs,H1Avg,NRs,NAvg,Ratio1]),
- if Ratio1 < 1.0 ->
- ct:fail({bad_ratio,Ratio1});
- true ->
- ok
- end,
-
- Receiver2 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, High, Low) end),
- Starter2 =
- spawn(fun() -> starter(High, Low, Receiver2) end),
- {H2Rs,H2Avg,LRs,LAvg,Ratio2} =
- receive
- {Receiver2,Res2} -> Res2
- end,
- exit(Starter2, kill),
- exit(Receiver2, kill),
- io:format("Reports: ~w high (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [H2Rs,H2Avg,LRs,LAvg,Ratio2]),
- if Ratio2 < 1.0 ->
- ct:fail({bad_ratio,Ratio2});
- true ->
- ok(Config)
- end.
-
-
-%%-----------------------------------------------------------------------------------
-%% Controller processes and help functions
-%%-----------------------------------------------------------------------------------
-
-receiver(T0, TimeSec, Main, {P1,P1N}, {P2,P2N}) ->
- %% prio should be max so that mailbox doesn't overflow
- process_flag(priority, max),
- receiver(T0, TimeSec*1000, Main, P1,P1N,0, P2,P2N,0, 100000).
-
-%% uncomment lines below to get life sign (debug)
-receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, 0) ->
- % T = erlang:convert_time_unit(erlang:monotonic_time() - T0, native, millisecond),
- % erlang:display({round(T/1000),P1Rs,P2Rs}),
- receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, 100000);
-
-receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, C) ->
- Remain = Time - erlang:convert_time_unit(erlang:monotonic_time() - T0,
- native, millisecond), % test time remaining
- Remain1 = if Remain < 0 ->
- 0;
- true ->
- Remain
- end,
- {P1Rs1,P2Rs1} =
- receive
- {_Pid,P1} -> % report from a P1 process
- {P1Rs+1,P2Rs};
- {_Pid,P2} -> % report from a P2 process
- {P1Rs,P2Rs+1}
- after Remain1 ->
- {P1Rs,P2Rs}
- end,
- if Remain > 0 -> % keep going
- receiver(T0, Time, Main, P1,P1N,P1Rs1, P2,P2N,P2Rs1, C-1);
- true -> % finish
- %% calculate results and send to main test process
- P1Avg = P1Rs1/P1N,
- P2Avg = P2Rs1/P2N,
- Ratio = if P2Avg < 1.0 -> P1Avg;
- true -> P1Avg/P2Avg
- end,
- Main ! {self(),{P1Rs1,round(P1Avg),P2Rs1,round(P2Avg),Ratio}},
- flush_loop()
- end.
-
-starter({P1,P1N}, {P2,P2N}, Receiver) ->
- %% start N1 processes with prio P1
- start_p(P1, P1N, Receiver),
- %% start N2 processes with prio P2
- start_p(P2, P2N, Receiver),
- erlang:display({started,P1N+P2N}),
- flush_loop().
-
-start_p(_, 0, _) ->
- ok;
-start_p(Prio, N, Receiver) ->
- spawn_link(fun() -> p(Prio, Receiver) end),
- start_p(Prio, N-1, Receiver).
-
-p(Prio, Receiver) ->
- %% set process priority
- process_flag(priority, Prio),
- p_loop(0, Prio, Receiver).
-
-p_loop(100, Prio, Receiver) ->
- receive after 0 -> ok end,
- %% if Receiver gone, we're done
- case is_process_alive(Receiver) of
- false -> exit(bye);
- true -> ok
- end,
- %% send report
- Receiver ! {self(),Prio},
- p_loop(0, Prio, Receiver);
-
-p_loop(N, Prio, Receiver) ->
- p_loop(N+1, Prio, Receiver).
-
-
-flush_loop() ->
- receive _ ->
- ok
- end,
- flush_loop().
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index 94ee9851dd..fccbaf13ee 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -153,7 +153,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[otp_6224, {group, stream}, basic_ping, slow_writes,
diff --git a/erts/emulator/test/port_trace_SUITE.erl b/erts/emulator/test/port_trace_SUITE.erl
index 03efdc15db..bfc3c8cb51 100644
--- a/erts/emulator/test/port_trace_SUITE.erl
+++ b/erts/emulator/test/port_trace_SUITE.erl
@@ -52,7 +52,7 @@
-define(ECHO_DRV_REMOTE_SEND_TERM, 15).
suite() -> [{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 2}}].
all() ->
[port_specs, ports, open_close,
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index e14185e881..4204d12eb3 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -134,6 +134,11 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
[{testcase, Func}|Config].
end_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ %% Restore max_heap_size to default value.
+ erlang:system_flag(max_heap_size,
+ #{size => 0,
+ kill => true,
+ error_logger => true}),
ok.
fun_spawn(Fun) ->
@@ -1024,36 +1029,48 @@ bump_big(Prev, Limit) ->
%% Priority 'low' should be mixed with 'normal' using a factor of
%% about 8. (OTP-2644)
low_prio(Config) when is_list(Config) ->
- case erlang:system_info(schedulers_online) of
- 1 ->
- ok = low_prio_test(Config);
- _ ->
- erlang:system_flag(multi_scheduling, block_normal),
- ok = low_prio_test(Config),
- erlang:system_flag(multi_scheduling, unblock_normal),
- {comment,
- "Test not written for SMP runtime system. "
- "Multi scheduling blocked during test."}
- end.
+ erlang:system_flag(multi_scheduling, block_normal),
+ Prop = low_prio_test(Config),
+ erlang:system_flag(multi_scheduling, unblock_normal),
+ Str = lists:flatten(io_lib:format("Low/high proportion is ~.3f",
+ [Prop])),
+ {comment,Str}.
low_prio_test(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- S = spawn_link(?MODULE, prio_server, [0, 0]),
+
+ %% Spawn the server running with high priority. The server must
+ %% not run at normal priority as that would skew the results for
+ %% two reasons:
+ %%
+ %% 1. There would be one more normal-priority processes than
+ %% low-priority processes.
+ %%
+ %% 2. The receive queue would grow faster than the server process
+ %% could process it. That would in turn trigger the reduction
+ %% punishment for the clients.
+ S = spawn_opt(?MODULE, prio_server, [0, 0], [link,{priority,high}]),
+
+ %% Spawn the clients and let them run for a while.
PCs = spawn_prio_clients(S, erlang:system_info(schedulers_online)),
- ct:sleep({seconds,3}),
+ ct:sleep({seconds,2}),
lists:foreach(fun (P) -> exit(P, kill) end, PCs),
+
+ %% Stop the server and retrieve the result.
S ! exit,
- receive {'EXIT', S, {A, B}} -> check_prio(A, B) end,
- ok.
+ receive
+ {'EXIT', S, {A, B}} ->
+ check_prio(A, B)
+ end.
check_prio(A, B) ->
Prop = A/B,
ok = io:format("Low=~p, High=~p, Prop=~p\n", [A, B, Prop]),
- %% It isn't 1/8, it's more like 0.3, but let's check that
- %% the low-prio processes get some little chance to run at all.
- true = (Prop < 1.0),
- true = (Prop > 1/32).
+ %% Prop is expected to be appr. 1/8. Allow a reasonable margin.
+ true = Prop < 1/4,
+ true = Prop > 1/16,
+ Prop.
prio_server(A, B) ->
receive
@@ -2057,6 +2074,7 @@ max_heap_size_test(Option, Size, Kill, ErrorLogger) ->
end,
if ErrorLogger ->
receive
+ %% There must be at least one error message.
{error, _, {emulator, _, [Pid|_]}} ->
ok
end;
@@ -2069,22 +2087,33 @@ max_heap_size_test(Option, Size, Kill, ErrorLogger) ->
{'DOWN', Ref, process, Pid, die} ->
ok
end,
- flush();
+ %% If the process was not killed, the limit may have
+ %% been reached more than once and there may be
+ %% more {error, ...} messages left.
+ receive_error_messages(Pid);
true ->
ok
end,
+
+ %% Make sure that there are no unexpected messages.
+ receive_unexpected().
+
+receive_error_messages(Pid) ->
receive
- M ->
- ct:fail({unexpected_message, M})
- after 10 ->
+ {error, _, {emulator, _, [Pid|_]}} ->
+ receive_error_messages(Pid)
+ after 1000 ->
ok
end.
-flush() ->
+receive_unexpected() ->
receive
- _M ->
- flush()
- after 1000 ->
+ {info_report, _, _} ->
+ %% May be an alarm message from os_mon. Ignore.
+ receive_unexpected();
+ M ->
+ ct:fail({unexpected_message, M})
+ after 10 ->
ok
end.
diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl
index 83653a7a36..c7d5a3f5a0 100644
--- a/erts/emulator/test/receive_SUITE.erl
+++ b/erts/emulator/test/receive_SUITE.erl
@@ -39,25 +39,43 @@ groups() ->
call_with_huge_message_queue(Config) when is_list(Config) ->
Pid = spawn_link(fun echo_loop/0),
-
- {Time,ok} = tc(fun() -> calls(10, Pid) end),
-
- [self() ! {msg,N} || N <- lists:seq(1, 500000)],
+ _WarmUpTime = time_calls(Pid),
+ Time = time_calls(Pid),
+ _ = [self() ! {msg,N} || N <- lists:seq(1, 500000)],
+ io:format("Time for empty message queue: ~p", [Time]),
erlang:garbage_collect(),
- {NewTime1,ok} = tc(fun() -> calls(10, Pid) end),
- {NewTime2,ok} = tc(fun() -> calls(10, Pid) end),
+ call_with_huge_message_queue_1(Pid, Time, 5).
+
+call_with_huge_message_queue_1(_Pid, _Time, 0) ->
+ ct:fail(bad_ratio);
+call_with_huge_message_queue_1(Pid, Time, NumTries) ->
+ HugeTime = time_calls(Pid),
+ io:format("Time for huge message queue: ~p", [HugeTime]),
+
+ case (HugeTime+1) / (Time+1) of
+ Q when Q < 10 ->
+ ok;
+ Q ->
+ io:format("Too high ratio: ~p\n", [Q]),
+ call_with_huge_message_queue_1(Pid, Time, NumTries-1)
+ end.
- io:format("Time for empty message queue: ~p", [Time]),
- io:format("Time1 for huge message queue: ~p", [NewTime1]),
- io:format("Time2 for huge message queue: ~p", [NewTime2]),
-
- case hd(lists:sort([(NewTime1+1) / (Time+1), (NewTime2+1) / (Time+1)])) of
- Q when Q < 10 ->
- ok;
- Q ->
- ct:fail("Best Q = ~p", [Q])
- end,
- ok.
+%% Time a number calls. Try to avoid returning a zero time.
+time_calls(Pid) ->
+ time_calls(Pid, 10).
+
+time_calls(_Pid, 0) ->
+ 0;
+time_calls(Pid, NumTries) ->
+ case timer:tc(fun() -> calls(Pid) end) of
+ {0,ok} ->
+ time_calls(Pid, NumTries-1);
+ {Time,ok} ->
+ Time
+ end.
+
+calls(Pid) ->
+ calls(100, Pid).
calls(0, _) -> ok;
calls(N, Pid) ->
@@ -108,6 +126,3 @@ echo_loop() ->
Pid ! {Ref,Msg},
echo_loop()
end.
-
-tc(Fun) ->
- timer:tc(erlang, apply, [Fun,[]]).
diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl
index 7cbd93a0f3..a977eb41c4 100644
--- a/erts/emulator/test/timer_bif_SUITE.erl
+++ b/erts/emulator/test/timer_bif_SUITE.erl
@@ -488,24 +488,40 @@ registered_process(Config) when is_list(Config) ->
same_time_yielding(Config) when is_list(Config) ->
Mem = mem(),
+ Ref = make_ref(),
SchdlrsOnln = erlang:system_info(schedulers_online),
Tmo = erlang:monotonic_time(millisecond) + 3000,
Tmrs = lists:map(fun (I) ->
process_flag(scheduler, (I rem SchdlrsOnln) + 1),
- erlang:start_timer(Tmo, self(), hej, [{abs, true}])
+ erlang:start_timer(Tmo, self(), Ref, [{abs, true}])
end,
lists:seq(1, (?TIMEOUT_YIELD_LIMIT*3+1)*SchdlrsOnln)),
true = mem_larger_than(Mem),
- lists:foreach(fun (Tmr) -> receive {timeout, Tmr, hej} -> ok end end, Tmrs),
+ receive_all_timeouts(length(Tmrs), Ref),
Done = erlang:monotonic_time(millisecond),
true = Done >= Tmo,
+ MsAfterTmo = Done - Tmo,
+ io:format("Done ~p ms after Tmo\n", [MsAfterTmo]),
case erlang:system_info(build_type) of
- opt -> true = Done < Tmo + 200;
- _ -> true = Done < Tmo + 1000
+ opt ->
+ true = MsAfterTmo < 200;
+ _ ->
+ true = MsAfterTmo < 1000
end,
Mem = mem(),
ok.
+%% Read out all timeouts in receive queue order. This is efficient
+%% even if there are very many messages.
+
+receive_all_timeouts(0, _Ref) ->
+ ok;
+receive_all_timeouts(N, Ref) ->
+ receive
+ {timeout, _Tmr, Ref} ->
+ receive_all_timeouts(N-1, Ref)
+ end.
+
same_time_yielding_with_cancel(Config) when is_list(Config) ->
same_time_yielding_with_cancel_test(false, false).
diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl
index 643c2e0472..bd0ea22de9 100644
--- a/erts/emulator/test/trace_SUITE.erl
+++ b/erts/emulator/test/trace_SUITE.erl
@@ -46,7 +46,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 5}}].
+ {timetrap, {minutes, 1}}].
all() ->
[cpu_timestamp, receive_trace, link_receive_call_correlation,
@@ -184,10 +184,10 @@ receive_trace(Config) when is_list(Config) ->
{'EXIT', Intruder, {badarg, _}} = receive_first(),
%% Untrace the process; we should not receive anything.
- ?line 1 = erlang:trace(Receiver, false, ['receive']),
- ?line Receiver ! {hello, there},
- ?line Receiver ! any_garbage,
- ?line receive_nothing(),
+ 1 = erlang:trace(Receiver, false, ['receive']),
+ Receiver ! {hello, there},
+ Receiver ! any_garbage,
+ receive_nothing(),
%% Verify restrictions in matchspec for 'receive'
F3 = fun (Pat) -> {'EXIT', {badarg,_}} = (catch erlang:trace_pattern('receive', Pat, [])) end,
diff --git a/erts/emulator/test/trace_port_SUITE.erl b/erts/emulator/test/trace_port_SUITE.erl
index e4db368ea1..5eb27a7b68 100644
--- a/erts/emulator/test/trace_port_SUITE.erl
+++ b/erts/emulator/test/trace_port_SUITE.erl
@@ -37,7 +37,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 2}}].
all() ->
[call_trace, return_trace, send, receive_trace,
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml
index c5074418cd..499a7e40c3 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -32,55 +32,6 @@
<p>This document describes the changes made to the asn1 application.</p>
-<section><title>Asn1 5.0</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Add compile option <c>-compile(no_native)</c> in modules
- with <c>on_load</c> directive which is not yet supported
- by HiPE.</p>
- <p>
- Own Id: OTP-14316 Aux Id: PR-1390 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>The <c>error</c> tuple returned from the <c>encode</c>
- and <c>decode</c> functions will now include the stack
- backtrace to make it easier to understand what went
- wrong.</p>
- <p>
- Own Id: OTP-13961</p>
- </item>
- <item>
- <p>The deprecated module <c>asn1rt</c> has been removed.
- The deprecated functions <c>asn1ct:encode/3</c> and
- <c>asn1ct:decode/3</c> have been removed. The
- undocumented function <c>asn1ct:encode/2</c> has been
- removed.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14146</p>
- </item>
- <item>
- <p>The new '<c>maps</c>' option changes the
- representation of the types <c>SEQUENCE</c> and
- <c>SET</c> to be maps (instead of records).</p>
- <p>
- Own Id: OTP-14219</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Asn1 4.0.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk
index 7329a9f879..e4bf3e2236 100644
--- a/lib/asn1/vsn.mk
+++ b/lib/asn1/vsn.mk
@@ -1 +1 @@
-ASN1_VSN = 5.0
+ASN1_VSN = 4.0.4
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index cc676e955b..a0079fd0c0 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -33,74 +33,6 @@
<file>notes.xml</file>
</header>
-<section><title>Common_Test 1.15</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Errors in the documentation for user HTML stylesheets
- have been corrected.</p>
- <p>
- Own Id: OTP-14332 Aux Id: seq13299 </p>
- </item>
- <item>
- <p>Internal code change: Calls to <c>catch</c> followed
- by a call to <c>erlang:get_stacktrace/0</c> has been
- rewritten to use <c>try</c> instead of <c>catch</c> to
- make the code future-proof.</p>
- <p>
- Own Id: OTP-14400</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>The <c>ct_slave</c> modules now handle nodenames in
- the same way as nodenames passed to <c>-sname</c>. That
- means <c>ct_slave:start('[email protected]').</c> will now
- work.</p>
- <p>
- Own Id: OTP-13806</p>
- </item>
- <item>
- <p>
- Added the new option, <c>keep_logs</c>. If setting the
- value for this option to an integer, N, common_test will
- remove all ct_run.* directories in the current log
- directory, except the N newest.</p>
- <p>
- Own Id: OTP-14179</p>
- </item>
- <item>
- <p>
- The existing <c>ct_netconfc:open/1,2</c> opens an SSH
- connection with one SSH channel realizing one Netconf
- session. To allow testing of multiple sessions over the
- same SSH connection, the following functions are added to
- <c>ct_netconfc</c>:</p>
- <p>
- * <c>connect/1,2</c> - establish an SSH connection *
- <c>disconnect/1</c> - close the given SSH connection *
- <c>session/1,2,3</c> - open an ssh channel on the given
- connection and send 'hello' to start a Netconf session</p>
- <p>
- Own Id: OTP-14284</p>
- </item>
- <item>
- <p>
- The function ct_ssh:shell/2,3 is added.</p>
- <p>
- Own Id: OTP-14415 Aux Id: seq13315 </p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Common_Test 1.14</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index a219aa4736..e6ae8b2e7a 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1 +1 @@
-COMMON_TEST_VSN = 1.15
+COMMON_TEST_VSN = 1.14
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index f11d6c73f2..1dc0c808e7 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -32,180 +32,6 @@
<p>This document describes the changes made to the Compiler
application.</p>
-<section><title>Compiler 7.1</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>For many releases, it has been legal to override a BIF
- with a local function having the same name. However,
- calling a local function with the same name as guard BIF
- as filter in a list comprehension was not allowed.</p>
- <p>
- Own Id: OTP-13690</p>
- </item>
- <item>
- <p>compile:forms/2 would not return the module name as
- documented when one of the options '<c>from_core</c>',
- '<c>from_asm</c>', or '<c>from_beam</c>' was given. Also,
- the compiler would crash if one of those options was
- combined with '<c>native</c>'.</p>
- <p>
- Own Id: OTP-14408 Aux Id: ERL-417 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Optimized test for tuples with an atom as first element.</p>
- <p>
- Own Id: OTP-12148</p>
- </item>
- <item>
- <p>
- Compilation of modules with huge literal binary strings
- is now much faster.</p>
- <p>
- Own Id: OTP-13794</p>
- </item>
- <item>
- <p>Replaced usage of deprecated symbolic <seealso
- marker="erts:erlang#type-time_unit"><c>time
- unit</c></seealso> representations.</p>
- <p>
- Own Id: OTP-13831 Aux Id: OTP-13735 </p>
- </item>
- <item>
- <p>The undocumented and unsupported module
- <c>sys_pre_expand</c> has been removed. As a partical
- replacement for the functionality, there is a new
- function <c>erl_internal:add_predefined_functions/1</c>
- and <c>erl_expand_records</c> will now add a module
- prefix to calls to BIFs and imported functions.</p>
- <p>
- Own Id: OTP-13856</p>
- </item>
- <item>
- <p>The internal compiler passes now start all generated
- variables with "@" to avoid any conflicts with variables
- in languages such as Elixir or LFE.</p>
- <p>
- Own Id: OTP-13924</p>
- </item>
- <item>
- <p>The function <c>fmod/2</c> has been added to the
- <c>math</c> module.</p>
- <p>
- Own Id: OTP-14000</p>
- </item>
- <item>
- <p>Code generation for complicated guards have been
- improved.</p>
- <p>
- Own Id: OTP-14042</p>
- </item>
- <item>
- <p>
- The compiler has new warnings for repeated identical map
- keys.</p>
- <p>
- A map expression such as,</p>
- <p>
- <c> #{'a' => 1, 'b' => 2, 'a' => 3}.</c></p>
- <p>
- will produce a warning for the repeated key 'a'.</p>
- <p>
- Own Id: OTP-14058</p>
- </item>
- <item>
- <p>By default, there will now be a warning when
- <c>export_all</c> is used. The warning can be disabled
- using <c>nowarn_export_all</c>.</p>
- <p>
- Own Id: OTP-14071</p>
- </item>
- <item>
- <p>
- Optimize maps pattern matching by only examining the
- common keys in each clause first instead of all keys.
- This will reduce the number of lookups of each key in
- maps pattern matching.</p>
- <p>
- Own Id: OTP-14072</p>
- </item>
- <item>
- <p>There is a new '<c>deterministc</c>' option to omit
- '<c>source</c>' and '<c>options</c>' tuples in the BEAM
- file.</p>
- <p>
- Own Id: OTP-14087</p>
- </item>
- <item>
- <p>
- Analyzing modules with binary construction with huge
- strings is now much faster. The compiler also compiles
- such modules slightly faster.</p>
- <p>
- Own Id: OTP-14125 Aux Id: ERL-308 </p>
- </item>
- <item>
- <p>Atoms may now contain arbitrary Unicode
- characters.</p>
- <p>
- Own Id: OTP-14178</p>
- </item>
- <item>
- <p><c>compile:file/2</c> now accepts the option
- <c>extra_chunks</c> to include extra chunks in the BEAM
- file.</p>
- <p>
- Own Id: OTP-14221</p>
- </item>
- <item>
- <p>The format of debug information that is stored in BEAM
- files (when <c>debug_info</c> is used) has been changed.
- The purpose of the change is to better support other
- BEAM-based languages such as Elixir or LFE.</p>
- <p>All tools included in OTP (dialyzer, debugger, cover,
- and so on) will handle both the new format and the
- previous format. Tools that retrieve the debug
- information using <c>beam_lib:chunk(Beam,
- [abstract_code])</c> will continue to work with both the
- new and old format. Tools that call
- <c>beam_lib:chunk(Beam, ["Abst"])</c> will not work with
- the new format.</p>
- <p>For more information, see the description of
- <c>debug_info</c> in the documentation for
- <c>beam_lib</c> and the description of the
- <c>{debug_info,{Backend,Data}}</c> option in the
- documentation for <c>compile</c>.</p>
- <p>
- Own Id: OTP-14369 Aux Id: PR-1367 </p>
- </item>
- <item>
- <p>In a future release, <c>erlang:get_stacktrace/0</c>
- will probably only work when called from within a
- '<c>try</c>' expression (otherwise it will return
- <c>[]</c>.</p>
- <p>To help prepare for that change, the compiler will now
- by default warn if '<c>get_stacktrace/0</c>' is used in a
- way that will not work in the future. Note that the
- warning will not be issued if '<c>get_stacktrace/0</c>'
- is used in a function that uses neither '<c>catch</c>'
- nor '<c>try</c>' (because that could be a legal use if
- the function is called from within a '<c>try</c>'.</p>
- <p>
- Own Id: OTP-14401</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Compiler 7.0.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index 463c264a5f..5c87304a01 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 7.1
+COMPILER_VSN = 7.0.4
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 4ae7edd8b2..688ec339aa 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -609,7 +609,7 @@ struct digest_type_t {
}md;
};
-struct digest_type_t digest_types[] =
+static struct digest_type_t digest_types[] =
{
{{"md4"}, {&EVP_md4}},
{{"md5"}, {&EVP_md5}},
@@ -666,7 +666,7 @@ struct cipher_type_t {
#define COND_NO_DES_PTR(Ptr) (Ptr)
#endif
-struct cipher_type_t cipher_types[] =
+static struct cipher_type_t cipher_types[] =
{
{{"rc2_cbc"},
#ifndef OPENSSL_NO_RC2
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index 9a98bfc7c7..62b013e463 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -31,134 +31,6 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
-<section><title>Crypto 4.0</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- LibreSSL can now be used by the modernized crypto app.</p>
- <p>
- Own Id: OTP-14247</p>
- </item>
- <item>
- <p>
- Add compile option <c>-compile(no_native)</c> in modules
- with <c>on_load</c> directive which is not yet supported
- by HiPE.</p>
- <p>
- Own Id: OTP-14316 Aux Id: PR-1390 </p>
- </item>
- <item>
- <p>
- Fix a bug in aes cfb128 function introduced by the bug
- fix in GitHub pull request <url
- href="https://github.com/erlang/otp/pull/1393">#1393</url>.</p>
- <p>
- Own Id: OTP-14435 Aux Id: PR-1462, PR-1393, OTP-14313 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Add basic support for CMAC</p>
- <p>
- Own Id: OTP-13779 Aux Id: ERL-82 PR-1138 </p>
- </item>
- <item>
- <p>
- Removed functions deprecated in crypto-3.0 first released
- in OTP-R16B01</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-13873</p>
- </item>
- <item>
- <p>
- The <c>crypto</c> application now supports OpenSSL 1.1.</p>
- <p>
- Own Id: OTP-13900</p>
- </item>
- <item>
- <p>
- Allow Erlang/OTP to use OpenSSL in FIPS-140 mode, in
- order to satisfy specific security requirements (mostly
- by different parts of the US federal government). </p>
- <p>
- See the new crypto users guide "FIPS mode" chapter about
- building and using the FIPS support which is disabled by
- default.</p>
- <p>
- (Thanks to dszoboszlay and legoscia)</p>
- <p>
- Own Id: OTP-13921 Aux Id: PR-1180 </p>
- </item>
- <item>
- <p>
- Crypto chacha20-poly1305 as in RFC 7539 enabled for
- OpenSSL >= 1.1.</p>
- <p>
- Thanks to mururu.</p>
- <p>
- Own Id: OTP-14092 Aux Id: PR-1291 </p>
- </item>
- <item>
- <p>
- RSA key generation added to <c>crypto:generate_key/2</c>.
- Thanks to wiml.</p>
- <p>
- An interface is also added to
- <c>public_key:generate_key/1</c>.</p>
- <p>
- Own Id: OTP-14140 Aux Id: ERL-165, PR-1299 </p>
- </item>
- <item>
- <p>
- Raised minimum requeriment for OpenSSL version to
- OpenSSL-0.9.8.c although we recommend a much higher
- version, that is a version that is still maintained
- officially by the OpenSSL project. Note that using such
- an old version may restrict the crypto algorithms
- supported.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14171</p>
- </item>
- <item>
- <p>
- Deprecate crypto:rand_uniform/2 as it is not
- cryptographically strong</p>
- <p>
- Own Id: OTP-14274</p>
- </item>
- <item>
- <p>
- The Crypto application now supports generation of
- cryptographically strong random numbers (floats &lt; 1.0
- and integer arbitrary ranges) as a plugin to the 'rand'
- module.</p>
- <p>
- Own Id: OTP-14317 Aux Id: PR-1372 </p>
- </item>
- <item>
- <p>
- This replaces the hard coded test values for AES, CMAC
- and GCM ciphers with the full validation set from NIST's
- CAVP program.</p>
- <p>
- Own Id: OTP-14436 Aux Id: PR-1396 </p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Crypto 3.7.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index 796e3b6d84..f3e0623ac9 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 4.0
+CRYPTO_VSN = 3.7.4
diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml
index fa85567a84..532a17bd81 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -33,42 +33,6 @@
<p>This document describes the changes made to the Debugger
application.</p>
-<section><title>Debugger 4.2.2</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p> The Erlang shell, <c>qlc:string_to_handle()</c>, and
- the Debugger (the Evaluator area and Edit variable window
- of the Bindings area) can parse pids, ports, references,
- and external funs, as long as they can be created in the
- running system. </p>
- <p>
- Own Id: OTP-14296</p>
- </item>
- <item>
- <p> Fix editing of simple binary values in the Bindings
- area of the Debugger's Attach Process Window. </p>
- <p>
- Own Id: OTP-14318</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p> Miscellaneous updates due to atoms containing
- arbitrary Unicode characters. </p>
- <p>
- Own Id: OTP-14285</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Debugger 4.2.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk
index 3534570ef5..f5440865ef 100644
--- a/lib/debugger/vsn.mk
+++ b/lib/debugger/vsn.mk
@@ -1 +1 @@
-DEBUGGER_VSN = 4.2.2
+DEBUGGER_VSN = 4.2.1
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 36ecc4a87b..f7613b3145 100644
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -32,69 +32,6 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
-<section><title>Dialyzer 3.2</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p> The check of bad type variables in type declarations
- was mistakingly removed in Erlang/OTP 18, and is now
- re-introduced. </p>
- <p>
- Own Id: OTP-14423 Aux Id: OTP-14323 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Analyzing modules with binary construction with huge
- strings is now much faster. The compiler also compiles
- such modules slightly faster.</p>
- <p>
- Own Id: OTP-14125 Aux Id: ERL-308 </p>
- </item>
- <item>
- <p> The peak memory consumption is reduced. </p>
- <p>
- Own Id: OTP-14127</p>
- </item>
- <item>
- <p>TypEr has been removed as separate application and is
- now a part of the Dialyzer application. Documentation for
- TypEr has been added in the Dialyzer application.</p>
- <p>
- Own Id: OTP-14336</p>
- </item>
- <item>
- <p>The format of debug information that is stored in BEAM
- files (when <c>debug_info</c> is used) has been changed.
- The purpose of the change is to better support other
- BEAM-based languages such as Elixir or LFE.</p>
- <p>All tools included in OTP (dialyzer, debugger, cover,
- and so on) will handle both the new format and the
- previous format. Tools that retrieve the debug
- information using <c>beam_lib:chunk(Beam,
- [abstract_code])</c> will continue to work with both the
- new and old format. Tools that call
- <c>beam_lib:chunk(Beam, ["Abst"])</c> will not work with
- the new format.</p>
- <p>For more information, see the description of
- <c>debug_info</c> in the documentation for
- <c>beam_lib</c> and the description of the
- <c>{debug_info,{Backend,Data}}</c> option in the
- documentation for <c>compile</c>.</p>
- <p>
- Own Id: OTP-14369 Aux Id: PR-1367 </p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Dialyzer 3.1.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk
index 4a1a7c25a0..0919fba834 100644
--- a/lib/dialyzer/vsn.mk
+++ b/lib/dialyzer/vsn.mk
@@ -1 +1 @@
-DIALYZER_VSN = 3.2
+DIALYZER_VSN = 3.1
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index 27b5a3ac3d..4982488335 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -32,28 +32,6 @@
<p>This document describes the changes made to the EDoc
application.</p>
-<section><title>Edoc 0.9</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>To support stable builds, <c>edoc</c> no longer
- includes time stamps in the footer for generated
- files.</p>
- <p>
- Own Id: OTP-14277</p>
- </item>
- <item>
- <p> Miscellaneous updates due to atoms containing
- arbitrary Unicode characters. </p>
- <p>
- Own Id: OTP-14285</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Edoc 0.8.1</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk
index 1a933b2ad8..d66802fdac 100644
--- a/lib/edoc/vsn.mk
+++ b/lib/edoc/vsn.mk
@@ -1 +1 @@
-EDOC_VSN = 0.9
+EDOC_VSN = 0.8.1
diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl
index ac3447cfe6..4bfb0dd291 100644
--- a/lib/eldap/test/eldap_basic_SUITE.erl
+++ b/lib/eldap/test/eldap_basic_SUITE.erl
@@ -119,7 +119,10 @@ init_per_suite(Config) ->
{ldaps_server, LDAPS_server} | Config].
end_per_suite(_Config) ->
- ssl:stop().
+ try ssl:stop()
+ catch
+ _:_ -> ok
+ end.
init_per_group(return_values, Config) ->
diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml
index 0653730572..4824a755d9 100644
--- a/lib/erl_docgen/doc/src/notes.xml
+++ b/lib/erl_docgen/doc/src/notes.xml
@@ -31,42 +31,7 @@
</header>
<p>This document describes the changes made to the <em>erl_docgen</em> application.</p>
- <section><title>Erl_Docgen 0.7</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Sort index of C functions alphabetically in the sidebar.</p>
- <p>
- Own Id: OTP-14333 Aux Id: ERL-393 </p>
- </item>
- <item>
- <p> The right side index of functions now handle
- functions with same name but different arity. </p>
- <p>
- Own Id: OTP-14431</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Improvements in the OTP documentation style.</p>
- <p>
- (Thanks to Mariano Guerra)</p>
- <p>
- Own Id: OTP-14371 Aux Id: PR-1215 </p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Erl_Docgen 0.6.1</title>
+ <section><title>Erl_Docgen 0.6.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index e586960c06..77d503b4d2 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -31,39 +31,6 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
-<section><title>Erl_Interface 3.10</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fix bug where gethostname would incorrectly fail with
- enametoolong on Linux.</p>
- <p>
- Own Id: OTP-14310</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Remove generation of atoms in old latin1 external format.
- The old latin1 format can still be decoded but is never
- generated by <c>term_to_binary</c> or sent on a
- distribution channel. The new utf8 format for atoms was
- introduced in OTP R16. An OTP 20 node can therefore not
- connect to nodes older than R16.</p>
- <p>
- Own Id: OTP-14337</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Erl_Interface 3.9.3</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index 01fcee86dd..563694a0c1 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1,2 +1,2 @@
-EI_VSN = 3.10
+EI_VSN = 3.9.3
ERL_INTERFACE_VSN = $(EI_VSN)
diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml
index 2a4ca6d12c..cd4e230254 100644
--- a/lib/eunit/doc/src/notes.xml
+++ b/lib/eunit/doc/src/notes.xml
@@ -33,21 +33,6 @@
</header>
<p>This document describes the changes made to the EUnit application.</p>
-<section><title>Eunit 2.3.3</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>The surefire reports from <c>eunit</c> will no longer
- have names with embedded double quotes.</p>
- <p>
- Own Id: OTP-14287</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Eunit 2.3.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk
index 107ad5c101..7eee75ee10 100644
--- a/lib/eunit/vsn.mk
+++ b/lib/eunit/vsn.mk
@@ -1 +1 @@
-EUNIT_VSN = 2.3.3
+EUNIT_VSN = 2.3.2
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index 9167d0aaec..38f8dbfea3 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -31,101 +31,6 @@
</header>
<p>This document describes the changes made to HiPE.</p>
-<section><title>Hipe 3.16</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fix hipe compiler flags <c>o0</c> and <c>o1</c> that have
- previously been ignored by mistake.</p>
- <p>
- Own Id: OTP-13862 Aux Id: PR-1154 </p>
- </item>
- <item>
- <p>
- Fix LLVM backend to not convert all remote calls to own
- module, like <c>?MODULE:foo()</c>, into local calls.</p>
- <p>
- Own Id: OTP-13983</p>
- </item>
- <item>
- <p>
- Hipe optional LLVM backend does require LLVM version 3.9
- or later as older versions forced strong dependencies on
- erts internals structures.</p>
- <p>
- Own Id: OTP-14238</p>
- </item>
- <item>
- <p>
- Fix a bug that has been seen causing failed loading of
- hipe compiled modules on NetBSD due to unaligned data
- pointers.</p>
- <p>
- Own Id: OTP-14302 Aux Id: ERL-376, PR-1386 </p>
- </item>
- <item>
- <p>
- Fix miscompilation bug in hipe that could cause wrong
- function clause to be called from non-tail calls, where
- the return value is unused, if the right function clause
- is only reachable from those non-tail calls.</p>
- <p>
- Own Id: OTP-14306 Aux Id: ERL-278, PR-1392 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Improve hipe compilation time for large functions.</p>
- <p>
- Own Id: OTP-13810 Aux Id: PR-1124 </p>
- </item>
- <item>
- <p>Replaced usage of deprecated symbolic <seealso
- marker="erts:erlang#type-time_unit"><c>time
- unit</c></seealso> representations.</p>
- <p>
- Own Id: OTP-13831 Aux Id: OTP-13735 </p>
- </item>
- <item>
- <p>
- Speed up hipe compile time register allocation for larger
- function.</p>
- <p>
- Own Id: OTP-13879</p>
- </item>
- <item>
- <p>
- Various code generation improvements.</p>
- <p>
- Own Id: OTP-14261 Aux Id: PR-1360 </p>
- </item>
- <item>
- <p>
- Improve hipe compiler to generate code with better CPU
- register utilization at runtime by the use of 'Live Range
- Splitting' techniques.</p>
- <p>
- Own Id: OTP-14293 Aux Id: PR-1380 </p>
- </item>
- <item>
- <p>
- Allow HiPE to run on VM built with
- <c>--enable-m32-build</c>.</p>
- <p>
- Own Id: OTP-14330 Aux Id: PR-1397 </p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Hipe 3.15.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index 0ef4aa7f09..172d976931 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.16
+HIPE_VSN = 3.15.4
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index ccf7628f72..1fad94fac1 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -33,49 +33,7 @@
<file>notes.xml</file>
</header>
- <section><title>Inets 6.4</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>Typos have been fixed.</p>
- <p>
- Own Id: OTP-14387</p>
- </item>
- <item>
- <p>
- httpd_util:rfc1123_date/1 gracefully handle invalid DST
- dates by returning the original time in the expected
- rfc1123 format.</p>
- <p>
- Own Id: OTP-14394</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Add unicode binary support to http_uri functions</p>
- <p>
- Own Id: OTP-14404</p>
- </item>
- <item>
- <p>
- httpc - Change timeout handling so the redirects casuse a
- new timer to be set. This means that a simple redirected
- request could return after 2*timeout milliseconds.</p>
- <p>
- Own Id: OTP-14429</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Inets 6.3.9</title>
+ <section><title>Inets 6.3.9</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 89c17a8679..4b2bcc7242 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -1175,17 +1175,20 @@ handle_empty_queue(Session, ProfileName, TimeOut, State) ->
%% If a pipline | keep_alive session has been idle for some time is not
%% closed by the server, the client may want to close it.
NewState = activate_queue_timeout(TimeOut, State),
- update_session(ProfileName, Session, #session.queue_length, 0),
- %% Note mfa will be initialized when a new request
- %% arrives.
- {noreply,
- NewState#state{request = undefined,
- mfa = undefined,
- status_line = undefined,
- headers = undefined,
- body = undefined
- }
- }.
+ case update_session(ProfileName, Session, #session.queue_length, 0) of
+ {stop, Reason} ->
+ {stop, {shutdown, Reason}, State};
+ _ ->
+ %% Note mfa will be initialized when a new request
+ %% arrives.
+ {noreply,
+ NewState#state{request = undefined,
+ mfa = undefined,
+ status_line = undefined,
+ headers = undefined,
+ body = undefined
+ }}
+ end.
receive_response(Request, Session, Data, State) ->
NewState = init_wait_for_response_state(Request, State),
@@ -1677,7 +1680,7 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) ->
Session2 = erlang:setelement(Pos, Session, Value),
insert_session(Session2, ProfileName);
error:badarg ->
- exit(normal); %% Manager has been shutdown
+ {stop, normal};
T:E ->
%% Unexpected this must be an error!
Stacktrace = erlang:get_stacktrace(),
@@ -1697,14 +1700,14 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) ->
Session,
(catch httpc_manager:lookup_session(SessionId, ProfileName)),
T, E]),
- exit({failed_updating_session,
- [{profile, ProfileName},
- {session_id, SessionId},
- {pos, Pos},
- {value, Value},
- {etype, T},
- {error, E},
- {stacktrace, Stacktrace}]})
+ {stop, {failed_updating_session,
+ [{profile, ProfileName},
+ {session_id, SessionId},
+ {pos, Pos},
+ {value, Value},
+ {etype, T},
+ {error, E},
+ {stacktrace, Stacktrace}]}}
end.
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 96796f11c0..758cef7ac4 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -19,6 +19,6 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 6.4
+INETS_VSN = 6.3.9
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml
index 9ae188be6c..30f607c357 100644
--- a/lib/jinterface/doc/src/notes.xml
+++ b/lib/jinterface/doc/src/notes.xml
@@ -31,26 +31,6 @@
</header>
<p>This document describes the changes made to the Jinterface application.</p>
-<section><title>Jinterface 1.8</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Remove generation of atoms in old latin1 external format.
- The old latin1 format can still be decoded but is never
- generated by <c>term_to_binary</c> or sent on a
- distribution channel. The new utf8 format for atoms was
- introduced in OTP R16. An OTP 20 node can therefore not
- connect to nodes older than R16.</p>
- <p>
- Own Id: OTP-14337</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Jinterface 1.7.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk
index 373e2dab22..c29d9df3d7 100644
--- a/lib/jinterface/vsn.mk
+++ b/lib/jinterface/vsn.mk
@@ -1 +1 @@
-JINTERFACE_VSN = 1.8
+JINTERFACE_VSN = 1.7.1
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index 975518d791..7127a59a0c 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -31,141 +31,6 @@
</header>
<p>This document describes the changes made to the Kernel application.</p>
-<section><title>Kernel 5.3</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fix bug where gethostname would incorrectly fail with
- enametoolong on Linux.</p>
- <p>
- Own Id: OTP-14310</p>
- </item>
- <item>
- <p>
- Fix bug causing <c>code:is_module_native</c> to falsely
- return true when <c>local</c> call trace is enabled for
- the module.</p>
- <p>
- Own Id: OTP-14390</p>
- </item>
- <item>
- <p>
- Add early reject of invalid node names from distributed
- nodes.</p>
- <p>
- Own Id: OTP-14426</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Since Unicode is now allowed in atoms an extra check is
- needed for node names, which are restricted to Latin-1.</p>
- <p>
- Own Id: OTP-13805</p>
- </item>
- <item>
- <p>Replaced usage of deprecated symbolic <seealso
- marker="erts:erlang#type-time_unit"><c>time
- unit</c></seealso> representations.</p>
- <p>
- Own Id: OTP-13831 Aux Id: OTP-13735 </p>
- </item>
- <item>
- <p><c>file:write_file(Name, Data, [raw])</c> would turn
- <c>Data</c> into a single binary before writing. This
- meant it could not take advantage of the <c>writev()</c>
- system call if it was given a list of binaries and told
- to write with <c>raw</c> mode.</p>
- <p>
- Own Id: OTP-13909</p>
- </item>
- <item>
- <p>The performance of the <c>disk_log</c> has been
- somewhat improved in some corner cases (big items), and
- the documentation has been clarified. </p>
- <p>
- Own Id: OTP-14057 Aux Id: PR-1245 </p>
- </item>
- <item>
- <p>Functions for detecting changed code has been added.
- <c>code:modified_modules/0</c> returns all currently
- loaded modules that have changed on disk.
- <c>code:module_status/1</c> returns the status for a
- module. In the shell and in <c>c</c> module, <c>mm/0</c>
- is short for <c>code:modified_modules/0</c>, and
- <c>lm/0</c> reloads all currently loaded modules that
- have changed on disk.</p>
- <p>
- Own Id: OTP-14059</p>
- </item>
- <item>
- <p>
- Introduce an event manager in Erlang to handle OS
- signals. A subset of OS signals may be subscribed to and
- those are described in the Kernel application.</p>
- <p>
- Own Id: OTP-14186</p>
- </item>
- <item>
- <p> Sockets can now be bound to device (SO_BINDTODEVICE)
- on platforms where it is supported. </p> <p> This has
- been implemented e.g to support VRF-Lite under Linux; see
- <url
- href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">
- VRF </url>, and GitHub pull request <url
- href="https://github.com/erlang/otp/pull/1326">#1326</url>.
- </p>
- <p>
- Own Id: OTP-14357 Aux Id: PR-1326 </p>
- </item>
- <item>
- <p>
- Added option to store shell_history on disk so that the
- history can be reused between sessions.</p>
- <p>
- Own Id: OTP-14409 Aux Id: PR-1420 </p>
- </item>
- <item>
- <p> The size of crash reports created by
- <c>gen_server</c>, <c>gen_statem</c> and <c>proc_lib</c>
- is limited with aid of the Kernel application variable
- <c>error_logger_format_depth</c>. The purpose is to limit
- the size of the <c>error_logger</c> process when
- processes with huge message queues or states crash. </p>
- <p> The new function
- <c>error_logger:get_format_depth/0</c> can be used to
- retrieve the value of the Kernel application variable
- <c>error_logger_format_depth</c>. </p>
- <p>
- Own Id: OTP-14417</p>
- </item>
- <item>
- <p> One of the ETS tables used by the <c>global</c>
- module is created with <c>{read_concurrency, true}</c> in
- order to reduce contention. </p>
- <p>
- Own Id: OTP-14419</p>
- </item>
- <item>
- <p>
- Warnings have been added to the relevant documentation
- about not using un-secure distributed nodes in exposed
- environments.</p>
- <p>
- Own Id: OTP-14425</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Kernel 5.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl
index 3cbb75a633..1233e362f2 100644
--- a/lib/kernel/test/os_SUITE.erl
+++ b/lib/kernel/test/os_SUITE.erl
@@ -319,31 +319,38 @@ perf_counter_api(_Config) ->
true = is_integer(os:perf_counter()),
true = os:perf_counter() > 0,
- T1 = os:perf_counter(),
+ Conv = fun(T1, T2) ->
+ erlang:convert_time_unit(T2 - T1, perf_counter, nanosecond)
+ end,
+
+ do_perf_counter_test([], Conv, 120000000, 80000000),
+ do_perf_counter_test([1000], fun(T1, T2) -> T2 - T1 end, 120, 80).
+
+do_perf_counter_test(CntArgs, Conv, Upper, Lower) ->
+ %% We run the test multiple times to try to get a somewhat
+ %% stable value... what does this test? That the
+ %% calculate_perf_counter_unit in sys_time.c works somewhat ok.
+ do_perf_counter_test(CntArgs, Conv, Upper, Lower, 10).
+
+do_perf_counter_test(CntArgs, _Conv, Upper, Lower, 0) ->
+ ct:fail("perf_counter_test ~p ~p ~p",[CntArgs, Upper, Lower]);
+do_perf_counter_test(CntArgs, Conv, Upper, Lower, Iters) ->
+
+ T1 = apply(os, perf_counter, CntArgs),
timer:sleep(100),
- T2 = os:perf_counter(),
- TsDiff = erlang:convert_time_unit(T2 - T1, perf_counter, nanosecond),
- ct:pal("T1: ~p~n"
+ T2 = apply(os, perf_counter, CntArgs),
+ TsDiff = Conv(T1, T2),
+ ct:log("T1: ~p~n"
"T2: ~p~n"
"TsDiff: ~p~n",
[T1,T2,TsDiff]),
- %% We allow a 15% diff
- true = TsDiff < 115000000,
- true = TsDiff > 85000000,
-
- T1Ms = os:perf_counter(1000),
- timer:sleep(100),
- T2Ms = os:perf_counter(1000),
- MsDiff = T2Ms - T1Ms,
- ct:pal("T1Ms: ~p~n"
- "T2Ms: ~p~n"
- "MsDiff: ~p~n",
- [T1Ms,T2Ms,MsDiff]),
-
- %% We allow a 15% diff
- true = MsDiff < 115,
- true = MsDiff > 85.
+ if
+ TsDiff < Upper, TsDiff > Lower ->
+ ok;
+ true ->
+ do_perf_counter_test(CntArgs, Conv, Upper, Lower, Iters-1)
+ end.
%% Util functions
diff --git a/lib/kernel/test/sendfile_SUITE.erl b/lib/kernel/test/sendfile_SUITE.erl
index 2673c38494..e839959623 100644
--- a/lib/kernel/test/sendfile_SUITE.erl
+++ b/lib/kernel/test/sendfile_SUITE.erl
@@ -100,13 +100,13 @@ init_per_testcase(TC,Config) when TC == t_sendfile_recvduring;
%% Check if sendfile is supported on this platform
case catch sendfile_send(Send) of
ok ->
- Config;
+ init_per_testcase(t_sendfile, Config);
Error ->
ct:log("Error: ~p",[Error]),
{skip,"Not supported"}
end;
init_per_testcase(_Tc,Config) ->
- Config.
+ Config ++ [{sendfile_opts,[{use_threads,false}]}].
t_sendfile_small(Config) when is_list(Config) ->
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index 4edecd8969..76b020e8ed 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 5.3
+KERNEL_VSN = 5.2
diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml
index aa3d434dd7..a05a339003 100644
--- a/lib/megaco/doc/src/notes.xml
+++ b/lib/megaco/doc/src/notes.xml
@@ -37,21 +37,7 @@
section is the version number of Megaco.</p>
- <section><title>Megaco 3.18.2</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>Typos have been fixed.</p>
- <p>
- Own Id: OTP-14387</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Megaco 3.18.1</title>
+ <section><title>Megaco 3.18.1</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk
index ca8049daee..0d40f863b2 100644
--- a/lib/megaco/vsn.mk
+++ b/lib/megaco/vsn.mk
@@ -19,6 +19,6 @@
# %CopyrightEnd%
APPLICATION = megaco
-MEGACO_VSN = 3.18.2
+MEGACO_VSN = 3.18.1
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)"
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index 3ca4026190..062a62298b 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -39,26 +39,7 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
- <section><title>Mnesia 4.15</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Removed the wrapping of select continuations in extension
- plugin handling. This might require the user to rewrite
- user backend plugin if used.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14039</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Mnesia 4.14.3</title>
+ <section><title>Mnesia 4.14.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index 17b47c059e..93a7e21f4e 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -1888,7 +1888,7 @@ info_format(Tab, Size, Mem, Media) ->
StrT = mnesia_lib:pad_name(atom_to_list(Tab), 15, []),
StrS = mnesia_lib:pad_name(integer_to_list(Size), 8, []),
StrM = mnesia_lib:pad_name(integer_to_list(Mem), 8, []),
- io:format("~s: with ~s records occupying ~s ~s~n",
+ io:format("~ts: with ~s records occupying ~s ~s~n",
[StrT, StrS, StrM, Media]).
%% Handle early arrived messages
diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk
index 81b15d65db..e272a469bb 100644
--- a/lib/mnesia/vsn.mk
+++ b/lib/mnesia/vsn.mk
@@ -1 +1 @@
-MNESIA_VSN = 4.15
+MNESIA_VSN = 4.14.3
diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml
index fbcfe67a12..bd9aa265f8 100644
--- a/lib/observer/doc/src/notes.xml
+++ b/lib/observer/doc/src/notes.xml
@@ -32,57 +32,6 @@
<p>This document describes the changes made to the Observer
application.</p>
-<section><title>Observer 2.4</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- <c>etop</c> had a hardcoded timeout value of 1 second
- when waiting for data from a remote node. When this
- expired, which could happen for instance if there were
- very many processes on the remote node, etop would exit
- with reason <c>connection_lost</c>. To overcome this
- problem, the timeout is now changed to be the same as the
- update interval, which is configurable.</p>
- <p>
- Own Id: OTP-14393</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Show dirty-scheduler threads in performance monitor graph
- and add a column with maximum allocated memory in the
- Memory Allocators table.</p>
- <p>
- Own Id: OTP-14137</p>
- </item>
- <item>
- <p>
- Keep table and port selection after refresh of tables.
- Store settings before shutdown and restore when starting
- application.</p>
- <p>
- Own Id: OTP-14270</p>
- </item>
- <item>
- <p>
- When observing a node older than OTP-19.0, a pop-up will
- be displayed when trying to access port information.
- Earlier, observer would crash in this situation.</p>
- <p>
- Own Id: OTP-14345 Aux Id: ERL-399 </p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Observer 2.3.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl
index 7352af936c..c7ee294719 100644
--- a/lib/observer/src/observer_lib.erl
+++ b/lib/observer/src/observer_lib.erl
@@ -636,12 +636,12 @@ user_term_multiline(Parent, Title, Default) ->
parse_string(Str) ->
try
- Tokens = case erl_scan:string(Str) of
+ Tokens = case erl_scan:string(Str, 1, [text]) of
{ok, Ts, _} -> Ts;
{error, {_SLine, SMod, SError}, _} ->
throw(io_lib:format("~s", [SMod:format_error(SError)]))
end,
- case erl_parse:parse_term(Tokens) of
+ case lib:extended_parse_term(Tokens) of
{error, {_PLine, PMod, PError}} ->
throw(io_lib:format("~s", [PMod:format_error(PError)]));
Res -> Res
diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk
index 21edfcd184..ca9ad72473 100644
--- a/lib/observer/vsn.mk
+++ b/lib/observer/vsn.mk
@@ -1 +1 @@
-OBSERVER_VSN = 2.4
+OBSERVER_VSN = 2.3.1
diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml
index e9f81fb86e..5a16445577 100644
--- a/lib/parsetools/doc/src/notes.xml
+++ b/lib/parsetools/doc/src/notes.xml
@@ -31,33 +31,6 @@
</header>
<p>This document describes the changes made to the Parsetools application.</p>
-<section><title>Parsetools 2.1.5</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Minor documentation fixes</p>
- <p>
- Own Id: OTP-14276 Aux Id: PR-1357 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p> Miscellaneous updates due to atoms containing
- arbitrary Unicode characters. </p>
- <p>
- Own Id: OTP-14285</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Parsetools 2.1.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk
index 502ca00a47..d102c63730 100644
--- a/lib/parsetools/vsn.mk
+++ b/lib/parsetools/vsn.mk
@@ -1 +1 @@
-PARSETOOLS_VSN = 2.1.5
+PARSETOOLS_VSN = 2.1.4
diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml
index 64592a6d87..dd83e1961d 100644
--- a/lib/public_key/doc/src/notes.xml
+++ b/lib/public_key/doc/src/notes.xml
@@ -35,41 +35,6 @@
<file>notes.xml</file>
</header>
-<section><title>Public_Key 1.4.1</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Bug for <c>public_key:generate_key({namedCurve,OID})</c>
- fixed.</p>
- <p>
- Own Id: OTP-14258</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Modernized internal representation used for crl
- validation by use of maps.</p>
- <p>
- Own Id: OTP-14111</p>
- </item>
- <item>
- <p>
- Support EC key in pkix_sign/2</p>
- <p>
- Own Id: OTP-14294</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Public_Key 1.4</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index 83a77d2a28..b94768ae77 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1 +1 @@
-PUBLIC_KEY_VSN = 1.4.1
+PUBLIC_KEY_VSN = 1.4
diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml
index ff11a6ca11..b47d451055 100644
--- a/lib/reltool/doc/src/notes.xml
+++ b/lib/reltool/doc/src/notes.xml
@@ -38,24 +38,7 @@
thus constitutes one section in this document. The title of each
section is the version number of Reltool.</p>
- <section><title>Reltool 0.7.4</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p> The User's Guide examples are updated after removal
- of support for Dets files created with Erlang/OTP R7 and
- earlier. </p> <p>The examples are not correct, and will
- be updated before the release of Erlang/OTP 20.0.</p>
- <p>
- Own Id: OTP-14422 Aux Id: OTP-13830 </p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Reltool 0.7.3</title>
+ <section><title>Reltool 0.7.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/reltool/doc/src/reltool_examples.xml b/lib/reltool/doc/src/reltool_examples.xml
index 83eee6017a..49bde56964 100644
--- a/lib/reltool/doc/src/reltool_examples.xml
+++ b/lib/reltool/doc/src/reltool_examples.xml
@@ -41,30 +41,31 @@
<p>The main process in Reltool is the server. It can be used as it
is or be used via the GUI frontend process. When the GUI is
started, a server process will automatically be started. The GUI
- process is started with <c>reltool:start/0</c>,
- <c>reltool:start/1</c> or <c>reltool:start_link/1</c>. The pid of
- its server can be obtained with <c>reltool:get_server/1</c></p>
+ process is started with
+ <seealso marker="reltool#start-0"><c>reltool:start/0</c></seealso>,
+ <seealso marker="reltool#start-1"><c>reltool:start/1</c></seealso> or
+ <seealso marker="reltool#start_link-1"><c>reltool:start_link/1</c></seealso>.
+ The pid of its server can be obtained with
+ <seealso marker="reltool#start_link-1"><c>reltool:get_server/1</c></seealso>
+ </p>
<pre>
-Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4]
- [async-threads:0] [kernel-poll:false]
-
-Eshell V5.7.3 (abort with ^G)
+Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
+[hipe] [kernel-poll:false]
+Eshell V9.0 (abort with ^G)
+1&gt;
1&gt; {ok, Win} = reltool:start([]).
{ok,&lt;0.36.01&gt;}
-2&gt; {ok, Server} = reltool:get_server([]).
+2&gt; {ok, Server} = reltool:get_server(Win).
{ok,&lt;0.37.01&gt;}
3&gt; reltool:get_config(Server).
{ok,{sys,[]}}
-4&gt; reltool:stop(Win).
-ok
-
-
-5&gt; {ok, Server2} = reltool:start_server([]).
+4&gt;
+4&gt; {ok, Server2} = reltool:start_server([]).
{ok,&lt;0.6535.01&gt;}
-6&gt; reltool:get_config(Server2).
+5&gt; reltool:get_config(Server2).
{ok,{sys,[]}}
-7&gt; reltool:stop(Server2).
+6&gt; reltool:stop(Server2).
ok
</pre>
@@ -74,13 +75,11 @@ ok
<title>Inspecting the configuration</title>
<pre>
-Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4]
- [async-threads:0] [kernel-poll:false]
-
-Eshell V5.7.3 (abort with ^G)
-1&gt; Config = {sys, [{escript,
- "examples/display_args",
- [{incl_cond, include}]},
+Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
+[hipe] [kernel-poll:false]
+Eshell V9.0 (abort with ^G)
+1&gt;
+1&gt; Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
{app, inets, [{incl_cond, include}]},
{app, mnesia, [{incl_cond, exclude}]},
{app, ssl, [{incl_cond, exclude}]},
@@ -92,88 +91,105 @@ Eshell V5.7.3 (abort with ^G)
{app,ssl,[{incl_cond,exclude}]},
{app,runtime_tools,[{incl_cond,exclude}]},
{app,syntax_tools,[{incl_cond,exclude}]}]}
-
-
-
+2&gt;
2&gt; {ok, Server} = reltool:start_server([Config]).
-{ok,&lt;0.35.0&gt;}
+{ok,&lt;0.66.0&gt;}
+3&gt;
3&gt; reltool:get_config(Server).
-{ok,{sys,[{escript,"/clearcase/otp/tools/reltool/examples/display_args",
- [{incl_cond,include}]}]}}
+{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
+ [{incl_cond,include}]},
+ {app,inets,[{incl_cond,include}]},
+ {app,mnesia,[{incl_cond,exclude}]},
+ {app,runtime_tools,[{incl_cond,exclude}]},
+ {app,ssl,[{incl_cond,exclude}]},
+ {app,syntax_tools,[{incl_cond,exclude}]}]}}
+4&gt;
4&gt; reltool:get_config(Server, false, false).
-{ok,{sys,[{escript,"/clearcase/otp/tools/reltool/examples/display_args",
- [{incl_cond,include}]}]}}
-
-
-
+{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
+ [{incl_cond,include}]},
+ {app,inets,[{incl_cond,include}]},
+ {app,mnesia,[{incl_cond,exclude}]},
+ {app,runtime_tools,[{incl_cond,exclude}]},
+ {app,ssl,[{incl_cond,exclude}]},
+ {app,syntax_tools,[{incl_cond,exclude}]}]}}
+5&gt;
5&gt; reltool:get_config(Server, true, false).
-{ok,{sys,[{root_dir,"/ldisk/hakan/otp_test"},
+{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
{lib_dirs,[]},
- {escript,"/clearcase/otp/tools/reltool/examples/display_args",
+ {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
[{incl_cond,include}]},
{mod_cond,all},
{incl_cond,derived},
+ {app,inets,
+ [{incl_cond,include},{vsn,undefined},{lib_dir,undefined}]},
+ {app,mnesia,[{incl_cond,exclude}]},
+ {app,runtime_tools,[{incl_cond,exclude}]},
+ {app,ssl,[{incl_cond,exclude}]},
+ {app,syntax_tools,[{incl_cond,exclude}]},
{boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
{emu_name,"beam"},
{relocatable,true},
{profile,development},
- {incl_sys_files,[".*"]},
- {excl_sys_files,[]},
- {incl_app_files,[".*"]},
- {excl_app_files,[]},
- {incl_archive_dirs,[".*"]},
- {excl_archive_dirs,["^include$","^priv$"]},
+ {incl_sys_filters,[".*"]},
+ {excl_sys_filters,[]},
+ {incl_app_filters,[".*"]},
+ {excl_app_filters,[]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,[[...]|...]},
{archive_opts,[]},
- {app_type,permanent},
- {app_file,keep},
- {debug_info,keep}]}}
-
-
-
+ {rel_app_type,...},
+ {...}|...]}}
+6&gt;
6&gt; reltool:get_config(Server, true, true).
-{ok,{sys,[{root_dir,"/ldisk/hakan/otp_test"},
+{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
{lib_dirs,[]},
- {escript,"/clearcase/otp/tools/reltool/examples/display_args",
+ {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
[{incl_cond,include}]},
{mod_cond,all},
{incl_cond,derived},
- {erts,[{vsn,"5.7.3"},
- {mod,erl_prim_loader,[]},
- {mod,erlang,[]},
- {mod,init,[]},
- {mod,otp_ring0,[]},
- {mod,prim_file,[]},
- {mod,prim_inet,[]},
- {mod,prim_zip,[]},
- {mod,zlib,[]}]},
+ {erts,[{app,erts,
+ [{vsn,"9.0"},
+ {lib_dir,"/usr/local/lib/erlang/lib/erts-9.0"},
+ {mod,erl_prim_loader,[]},
+ {mod,erl_tracer,[]},
+ {mod,erlang,[]},
+ {mod,erts_code_purger,[]},
+ {mod,erts_dirty_process_code_checker,[]},
+ {mod,erts_internal,[]},
+ {mod,erts_literal_area_collector,[]},
+ {mod,init,[]},
+ {mod,otp_ring0,...},
+ {mod,...},
+ {...}|...]}]},
{app,compiler,
- [{vsn,"4.6.3"},
+ [{vsn,"7.0.4"},
+ {lib_dir,"/usr/local/lib/erlang/lib/compiler-7.0.4"},
+ {mod,beam_a,[]},
{mod,beam_asm,[]},
{mod,beam_block,[]},
- {mod,beam_bool,[]},
+ {mod,beam_bs,[]},
{mod,beam_bsm,[]},
{mod,beam_clean,[]},
{mod,beam_dead,[]},
{mod,beam_dict,[]},
{mod,beam_disasm,[]},
- {mod,beam_flatten,[]},
- {mod,beam_jump,[]},
- {mod,beam_listing,[]},
- {mod,beam_opcodes,...},
+ {mod,beam_except,[]},
+ {mod,beam_flatten,...},
{mod,...},
{...}|...]},
{app,crypto,
- [{vsn,"1.6.1"},
+ [{vsn,"3.7.4"},
+ {lib_dir,"/usr/local/lib/erlang/lib/crypto-3.7.4"},
{mod,crypto,[]},
- {mod,crypto_app,[]},
- {mod,crypto_server,[]},
- {mod,crypto_sup,[]}]},
+ {mod,crypto_ec_curves,[]}]},
{app,hipe,
- [{vsn,"3.7.3"},
+ [{vsn,"3.15.4"},
+ {lib_dir,"/usr/local/lib/erlang/lib/hipe-3.15.4"},
{mod,cerl_cconv,[]},
{mod,cerl_closurean,[]},
{mod,cerl_hipeify,[]},
- {mod,cerl_hybrid_transform,[]},
{mod,cerl_lib,[]},
{mod,cerl_messagean,[]},
{mod,cerl_pmatch,[]},
@@ -182,65 +198,110 @@ Eshell V5.7.3 (abort with ^G)
{mod,cerl_typean,...},
{mod,...},
{...}|...]},
+ {app,inets,
+ [{incl_cond,include},
+ {vsn,"6.3.9"},
+ {lib_dir,"/usr/local/lib/erlang/lib/inets-6.3.9"},
+ {mod,ftp,[]},
+ {mod,ftp_progress,[]},
+ {mod,ftp_response,[]},
+ {mod,ftp_sup,[]},
+ {mod,http_chunk,[]},
+ {mod,http_request,[]},
+ {mod,http_response,...},
+ {mod,...},
+ {...}|...]},
{app,kernel,
- [{vsn,"2.13.3"},
+ [{vsn,"5.2"},
+ {lib_dir,"/usr/local/lib/erlang/lib/kernel-5.2"},
{mod,application,[]},
{mod,application_controller,[]},
{mod,application_master,[]},
{mod,application_starter,[]},
{mod,auth,[]},
{mod,code,[]},
- {mod,code_server,[]},
- {mod,disk_log,[]},
- {mod,disk_log_1,...},
+ {mod,code_server,...},
+ {mod,...},
+ {...}|...]},
+ {app,mnesia,[{incl_cond,exclude}]},
+ {app,runtime_tools,[{incl_cond,exclude}]},
+ {app,sasl,
+ [{vsn,"3.0.3"},
+ {lib_dir,"/usr/local/lib/erlang/lib/sasl-3.0.3"},
+ {mod,alarm_handler,[]},
+ {mod,erlsrv,[]},
+ {mod,format_lib_supp,[]},
+ {mod,misc_supp,...},
{mod,...},
{...}|...]},
+ {app,ssl,[{incl_cond,exclude}]},
{app,stdlib,
- [{vsn,"1.16.3"},
+ [{vsn,"3.3"},
+ {lib_dir,"/usr/local/lib/erlang/lib/stdlib-3.3"},
{mod,array,[]},
- {mod,base64,[]},
- {mod,beam_lib,[]},
- {mod,c,[]},
- {mod,calendar,[]},
- {mod,dets,[]},
- {mod,dets_server,[]},
- {mod,dets_sup,...},
+ {mod,base64,...},
{mod,...},
{...}|...]},
+ {app,syntax_tools,[{incl_cond,exclude}]},
+ {app,tools,
+ [{vsn,"2.9.1"},{lib_dir,[...]},{mod,...},{...}|...]},
{boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[...]},
{emu_name,"beam"},
{relocatable,true},
- {profile,development},
- {incl_sys_files,[".*"]},
- {excl_sys_files,[]},
- {incl_app_files,[".*"]},
- {excl_app_files,[]},
- {incl_archive_dirs,[".*"]},
- {excl_archive_dirs,["^include$",[...]]},
- {archive_opts,[]},
- {app_type,permanent},
- {app_file,...},
- {...}]}}
-
-
-
-7&gt; reltool:get_config([{sys,[{profile, embedded}]}]).
-{ok,{sys,[{profile,embedded},
+ {profile,...},
+ {...}|...]}}
+7&gt;
+7&gt; reltool:get_config([{sys, [{profile, embedded}]}], true, false).
+{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
+ {lib_dirs,[]},
+ {mod_cond,all},
+ {incl_cond,derived},
+ {boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
+ {emu_name,"beam"},
+ {relocatable,true},
+ {profile,embedded},
{incl_sys_filters,["^bin","^erts","^lib","^releases"]},
{excl_sys_filters,["^bin/(erlc|dialyzer|typer)(|\\.exe)$",
"^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$",
"^erts.*/bin/.*(debug|pdb)"]},
- {incl_app_filters,["^ebin","^include","^priv"]}]}}
-8&gt; reltool:get_config([{sys,[{profile, standalone}]}]).
-{ok,{sys,[{profile,standalone},
+ {incl_app_filters,["^ebin","^include","^priv"]},
+ {excl_app_filters,[]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,["^include$","^priv$"]},
+ {archive_opts,[]},
+ {rel_app_type,permanent},
+ {embedded_app_type,load},
+ {app_file,keep},
+ {debug_info,keep}]}}
+8&gt;
+8&gt; reltool:get_config([{sys, [{profile, standalone}]}], true, false).
+{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
+ {lib_dirs,[]},
+ {mod_cond,all},
+ {incl_cond,derived},
+ {boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
+ {emu_name,"beam"},
+ {relocatable,true},
+ {profile,standalone},
{incl_sys_filters,["^bin/(erl|epmd)(|\\.exe|\\.ini)$",
"^bin/start(|_clean).boot$","^erts.*/bin","^lib$"]},
{excl_sys_filters,["^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$",
"^erts.*/bin/(start|escript|to_erl|run_erl)(|\\.exe)$",
"^erts.*/bin/.*(debug|pdb)"]},
{incl_app_filters,["^ebin","^priv"]},
- {excl_app_filters,["^ebin/.*\\.appup$"]}]}}
-
+ {excl_app_filters,["^ebin/.*\\.appup$"]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,["^include$","^priv$"]},
+ {archive_opts,[]},
+ {rel_app_type,permanent},
+ {app_file,keep},
+ {debug_info,keep}]}}
</pre>
</section>
@@ -248,43 +309,51 @@ Eshell V5.7.3 (abort with ^G)
<section>
<title>Generate release and script files</title>
<pre>
-5&gt; {ok, Server} = reltool:start_server([{config, {sys, [{boot_rel, "NAME"},
+Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
+[hipe] [kernel-poll:false]
+Eshell V9.0 (abort with ^G)
+1&gt;
+1&gt; {ok, Server} = reltool:start_server([{config, {sys, [{boot_rel, "NAME"},
{rel, "NAME", "VSN",
[sasl]}]}}]).
{ok,&lt;0.1288.0&gt;}
-6&gt; reltool:get_config(Server).
+2&gt;
+2&gt; reltool:get_config(Server).
{ok,{sys,[{boot_rel,"NAME"},
{rel,"NAME","VSN",[sasl]}]}}
-7&gt; reltool:get_rel(Server, "NAME").
+3&gt;
+3&gt; reltool:get_rel(Server, "NAME").
{ok,{release,{"NAME","VSN"},
- {erts,"5.7"},
- [{kernel,"2.13"},{stdlib,"1.16"},{sasl,"2.1.6"}]}}
-8&gt; reltool:get_script(Server, "NAME").
+ {erts,"9.0"},
+ [{kernel,"5.2"},{stdlib,"3.3"},{sasl,"3.0.3"}]}}
+4&gt;
+4&gt; reltool:get_script(Server, "NAME").
{ok,{script,{"NAME","VSN"},
- [{preLoaded,[erl_prim_loader,erlang,init,otp_ring0,
- prim_eval,prim_file,prim_inet,prim_zip,
- zlib]},
+ [{preLoaded,[erl_prim_loader,erl_tracer,erlang,
+ erts_code_purger,erts_dirty_process_code_checker,
+ erts_internal,erts_literal_area_collector,init,otp_ring0,
+ prim_eval,prim_file,prim_inet,prim_zip,zlib]},
{progress,preloaded},
- {path,["$ROOT/lib/kernel-2.13/ebin",
- "$ROOT/lib/stdlib-1.16/ebin"]},
+ {path,["$ROOT/lib/kernel-5.2/ebin",
+ "$ROOT/lib/stdlib-3.3/ebin"]},
{primLoad,[error_handler]},
{kernel_load_completed},
{progress,kernel_load_completed},
- {path,["$ROOT/lib/kernel-2.13/ebin"]},
+ {path,["$ROOT/lib/kernel-5.2/ebin"]},
{primLoad,[application,application_controller,
application_master,application_starter,auth,code,
code_server,disk_log,disk_log_1,disk_log_server,
disk_log_sup,dist_ac,dist_util,erl_boot_server|...]},
- {path,["$ROOT/lib/stdlib-1.16/ebin"]},
- {primLoad,[array,base64,beam_lib,c,calendar,dets,
+ {path,["$ROOT/lib/stdlib-3.3/ebin"]},
+ {primLoad,[array,base64,beam_lib,binary,c,calendar,dets,
dets_server,dets_sup,dets_utils,dets_v9,dict|...]},
- {path,["$ROOT/lib/sasl-2.1.6/ebin"]},
+ {path,["$ROOT/lib/sasl-3.0.3/ebin"]},
{primLoad,[alarm_handler,erlsrv,format_lib_supp,misc_supp,
- overload,rb,rb_format_supp,release_handler,
- release_handler_1,sasl|...]},
+ rb,rb_format_supp,release_handler,release_handler_1,sasl,
+ sasl_report|...]},
{progress,modules_loaded},
- {path,["$ROOT/lib/kernel-2.13/ebin",
- "$ROOT/lib/stdlib-1.16/ebin","$ROOT/lib/sasl-2.1.6/ebin"]},
+ {path,["$ROOT/lib/kernel-5.2/ebin",
+ "$ROOT/lib/stdlib-3.3/ebin","$ROOT/lib/sasl-3.0.3/ebin"]},
{kernelProcess,heart,{heart,start,[]}},
{kernelProcess,error_logger,{error_logger,start_link,[]}},
{kernelProcess,application_controller,
@@ -296,7 +365,8 @@ Eshell V5.7.3 (abort with ^G)
{apply,{...}},
{apply,...},
{...}|...]}}
-9&gt; reltool:stop(Server).
+5&gt;
+5&gt; reltool:stop(Server).
ok
</pre>
</section>
@@ -304,13 +374,11 @@ ok
<section>
<title>Create a target system</title>
<pre>
-Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4]
- [async-threads:0] [kernel-poll:false]
-
-Eshell V5.7.3 (abort with ^G)
-1&gt; Config = {sys, [{escript,
- "examples/display_args",
- [{incl_cond, include}]},
+Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
+[hipe] [kernel-poll:false]
+Eshell V9.0 (abort with ^G)
+1&gt;
+1&gt; Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
{app, inets, [{incl_cond, include}]},
{app, mnesia, [{incl_cond, exclude}]},
{app, ssl, [{incl_cond, exclude}]},
@@ -322,156 +390,183 @@ Eshell V5.7.3 (abort with ^G)
{app,ssl,[{incl_cond,exclude}]},
{app,runtime_tools,[{incl_cond,exclude}]},
{app,syntax_tools,[{incl_cond,exclude}]}]}
-
-
-
+2&gt;
2&gt; {ok, Spec} = reltool:get_target_spec([Config]).
{ok,[{create_dir,"releases",
- [{write_file,"start_erl.data","5.7.3 1.0"},
- {create_dir,"1.0",
- [{write_file,"start_clean.rel",
- [37,37,32,114,101,108,32,103,101,110,101|...]},
- {write_file,"start_clean.script",
- [37,37,32,115,99,114,105,112,116,32|...]},
- {write_file,"start_clean.boot",
- &lt;&lt;131,104,3,100,0,6,115,99,114,...&gt;&gt;},
- {write_file,"start_sasl.rel",
- [37,37,32,114,101,108,32,103,101,110,101|...]},
- {write_file,"start_sasl.script",
- [37,37,32,115,99,114,105,112,116,32|...]},
- {write_file,"start_sasl.boot",
- &lt;&lt;131,104,3,100,0,6,115,99,114,...&gt;&gt;}]}]},
+ [{write_file,"start_erl.data","9.0 1.0\n"},
+ {create_dir,"1.0",
+ [{write_file,"start_clean.rel",
+ [37,37,32,114,101,108,32,103,101,110,101,114,97,116|...]},
+ {write_file,"start_clean.script",
+ [37,37,32,115,99,114,105,112,116,32,103,101,110|...]},
+ {write_file,"start_clean.boot",
+ &lt;&lt;131,104,3,119,6,115,99,114,105,112,116,104,...&gt;&gt;},
+ {write_file,"start_sasl.rel",
+ [37,37,32,114,101,108,32,103,101,110,101|...]},
+ {write_file,"start_sasl.script",
+ [37,37,32,115,99,114,105,112,116,32|...]},
+ {write_file,"start_sasl.boot",
+ &lt;&lt;131,104,3,119,6,115,99,114,105,...&gt;&gt;}]}]},
{create_dir,"bin",
- [{copy_file,"display_args.escript",
- "/clearcase/otp/tools/reltool/examples/display_args"},
- {copy_file,"display_args","erts-5.7.3/bin/escript"},
- {copy_file,"start","erts-5.7.3/bin/start"},
- {copy_file,"erl","erts-5.7.3/bin/dyn_erl"},
- {copy_file,"epmd","erts-5.7.3/bin/epmd"},
- {copy_file,"to_erl","erts-5.7.3/bin/to_erl"},
- {copy_file,"run_erl","erts-5.7.3/bin/run_erl"},
- {copy_file,"escript","erts-5.7.3/bin/escript"},
- {copy_file,"erlc","erts-5.7.3/bin/erlc"},
- {copy_file,"dialyzer","erts-5.7.3/bin/dialyzer"},
- {copy_file,"typer","erts-5.7.3/bin/typer"},
- {write_file,"start_clean.boot",
- &lt;&lt;131,104,3,100,0,6,115,...&gt;&gt;},
- {write_file,"start_sasl.boot",&lt;&lt;131,104,3,100,0,6,...&gt;&gt;},
- {write_file,"start.boot",&lt;&lt;131,104,3,100,0,...&gt;&gt;}]},
- {create_dir,"misc",
- [{copy_file,"makewhatis"},{copy_file,"format_man_pages"}]},
+ [{copy_file,"display_args.escript",
+ "/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args"},
+ {copy_file,"display_args","erts-9.0/bin/escript"},
+ {copy_file,"start","erts-9.0/bin/start"},
+ {copy_file,"ct_run","erts-9.0/bin/ct_run"},
+ {copy_file,"dialyzer","erts-9.0/bin/dialyzer"},
+ {copy_file,"run_erl","erts-9.0/bin/run_erl"},
+ {copy_file,"erl","erts-9.0/bin/dyn_erl"},
+ {copy_file,"to_erl","erts-9.0/bin/to_erl"},
+ {copy_file,"epmd","erts-9.0/bin/epmd"},
+ {copy_file,"erlc","erts-9.0/bin/erlc"},
+ {copy_file,"typer","erts-9.0/bin/typer"},
+ {copy_file,"escript","erts-9.0/bin/escript"},
+ {write_file,"start_clean.boot",&lt;&lt;131,104,3,119,6,115,...&gt;&gt;},
+ {write_file,"start_sasl.boot",&lt;&lt;131,104,3,119,6,...&gt;&gt;},
+ {write_file,"start.boot",&lt;&lt;131,104,3,119,...&gt;&gt;}]},
{copy_file,"Install"},
+ {create_dir,"misc",
+ [{copy_file,"makewhatis"},{copy_file,"format_man_pages"}]},
{create_dir,"usr",
- [{create_dir,"lib",
- [{copy_file,"liberts_r.a"},{copy_file,"liberts.a"}]},
- {create_dir,"include",
- [{copy_file,"erl_fixed_size_int_types.h"},
- {copy_file,"erl_int_sizes_config.h"},
- {copy_file,"erl_memory_trace_parser.h"},
- {create_dir,"obsolete",[{copy_file,"driver.h"}]},
- {copy_file,"driver_int.h"},
- {copy_file,"erl_driver.h"}]}]},
- {create_dir,"erts-5.7.3",
- [{create_dir,"lib",
- [{create_dir,"internal",
- [{copy_file,"liberts_internal_r.a"},
- {copy_file,"liberts_internal.a"},
- {copy_file,"libethread.a"},
- {copy_file,"README"}]},
- {copy_file,"liberts_r.a"},
- {copy_file,"liberts.a"}]},
- {create_dir,"bin",
- [{copy_file,"start"},
- {copy_file,"erl","erts-5.7.3/bin/dyn_erl"},
- {copy_file,"epmd"},
- {copy_file,"to_erl"},
- {copy_file,"run_erl"},
- {copy_file,"escript"},
- {copy_file,"erlc"},
- {copy_file,"dialyzer"},
- {copy_file,"typer"},
- {copy_file,"erlexec"},
- {copy_file,[...]},
- {copy_file,...},
- {...}|...]},
- {create_dir,"doc",[]},
- {create_dir,"man",[]},
- {create_dir,"include",
- [{create_dir,"internal",
- [{create_dir,"tile",[{copy_file,...},{...}]},
- {create_dir,"sparc64",[{...}]},
- {create_dir,"sparc32",[...]},
- {create_dir,[...],...},
- {create_dir,...},
- {...}|...]},
- {copy_file,"erl_fixed_size_int_types.h"},
- {copy_file,"erl_int_sizes_config.h"},
- {copy_file,"erl_memory_trace_parser.h"},
- {copy_file,"driver_int.h"},
- {copy_file,"erl_driver.h"}]},
- {create_dir,"src",[{copy_file,"setuid_socket_wrap.c"}]}]},
+ [{create_dir,"lib",
+ [{copy_file,"liberts.a"},
+ {copy_file,"liberl_interface_st.a"},
+ {copy_file,"liberts_r.a"},
+ {copy_file,"libic.a"},
+ {copy_file,"liberl_interface.a"},
+ {copy_file,"libei_st.a"},
+ {copy_file,"libei.a"}]},
+ {create_dir,"include",
+ [{copy_file,"erl_memory_trace_parser.h"},
+ {copy_file,"driver_int.h"},
+ {copy_file,"ei_connect.h"},
+ {copy_file,"ei.h"},
+ {copy_file,"erl_nif_api_funcs.h"},
+ {copy_file,"erl_fixed_size_int_types.h"},
+ {copy_file,"erl_int_sizes_config.h"},
+ {copy_file,"erl_interface.h"},
+ {copy_file,"eicode.h"},
+ {copy_file,"erl_driver.h"},
+ {copy_file,"erlang.idl"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}]}]},
+ {create_dir,"erts-9.0",
+ [{create_dir,"bin",
+ [{copy_file,"start"},
+ {copy_file,"ct_run"},
+ {copy_file,"erlexec"},
+ {copy_file,"dialyzer"},
+ {copy_file,"beam.smp"},
+ {copy_file,"run_erl"},
+ {copy_file,"erl","erts-9.0/bin/dyn_erl"},
+ {copy_file,"to_erl"},
+ {copy_file,"epmd"},
+ {copy_file,"erl_child_setup"},
+ {copy_file,"heart"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}|...]},
+ {create_dir,"lib",
+ [{create_dir,"internal",
+ [{copy_file,"liberts_internal.a"},
+ {copy_file,"liberts_internal_r.a"},
+ {copy_file,"libethread.a"},
+ {copy_file,"README"}]},
+ {copy_file,"liberts.a"},
+ {copy_file,"liberts_r.a"}]},
+ {create_dir,"src",[{copy_file,"setuid_socket_wrap.c"}]},
+ {create_dir,"doc",[]},
+ {create_dir,"man",[]},
+ {create_dir,"include",
+ [{create_dir,"internal",
+ [{create_dir,"i386",[{...}|...]},
+ {copy_file,"erl_errno.h"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}|...]},
+ {copy_file,"erl_memory_trace_parser.h"},
+ {copy_file,"driver_int.h"},
+ {copy_file,"erl_nif_api_funcs.h"},
+ {copy_file,"erl_fixed_size_int_types.h"},
+ {copy_file,"erl_int_sizes_config.h"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}]}]},
{create_dir,"lib",
- [{archive,"compiler-4.6.3.ez",[],
- [{create_dir,"compiler-4.6.3",
- [{create_dir,"ebin",
- [{copy_file,"compiler.appup"},
- {copy_file,[...]},
- {copy_file,...},
- {...}|...]},
- {create_dir,"src",
- [{copy_file,[...]},
- {copy_file,...},{...}|...]}]}]},
- {archive,"crypto-1.6.1.ez",[],
- [{create_dir,"crypto-1.6.1",
- [{create_dir,"ebin",
- [{copy_file,[...]},
- {copy_file,...},{...}|...]},
- {create_dir,"src",[{copy_file,...},{...}|...]}]}]},
- {create_dir,"crypto-1.6.1",
- [{create_dir,"priv",
- [{create_dir,"lib",[{copy_file,[...]}]},
- {create_dir,"obj",[{copy_file,...},{...}]}]}]},
- {archive,"erts-5.7.3.ez",[],
- [{create_dir,"erts-5.7.3",
- [{create_dir,"ebin",[{...}|...]},
- {create_dir,"src",[...]}]}]},
- {archive,"hipe-3.7.3.ez",[],
- [{create_dir,"hipe-3.7.3",
- [{create_dir,"util",[...]},
- {create_dir,[...],...},
- {create_dir,...},
- {...}|...]}]},
- {archive,"kernel-2.13.3.ez",[],
- [{create_dir,"kernel-2.13.3",
- [{create_dir,[...],...},{create_dir,...},{...}]}]},
- {create_dir,"kernel-2.13.3",
- [{create_dir,"include",
- [{copy_file,[...]},{copy_file,...},{...}]}]},
- {archive,"stdlib-1.16.3.ez",[],
- [{create_dir,"stdlib-1.16.3",[{...}|...]}]},
- {create_dir,"stdlib-1.16.3",
- [{create_dir,"include",[{...}|...]}]}]}]}
-
-
-
-3&gt; TargetDir = "my_target_dir".
-"my_target_dir"
+ [{archive,"compiler-7.0.4.ez",[],
+ [{create_dir,"compiler-7.0.4",
+ [{create_dir,"src",
+ [{copy_file,"beam_flatten.erl"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}|...]},
+ {create_dir,"ebin",
+ [{copy_file,[...]},{copy_file,...},{...}|...]}]}]},
+ {archive,"crypto-3.7.4.ez",[],
+ [{create_dir,"crypto-3.7.4",
+ [{create_dir,"src",[{copy_file,[...]},{copy_file,...}]},
+ {create_dir,"ebin",[{copy_file,...},{...}|...]}]}]},
+ {create_dir,"crypto-3.7.4",
+ [{create_dir,"priv",
+ [{create_dir,"lib",[{copy_file,[...]},{copy_file,...}]},
+ {create_dir,"obj",[{copy_file,...},{...}|...]}]}]},
+ {archive,"erts-9.0.ez",[],
+ [{create_dir,"erts-9.0",
+ [{create_dir,"src",[{...}|...]},
+ {create_dir,"ebin",[...]}]}]},
+ {archive,"hipe-3.15.4.ez",[],
+ [{create_dir,"hipe-3.15.4",
+ [{create_dir,"flow",[...]},
+ {copy_file,[...]},
+ {create_dir,...},
+ {...}|...]}]},
+ {archive,"inets-6.3.9.ez",[],
+ [{create_dir,"inets-6.3.9",
+ [{create_dir,[...],...},{create_dir,...},{...}]}]},
+ {create_dir,"inets-6.3.9",
+ [{create_dir,"priv",[{create_dir,[...],...}]},
+ {create_dir,"include",[{copy_file,...},{...}]}]},
+ {archive,"kernel-5.2.ez",[],
+ [{create_dir,"kernel-5.2",[{...}|...]}]},
+ {create_dir,"kernel-5.2",
+ [{create_dir,"include",[{...}|...]}]},
+ {archive,"sasl-3.0.3.ez",[],[{create_dir,[...],...}]},
+ {archive,"stdlib-3.3.ez",[],[{create_dir,...}]},
+ {create_dir,"stdlib-3.3",[{create_dir,...}]},
+ {archive,"tools-2.9.1.ez",[],[...]}]}]}
+3&gt;
+3&gt; TargetDir = "/tmp/my_target_dir".
+"/tmp/my_target_dir"
+4&gt;
4&gt; reltool:eval_target_spec(Spec, code:root_dir(), TargetDir).
-{error,"/clearcase/otp/tools/reltool/my_target_dir: no such file or directory"}
-5&gt; file:make_dir("my_target_dir").
+{error,"/tmp/my_target_dir: no such file or directory"}
+5&gt;
+5&gt; file:make_dir(TargetDir).
ok
+6&gt;
6&gt; reltool:eval_target_spec(Spec, code:root_dir(), TargetDir).
ok
+7&gt;
7&gt; file:list_dir(TargetDir).
-{ok,["lib","erts-5.7.3","usr","Install","misc","bin","releases"]}
+{ok,["bin","Install","lib","misc","usr","erts-9.0",
+ "releases"]}
+8&gt;
8&gt; file:list_dir(filename:join([TargetDir,"lib"])).
-{ok,["stdlib-1.16.3","stdlib-1.16.3.ez","kernel-2.13.3",
- "kernel-2.13.3.ez","hipe-3.7.3.ez","erts-5.7.3.ez",
- "crypto-1.6.1","crypto-1.6.1.ez","compiler-4.6.3.ez"]}
-9&gt; file:make_dir("yet_another_target_dir").
+{ok,["tools-2.9.1.ez","kernel-5.2.ez","inets-6.3.9.ez",
+ "kernel-5.2","sasl-3.0.3.ez","hipe-3.15.4.ez","inets-6.3.9",
+ "crypto-3.7.4","crypto-3.7.4.ez","stdlib-3.3.ez",
+ "erts-9.0.ez","stdlib-3.3","compiler-7.0.4.ez"]}
+9&gt;
+9&gt; file:make_dir("/tmp/yet_another_target_dir").
ok
-10&gt; reltool:create_target(Config, "yet_another_target_dir").
+10&gt;
+10&gt; reltool:create_target([Config], "/tmp/yet_another_target_dir").
ok
+11&gt;
+11&gt; file:list_dir("/tmp/yet_another_target_dir").
+{ok,["bin","Install","lib","misc","usr","erts-9.0",
+ "releases"]}
</pre>
</section>
diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk
index 3617f6e0d9..2d07eeb8f0 100644
--- a/lib/reltool/vsn.mk
+++ b/lib/reltool/vsn.mk
@@ -1 +1 @@
-RELTOOL_VSN = 0.7.4
+RELTOOL_VSN = 0.7.3
diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml
index 388fa54fa8..49615cf077 100644
--- a/lib/runtime_tools/doc/src/notes.xml
+++ b/lib/runtime_tools/doc/src/notes.xml
@@ -32,41 +32,6 @@
<p>This document describes the changes made to the Runtime_Tools
application.</p>
-<section><title>Runtime_Tools 1.12</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Add compile option <c>-compile(no_native)</c> in modules
- with <c>on_load</c> directive which is not yet supported
- by HiPE.</p>
- <p>
- Own Id: OTP-14316 Aux Id: PR-1390 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p> Sockets can now be bound to device (SO_BINDTODEVICE)
- on platforms where it is supported. </p> <p> This has
- been implemented e.g to support VRF-Lite under Linux; see
- <url
- href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">
- VRF </url>, and GitHub pull request <url
- href="https://github.com/erlang/otp/pull/1326">#1326</url>.
- </p>
- <p>
- Own Id: OTP-14357 Aux Id: PR-1326 </p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Runtime_Tools 1.11.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk
index 5ee39a25fe..8ec532de76 100644
--- a/lib/runtime_tools/vsn.mk
+++ b/lib/runtime_tools/vsn.mk
@@ -1 +1 @@
-RUNTIME_TOOLS_VSN = 1.12
+RUNTIME_TOOLS_VSN = 1.11.1
diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml
index 03b8a333a9..8684151b3a 100644
--- a/lib/sasl/doc/src/notes.xml
+++ b/lib/sasl/doc/src/notes.xml
@@ -31,23 +31,6 @@
</header>
<p>This document describes the changes made to the SASL application.</p>
-<section><title>SASL 3.0.4</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Documented default values for the 'mod' and
- 'start_phases' fields in .app files were not allowed as
- actual values in a .app file. This is now corrected.</p>
- <p>
- Own Id: OTP-14029</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>SASL 3.0.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk
index 2608ca5e00..6aa662a743 100644
--- a/lib/sasl/vsn.mk
+++ b/lib/sasl/vsn.mk
@@ -1 +1 @@
-SASL_VSN = 3.0.4
+SASL_VSN = 3.0.3
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 1cc76904e7..f1919a6bb1 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -34,24 +34,7 @@
</header>
- <section><title>SNMP 5.2.6</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>Internal code change: Calls to <c>catch</c> followed
- by a call to <c>erlang:get_stacktrace/0</c> has been
- rewritten to use <c>try</c> instead of <c>catch</c> to
- make the code future-proof.</p>
- <p>
- Own Id: OTP-14400</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>SNMP 5.2.5</title>
+ <section><title>SNMP 5.2.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index d41b1999cc..30b8ee1124 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -19,6 +19,6 @@
# %CopyrightEnd%
APPLICATION = snmp
-SNMP_VSN = 5.2.6
+SNMP_VSN = 5.2.5
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)"
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index f6b6f53d33..bddae00dd2 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -30,169 +30,6 @@
<file>notes.xml</file>
</header>
-<section><title>Ssh 4.5</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- The internal handling of SSH options is re-written.</p>
- <p>
- Previously there were no checks if a client option was
- given to a daemon or vice versa. This is corrected now.
- If your code has e.g. a client-only option in a call to
- start a daemon, the call will fail.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-12872</p>
- </item>
- <item>
- <p>
- Modernization of key exchange algorithms. See
- draft-ietf-curdle-ssh-kex-sha2 for a discussion.</p>
- <p>
- Removed an outdated weak algorithm and added stronger
- replacements to keep interoperability with other modern
- ssh clients and servers. The default ordering of the
- algorithms is also adjusted.</p>
- <p>
- Retired: The nowadays unsecure key-exchange
- <c>diffie-hellman-group1-sha1</c> is not enabled by
- default, but can be enabled with the option
- <c>preferred-algorithms</c>.</p>
- <p>
- Added: The new stronger key-exchange
- <c>diffie-hellman-group16-sha512</c>,
- <c>diffie-hellman-group18-sha512</c> and
- <c>diffie-hellman-group14-sha256</c> are added and
- enabled by default.</p>
- <p>
- The questionable [RFC 6194] sha1-based algorithms
- <c>diffie-hellman-group-exchange-sha1</c> and
- <c>diffie-hellman-group14-sha1</c> are however still kept
- enabled by default for compatibility with ancient clients
- and servers that lack modern key-exchange alternatives.
- When the draft-ietf-curdle-ssh-kex-sha2 becomes an rfc,
- those sha1-based algorithms and
- <c>diffie-hellman-group1-sha1</c> will be deprecated by
- IETF. They might then be removed from the default list in
- Erlang/OTP.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14110</p>
- </item>
- <item>
- <p>
- Modernized internal representation of sftp by use of
- maps.</p>
- <p>
- Own Id: OTP-14117</p>
- </item>
- <item>
- <p>
- The Extension Negotiation Mechanism and the extension
- <c>server-sig-algs</c> in
- draft-ietf-curdle-ssh-ext-info-05 are implemented.</p>
- <p>
- The related draft-ietf-curdle-rsa-sha2-05 is implemented
- and introduces the signature algorithms
- <c>rsa-sha2-256</c> and <c>rsa-sha2-512</c>.</p>
- <p>
- Own Id: OTP-14193</p>
- </item>
- <item>
- <p>
- The functions <c>ssh:connect</c>, <c>ssh:shell</c> and
- <c>ssh:start_channel</c> now accept an IP-tuple as Host
- destination argument.</p>
- <p>
- Own Id: OTP-14243</p>
- </item>
- <item>
- <p>
- The function <c>ssh:daemon_info/1</c> now returns Host
- and Profile as well as the Port info in the property
- list.</p>
- <p>
- Own Id: OTP-14259</p>
- </item>
- <item>
- <p>
- Removed the option <c>public_key_alg</c> which was
- deprecated in 18.2. Use <c>pref_public_key_algs</c>
- instead.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14263</p>
- </item>
- <item>
- <p>
- The SSH application is refactored regarding daemon
- starting. The resolution of contradicting <c>Host</c>
- argument and <c>ip</c> option were not described. There
- were also strange corner cases when the <c>'any'</c>
- value was used in <c>Host</c> argument or <c>ip</c>
- option. This is (hopefully) resolved now, but it may
- cause incompatibilities for code using both <c>Host</c>
- and the <c>ip</c> option. The value 'loopback' has been
- added for a correct way of naming those addresses.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14264</p>
- </item>
- <item>
- <p>
- The supervisor code is refactored. The naming of
- listening IP-Port-Profile triples are slightly changed to
- improve consistency in strange corner cases as resolved
- by OTP-14264</p>
- <p>
- Own Id: OTP-14267 Aux Id: OTP-14266 </p>
- </item>
- <item>
- <p>
- The <c>idle_time</c> option can now be used in daemons.</p>
- <p>
- Own Id: OTP-14312</p>
- </item>
- <item>
- <p>
- Added test cases for IETF-CURDLE Extension Negotiation
- (ext-info)</p>
- <p>
- Own Id: OTP-14361</p>
- </item>
- <item>
- <p>
- Testcases for IETF-CURDLE extension
- <c>server-sig-algs</c> including <c>rsa-sha2-*</c></p>
- <p>
- Own Id: OTP-14362 Aux Id: OTP-14361 </p>
- </item>
- <item>
- <p>
- The option <c>auth_methods</c> can now also be used in
- clients to select which authentication options that are
- used and in which order.</p>
- <p>
- Own Id: OTP-14399</p>
- </item>
- <item>
- <p>
- Checks that a ECDSA public key (<c>ecdsa-sha2-nistp*</c>)
- stored in a file has the correct size.</p>
- <p>
- Own Id: OTP-14410</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Ssh 4.4.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index 6cf659f830..ac64a7bf14 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -28,7 +28,8 @@
-include("ssh_auth.hrl").
-include("ssh_transport.hrl").
--export([publickey_msg/1, password_msg/1, keyboard_interactive_msg/1,
+-export([get_public_key/2,
+ publickey_msg/1, password_msg/1, keyboard_interactive_msg/1,
service_request_msg/1, init_userauth_request_msg/1,
userauth_request_msg/1, handle_userauth_request/3,
handle_userauth_info_request/2, handle_userauth_info_response/2
@@ -136,41 +137,49 @@ keyboard_interactive_msg([#ssh{user = User,
Ssh)
end.
-publickey_msg([SigAlg, #ssh{user = User,
- session_id = SessionId,
- service = Service,
- opts = Opts} = Ssh]) ->
- Hash = ssh_transport:sha(SigAlg),
+
+get_public_key(SigAlg, #ssh{opts = Opts}) ->
KeyAlg = key_alg(SigAlg),
{KeyCb,KeyCbOpts} = ?GET_OPT(key_cb, Opts),
UserOpts = ?GET_OPT(user_options, Opts),
case KeyCb:user_key(KeyAlg, [{key_cb_private,KeyCbOpts}|UserOpts]) of
- {ok, PrivKey} ->
- SigAlgStr = atom_to_list(SigAlg),
+ {ok, PrivKey} ->
try
Key = ssh_transport:extract_public_key(PrivKey),
public_key:ssh_encode(Key, ssh2_pubkey)
of
- PubKeyBlob ->
- SigData = build_sig_data(SessionId, User, Service,
- PubKeyBlob, SigAlgStr),
- Sig = ssh_transport:sign(SigData, Hash, PrivKey),
- SigBlob = list_to_binary([?string(SigAlgStr),
- ?binary(Sig)]),
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = Service,
- method = "publickey",
- data = [?TRUE,
- ?string(SigAlgStr),
- ?binary(PubKeyBlob),
- ?binary(SigBlob)]},
- Ssh)
+ PubKeyBlob -> {ok,{PrivKey,PubKeyBlob}}
catch
_:_ ->
- {not_ok, Ssh}
+ not_ok
end;
- _Error ->
+ _Error ->
+ not_ok
+ end.
+
+
+publickey_msg([SigAlg, #ssh{user = User,
+ session_id = SessionId,
+ service = Service} = Ssh]) ->
+ case get_public_key(SigAlg, Ssh) of
+ {ok, {PrivKey,PubKeyBlob}} ->
+ SigAlgStr = atom_to_list(SigAlg),
+ SigData = build_sig_data(SessionId, User, Service,
+ PubKeyBlob, SigAlgStr),
+ Hash = ssh_transport:sha(SigAlg),
+ Sig = ssh_transport:sign(SigData, Hash, PrivKey),
+ SigBlob = list_to_binary([?string(SigAlgStr),
+ ?binary(Sig)]),
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_request{user = User,
+ service = Service,
+ method = "publickey",
+ data = [?TRUE,
+ ?string(SigAlgStr),
+ ?binary(PubKeyBlob),
+ ?binary(SigBlob)]},
+ Ssh);
+ _ ->
{not_ok, Ssh}
end.
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index f1ce337947..8d3ddb09a4 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -453,16 +453,20 @@ init_ssh_record(Role, _Socket, PeerAddr, Opts) ->
PeerName0 when is_list(PeerName0) ->
PeerName0
end,
- S0#ssh{c_vsn = Vsn,
- c_version = Version,
- io_cb = case ?GET_OPT(user_interaction, Opts) of
- true -> ssh_io;
- false -> ssh_no_io
- end,
- userauth_pubkeys = ?GET_OPT(pref_public_key_algs, Opts),
- userauth_quiet_mode = ?GET_OPT(quiet_mode, Opts),
- peer = {PeerName, PeerAddr}
- };
+ S1 =
+ S0#ssh{c_vsn = Vsn,
+ c_version = Version,
+ io_cb = case ?GET_OPT(user_interaction, Opts) of
+ true -> ssh_io;
+ false -> ssh_no_io
+ end,
+ userauth_quiet_mode = ?GET_OPT(quiet_mode, Opts),
+ peer = {PeerName, PeerAddr}
+ },
+ S1#ssh{userauth_pubkeys = [K || K <- ?GET_OPT(pref_public_key_algs, Opts),
+ is_usable_user_pubkey(K, S1)
+ ]
+ };
server ->
S0#ssh{s_vsn = Vsn,
@@ -1700,29 +1704,49 @@ handle_ssh_msg_ext_info(#ssh_msg_ext_info{data=Data}, D0) ->
lists:foldl(fun ext_info/2, D0, Data).
-ext_info({"server-sig-algs",SigAlgs}, D0 = #data{ssh_params=#ssh{role=client,
- userauth_pubkeys=ClientSigAlgs}=Ssh0}) ->
- %% Make strings to eliminate risk of beeing bombed with odd strings that fills the atom table:
- SupportedAlgs = lists:map(fun erlang:atom_to_list/1, ssh_transport:supported_algorithms(public_key)),
- ServerSigAlgs = [list_to_atom(SigAlg) || SigAlg <- string:tokens(SigAlgs,","),
- %% length of SigAlg is implicitly checked by the comparison
- %% in member/2:
- lists:member(SigAlg, SupportedAlgs)
- ],
- CommonAlgs = [Alg || Alg <- ServerSigAlgs,
- lists:member(Alg, ClientSigAlgs)],
- SelectedAlgs =
- case CommonAlgs of
- [] -> ClientSigAlgs; % server-sig-algs value is just an advice
- _ -> CommonAlgs
- end,
- D0#data{ssh_params = Ssh0#ssh{userauth_pubkeys = SelectedAlgs} };
+ext_info({"server-sig-algs",SigAlgsStr},
+ D0 = #data{ssh_params=#ssh{role=client,
+ userauth_pubkeys=ClientSigAlgs}=Ssh0}) ->
+ %% ClientSigAlgs are the pub_key algortithms that:
+ %% 1) is usable, that is, the user has such a public key and
+ %% 2) is either the default list or set by the caller
+ %% with the client option 'pref_public_key_algs'
+ %%
+ %% The list is already checked for duplicates.
+
+ SigAlgs = [A || Astr <- string:tokens(SigAlgsStr, ","),
+ A <- try [list_to_existing_atom(Astr)]
+ %% list_to_existing_atom will fail for unknown algorithms
+ catch _:_ -> []
+ end],
+
+ CommonAlgs = [A || A <- SigAlgs,
+ lists:member(A, ClientSigAlgs)],
+
+ %% Re-arrange the client supported public-key algorithms so that the server
+ %% preferred ones are tried first.
+ %% Trying algorithms not mentioned by the server is ok, since the server can't know
+ %% if the client supports 'server-sig-algs' or not.
+
+ D0#data{
+ ssh_params =
+ Ssh0#ssh{
+ userauth_pubkeys =
+ CommonAlgs ++ (ClientSigAlgs -- CommonAlgs)
+ }};
ext_info(_, D0) ->
%% Not implemented
D0.
%%%----------------------------------------------------------------
+is_usable_user_pubkey(A, Ssh) ->
+ case ssh_auth:get_public_key(A, Ssh) of
+ {ok,_} -> true;
+ _ -> false
+ end.
+
+%%%----------------------------------------------------------------
handle_request(ChannelPid, ChannelId, Type, Data, WantReply, From, D) ->
case ssh_channel:cache_lookup(cache(D), ChannelId) of
#channel{remote_id = Id} = Channel ->
diff --git a/lib/ssh/src/ssh_dbg.erl b/lib/ssh/src/ssh_dbg.erl
index 003b3856e6..3f742ad9b6 100644
--- a/lib/ssh/src/ssh_dbg.erl
+++ b/lib/ssh/src/ssh_dbg.erl
@@ -22,10 +22,8 @@
-module(ssh_dbg).
--export([messages/0, messages/1, messages/2,
- ct_messages/0,
- auth/0, auth/1, auth/2,
- ct_auth/0,
+-export([messages/0, messages/1, messages/2, messages/3,
+ auth/0, auth/1, auth/2, auth/3,
stop/0
]).
@@ -37,50 +35,52 @@
-include("ssh_connect.hrl").
-include("ssh_auth.hrl").
--record(data, {
- writer,
- acc = []}).
%%%================================================================
-messages() ->
- messages(fun(String,_D) -> io:format(String) end).
+messages() -> start(msg).
+messages(F) -> start(msg,F).
+messages(F,X) -> start(msg,F,X).
+messages(F,M,I) -> start(msg,F,M,I).
-ct_messages() ->
- messages(fun(String,_D) -> ct:log(String,[]) end).
+auth() -> start(auth).
+auth(F) -> start(auth,F).
+auth(F,X) -> start(auth,F,X).
+auth(F,M,I) -> start(auth,F,M,I).
-messages(Write) when is_function(Write,2) ->
- messages(Write, fun(X) -> X end).
-
-messages(Write, MangleArg) when is_function(Write,2),
- is_function(MangleArg,1) ->
- cond_start(msg, Write, MangleArg),
- dbg_ssh_messages(),
- dbg_ssh_auth().
+stop() -> dbg:stop().
+%%%----------------------------------------------------------------
+start(Type) -> start(Type, fun io:format/2).
-auth() ->
- auth(fun(String,_D) -> io:format(String) end).
+start(Type, F) when is_function(F,2) -> start(Type, fmt_fun(F));
+start(Type, F) when is_function(F,3) -> start(Type, F, id_fun()).
-ct_auth() ->
- auth(fun(String,_D) -> ct:log(String,[]) end).
+start(Type, WriteFun, MangleArgFun) when is_function(WriteFun, 3),
+ is_function(MangleArgFun, 1) ->
+ start(Type, WriteFun, MangleArgFun, []);
+start(Type, WriteFun, InitValue) ->
+ start(Type, WriteFun, id_fun(), InitValue).
-auth(Write) when is_function(Write,2) ->
- auth(Write, fun(X) -> X end).
+start(Type, WriteFun, MangleArgFun, InitValue) when is_function(WriteFun, 3),
+ is_function(MangleArgFun, 1) ->
+ cond_start(Type, WriteFun, MangleArgFun, InitValue),
+ dbg_ssh(Type).
-auth(Write, MangleArg) when is_function(Write,2),
- is_function(MangleArg,1) ->
- cond_start(auth, Write, MangleArg),
- dbg_ssh_auth().
+%%%----------------------------------------------------------------
+fmt_fun(F) -> fun(Fmt,Args,Data) -> F(Fmt,Args), Data end.
+id_fun() -> fun(X) -> X end.
-dbg_ssh_messages() ->
+%%%----------------------------------------------------------------
+dbg_ssh(msg) ->
+ dbg_ssh(auth),
dbg:tp(ssh_message,encode,1, x),
dbg:tp(ssh_message,decode,1, x),
dbg:tpl(ssh_transport,select_algorithm,4, x),
dbg:tp(ssh_transport,hello_version_msg,1, x),
dbg:tp(ssh_transport,handle_hello_version,1, x),
- dbg:tpl(ssh_connection_handler,ext_info,2, x).
+ dbg:tpl(ssh_connection_handler,ext_info,2, x);
-dbg_ssh_auth() ->
+dbg_ssh(auth) ->
dbg:tp(ssh_transport,hello_version_msg,1, x),
dbg:tp(ssh_transport,handle_hello_version,1, x),
dbg:tp(ssh_message,encode,1, x),
@@ -89,15 +89,11 @@ dbg_ssh_auth() ->
lists:foreach(fun(F) -> dbg:tp(ssh_auth, F, x) end,
[publickey_msg, password_msg, keyboard_interactive_msg]).
-%%%----------------------------------------------------------------
-stop() ->
- dbg:stop().
-
%%%================================================================
-cond_start(Type, Write, MangleArg) ->
+cond_start(Type, WriteFun, MangleArgFun, Init) ->
try
dbg:start(),
- setup_tracer(Type, Write, MangleArg),
+ setup_tracer(Type, WriteFun, MangleArgFun, Init),
dbg:p(new,[c,timestamp])
catch
_:_ -> ok
@@ -136,12 +132,13 @@ msg_formater(_, {trace_ts,Pid,call,{ssh_transport,handle_hello_version,[Hello]},
msg_formater(_, {trace_ts,_Pid,return_from,{ssh_transport,handle_hello_version,1},_,_TS}, D) ->
D;
-msg_formater(_, {trace_ts,Pid,call,{ssh_connection_handler,ext_info,[{"server-sig-algs",_SigAlgs},State]},TS}, D) ->
+msg_formater(_, {trace_ts,Pid,call,{ssh_connection_handler,ext_info,[{"server-sig-algs",SigAlgs},State]},TS}, D) ->
try lists:keyfind(ssh, 1, tuple_to_list(State)) of
false ->
D;
#ssh{userauth_pubkeys = PKs} ->
- fmt("~n~s ~p Client got suggestion to use user public key sig-algs~n ~p~n", [ts(TS),Pid,PKs], D)
+ fmt("~n~s ~p Client got suggestion to use user public key sig-algs~n ~p~n and can use~n ~p~n",
+ [ts(TS),Pid,string:tokens(SigAlgs,","),PKs], D)
catch
_:_ ->
D
@@ -206,21 +203,25 @@ msg_formater(msg, {trace_ts,Pid,'receive',ErlangMsg,TS}, D) ->
msg_formater(_, _, D) ->
D.
+%%%----------------------------------------------------------------
+-record(data, {writer,
+ acc}).
-fmt(Fmt, Args, D=#data{writer=Write,acc=Acc}) ->
- D#data{acc = Write(io_lib:format(Fmt, Args), Acc)}.
+fmt(Fmt, Args, D=#data{writer=Write, acc=Acc}) ->
+ D#data{acc = Write(Fmt,Args,Acc)}.
ts({_,_,Usec}=Now) ->
{_Date,{HH,MM,SS}} = calendar:now_to_local_time(Now),
io_lib:format("~.2.0w:~.2.0w:~.2.0w.~.6.0w",[HH,MM,SS,Usec]);
ts(_) ->
"-".
-%%%----------------------------------------------------------------
-setup_tracer(Type, Write, MangleArg) ->
+
+setup_tracer(Type, WriteFun, MangleArgFun, Init) ->
Handler = fun(Arg, D) ->
- msg_formater(Type, MangleArg(Arg), D)
+ msg_formater(Type, MangleArgFun(Arg), D)
end,
- InitialData = #data{writer = Write},
+ InitialData = #data{writer = WriteFun,
+ acc = Init},
{ok,_} = dbg:tracer(process, {Handler, InitialData}),
ok.
diff --git a/lib/ssh/src/ssh_options.erl b/lib/ssh/src/ssh_options.erl
index aebb5a7062..7eeed70739 100644
--- a/lib/ssh/src/ssh_options.erl
+++ b/lib/ssh/src/ssh_options.erl
@@ -674,7 +674,11 @@ check_pref_public_key_algs(V) ->
PKs = ssh_transport:supported_algorithms(public_key),
CHK = fun(A, Ack) ->
case lists:member(A, PKs) of
- true -> [A|Ack];
+ true ->
+ case lists:member(A,Ack) of
+ false -> [A|Ack];
+ true -> Ack % Remove duplicates
+ end;
false -> error_in_check(A, "Not supported public key")
end
end,
diff --git a/lib/ssh/test/ssh_algorithms_SUITE.erl b/lib/ssh/test/ssh_algorithms_SUITE.erl
index 0f69910e40..98964a2c8a 100644
--- a/lib/ssh/test/ssh_algorithms_SUITE.erl
+++ b/lib/ssh/test/ssh_algorithms_SUITE.erl
@@ -131,9 +131,14 @@ init_per_group(public_key=Tag, Alg, Config) ->
ct:log("Init tests for public_key ~p",[Alg]),
PrefAlgs = {preferred_algorithms,[{Tag,[Alg]}]},
%% Daemon started later in init_per_testcase
- [{pref_algs,PrefAlgs},
- {tag_alg,{Tag,Alg}}
- | Config];
+ try
+ setup_pubkey(Alg,
+ [{pref_algs,PrefAlgs},
+ {tag_alg,{Tag,Alg}}
+ | Config])
+ catch
+ _:_ -> {skip, io_lib:format("Unsupported: ~p",[Alg])}
+ end;
init_per_group(Tag, Alg, Config) ->
PA =
@@ -167,18 +172,24 @@ init_per_testcase(TC, Config) ->
init_per_testcase(TC, proplists:get_value(tag_alg,Config), Config).
-init_per_testcase(_, {public_key,Alg}, Config) ->
- Opts = pubkey_opts(Config),
+init_per_testcase(TC, {public_key,Alg}, Config) ->
+ ExtraOpts = case TC of
+ simple_connect ->
+ [{user_dir, proplists:get_value(priv_dir,Config)}];
+ _ ->
+ []
+ end,
+ Opts = pubkey_opts(Config) ++ ExtraOpts,
case {ssh_file:user_key(Alg,Opts), ssh_file:host_key(Alg,Opts)} of
{{ok,_}, {ok,_}} ->
- ssh_dbg:ct_auth(),
- start_pubkey_daemon([proplists:get_value(pref_algs,Config)],
+ start_pubkey_daemon([proplists:get_value(pref_algs,Config)
+ | ExtraOpts],
[{extra_daemon,true}|Config]);
- {{ok,_}, _} ->
- {skip, "No host key"};
+ {{ok,_}, {error,Err}} ->
+ {skip, io_lib:format("No host key: ~p",[Err])};
- {_, {ok,_}} ->
- {skip, "No user key"};
+ {{error,Err}, {ok,_}} ->
+ {skip, io_lib:format("No user key: ~p",[Err])};
_ ->
{skip, "Neither host nor user key"}
@@ -193,7 +204,6 @@ init_per_testcase(_, _, Config) ->
end_per_testcase(_TC, Config) ->
- catch ssh_dbg:stop(),
case proplists:get_value(extra_daemon, Config, false) of
true ->
case proplists:get_value(srvr_pid,Config) of
@@ -223,6 +233,19 @@ simple_exec(Config) ->
ssh_test_lib:std_simple_exec(Host, Port, Config).
%%--------------------------------------------------------------------
+%% A simple exec call
+simple_connect(Config) ->
+ {Host,Port} = proplists:get_value(srvr_addr, Config),
+ Opts =
+ case proplists:get_value(tag_alg, Config) of
+ {public_key,Alg} -> [{pref_public_key_algs,[Alg]}];
+ _ -> []
+ end,
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
+ ct:log("~p:~p connected! ~p",[?MODULE,?LINE,ConnectionRef]),
+ ssh:close(ConnectionRef).
+
+%%--------------------------------------------------------------------
%% Testing if no group matches
simple_exec_groups_no_match_too_small(Config) ->
try_exec_simple_group({400,500,600}, Config).
@@ -304,9 +327,15 @@ sshc_simple_exec_os_cmd(Config) ->
%%--------------------------------------------------------------------
%% Connect to the ssh server of the OS
sshd_simple_exec(Config) ->
+ ClientPubKeyOpts =
+ case proplists:get_value(tag_alg,Config) of
+ {public_key,Alg} -> [{pref_public_key_algs,[Alg]}];
+ _ -> []
+ end,
ConnectionRef = ssh_test_lib:connect(22, [{silently_accept_hosts, true},
proplists:get_value(pref_algs,Config),
- {user_interaction, false}]),
+ {user_interaction, false}
+ | ClientPubKeyOpts]),
{ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
success = ssh_connection:exec(ConnectionRef, ChannelId0,
"echo testing", infinity),
@@ -363,8 +392,8 @@ split(Alg) -> ssh_test_lib:to_atoms(string:tokens(atom_to_list(Alg), " + ")).
specific_test_cases(Tag, Alg, SshcAlgos, SshdAlgos, TypeSSH) ->
case Tag of
- public_key -> [];
- _ -> [simple_exec, simple_sftp]
+ public_key -> [simple_connect];
+ _ -> [simple_connect, simple_exec, simple_sftp]
end
++ case supports(Tag, Alg, SshcAlgos) of
true when TypeSSH == openSSH ->
@@ -439,10 +468,26 @@ setup_pubkey(Config) ->
Keys =
[ssh_test_lib:setup_dsa(DataDir, UserDir),
ssh_test_lib:setup_rsa(DataDir, UserDir),
- ssh_test_lib:setup_ecdsa("256", DataDir, UserDir)],
+ ssh_test_lib:setup_ecdsa("256", DataDir, UserDir)
+ ],
ssh_test_lib:write_auth_keys(Keys, UserDir), % 'authorized_keys' shall contain ALL pub keys
Config.
+setup_pubkey(Alg, Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ UserDir = proplists:get_value(priv_dir, Config),
+ ct:log("Setup keys for ~p",[Alg]),
+ case Alg of
+ 'ssh-dss' -> ssh_test_lib:setup_dsa(DataDir, UserDir);
+ 'ssh-rsa' -> ssh_test_lib:setup_rsa(DataDir, UserDir);
+ 'rsa-sha2-256' -> ssh_test_lib:setup_rsa(DataDir, UserDir);
+ 'rsa-sha2-512' -> ssh_test_lib:setup_rsa(DataDir, UserDir);
+ 'ecdsa-sha2-nistp256' -> ssh_test_lib:setup_ecdsa("256", DataDir, UserDir);
+ 'ecdsa-sha2-nistp384' -> ssh_test_lib:setup_ecdsa("384", DataDir, UserDir);
+ 'ecdsa-sha2-nistp521' -> ssh_test_lib:setup_ecdsa("521", DataDir, UserDir)
+ end,
+ Config.
+
simple_exec_group(I, Config) when is_integer(I) ->
simple_exec_group({I,I,I}, Config);
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4c39e916e9
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDAughXu55DNyhxe6x+MNjv4oZKWUDh7bhi4CqjvxhCp9KMpsybltcq+
+lsuKTarzTdKgBwYFK4EEACKhZANiAASu1vvDL0SQoXGtzlltaPHPyDfEVMG/sKLA
+pqv8vfRN5Wcs7+yaRKw92nYEKGXfZLbhVX8ArFPMtXPWHcRHCntvL1Acn2kJQ8Gc
+7iL4NAr8JhTIUBv4YMhHDa9Pv/CH2zk=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..caa9604c84
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBK7W+8MvRJChca3OWW1o8c/IN8RUwb+wosCmq/y99E3lZyzv7JpErD3adgQoZd9ktuFVfwCsU8y1c9YdxEcKe28vUByfaQlDwZzuIvg0CvwmFMhQG/hgyEcNr0+/8IfbOQ== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..1e16fcbd57
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEEWXGoVLiNwQVUwAGZWxOu6uxtU8ntxyZNlcWU4Z8pze9kq3eK7a9XH
+l/wxL75Vk1QdOiR/rE3s/L/zOuChp44o1aAHBgUrgQQAI6GBiQOBhgAEAfCrtwjO
+kQYKr4/F3uanS7Eby1+SYDdRl1ABuDFhNC3CivVBFt4CnRneV+Mf0viDAxD+HEpd
+/GaE2CdsFoVpglN5AVG+fEePY2PiCLHmjc4/pBuR+tWhErzcWAd0KLBCBuc4OAvl
+aLLYV1NAJI6COnnfGTCVvYYE5nKMG4LLX0zaWtWl
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..069683eba7
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHwq7cIzpEGCq+Pxd7mp0uxG8tfkmA3UZdQAbgxYTQtwor1QRbeAp0Z3lfjH9L4gwMQ/hxKXfxmhNgnbBaFaYJTeQFRvnxHj2Nj4gix5o3OP6QbkfrVoRK83FgHdCiwQgbnODgL5Wiy2FdTQCSOgjp53xkwlb2GBOZyjBuCy19M2lrVpQ== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..5835bcd74c
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDB+l0+SMLYgQ3ZRzg2Pn5u+1ZwKbEnJzXsTKTJM9QSJbKkbA7uCnjdS
+CvEW+66CoHqgBwYFK4EEACKhZANiAAT6awCCIrcCr9H4wq0bJ/rQou3tpLHyyf33
+c8D6FPn48/hNqinpx7b0le/0D+Rrhdl9edIplAf6oki7yoFFGl4yuzWtv7rag9jB
+vv6w1508ChOmyQ094rFt/xj4KVBhEHI=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..714fc4eb89
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPprAIIitwKv0fjCrRsn+tCi7e2ksfLJ/fdzwPoU+fjz+E2qKenHtvSV7/QP5GuF2X150imUB/qiSLvKgUUaXjK7Na2/utqD2MG+/rDXnTwKE6bJDT3isW3/GPgpUGEQcg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..81aa8df39f
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEHHxgYEfDclsu5bW+pZfg+bkaqWpgEpXtuzLVm++FFPjhAPhMkurSRj
+WQ+CuI2TxgYkBbYFNjn9JqgdMF7FzaiojKAHBgUrgQQAI6GBiQOBhgAEAFTM8TKG
+xexxmfAGuyl/Tpk4wytB/OyuVfkF+Q3H1v17HLcpMacA5xUFr80+D5XnjxGttBsS
++X0uexR7QbPbhhPqADgQzFqvTsB1mUNAZnJBD6QNCZkfWwRRwFYQWSmisb43H6G3
+iUTKqiCXMXO8drKLA+Wi+L7VyfoI1CvatBBlDHbV
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..17b9a1d834
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBABUzPEyhsXscZnwBrspf06ZOMMrQfzsrlX5BfkNx9b9exy3KTGnAOcVBa/NPg+V548RrbQbEvl9LnsUe0Gz24YT6gA4EMxar07AdZlDQGZyQQ+kDQmZH1sEUcBWEFkporG+Nx+ht4lEyqoglzFzvHayiwPlovi+1cn6CNQr2rQQZQx21Q== uabhnil@elxadlj3q32
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 7208baca6e..48332d2e5a 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,5 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 4.5
+SSH_VSN = 4.4.2
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index 1a93572dc7..29ec3f9d57 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -28,114 +28,6 @@
<p>This document describes the changes made to the SSL application.</p>
-<section><title>SSL 8.2</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- ECDH-ECDSA key exchange supported, was accidently
- dismissed in earlier versions.</p>
- <p>
- Own Id: OTP-14421</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- TLS-1.2 clients will now always send hello messages on
- its own format, as opposed to earlier versions that will
- send the hello on the lowest supported version, this is a
- change supported by the latest RFC.</p>
- <p>
- This will make interoperability with some newer servers
- smoother. Potentially, but unlikely, this could cause a
- problem with older servers if they do not adhere to the
- RFC and ignore unknown extensions.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-13820</p>
- </item>
- <item>
- <p>
- Allow Erlang/OTP to use OpenSSL in FIPS-140 mode, in
- order to satisfy specific security requirements (mostly
- by different parts of the US federal government). </p>
- <p>
- See the new crypto users guide "FIPS mode" chapter about
- building and using the FIPS support which is disabled by
- default.</p>
- <p>
- (Thanks to dszoboszlay and legoscia)</p>
- <p>
- Own Id: OTP-13921 Aux Id: PR-1180 </p>
- </item>
- <item>
- <p>
- Implemented DTLS cookie generation, requiered by spec,
- instead of using hardcode value.</p>
- <p>
- Own Id: OTP-14076</p>
- </item>
- <item>
- <p>
- Implement sliding window replay protection of DTLS
- records.</p>
- <p>
- Own Id: OTP-14077</p>
- </item>
- <item>
- <p>
- TLS client processes will by default call
- public_key:pkix_verify_hostname/2 to verify the hostname
- of the connection with the server certifcates specified
- hostname during certificate path validation. The user may
- explicitly disables it. Also if the hostname can not be
- derived from the first argument to connnect or is not
- supplied by the server name indication option, the check
- will not be performed.</p>
- <p>
- Own Id: OTP-14197</p>
- </item>
- <item>
- <p>
- Extend connection_information/[1,2] . The values
- session_id, master_secret, client_random and
- server_random can no be accessed by
- connection_information/2. Note only session_id will be
- added to connection_information/1. The rational is that
- values concerning the connection security should have to
- be explicitly requested.</p>
- <p>
- Own Id: OTP-14291</p>
- </item>
- <item>
- <p>
- Chacha cipher suites are currently not tested enough to
- be most prefered ones</p>
- <p>
- Own Id: OTP-14382</p>
- </item>
- <item>
- <p>
- Basic support for DTLS that been tested together with
- OpenSSL.</p>
- <p>
- Test by providing the option {protocol, dtls} to the ssl
- API functions connect and listen.</p>
- <p>
- Own Id: OTP-14388</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>SSL 8.1.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl
index 2de947d8b4..f338471829 100644
--- a/lib/ssl/src/dtls_connection.erl
+++ b/lib/ssl/src/dtls_connection.erl
@@ -115,7 +115,7 @@ send_handshake_flight(#state{socket = Socket,
{Encoded, ConnectionStates} =
encode_handshake_flight(lists:reverse(Flight), Version, 1400, Epoch, ConnectionStates0),
send(Transport, Socket, Encoded),
- start_flight(State0#state{connection_states = ConnectionStates});
+ {State0#state{connection_states = ConnectionStates}, []};
send_handshake_flight(#state{socket = Socket,
transport_cb = Transport,
@@ -129,7 +129,7 @@ send_handshake_flight(#state{socket = Socket,
{EncChangeCipher, ConnectionStates} = encode_change_cipher(ChangeCipher, Version, Epoch, ConnectionStates1),
send(Transport, Socket, [HsBefore, EncChangeCipher]),
- start_flight(State0#state{connection_states = ConnectionStates});
+ {State0#state{connection_states = ConnectionStates}, []};
send_handshake_flight(#state{socket = Socket,
transport_cb = Transport,
@@ -145,7 +145,7 @@ send_handshake_flight(#state{socket = Socket,
{HsAfter, ConnectionStates} =
encode_handshake_flight(lists:reverse(Flight1), Version, 1400, Epoch, ConnectionStates2),
send(Transport, Socket, [HsBefore, EncChangeCipher, HsAfter]),
- start_flight(State0#state{connection_states = ConnectionStates});
+ {State0#state{connection_states = ConnectionStates}, []};
send_handshake_flight(#state{socket = Socket,
transport_cb = Transport,
@@ -159,7 +159,7 @@ send_handshake_flight(#state{socket = Socket,
{HsAfter, ConnectionStates} =
encode_handshake_flight(lists:reverse(Flight1), Version, 1400, Epoch, ConnectionStates1),
send(Transport, Socket, [EncChangeCipher, HsAfter]),
- start_flight(State0#state{connection_states = ConnectionStates}).
+ {State0#state{connection_states = ConnectionStates}, []}.
queue_change_cipher(ChangeCipher, #state{flight_buffer = Flight,
connection_states = ConnectionStates0} = State) ->
@@ -235,12 +235,14 @@ init([Role, Host, Port, Socket, Options, User, CbInfo]) ->
end.
callback_mode() ->
- state_functions.
+ [state_functions, state_enter].
%%--------------------------------------------------------------------
%% State functions
%%--------------------------------------------------------------------
+init(enter, _, State) ->
+ {keep_state, State};
init({call, From}, {start, Timeout},
#state{host = Host, port = Port, role = client,
ssl_options = SslOpts,
@@ -282,6 +284,8 @@ init({call, _} = Type, Event, #state{role = server} = State) ->
init(Type, Event, State) ->
ssl_connection:init(Type, Event, State, ?MODULE).
+error(enter, _, State) ->
+ {keep_state, State};
error({call, From}, {start, _Timeout}, {Error, State}) ->
{stop_and_reply, normal, {reply, From, {error, Error}}, State};
error({call, From}, Msg, State) ->
@@ -295,6 +299,11 @@ error(_, _, _) ->
#state{}) ->
gen_statem:state_function_result().
%%--------------------------------------------------------------------
+hello(enter, _, #state{role = server} = State) ->
+ {keep_state, State};
+hello(enter, _, #state{role = client} = State0) ->
+ {State, Actions} = handle_flight_timer(State0),
+ {keep_state, State, Actions};
hello(internal, #client_hello{cookie = <<>>,
client_version = Version} = Hello, #state{role = server,
transport_cb = Transport,
@@ -374,6 +383,9 @@ hello(state_timeout, Event, State) ->
hello(Type, Event, State) ->
ssl_connection:hello(Type, Event, State, ?MODULE).
+abbreviated(enter, _, State0) ->
+ {State, Actions} = handle_flight_timer(State0),
+ {keep_state, State, Actions};
abbreviated(info, Event, State) ->
handle_info(Event, abbreviated, State);
abbreviated(internal = Type,
@@ -391,6 +403,9 @@ abbreviated(state_timeout, Event, State) ->
abbreviated(Type, Event, State) ->
ssl_connection:abbreviated(Type, Event, State, ?MODULE).
+certify(enter, _, State0) ->
+ {State, Actions} = handle_flight_timer(State0),
+ {keep_state, State, Actions};
certify(info, Event, State) ->
handle_info(Event, certify, State);
certify(internal = Type, #server_hello_done{} = Event, State) ->
@@ -400,6 +415,9 @@ certify(state_timeout, Event, State) ->
certify(Type, Event, State) ->
ssl_connection:certify(Type, Event, State, ?MODULE).
+cipher(enter, _, State0) ->
+ {State, Actions} = handle_flight_timer(State0),
+ {keep_state, State, Actions};
cipher(info, Event, State) ->
handle_info(Event, cipher, State);
cipher(internal = Type, #change_cipher_spec{type = <<1>>} = Event,
@@ -417,6 +435,8 @@ cipher(state_timeout, Event, State) ->
cipher(Type, Event, State) ->
ssl_connection:cipher(Type, Event, State, ?MODULE).
+connection(enter, _, State) ->
+ {keep_state, State};
connection(info, Event, State) ->
handle_info(Event, connection, State);
connection(internal, #hello_request{}, #state{host = Host, port = Port,
@@ -449,6 +469,9 @@ connection(internal, #client_hello{}, #state{role = server, allow_renegotiate =
connection(Type, Event, State) ->
ssl_connection:connection(Type, Event, State, ?MODULE).
+%%TODO does this make sense for DTLS ?
+downgrade(enter, _, State) ->
+ {keep_state, State};
downgrade(Type, Event, State) ->
ssl_connection:downgrade(Type, Event, State, ?MODULE).
@@ -750,14 +773,16 @@ next_event(connection = StateName, no_record,
{#ssl_tls{epoch = Epoch,
type = ?HANDSHAKE,
version = _Version}, State1} = _Record when Epoch == CurrentEpoch-1 ->
- {State, MoreActions} = send_handshake_flight(State1, CurrentEpoch),
- {next_state, StateName, State, Actions ++ MoreActions};
+ {State2, MoreActions} = send_handshake_flight(State1, CurrentEpoch),
+ {NextRecord, State} = next_record(State2),
+ next_event(StateName, NextRecord, State, Actions ++ MoreActions);
%% From FLIGHT perspective CHANGE_CIPHER_SPEC is treated as a handshake
{#ssl_tls{epoch = Epoch,
type = ?CHANGE_CIPHER_SPEC,
version = _Version}, State1} = _Record when Epoch == CurrentEpoch-1 ->
- {State, MoreActions} = send_handshake_flight(State1, CurrentEpoch),
- {next_state, StateName, State, Actions ++ MoreActions};
+ {State2, MoreActions} = send_handshake_flight(State1, CurrentEpoch),
+ {NextRecord, State} = next_record(State2),
+ next_event(StateName, NextRecord, State, Actions ++ MoreActions);
{#ssl_tls{epoch = _Epoch,
version = _Version}, State1} ->
%% TODO maybe buffer later epoch
@@ -774,14 +799,16 @@ next_event(connection = StateName, Record,
#ssl_tls{epoch = Epoch,
type = ?HANDSHAKE,
version = _Version} when Epoch == CurrentEpoch-1 ->
- {State, MoreActions} = send_handshake_flight(State0, CurrentEpoch),
- {next_state, StateName, State, Actions ++ MoreActions};
+ {State1, MoreActions} = send_handshake_flight(State0, CurrentEpoch),
+ {NextRecord, State} = next_record(State1),
+ next_event(StateName, NextRecord, State, Actions ++ MoreActions);
%% From FLIGHT perspective CHANGE_CIPHER_SPEC is treated as a handshake
#ssl_tls{epoch = Epoch,
type = ?CHANGE_CIPHER_SPEC,
version = _Version} when Epoch == CurrentEpoch-1 ->
- {State, MoreActions} = send_handshake_flight(State0, CurrentEpoch),
- {next_state, StateName, State, Actions ++ MoreActions};
+ {State1, MoreActions} = send_handshake_flight(State0, CurrentEpoch),
+ {NextRecord, State} = next_record(State1),
+ next_event(StateName, NextRecord, State, Actions ++ MoreActions);
_ ->
next_event(StateName, no_record, State0, Actions)
end;
@@ -841,13 +868,13 @@ next_flight(Flight) ->
change_cipher_spec => undefined,
handshakes_after_change_cipher_spec => []}.
-start_flight(#state{transport_cb = gen_udp,
- flight_state = {retransmit, Timeout}} = State) ->
+handle_flight_timer(#state{transport_cb = gen_udp,
+ flight_state = {retransmit, Timeout}} = State) ->
start_retransmision_timer(Timeout, State);
-start_flight(#state{transport_cb = gen_udp,
+handle_flight_timer(#state{transport_cb = gen_udp,
flight_state = connection} = State) ->
{State, []};
-start_flight(State) ->
+handle_flight_timer(State) ->
%% No retransmision needed i.e DTLS over SCTP
{State#state{flight_state = reliable}, []}.
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 96c3ab86e9..352874c77d 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -600,8 +600,12 @@ next_record(#state{protocol_buffers =
next_record(#state{protocol_buffers = #protocol_buffers{tls_packets = [], tls_cipher_texts = []},
socket = Socket,
transport_cb = Transport} = State) ->
- tls_socket:setopts(Transport, Socket, [{active,once}]),
- {no_record, State};
+ case tls_socket:setopts(Transport, Socket, [{active,once}]) of
+ ok ->
+ {no_record, State};
+ _ ->
+ {socket_closed, State}
+ end;
next_record(State) ->
{no_record, State}.
@@ -626,10 +630,15 @@ passive_receive(State0 = #state{user_data_buffer = Buffer}, StateName) ->
next_event(StateName, Record, State) ->
next_event(StateName, Record, State, []).
+next_event(StateName, socket_closed, State, _) ->
+ ssl_connection:handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State),
+ {stop, {shutdown, transport_closed}, State};
next_event(connection = StateName, no_record, State0, Actions) ->
case next_record_if_active(State0) of
{no_record, State} ->
ssl_connection:hibernate_after(StateName, State, Actions);
+ {socket_closed, State} ->
+ next_event(StateName, socket_closed, State, Actions);
{#ssl_tls{} = Record, State} ->
{next_state, StateName, State, [{next_event, internal, {protocol_record, Record}} | Actions]};
{#alert{} = Alert, State} ->
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 58870a3419..d13b1b3f2a 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -240,6 +240,7 @@ error_handling_tests()->
error_handling_tests_tls()->
[controller_dies,
tls_client_closes_socket,
+ tls_closed_in_active_once,
tls_tcp_error_propagation_in_active_mode,
tls_tcp_connect,
tls_tcp_connect_big,
@@ -430,6 +431,7 @@ init_per_testcase(prf, Config) ->
init_per_testcase(TestCase, Config) when TestCase == tls_ssl_accept_timeout;
TestCase == tls_client_closes_socket;
+ TestCase == tls_closed_in_active_once;
TestCase == tls_downgrade ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
ct:timetrap({seconds, 15}),
@@ -961,6 +963,48 @@ tls_client_closes_socket(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, {error,closed}).
%%--------------------------------------------------------------------
+tls_closed_in_active_once() ->
+ [{doc, "Test that ssl_closed is delivered in active once with non-empty buffer, check ERL-420."}].
+
+tls_closed_in_active_once(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ {_ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+ Port = ssl_test_lib:inet_port(node()),
+ Server = fun() ->
+ {ok, Listen} = gen_tcp:listen(Port, TcpOpts),
+ {ok, TcpServerSocket} = gen_tcp:accept(Listen),
+ {ok, ServerSocket} = ssl:ssl_accept(TcpServerSocket, ServerOpts),
+ lists:foreach(
+ fun(_) ->
+ ssl:send(ServerSocket, "some random message\r\n")
+ end, lists:seq(1, 20)),
+ %% Close TCP instead of SSL socket to trigger the bug:
+ gen_tcp:close(TcpServerSocket),
+ gen_tcp:close(Listen)
+ end,
+ spawn_link(Server),
+ {ok, Socket} = ssl:connect(Hostname, Port, [{active, false} | ClientOpts]),
+ Result = tls_closed_in_active_once_loop(Socket),
+ ssl:close(Socket),
+ case Result of
+ ok -> ok;
+ _ -> ct:fail(Result)
+ end.
+
+tls_closed_in_active_once_loop(Socket) ->
+ ssl:setopts(Socket, [{active, once}]),
+ receive
+ {ssl, Socket, _} ->
+ tls_closed_in_active_once_loop(Socket);
+ {ssl_closed, Socket} ->
+ ok
+ after 5000 ->
+ no_ssl_closed_received
+ end.
+
+%%--------------------------------------------------------------------
connect_dist() ->
[{doc,"Test a simple connect as is used by distribution"}].
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml
index ad7f2f2e95..a7caa71dcb 100644
--- a/lib/stdlib/doc/src/gen_statem.xml
+++ b/lib/stdlib/doc/src/gen_statem.xml
@@ -1098,7 +1098,7 @@ handle_event(_, _, State, Data) ->
<seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
or
<seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>
- would be weird on the border of whichcraft
+ would be weird on the border of witchcraft
since there has been no earlier call to a
<seealso marker="#state callback">state callback</seealso>
in this server.
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index fad0896d9b..a8a252cb35 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -31,418 +31,6 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
-<section><title>STDLIB 3.4</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>For many releases, it has been legal to override a BIF
- with a local function having the same name. However,
- calling a local function with the same name as guard BIF
- as filter in a list comprehension was not allowed.</p>
- <p>
- Own Id: OTP-13690</p>
- </item>
- <item>
- <p> A new (default) pseudo-random number generator
- algorithm Xoroshiro116+ has been implemented in the
- <c>rand</c> module. </p><p> The old algorithm
- implementations had a number of flaws so they are all
- deprecated, but corrected versions of two of them have
- been added. See the documentation. </p>
- <p>
- Own Id: OTP-14295 Aux Id: PR-1372 </p>
- </item>
- <item>
- <p> The Erlang shell, <c>qlc:string_to_handle()</c>, and
- the Debugger (the Evaluator area and Edit variable window
- of the Bindings area) can parse pids, ports, references,
- and external funs, as long as they can be created in the
- running system. </p>
- <p>
- Own Id: OTP-14296</p>
- </item>
- <item>
- <p>Internal code change: Calls to <c>catch</c> followed
- by a call to <c>erlang:get_stacktrace/0</c> has been
- rewritten to use <c>try</c> instead of <c>catch</c> to
- make the code future-proof.</p>
- <p>
- Own Id: OTP-14400</p>
- </item>
- <item>
- <p> The state machine engine <c>gen_statem</c> can now
- handle generic time-outs (multiple named) as well as
- absolute time-out time. See the documentation. </p><p>
- The <c>gen_statem</c> callback <c>Module:init/1</c> has
- become mandatory to harmonize with other <c>gen_*</c>
- modules. This may be an incompatibility for
- <c>gen_statem</c> callback modules that use
- <c>gen_statem:enter_loop/4-6</c>. </p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14531</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Improved unicode support for strings. Added normalization
- functions in the <c>unicode</c> module. Extended the
- <c>string</c> module API with new functions with improved
- unicode handling and that works on grapheme clusters. The
- new functions operates on the <c>unicode:chardata()</c>
- type, thus they also accept <c>UTF-8 binaries</c> as
- input. </p>
- <p>
- The old string API have been marked as obsolete. The
- return values have been changed for some error cases.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-10289 Aux Id: OTP-10309 </p>
- </item>
- <item>
- <p>There are two new guard BIFs '<c>floor/1</c>' and
- '<c>ceil/1</c>'. They both return integers. In the
- '<c>math</c>' module, there are two new BIFs with the
- same names that return floating point values.</p>
- <p>
- Own Id: OTP-13692</p>
- </item>
- <item>
- <p>
- Making code_change, terminate and handle_info callbacks
- optional in the OTP behaviours.</p>
- <p>
- Own Id: OTP-13801</p>
- </item>
- <item>
- <p> The support for Dets files created with Erlang/OTP R7
- and earlier is removed. </p>
- <p>
- Own Id: OTP-13830</p>
- </item>
- <item>
- <p>Replaced usage of deprecated symbolic <seealso
- marker="erts:erlang#type-time_unit"><c>time
- unit</c></seealso> representations.</p>
- <p>
- Own Id: OTP-13831 Aux Id: OTP-13735 </p>
- </item>
- <item>
- <p>The function <c>fmod/2</c> has been added to the
- <c>math</c> module.</p>
- <p>
- Own Id: OTP-14000</p>
- </item>
- <item>
- <p>The EXIT signals received from processes using
- <c>proc_lib</c> now looks like EXIT signals from
- processes that were spawned using <c>spawn_link</c>. In
- particular, that means that the stack trace is now
- included in the EXIT signal so that it can see where the
- process crashed.</p>
- <p>
- Own Id: OTP-14001</p>
- </item>
- <item>
- <p><c>sets:add_element/2</c> is faster when adding an
- element that is already present, and
- <c>sets:del_element/2</c> is faster when the element to
- be deleted is not present. This optimization can make
- certain operations, such as sets:union/2 with many
- overlapping elements, up to two orders of magnitude
- faster.</p>
- <p>
- Own Id: OTP-14035</p>
- </item>
- <item>
- <p>
- Add information in doc about supervisor shutdown reason
- when maximum restart frequency is reached.</p>
- <p>
- Own Id: OTP-14037 Aux Id: PR-1233 </p>
- </item>
- <item>
- <p>
- Added <c>rand:jump/[0|1]</c> functions.</p>
- <p>
- Own Id: OTP-14038 Aux Id: PR-1235 </p>
- </item>
- <item>
- <p>Functions for detecting changed code has been added.
- <c>code:modified_modules/0</c> returns all currently
- loaded modules that have changed on disk.
- <c>code:module_status/1</c> returns the status for a
- module. In the shell and in <c>c</c> module, <c>mm/0</c>
- is short for <c>code:modified_modules/0</c>, and
- <c>lm/0</c> reloads all currently loaded modules that
- have changed on disk.</p>
- <p>
- Own Id: OTP-14059</p>
- </item>
- <item>
- <p>Each assert macro in <c>assert.hrl</c> now has a
- corresponding version with an extra argument, for adding
- comments to assertions. These can for example be printed
- as part of error reports, to clarify the meaning of the
- check that failed.</p>
- <p>
- Own Id: OTP-14066</p>
- </item>
- <item>
- <p><c>error_logger_tty_h</c> and
- <c>error_logger_file_h</c> now inserts the node
- information for nonlocal messages before the message
- itself instead of after, both for readability and so as
- not to change the line termination property at the end of
- the message.</p>
- <p>
- Own Id: OTP-14068</p>
- </item>
- <item>
- <p>The Erlang code linter checks for badly formed type
- constraints. </p>
- <p>
- Own Id: OTP-14070 Aux Id: PR-1214 </p>
- </item>
- <item>
- <p>By default, there will now be a warning when
- <c>export_all</c> is used. The warning can be disabled
- using <c>nowarn_export_all</c>.</p>
- <p>
- Own Id: OTP-14071</p>
- </item>
- <item>
- <p>When a <c>gen_server</c> process crashes, the
- stacktrace for the client will be printed to facilitate
- debugging.</p>
- <p>
- Own Id: OTP-14089</p>
- </item>
- <item>
- <p>
- Optimized ETS operations by changing table identifier
- type from integer to reference. The reference enables a
- more direct mapping to the table with less potential lock
- contention and makes especially creation and deletion of
- tables scale much better.</p>
- <p>
- The change of the opaque type for the ETS table
- identifiers may cause failure in code that make faulty
- assumptions about this opaque type.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14094</p>
- </item>
- <item>
- <p><c>take/2</c> has been added to <c>dict</c>,
- <c>orddict</c>, and <c>gb_trees</c>. <c>take_any/2</c>
- has been added to <c>gb_trees</c>.</p>
- <p>
- Own Id: OTP-14102</p>
- </item>
- <item>
- <p>
- Extend gen_event API to handle options as well.</p>
- <p>
- Own Id: OTP-14123</p>
- </item>
- <item>
- <p>
- Advice on how to tune the supervisor restart frequency
- (intensity and period) is added to System Documentation -
- Design Principles - Supervisor Behaviour.</p>
- <p>
- Own Id: OTP-14168 Aux Id: PR-1289 </p>
- </item>
- <item>
- <p>
- gen_fsm is deprecated and is replaced by gen_statem,
- however for backwards compatibility reasons gen_fsm may
- continue to exist as an undocumented feature for quite
- some time.</p>
- <p>
- Own Id: OTP-14183</p>
- </item>
- <item>
- <p>The shell functions <c>c/1</c> and <c>c/2</c> have
- been extended so that if the argument is a module name
- instead of a file name, it automatically locates the
- .beam file and the corresponding source file, and then
- recompiles the module using the same compiler options
- (plus any options passed to c/2). If compilation fails,
- the old beam file is preserved. Also adds <c>c(Mod, Opts,
- Filter)</c>, where the Filter argument allows you to
- remove old compiler options before the new options are
- added.</p> <p>New utility functions <c>file_find/2/3</c>
- and <c>find_source/1/2/3</c> have been added to
- <c>filelib</c>.</p>
- <p>
- Own Id: OTP-14190</p>
- </item>
- <item>
- <p><c>erl_tar</c> in previous versions of OTP only
- supports the USTAR format. That limited path names to at
- most 255 bytes, and did not support Unicode characters in
- names in a portable way.</p>
- <p><c>erl_tar</c> now has support for reading tar
- archives in the formats currently in common use, such as
- v7, STAR, USTAR, PAX, and GNU tar's extensions to the
- STAR/USTAR format. When writing tar archives,
- <c>erl_tar</c> can now write them in the <c>PAX</c>
- format if necessary (for example, to support very long
- filenames or filenames with Unicode characters). If
- possible, <c>erl_tar</c> will still write tar archives in
- the USTAR for maximum portability.</p>
- <p>
- Own Id: OTP-14226</p>
- </item>
- <item>
- <p><c>base64:mime_decode/1</c> has been optimized so that
- it is now almost as fast as<c>base64:decode/1</c>; it
- used be noticably slower.</p>
- <p>
- Own Id: OTP-14245</p>
- </item>
- <item>
- <p><c>erl_tar</c> will now strip any leading '<c>/</c>'
- from pathnames when extracting files from a tar archive
- and write a message to the error logger. There is also
- new check for directory traversal attacks; if a relative
- path points above the current working directory the
- extraction will be aborted.</p>
- <p>
- Own Id: OTP-14278</p>
- </item>
- <item>
- <p> Miscellaneous updates due to atoms containing
- arbitrary Unicode characters. </p>
- <p>
- Own Id: OTP-14285</p>
- </item>
- <item>
- <p>
- The Crypto application now supports generation of
- cryptographically strong random numbers (floats &lt; 1.0
- and integer arbitrary ranges) as a plugin to the 'rand'
- module.</p>
- <p>
- Own Id: OTP-14317 Aux Id: PR-1372 </p>
- </item>
- <item>
- <p>
- Add new function <c>ets:select_replace/2</c> which
- performs atomic "compare-and-swap" operations for ETS
- objects using match specifications.</p>
- <p>
- Own Id: OTP-14319 Aux Id: PR-1076 </p>
- </item>
- <item>
- <p> The Erlang code linter checks for bad <c>dialyzer</c>
- attributes. It also checks for bad type variables in type
- declarations. </p>
- <p>
- Own Id: OTP-14323</p>
- </item>
- <item>
- <p> Two new functions has been implemented in the
- <c>rand</c> module; <c>normal/2</c> and
- <c>normal_s/3</c>, that both produce normal distribution
- (pseudo) random numbers with mean value and variance
- according to arguments. </p>
- <p>
- Own Id: OTP-14328 Aux Id: PR-1382 </p>
- </item>
- <item>
- <p>
- Upgraded the OTP internal PCRE library from version 8.33
- to version 8.40. This library is used for implementation
- of the <seealso marker="stdlib:re"><c>re</c></seealso>
- regular expressions module.</p>
- <p>
- Besides various bug fixes, the new version allows for
- better stack protection. In order to utilize this
- feature, the stack size of normal scheduler threads is
- now by default set to 128 kilo words on all platforms.
- The stack size of normal scheduler threads can be set
- upon system start by passing the <seealso
- marker="erts:erl#sched_thread_stack_size"><c>+sss</c></seealso>
- command line argument to the <seealso
- marker="erts:erl"><c>erl</c></seealso> command.</p>
- <p>
- See <url
- href="http://pcre.org/original/changelog.txt"><c>http://pcre.org/original/changelog.txt</c></url>
- for information about changes made to PCRE between the
- versions 8.33 and 8.40.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14331 Aux Id: ERL-208 </p>
- </item>
- <item>
- <p>
- Added function <c>re:version/0</c> which returns
- information about the OTP internal PCRE version used for
- implementation of the <c>re</c> module.</p>
- <p>
- Own Id: OTP-14347 Aux Id: PR-1412 </p>
- </item>
- <item>
- <p>The format of debug information that is stored in BEAM
- files (when <c>debug_info</c> is used) has been changed.
- The purpose of the change is to better support other
- BEAM-based languages such as Elixir or LFE.</p>
- <p>All tools included in OTP (dialyzer, debugger, cover,
- and so on) will handle both the new format and the
- previous format. Tools that retrieve the debug
- information using <c>beam_lib:chunk(Beam,
- [abstract_code])</c> will continue to work with both the
- new and old format. Tools that call
- <c>beam_lib:chunk(Beam, ["Abst"])</c> will not work with
- the new format.</p>
- <p>For more information, see the description of
- <c>debug_info</c> in the documentation for
- <c>beam_lib</c> and the description of the
- <c>{debug_info,{Backend,Data}}</c> option in the
- documentation for <c>compile</c>.</p>
- <p>
- Own Id: OTP-14369 Aux Id: PR-1367 </p>
- </item>
- <item>
- <p>
- Add option hibernate_after to gen_server, gen_statem and
- gen_event. Also added to the deprecated gen_fsm
- behaviour.</p>
- <p>
- Own Id: OTP-14405</p>
- </item>
- <item>
- <p> The size of crash reports created by
- <c>gen_server</c>, <c>gen_statem</c> and <c>proc_lib</c>
- is limited with aid of the Kernel application variable
- <c>error_logger_format_depth</c>. The purpose is to limit
- the size of the <c>error_logger</c> process when
- processes with huge message queues or states crash. </p>
- <p> The new function
- <c>error_logger:get_format_depth/0</c> can be used to
- retrieve the value of the Kernel application variable
- <c>error_logger_format_depth</c>. </p>
- <p>
- Own Id: OTP-14417</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>STDLIB 3.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index f062c7fe6e..f7bd21472c 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 3.4
+STDLIB_VSN = 3.3
diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml
index 11c37459d6..e8de0ffce2 100644
--- a/lib/syntax_tools/doc/src/notes.xml
+++ b/lib/syntax_tools/doc/src/notes.xml
@@ -32,21 +32,6 @@
<p>This document describes the changes made to the Syntax_Tools
application.</p>
-<section><title>Syntax_Tools 2.1.2</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p> Miscellaneous updates due to atoms containing
- arbitrary Unicode characters. </p>
- <p>
- Own Id: OTP-14285</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Syntax_Tools 2.1.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk
index 9b33f1e1f4..c5e363112b 100644
--- a/lib/syntax_tools/vsn.mk
+++ b/lib/syntax_tools/vsn.mk
@@ -1 +1 @@
-SYNTAX_TOOLS_VSN = 2.1.2
+SYNTAX_TOOLS_VSN = 2.1.1
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index ae2b4b00a0..bc17fd5307 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -31,35 +31,6 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
-<section><title>Tools 2.10</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- In some situations, <c>make:all()</c> and friends did not
- detect changes in include files located in the current
- directory. This is now corrected.</p>
- <p>
- Own Id: OTP-14339 Aux Id: ERL-395 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>The <c>make</c> module now accepts the
- <c>{emake,Emake}</c> option.</p>
- <p>
- Own Id: OTP-14253</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Tools 2.9.1</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 8aa7814e1d..f60da27c44 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1 +1 @@
-TOOLS_VSN = 2.10
+TOOLS_VSN = 2.9.1
diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml
index 18661d1071..9086117c81 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -32,21 +32,6 @@
<p>This document describes the changes made to the wxErlang
application.</p>
-<section><title>Wx 1.8.1</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fix a livelock that could be caused by <c>wx:batch/1</c>.</p>
- <p>
- Own Id: OTP-14289</p>
- </item>
- </list>
- </section>
-
-</section>
-
<section><title>Wx 1.8</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk
index b9100e7c87..cfa256fb12 100644
--- a/lib/wx/vsn.mk
+++ b/lib/wx/vsn.mk
@@ -1 +1 @@
-WX_VSN = 1.8.1
+WX_VSN = 1.8
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index a7592dc344..56856d026e 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -37,14 +37,16 @@
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
- <p>
- Improves accumulator fun in xmerl_scan so that only one
- #xmlText record is returned for strings which have
- character references.</p>
- <p>
- (Thanks to Jimmy Zöger)</p>
- <p>
- Own Id: OTP-14377 Aux Id: PR-1369 </p>
+ <p> A couple of bugs are fixed in the sax parser
+ (xmerl_sax_parser). </p> <list> <item>The continuation
+ function was not called correctly when the XML directive
+ was fragmented. </item> <item>When the event callback
+ modules (xmerl_sax_old_dom and xmerl_sax_simple) got an
+ endDocument event at certain conditions the parser
+ crashed.</item> <item>Replaced internal ets table with
+ map to avoid table leakage.</item> </list>
+ <p>
+ Own Id: OTP-14430</p>
</item>
</list>
</section>
diff --git a/lib/xmerl/src/xmerl_sax_old_dom.erl b/lib/xmerl/src/xmerl_sax_old_dom.erl
index fefcf03fce..411121370f 100644
--- a/lib/xmerl/src/xmerl_sax_old_dom.erl
+++ b/lib/xmerl/src/xmerl_sax_old_dom.erl
@@ -127,9 +127,10 @@ build_dom(endDocument,
State#xmerl_sax_old_dom_state{dom=[Decl, Current#xmlElement{
content=lists:reverse(C)
}]};
- _ ->
- %%?dbg("~p\n", [D]),
- ?error("we're not at end the document when endDocument event is encountered.")
+ _ ->
+ %% endDocument is also sent by the parser when a fault occur to tell
+ %% the event receiver that no more input will be sent
+ State
end;
%% Element
diff --git a/lib/xmerl/src/xmerl_sax_parser.erl b/lib/xmerl/src/xmerl_sax_parser.erl
index 1aef6c58c4..e383c4c349 100644
--- a/lib/xmerl/src/xmerl_sax_parser.erl
+++ b/lib/xmerl/src/xmerl_sax_parser.erl
@@ -64,7 +64,7 @@
%% Description: Parse file containing an XML document.
%%----------------------------------------------------------------------
file(Name,Options) ->
- case file:open(Name, [raw, read,binary]) of
+ case file:open(Name, [raw, read_ahead, read,binary]) of
{error, Reason} ->
{error,{Name, file:format_error(Reason)}};
{ok, FD} ->
@@ -120,21 +120,22 @@ stream(Xml, Options, InputType) when is_binary(Xml), is_list(Options) ->
normal ->
parse
end,
- case detect_charset(Xml, State) of
- {error, Reason} -> {fatal_error,
- {
- State#xmerl_sax_parser_state.current_location,
- State#xmerl_sax_parser_state.entity,
- 1
- },
- Reason,
- [],
- State#xmerl_sax_parser_state.event_state};
- {Xml1, State1} ->
- parse_binary(Xml1,
- State1#xmerl_sax_parser_state{input_type = InputType},
- ParseFunction)
- end
+ try
+ {Xml1, State1} = detect_charset(Xml, State),
+ parse_binary(Xml1,
+ State1#xmerl_sax_parser_state{input_type = InputType},
+ ParseFunction)
+ catch
+ throw:{fatal_error, {State2, Reason}} ->
+ {fatal_error,
+ {
+ State2#xmerl_sax_parser_state.current_location,
+ State2#xmerl_sax_parser_state.entity,
+ 1
+ },
+ Reason, [],
+ State2#xmerl_sax_parser_state.event_state}
+ end
end.
%%----------------------------------------------------------------------
@@ -156,8 +157,8 @@ parse_binary(Xml, #xmerl_sax_parser_state{encoding={utf16,big}}=State, F) ->
xmerl_sax_parser_utf16be:F(Xml, State);
parse_binary(Xml, #xmerl_sax_parser_state{encoding=latin1}=State, F) ->
xmerl_sax_parser_latin1:F(Xml, State);
-parse_binary(_, #xmerl_sax_parser_state{encoding=Enc}, _) ->
- {error, lists:flatten(io_lib:format("Charcter set ~p not supported", [Enc]))}.
+parse_binary(_, #xmerl_sax_parser_state{encoding=Enc}, State) ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Charcter set ~p not supported", [Enc]))).
%%----------------------------------------------------------------------
%% Function: initial_state/0
@@ -211,8 +212,7 @@ parse_options([{entity, Entity} |Options], State) ->
parse_options([skip_external_dtd |Options], State) ->
parse_options(Options, State#xmerl_sax_parser_state{skip_external_dtd = true});
parse_options([O |_], _State) ->
- {error,
- lists:flatten(io_lib:format("Option: ~p not supported", [O]))}.
+ {error, lists:flatten(io_lib:format("Option: ~p not supported", [O]))}.
check_encoding_option(E) when E==utf8; E=={utf16,little}; E=={utf16,big};
@@ -230,16 +230,10 @@ check_encoding_option(E) ->
%% Output: {utf8|utf16le|utf16be|iso8859, Xml, State}
%% Description: Detects which character set is used in a binary stream.
%%----------------------------------------------------------------------
-detect_charset(<<>>, #xmerl_sax_parser_state{continuation_fun = undefined} = _) ->
- {error, "Can't detect character encoding due to no indata"};
-detect_charset(<<>>, #xmerl_sax_parser_state{continuation_fun = CFun,
- continuation_state = CState} = State) ->
- case CFun(CState) of
- {<<>>, _} ->
- {error, "Can't detect character encoding due to lack of indata"};
- {NewBytes, NewContState} ->
- detect_charset(NewBytes, State#xmerl_sax_parser_state{continuation_state = NewContState})
- end;
+detect_charset(<<>>, #xmerl_sax_parser_state{continuation_fun = undefined} = State) ->
+ ?fatal_error(State, "Can't detect character encoding due to lack of indata");
+detect_charset(<<>>, State) ->
+ cf(<<>>, State, fun detect_charset/2);
detect_charset(Bytes, State) ->
case unicode:bom_to_encoding(Bytes) of
{latin1, 0} ->
@@ -249,25 +243,47 @@ detect_charset(Bytes, State) ->
{RealBytes, State#xmerl_sax_parser_state{encoding=Enc}}
end.
+detect_charset_1(<<16#00>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#00, 16#3C>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#00, 16#3C, 16#00>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
detect_charset_1(<<16#00, 16#3C, 16#00, 16#3F, _/binary>> = Xml, State) ->
{Xml, State#xmerl_sax_parser_state{encoding={utf16, big}}};
+detect_charset_1(<<16#3C>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#00>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#00, 16#3F>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
detect_charset_1(<<16#3C, 16#00, 16#3F, 16#00, _/binary>> = Xml, State) ->
{Xml, State#xmerl_sax_parser_state{encoding={utf16, little}}};
-detect_charset_1(<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml2/binary>> = Xml, State) ->
- case parse_xml_directive(Xml2) of
+detect_charset_1(<<16#3C>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#3F>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#3F, 16#78>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#3F, 16#78, 16#6D>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml2/binary>>, State) ->
+ {Xml3, State1} = read_until_end_of_xml_directive(Xml2, State),
+ case parse_xml_directive(Xml3) of
{error, Reason} ->
- {error, Reason};
+ ?fatal_error(State, Reason);
AttrList ->
case lists:keysearch("encoding", 1, AttrList) of
{value, {_, E}} ->
case convert_encoding(E) of
{error, Reason} ->
- {error, Reason};
+ ?fatal_error(State, Reason);
Enc ->
- {Xml, State#xmerl_sax_parser_state{encoding=Enc}}
+ {<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml3/binary>>,
+ State1#xmerl_sax_parser_state{encoding=Enc}}
end;
_ ->
- {Xml, State}
+ {<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml3/binary>>, State1}
end
end;
detect_charset_1(Xml, State) ->
@@ -377,7 +393,7 @@ parse_value_1(<<C, Rest/binary>>, Stop, Acc) ->
parse_value_1(Rest, Stop, [C |Acc]).
%%======================================================================
-%%Default functions
+%% Default functions
%%======================================================================
%%----------------------------------------------------------------------
%% Function: default_event_cb(Event, LineNo, State) -> Result
@@ -393,7 +409,7 @@ default_event_cb(_Event, _LineNo, State) ->
%%----------------------------------------------------------------------
%% Function: default_continuation_cb(IoDevice) -> Result
%% IoDevice = iodevice()
-%% Output: Result = {[char()], State}
+%% Output: Result = {binary(), IoDevice}
%% Description: Default continuation callback reading blocks.
%%----------------------------------------------------------------------
default_continuation_cb(IoDevice) ->
@@ -403,3 +419,82 @@ default_continuation_cb(IoDevice) ->
{ok, FileBin} ->
{FileBin, IoDevice}
end.
+
+%%----------------------------------------------------------------------
+%% Function: read_until_end_of_xml_directive(Rest, State) -> Result
+%% Rest = binary()
+%% Output: Result = {binary(), State}
+%% Description: Reads a utf8 or latin1 until it finds '?>'
+%%----------------------------------------------------------------------
+read_until_end_of_xml_directive(Rest, State) ->
+ case binary:match(Rest, <<"?>">>) of
+ nomatch ->
+ case cf(Rest, State) of
+ {<<>>, _} ->
+ ?fatal_error(State, "Can't detect character encoding due to lack of indata");
+ {NewBytes, NewState} ->
+ read_until_end_of_xml_directive(NewBytes, NewState)
+ end;
+ _ ->
+ {Rest, State}
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Function : cf(Rest, State) -> Result
+%% Parameters: Rest = binary()
+%% State = #xmerl_sax_parser_state{}
+%% NextCall = fun()
+%% Result : {Rest, State}
+%% Description: Function that uses provided fun to read another chunk from
+%% input stream and calls the fun in NextCall.
+%%----------------------------------------------------------------------
+cf(_Rest, #xmerl_sax_parser_state{continuation_fun = undefined} = State) ->
+ ?fatal_error(State, "Continuation function undefined");
+cf(Rest, #xmerl_sax_parser_state{continuation_fun = CFun, continuation_state = CState} = State) ->
+ Result =
+ try
+ CFun(CState)
+ catch
+ throw:ErrorTerm ->
+ ?fatal_error(State, ErrorTerm);
+ exit:Reason ->
+ ?fatal_error(State, {'EXIT', Reason})
+ end,
+ case Result of
+ {<<>>, _} ->
+ ?fatal_error(State, "Can't detect character encoding due to lack of indata");
+ {NewBytes, NewContState} ->
+ {<<Rest/binary, NewBytes/binary>>,
+ State#xmerl_sax_parser_state{continuation_state = NewContState}}
+ end.
+
+%%----------------------------------------------------------------------
+%% Function : cf(Rest, State, NextCall) -> Result
+%% Parameters: Rest = binary()
+%% State = #xmerl_sax_parser_state{}
+%% NextCall = fun()
+%% Result : {Rest, State}
+%% Description: Function that uses provided fun to read another chunk from
+%% input stream and calls the fun in NextCall.
+%%----------------------------------------------------------------------
+cf(_Rest, #xmerl_sax_parser_state{continuation_fun = undefined} = State, _) ->
+ ?fatal_error(State, "Continuation function undefined");
+cf(Rest, #xmerl_sax_parser_state{continuation_fun = CFun, continuation_state = CState} = State,
+ NextCall) ->
+ Result =
+ try
+ CFun(CState)
+ catch
+ throw:ErrorTerm ->
+ ?fatal_error(State, ErrorTerm);
+ exit:Reason ->
+ ?fatal_error(State, {'EXIT', Reason})
+ end,
+ case Result of
+ {<<>>, _} ->
+ ?fatal_error(State, "Can't detect character encoding due to lack of indata");
+ {NewBytes, NewContState} ->
+ NextCall(<<Rest/binary, NewBytes/binary>>,
+ State#xmerl_sax_parser_state{continuation_state = NewContState})
+ end.
diff --git a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
index f3470b2809..1dca9608cb 100644
--- a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
@@ -64,38 +64,42 @@
%% Description: Parsing XML from input stream.
%%----------------------------------------------------------------------
parse(Xml, State) ->
- RefTable = ets:new(xmerl_sax_entity_refs, [private]),
-
- State1 = event_callback(startDocument, State),
-
- case catch parse_document(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of
- {ok, Rest, State2} ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- case check_if_rest_ok(State3#xmerl_sax_parser_state.input_type, Rest) of
- true ->
- {ok, State3#xmerl_sax_parser_state.event_state, Rest};
- false ->
- format_error(fatal_error, State3, "Input found after legal document")
- end;
- {fatal_error, {State2, Reason}} ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- format_error(fatal_error, State3, Reason);
- {event_receiver_error, State2, {Tag, Reason}} ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- format_error(Tag, State3, Reason);
- {endDocument, Rest, State2} ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- {ok, State3#xmerl_sax_parser_state.event_state, Rest};
- Other ->
- _State2 = event_callback(endDocument, State1),
- ets:delete(RefTable),
- {fatal_error, Other}
+ RefTable = maps:new(),
+
+ try
+ State1 = event_callback(startDocument, State),
+ Result = parse_document(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}),
+ handle_end_document(Result)
+ catch
+ throw:Exception ->
+ handle_end_document(Exception);
+ _:OtherError ->
+ handle_end_document({other, OtherError, State})
end.
+ % case catch parse_document(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of
+ % {ok, Rest, State2} ->
+ % State3 = event_callback(endDocument, State2),
+ % case check_if_rest_ok(State3#xmerl_sax_parser_state.input_type, Rest) of
+ % true ->
+ % {ok, State3#xmerl_sax_parser_state.event_state, Rest};
+ % false ->
+ % format_error(fatal_error, State3, "Input found after legal document")
+ % end;
+ % {fatal_error, {State2, Reason}} ->
+ % State3 = event_callback(endDocument, State2),
+ % format_error(fatal_error, State3, Reason);
+ % {event_receiver_error, State2, {Tag, Reason}} ->
+ % State3 = event_callback(endDocument, State2),
+ % format_error(Tag, State3, Reason);
+ % {endDocument, Rest, State2} ->
+ % State3 = event_callback(endDocument, State2),
+ % {ok, State3#xmerl_sax_parser_state.event_state, Rest};
+ % Other ->
+ % _State2 = event_callback(endDocument, State1),
+ % {fatal_error, Other}
+ % end.
+
%%----------------------------------------------------------------------
%% Function: parse_dtd(Xml, State) -> Result
%% Input: Xml = string() | binary()
@@ -105,38 +109,120 @@ parse(Xml, State) ->
%% Description: Parsing XML DTD from input stream.
%%----------------------------------------------------------------------
parse_dtd(Xml, State) ->
- RefTable = ets:new(xmerl_sax_entity_refs, [private]),
-
- State1 = event_callback(startDocument, State),
-
- case catch parse_external_entity_1(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of
- {fatal_error, {State2, Reason}} ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- format_error(fatal_error, State3, Reason);
- {event_receiver_error, State2, {Tag, Reason}} ->
- State3 = event_callback(endDocument, State2),
- format_error(Tag, State3, Reason);
- {Rest, State2} when is_record(State2, xmerl_sax_parser_state) ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- {ok, State3#xmerl_sax_parser_state.event_state, Rest};
- {endDocument, Rest, State2} when is_record(State2, xmerl_sax_parser_state) ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- {ok, State3#xmerl_sax_parser_state.event_state, Rest};
- Other ->
- _State2 = event_callback(endDocument, State1),
- ets:delete(RefTable),
- {fatal_error, Other}
+ RefTable = maps:new(),
+
+ try
+ State1 = event_callback(startDocument, State),
+ Result = parse_external_entity_1(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}),
+ handle_end_document(Result)
+ catch
+ throw:Exception ->
+ handle_end_document(Exception);
+ _:OtherError ->
+ handle_end_document({other, OtherError, State})
end.
+ % case catch parse_external_entity_1(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of
+ % {fatal_error, {State2, Reason}} ->
+ % State3 = event_callback(endDocument, State2),
+ % format_error(fatal_error, State3, Reason);
+ % {event_receiver_error, State2, {Tag, Reason}} ->
+ % State3 = event_callback(endDocument, State2),
+ % format_error(Tag, State3, Reason);
+ % {Rest, State2} when is_record(State2, xmerl_sax_parser_state) ->
+ % State3 = event_callback(endDocument, State2),
+ % {ok, State3#xmerl_sax_parser_state.event_state, Rest};
+ % {endDocument, Rest, State2} when is_record(State2, xmerl_sax_parser_state) ->
+ % State3 = event_callback(endDocument, State2),
+ % {ok, State3#xmerl_sax_parser_state.event_state, Rest};
+ % Other ->
+ % _State2 = event_callback(endDocument, State1),
+ % {fatal_error, Other}
+ % end.
+
+
%%======================================================================
%% Internal functions
%%======================================================================
%%----------------------------------------------------------------------
+%% Function: handle_end_document(ParserResult) -> Result
+%% Input: ParseResult = term()
+%% Output: Result = {ok, Rest, EventState} |
+%% EventState = term()
+%% Description: Ends the parsing and formats output
+%%----------------------------------------------------------------------
+handle_end_document({ok, Rest, State}) ->
+ %%ok case from parse
+ try
+ State1 = event_callback(endDocument, State),
+ case check_if_rest_ok(State1#xmerl_sax_parser_state.input_type, Rest) of
+ true ->
+ {ok, State1#xmerl_sax_parser_state.event_state, Rest};
+ false ->
+ format_error(fatal_error, State1, "Input found after legal document")
+ end
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({endDocument, Rest, State}) ->
+ %% ok case from parse and parse_dtd
+ try
+ State1 = event_callback(endDocument, State),
+ {ok, State1#xmerl_sax_parser_state.event_state, Rest}
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({fatal_error, {State, Reason}}) ->
+ try
+ State1 = event_callback(endDocument, State),
+ format_error(fatal_error, State1, Reason)
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({event_receiver_error, State, {Tag, Reason}}) ->
+ try
+ State1 = event_callback(endDocument, State),
+ format_error(Tag, State1, Reason)
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({Rest, State}) when is_record(State, xmerl_sax_parser_state) ->
+ %%ok case from parse_dtd
+ try
+ State1 = event_callback(endDocument, State),
+ {ok, State1#xmerl_sax_parser_state.event_state, Rest}
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({other, Error, State}) ->
+ try
+ _State1 = event_callback(endDocument, State),
+ {fatal_error, Error}
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end.
+
+%%----------------------------------------------------------------------
%% Function: parse_document(Rest, State) -> Result
%% Input: Rest = string() | binary()
%% State = #xmerl_sax_parser_state{}
@@ -439,6 +525,7 @@ check_if_rest_ok(stream, _) ->
check_if_rest_ok(_, _) ->
false.
+
%%----------------------------------------------------------------------
%% Function: parse_pi_1(Rest, State) -> Result
%% Input: Rest = string() | binary()
@@ -883,11 +970,11 @@ send_end_prefix_mapping_event([{Prefix, _Uri} |Ns], State) ->
parse_eq(?STRING_EMPTY, State) ->
cf(?STRING_EMPTY, State, fun parse_eq/2);
parse_eq(?STRING_REST("=", Rest), State) ->
- {Rest, State};
+ {Rest, State};
parse_eq(?STRING_UNBOUND_REST(C, _) = Bytes, State) when ?is_whitespace(C) ->
- {_WS, Rest, State1} =
- whitespace(Bytes, State, []),
- parse_eq(Rest, State1);
+ {_WS, Rest, State1} =
+ whitespace(Bytes, State, []),
+ parse_eq(Rest, State1);
parse_eq(Bytes, State) ->
unicode_incomplete_check([Bytes, State, fun parse_eq/2],
"expecting = or whitespace").
@@ -905,11 +992,11 @@ parse_eq(Bytes, State) ->
parse_att_value(?STRING_EMPTY, State) ->
cf(?STRING_EMPTY, State, fun parse_att_value/2);
parse_att_value(?STRING_UNBOUND_REST(C, Rest), State) when C == $'; C == $" ->
- parse_att_value(Rest, State, C, []);
+ parse_att_value(Rest, State, C, []);
parse_att_value(?STRING_UNBOUND_REST(C, _) = Bytes, State) when ?is_whitespace(C) ->
- {_WS, Rest, State1} =
- whitespace(Bytes, State, []),
- parse_att_value(Rest, State1);
+ {_WS, Rest, State1} =
+ whitespace(Bytes, State, []),
+ parse_att_value(Rest, State1);
parse_att_value(Bytes, State) ->
unicode_incomplete_check([Bytes, State, fun parse_att_value/2],
"\', \" or whitespace expected").
@@ -1360,17 +1447,20 @@ parse_pe_reference_1(Bytes, State, Name) ->
%%----------------------------------------------------------------------
-%% Function: insert_reference(Reference, State) -> Result
-%% Parameters: Reference = string()
+%% Function: insert_reference(Name, Ref, State) -> Result
+%% Parameters: Name = string()
+%% Ref = {Type, Value}
+%% Type = atom()
+%% Value = term()
%% State = #xmerl_sax_parser_state{}
%% Result :
%%----------------------------------------------------------------------
-insert_reference({Name, Type, Value}, Table) ->
- case ets:lookup(Table, Name) of
- [{Name, _, _}] ->
- ok;
+insert_reference(Name, Value, #xmerl_sax_parser_state{ref_table = Map} = State) ->
+ case maps:find(Name, Map) of
+ error ->
+ State#xmerl_sax_parser_state{ref_table = maps:put(Name, Value, Map)};
_ ->
- ets:insert(Table, {Name, Type, Value})
+ State
end.
@@ -1391,8 +1481,8 @@ look_up_reference("apos", _, _) ->
look_up_reference("quot", _, _) ->
{internal_general, "quot", "\""};
look_up_reference(Name, HaveToExist, State) ->
- case ets:lookup(State#xmerl_sax_parser_state.ref_table, Name) of
- [{Name, Type, Value}] ->
+ case maps:find(Name, State#xmerl_sax_parser_state.ref_table) of
+ {ok, {Type, Value}} ->
{Type, Name, Value};
_ ->
case HaveToExist of
@@ -1474,7 +1564,7 @@ parse_system_litteral(?STRING_EMPTY, State, Stop, Acc) ->
parse_system_litteral(?STRING_UNBOUND_REST(Stop, Rest), State, Stop, Acc) ->
{lists:reverse(Acc), Rest, State};
parse_system_litteral(?STRING_UNBOUND_REST(C, Rest), State, Stop, Acc) ->
- parse_system_litteral(Rest, State, Stop, [C |Acc]);
+ parse_system_litteral(Rest, State, Stop, [C |Acc]);
parse_system_litteral(Bytes, State, Stop, Acc) ->
unicode_incomplete_check([Bytes, State, Stop, Acc, fun parse_system_litteral/4],
undefined).
@@ -1646,9 +1736,11 @@ parse_external_entity(State, _PubId, SysId) ->
end_tags = []},
- EventState = handle_external_entity(ExtRef, State1),
+ {EventState, RefTable} = handle_external_entity(ExtRef, State1),
- NewState = event_callback({endEntity, SysId}, SaveState#xmerl_sax_parser_state{event_state=EventState}),
+ NewState = event_callback({endEntity, SysId},
+ SaveState#xmerl_sax_parser_state{event_state=EventState,
+ ref_table=RefTable}),
NewState#xmerl_sax_parser_state{file_type=normal}.
@@ -1675,7 +1767,8 @@ handle_external_entity({file, FileToOpen}, State) ->
entity=filename:basename(FileToOpen),
input_type=file}),
ok = file:close(FD),
- EntityState#xmerl_sax_parser_state.event_state
+ {EntityState#xmerl_sax_parser_state.event_state,
+ EntityState#xmerl_sax_parser_state.ref_table}
end;
handle_external_entity({http, Url}, State) ->
@@ -1695,7 +1788,9 @@ handle_external_entity({http, Url}, State) ->
input_type=file}),
ok = file:close(FD),
ok = file:delete(TmpFile),
- EntityState#xmerl_sax_parser_state.event_state
+ {EntityState#xmerl_sax_parser_state.event_state,
+ EntityState#xmerl_sax_parser_state.ref_table}
+
end
catch
throw:{error, Error} ->
@@ -1716,7 +1811,7 @@ handle_external_entity({Tag, _Url}, State) ->
parse_external_entity_1(?STRING_EMPTY, #xmerl_sax_parser_state{file_type=Type} = State) ->
case catch cf(?STRING_EMPTY, State, fun parse_external_entity_1/2) of
{Rest, State1} when is_record(State1, xmerl_sax_parser_state) ->
- {Rest, State};
+ {Rest, State1};
{fatal_error, {State1, "No more bytes"}} when Type == dtd; Type == entity ->
{?STRING_EMPTY, State1};
Other ->
@@ -2442,24 +2537,24 @@ parse_entity_def(?STRING_EMPTY, State, Name) ->
cf(?STRING_EMPTY, State, Name, fun parse_entity_def/3);
parse_entity_def(?STRING_UNBOUND_REST(C, Rest), State, Name) when C == $'; C == $" ->
{Value, Rest1, State1} = parse_entity_value(Rest, State, C, []),
- insert_reference({Name, internal_general, Value}, State1#xmerl_sax_parser_state.ref_table),
- State2 = event_callback({internalEntityDecl, Name, Value}, State1),
- {_WS, Rest2, State3} = whitespace(Rest1, State2, []),
- parse_def_end(Rest2, State3);
+ State2 = insert_reference(Name, {internal_general, Value}, State1),
+ State3 = event_callback({internalEntityDecl, Name, Value}, State2),
+ {_WS, Rest2, State4} = whitespace(Rest1, State3, []),
+ parse_def_end(Rest2, State4);
parse_entity_def(?STRING_UNBOUND_REST(C, _) = Rest, State, Name) when C == $S; C == $P ->
{PubId, SysId, Rest1, State1} = parse_external_id(Rest, State, false),
{Ndata, Rest2, State2} = parse_ndata(Rest1, State1),
case Ndata of
undefined ->
- insert_reference({Name, external_general, {PubId, SysId}},
- State2#xmerl_sax_parser_state.ref_table),
- State3 = event_callback({externalEntityDecl, Name, PubId, SysId}, State2),
- {Rest2, State3};
+ State3 = insert_reference(Name, {external_general, {PubId, SysId}},
+ State2),
+ State4 = event_callback({externalEntityDecl, Name, PubId, SysId}, State3),
+ {Rest2, State4};
_ ->
- insert_reference({Name, unparsed, {PubId, SysId, Ndata}},
- State2#xmerl_sax_parser_state.ref_table),
- State3 = event_callback({unparsedEntityDecl, Name, PubId, SysId, Ndata}, State2),
- {Rest2, State3}
+ State3 = insert_reference(Name, {unparsed, {PubId, SysId, Ndata}},
+ State2),
+ State4 = event_callback({unparsedEntityDecl, Name, PubId, SysId, Ndata}, State3),
+ {Rest2, State4}
end;
parse_entity_def(Bytes, State, Name) ->
unicode_incomplete_check([Bytes, State, Name, fun parse_entity_def/3],
@@ -2636,19 +2731,19 @@ parse_pe_def(?STRING_EMPTY, State, Name) ->
parse_pe_def(?STRING_UNBOUND_REST(C, Rest), State, Name) when C == $'; C == $" ->
{Value, Rest1, State1} = parse_entity_value(Rest, State, C, []),
Name1 = "%" ++ Name,
- insert_reference({Name1, internal_parameter, Value},
- State1#xmerl_sax_parser_state.ref_table),
- State2 = event_callback({internalEntityDecl, Name1, Value}, State1),
- {_WS, Rest2, State3} = whitespace(Rest1, State2, []),
- parse_def_end(Rest2, State3);
+ State2 = insert_reference(Name1, {internal_parameter, Value},
+ State1),
+ State3 = event_callback({internalEntityDecl, Name1, Value}, State2),
+ {_WS, Rest2, State4} = whitespace(Rest1, State3, []),
+ parse_def_end(Rest2, State4);
parse_pe_def(?STRING_UNBOUND_REST(C, _) = Bytes, State, Name) when C == $S; C == $P ->
{PubId, SysId, Rest1, State1} = parse_external_id(Bytes, State, false),
Name1 = "%" ++ Name,
- insert_reference({Name1, external_parameter, {PubId, SysId}},
- State1#xmerl_sax_parser_state.ref_table),
- State2 = event_callback({externalEntityDecl, Name1, PubId, SysId}, State1),
- {_WS, Rest2, State3} = whitespace(Rest1, State2, []),
- parse_def_end(Rest2, State3);
+ State2 = insert_reference(Name1, {external_parameter, {PubId, SysId}},
+ State1),
+ State3 = event_callback({externalEntityDecl, Name1, PubId, SysId}, State2),
+ {_WS, Rest2, State4} = whitespace(Rest1, State3, []),
+ parse_def_end(Rest2, State4);
parse_pe_def(Bytes, State, Name) ->
unicode_incomplete_check([Bytes, State, Name, fun parse_pe_def/3],
"\", \', SYSTEM or PUBLIC expected").
diff --git a/lib/xmerl/src/xmerl_sax_simple_dom.erl b/lib/xmerl/src/xmerl_sax_simple_dom.erl
index 7eb3afd499..d842bd982b 100644
--- a/lib/xmerl/src/xmerl_sax_simple_dom.erl
+++ b/lib/xmerl/src/xmerl_sax_simple_dom.erl
@@ -129,8 +129,9 @@ build_dom(endDocument,
State#xmerl_sax_simple_dom_state{dom=[Decl, {Tag, Attributes,
lists:reverse(Content)}]};
_ ->
- ?dbg("~p\n", [D]),
- ?error("we're not at end the document when endDocument event is encountered.")
+ %% endDocument is also sent by the parser when a fault occur to tell
+ %% the event receiver that no more input will be sent
+ State
end;
%% Element
diff --git a/lib/xmerl/test/Makefile b/lib/xmerl/test/Makefile
index e5c89f84b9..3204f081ba 100644
--- a/lib/xmerl/test/Makefile
+++ b/lib/xmerl/test/Makefile
@@ -126,5 +126,6 @@ release_tests_spec: opt
@tar cfh - xmerl_xsd_MS2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
@tar cfh - xmerl_xsd_NIST2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
@tar cfh - xmerl_xsd_Sun2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
+ @tar cfh - xmerl_sax_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
@tar cfh - xmerl_sax_stream_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
chmod -R u+w "$(RELSYSDIR)"
diff --git a/lib/xmerl/test/xmerl_sax_SUITE.erl b/lib/xmerl/test/xmerl_sax_SUITE.erl
index eb9cefe0df..68b9bcc4a2 100644
--- a/lib/xmerl/test/xmerl_sax_SUITE.erl
+++ b/lib/xmerl/test/xmerl_sax_SUITE.erl
@@ -33,7 +33,6 @@
%%======================================================================
%% External functions
%%======================================================================
-
%%----------------------------------------------------------------------
%% Initializations
%%----------------------------------------------------------------------
@@ -42,12 +41,15 @@ all() ->
[{group, bugs}].
groups() ->
- [{bugs, [], [ticket_8213, ticket_8214, ticket_11551]}].
+ [{bugs, [], [ticket_8213, ticket_8214, ticket_11551,
+ fragmented_xml_directive,
+ old_dom_event_fun_endDocument_bug,
+ event_fun_endDocument_error_test,
+ event_fun_startDocument_error_test]}].
-%%----------------------------------------------------------------------
+%%======================================================================
%% Tests
-%%----------------------------------------------------------------------
-
+%%======================================================================
%%----------------------------------------------------------------------
%% Test Case
%% ID: ticket_8213
@@ -56,7 +58,6 @@ ticket_8213(_Config) ->
{ok,ok,[]} = xmerl_sax_parser:stream("<elem/>", [{event_fun, fun (_E,_,_) -> ok end}]),
ok.
-
%%----------------------------------------------------------------------
%% Test Case
%% ID: ticket_8214
@@ -99,3 +100,66 @@ ticket_11551(_Config) ->
<a>hej</a>">>,
{ok, undefined, <<"\n\n<?xml", _/binary>>} = xmerl_sax_parser:stream(Stream3, []),
ok.
+
+%%----------------------------------------------------------------------
+%% Test Case
+%% ID: fragmented_xml_directive
+%% Test of fragmented xml directive by reading one byte per continuation ca
+fragmented_xml_directive(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ Name = filename:join(DataDir, "test_data_1.xml"),
+ {ok, Fd} = file:open(Name, [raw, read,binary]),
+ Cf = fun cf_fragmented_xml_directive/1,
+ {ok, undefined, _} = xmerl_sax_parser:stream(<<>>,
+ [{continuation_fun, Cf},
+ {continuation_state, Fd}]),
+ ok.
+
+%%----------------------------------------------------------------------
+%% Test Case
+%% ID: old_dom_event_fun_endDocument_bug
+%% The old_dom backend previous generateded an uncatched exception
+%% instead of the correct fatal_error from the parser.
+old_dom_event_fun_endDocument_bug(_Config) ->
+ %% Stream contains bad characters,
+ {fatal_error, _, _, _, _} =
+ xmerl_sax_parser:stream([60,63,120,109,108,32,118,101,114,115,105,111,110,61,39,49,46,48,39,32,101,110,99,111,100,105,110,103,61,39,117,116,102,45,56,39,63,62,60,
+ 99,111,109,109,97,110,100,62,60,104,101,97,100,101,114,62,60,116,114,97,110,115,97,99,116,105,111,110,73,100,62,49,60,47,116,114,97,110,
+ 115,97,99,116,105,111,110,73,100,62,60,47,104,101,97,100,101,114,62,60,98,111,100,121,62,95,226,130,172,59,60,60,47,98,111,100,121,62,60,
+ 47,99,111,109,109,97,110,100,62,60,47,120,49,95,49,62],
+ [{event_fun,fun xmerl_sax_old_dom:event/3},
+ {event_state,xmerl_sax_old_dom:initial_state()}]),
+ ok.
+
+%%----------------------------------------------------------------------
+%% Test Case
+%% ID: event_fun_endDocument_error_test
+event_fun_endDocument_error_test(_Config) ->
+ Stream = <<"<?xml version=\"1.0\" encoding=\"utf-8\"?><a>hej</a>">>,
+ Ef = fun(endDocument, _ , _) -> throw({event_error, "endDocument error"});
+ (_, _, S) -> S
+ end,
+ {event_error, _, _, _, _} = xmerl_sax_parser:stream(Stream, [{event_fun, Ef}]),
+ ok.
+
+%%----------------------------------------------------------------------
+%% Test Case
+%% ID: event_fun_startDocument_error_test
+event_fun_startDocument_error_test(_Config) ->
+ Stream = <<"<?xml version=\"1.0\" encoding=\"utf-8\"?><a>hej</a>">>,
+ Ef = fun(startDocument, _ , _) -> throw({event_error, "endDocument error"});
+ (_, _, S) -> S
+ end,
+ {event_error, _, _, _, _} = xmerl_sax_parser:stream(Stream, [{event_fun, Ef}]),
+ ok.
+
+%%======================================================================
+%% Internal functions
+%%======================================================================
+cf_fragmented_xml_directive(IoDevice) ->
+ case file:read(IoDevice, 1) of
+ eof ->
+ {<<>>, IoDevice};
+ {ok, FileBin} ->
+ {FileBin, IoDevice}
+ end.
diff --git a/lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml b/lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml
new file mode 100644
index 0000000000..efbaee6b81
--- /dev/null
+++ b/lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<a>
+Hej
+</a>
diff --git a/lib/xmerl/test/xmerl_sax_stream_SUITE.erl b/lib/xmerl/test/xmerl_sax_stream_SUITE.erl
index a306eb66a2..7315f67374 100644
--- a/lib/xmerl/test/xmerl_sax_stream_SUITE.erl
+++ b/lib/xmerl/test/xmerl_sax_stream_SUITE.erl
@@ -40,7 +40,8 @@ all() ->
[
one_document,
two_documents,
- one_document_and_junk
+ one_document_and_junk,
+ end_of_stream
].
%%----------------------------------------------------------------------
@@ -62,6 +63,9 @@ end_per_testcase(_Func, _Config) ->
%%----------------------------------------------------------------------
%% Tests
%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Send One doc over stream
one_document(Config) ->
Port = 11111,
@@ -107,6 +111,8 @@ one_document(Config) ->
end,
ok.
+%%----------------------------------------------------------------------
+%% Send Two doc over stream
two_documents(Config) ->
Port = 11111,
@@ -152,6 +158,8 @@ two_documents(Config) ->
end,
ok.
+%%----------------------------------------------------------------------
+%% Send one doc and then junk on stream
one_document_and_junk(Config) ->
Port = 11111,
@@ -196,6 +204,13 @@ one_document_and_junk(Config) ->
ct:fail("Timeout")
end,
ok.
+
+%%----------------------------------------------------------------------
+%% Test of continuation when end of stream
+end_of_stream(Config) ->
+ Stream = <<"<?xml version=\"1.0\" encoding=\"utf-8\"?><a>hej</a>">>,
+ {ok, undefined, <<>>} = xmerl_sax_parser:stream(Stream, []),
+ ok.
%%----------------------------------------------------------------------
%% Utility functions
diff --git a/otp_versions.table b/otp_versions.table
index 1e94dcee88..e86ace6e02 100644
--- a/otp_versions.table
+++ b/otp_versions.table
@@ -1,4 +1,4 @@
-OTP-20.0 : asn1-5.0 common_test-1.15 compiler-7.1 cosProperty-1.2.2 crypto-4.0 debugger-4.2.2 dialyzer-3.2 edoc-0.9 erl_docgen-0.7 erl_interface-3.10 erts-9.0 eunit-2.3.3 hipe-3.16 inets-6.4 jinterface-1.8 kernel-5.3 megaco-3.18.2 mnesia-4.15 observer-2.4 orber-3.8.3 parsetools-2.1.5 public_key-1.4.1 reltool-0.7.4 runtime_tools-1.12 sasl-3.0.4 snmp-5.2.6 ssh-4.5 ssl-8.2 stdlib-3.4 syntax_tools-2.1.2 tools-2.10 wx-1.8.1 xmerl-1.3.14 # cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 diameter-1.12.2 eldap-1.2.2 et-1.6 ic-4.4.2 odbc-2.12 os_mon-2.4.2 otp_mibs-1.1.1 :
+OTP-19.3.5 : erts-8.3.4 xmerl-1.3.14 # asn1-4.0.4 common_test-1.14 compiler-7.0.4 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.4 debugger-4.2.1 dialyzer-3.1.1 diameter-1.12.2 edoc-0.8.1 eldap-1.2.2 erl_docgen-0.6.1 erl_interface-3.9.3 et-1.6 eunit-2.3.2 gs-1.6.2 hipe-3.15.4 ic-4.4.2 inets-6.3.9 jinterface-1.7.1 kernel-5.2 megaco-3.18.1 mnesia-4.14.3 observer-2.3.1 odbc-2.12 orber-3.8.2 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.4 percept-0.9 public_key-1.4 reltool-0.7.3 runtime_tools-1.11.1 sasl-3.0.3 snmp-5.2.5 ssh-4.4.2 ssl-8.1.3 stdlib-3.3 syntax_tools-2.1.1 tools-2.9.1 typer-0.9.12 wx-1.8 :
OTP-19.3.4 : inets-6.3.9 ssl-8.1.3 # asn1-4.0.4 common_test-1.14 compiler-7.0.4 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.4 debugger-4.2.1 dialyzer-3.1.1 diameter-1.12.2 edoc-0.8.1 eldap-1.2.2 erl_docgen-0.6.1 erl_interface-3.9.3 erts-8.3.3 et-1.6 eunit-2.3.2 gs-1.6.2 hipe-3.15.4 ic-4.4.2 jinterface-1.7.1 kernel-5.2 megaco-3.18.1 mnesia-4.14.3 observer-2.3.1 odbc-2.12 orber-3.8.2 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.4 percept-0.9 public_key-1.4 reltool-0.7.3 runtime_tools-1.11.1 sasl-3.0.3 snmp-5.2.5 ssh-4.4.2 stdlib-3.3 syntax_tools-2.1.1 tools-2.9.1 typer-0.9.12 wx-1.8 xmerl-1.3.13 :
OTP-19.3.3 : dialyzer-3.1.1 erts-8.3.3 inets-6.3.8 # asn1-4.0.4 common_test-1.14 compiler-7.0.4 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.4 debugger-4.2.1 diameter-1.12.2 edoc-0.8.1 eldap-1.2.2 erl_docgen-0.6.1 erl_interface-3.9.3 et-1.6 eunit-2.3.2 gs-1.6.2 hipe-3.15.4 ic-4.4.2 jinterface-1.7.1 kernel-5.2 megaco-3.18.1 mnesia-4.14.3 observer-2.3.1 odbc-2.12 orber-3.8.2 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.4 percept-0.9 public_key-1.4 reltool-0.7.3 runtime_tools-1.11.1 sasl-3.0.3 snmp-5.2.5 ssh-4.4.2 ssl-8.1.2 stdlib-3.3 syntax_tools-2.1.1 tools-2.9.1 typer-0.9.12 wx-1.8 xmerl-1.3.13 :
OTP-19.3.2 : erts-8.3.2 # asn1-4.0.4 common_test-1.14 compiler-7.0.4 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.4 debugger-4.2.1 dialyzer-3.1 diameter-1.12.2 edoc-0.8.1 eldap-1.2.2 erl_docgen-0.6.1 erl_interface-3.9.3 et-1.6 eunit-2.3.2 gs-1.6.2 hipe-3.15.4 ic-4.4.2 inets-6.3.7 jinterface-1.7.1 kernel-5.2 megaco-3.18.1 mnesia-4.14.3 observer-2.3.1 odbc-2.12 orber-3.8.2 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.4 percept-0.9 public_key-1.4 reltool-0.7.3 runtime_tools-1.11.1 sasl-3.0.3 snmp-5.2.5 ssh-4.4.2 ssl-8.1.2 stdlib-3.3 syntax_tools-2.1.1 tools-2.9.1 typer-0.9.12 wx-1.8 xmerl-1.3.13 :